奇怪但实用的2D装箱优化
问题内容:
我正在尝试编写一个为分隔面板生成图形的应用程序。
我有N个小隔间(二维矩形)(N <= 40)。对于每个隔间,都有一个最小高度(minHeight [i])和最小宽度(minWidth
[i])关联。面板本身也具有MAXIMUM_HEIGHT约束。
这些N个小卧室必须布置在列式网格中,以便每个小卧室都满足上述约束。
同样,每列的宽度由该列中每个小隔间的minWidths最大值确定。
另外,每列的高度应相同。这决定了面板的高度
我们可以在任何列的剩余空间中添加备用柜,也可以将任何柜的高度/宽度增加到指定的最小值以下。但是,我们不能旋转任何隔间。
OBJECTIVE: TO MINIMIZE TOTAL PANEL WIDTH.
目前,我只是通过在优化中忽略小隔间的宽度来实现它。我只是选择具有最大minHeight的小隔间,然后尝试使其适合我的面板。但是,它不能保证最佳解决方案。
我能比这更好吗?
编辑1:面板的MAXIMUM_HEIGHT = 2100mm,最小宽度范围(350mm至800mm),最小高度范围(225mm至2100mm)
编辑2:问题目的:最小化面板宽度(不是面板区域)。
问题答案:
公式
鉴于:
- 对于每个单元格
i = 1, ..., M
,(最小)宽度W_i
和(最小)高度H_i
- 任何堆栈的最大允许高度,
T
我们可以制定混合整数程序,如下所示:
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