我正在尝试编写一个为分区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:问题目标:最小化面板宽度(不是面板区域)。
答案 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。问题已经很困难但是隔间可以共享宽度或高度。因此搜索空间变大了。