假设我们有几个相同大小的正方形。我们想要绘制n
矩形(这里是红色和黄色矩形)来包含这些方块。
目标是尽可能减少空间浪费。
在下面的示例中,n = 2
和右侧的解决方案是首选,因为它只会导致一个浪费的空间。
是否已有任何已知算法可以解决这类问题?
更新 正方形的排列是任意的,它们总是在X轴之上!
UPDATE2: 为了使问题更容易,我们假设所谓的容器矩形是彼此重叠的! (这里有红色和黄色矩形)
一个更复杂的案例: 我们假设这个也使用了两个矩形。可以看出,第三种解决方案导致空间浪费最少。
答案 0 :(得分:2)
这个问题几乎与ITA Software提出的招聘难题相同,称为"Strawberry Fields"(向下滚动草莓田;将温室成本从10改为0)。我可以确认整数编程,特别是branch and price,其中高级决策是否将两个正方形放在同一个矩形中,对于这个问题非常有效。这是我的custom solver,用C语言编写。您需要将strawberry_fields.h
中的温室成本从10改为0.
答案 1 :(得分:1)
这种类型的矩形覆盖很难(NP-hard实际上,你可以用它来解决矩形覆盖问题),但你可以用整数线性编程来解决这个问题,如下所示:
minimize sum[i] take[i] * area[i]
st
sum[i] take[i] == n
for every filled cell x,y:
sum[rectangle i covers x,y] take[i] == 1
take[i] in { 0, 1 }
矩形列表仅包含您可能需要的“合理”矩形。也就是说,只有在不露出一些填充的单元格的情况下才能制作得更小的矩形,并且你可以跳过某些“内部矩形”,你可以告诉它们永远不能成为解决方案的一部分,因为它们会留下一个难以覆盖的形状。生成这些矩形本身就是一项有趣的练习,但生成太多并不是一个大问题,只是速度较慢。在解决方案中,任何1的take[i]
都对应于您所采用的矩形。
您可以将其投入任何可用的解算器,例如GLPK(免费)或Gurobi(可获得商业和学术许可)。
这通常应该比蛮力更快,因为线性松弛(与上面相同的模型,但最后一个约束转换为0 <= take[i] <= 1
)可以用来指导搜索,并且可以应用各种平面切割技巧
在this paper中可以找到更高级的技巧,例如使用线性松弛的分数解的技巧。