奇怪但实用的2D箱包装优化

时间:2013-08-30 16:12:49

标签: algorithm math optimization knapsack-problem

Sample Sub-optimal output

我正在尝试编写一个为分区Panel生成绘图的应用程序。

我有N个小隔间(2D矩形)(N <= 40)。对于每个隔间,存在最小高度(minHeight [i])和最小宽度(minWidth [i])。面板本身也有一个MAXIMUM_HEIGHT约束。

这些N小隔间必须以列式网格排列,以便满足每个隔间的上述限制。

此外,每列的宽度由该列中每个隔间的最大minWidth决定。

此外,每列的高度应相同。这决定了面板的高度

我们可以在任何列的左侧空白处添加备用隔间,或者我们可以将任何隔间的高度/宽度增加到指定的最小值以外。但是我们无法旋转任何隔间。

OBJECTIVE: TO MINIMIZE TOTAL PANEL WIDTH.

目前我只是通过忽略优化中的小隔间宽度来实现它。我只选择具有最大minHeight的隔间并尝试将其放入我的面板中。但是,它并不保证最佳解决方案。

我能比这更好吗?

编辑1:面板的最大高度= 2100mm,最小宽度范围(350mm至800mm),最小高度范围(225mm至2100mm)

编辑2:问题目标:最小化面板宽度(不是面板区域)。

3 个答案:

答案 0 :(得分:7)

制剂

假设:

  • 表示每个单元格i = 1, ..., M,(最小)宽度W_i和(最小)高度H_i
  • 任何堆栈的最大允许高度T

我们可以按如下方式制定混合integer program

minimize sum { CW_k | k = 1, ..., N }
with respect to

    C_i in { 1, ..., N },                        i = 1, ..., M

    CW_k >= 0,                                   k = 1, ..., N

and subject to

[1] sum { H_i | C_i = k } <= T,                  k = 1, ..., N

[2] CW_k = max { W_i | C_i = k },                k = 1, ..., N
           (or 0 when set is empty)

您可以选择N为任意足够大的整数(例如N = M)。

算法

将此混合整数程序插入现有的混合整数程序求解器,以确定最佳C_i, i = 1, ..., M值给出的单元到列映射。

这是你不想重塑自己的部分。使用现有的求解器!

注意

根据混合整数程序求解程序包的表达能力,您可能会或可能无法直接应用上述配方。如果由于基于“基于集合”的性质或[1]而无法指定约束[2]max,则可以手动将公式转换为等效不那么陈述但更规范的,不需要这种表达能力:

minimize sum { CW_k | k = 1, ..., N }
with respect to

    C_i_k in { 0, 1 },                           i = 1, ..., M; k = 1, ..., N

    CW_k >= 0,                                   k = 1, ..., N

and subject to

[1] sum { H_i * C_i_k | i = 1, ..., M } <= T,    k = 1, ..., N

[2] CW_k >= W_i * C_i_k,                         i = 1, ..., M; k = 1, ..., N

[3] sum { C_i_k | k = 1, ..., N } = 1,           i = 1, ..., M

以前的C_i变量(取{ 1, ..., N }中的值)已替换为C_i_k变量(在{ 0, 1 }中取值)C_i = sum { C_i_k | k = 1, ..., N } }。

最后的单元格到列的映射由C_i_k:单元格i属于k列描述,当且仅当C_i_k = 1

答案 1 :(得分:2)

一种解决方案是将隔间行的宽度除以最小宽度。这为您提供了可以放入一行的最大小隔间数。

将第一个分度的剩余部分除以小隔间数。这为您提供了额外的宽度,可以添加到最小宽度,使所有小隔间宽度均匀。

示例:您有一个63米的隔间行。每个隔间的最小宽度为2米。我假设其中一个隔间墙的厚度包含在2米内。我还假设一个小隔间靠墙。

进行数学计算,得到63/2 = 31.5或31个小隔间。

现在我们划分0.5米乘31个小隔间,得到16毫米。因此,隔间宽度为2.016米。

答案 2 :(得分:2)

您可以查看vm打包,特别是用于虚拟机并置的共享感知算法:http://dl.acm.org/citation.cfm?id=1989554。您还可以阅读@ http://en.m.wikipedia.org/wiki/Bin_packing_problem。问题已经很困难但是隔间可以共享宽度或高度。因此搜索空间变大了。