【问题标题】:2D bin packing with predefined gaps in container容器中具有预定义间隙的 2D 装箱
【发布时间】:2017-10-08 11:21:15
【问题描述】:

我在矩形容器中优化放置不同大小和数量的矩形对象时遇到问题。该问题可以通过二维装箱算法之一完美解决,但仅限于空容器。对我来说,几乎总是不是这样。我的容器可以有一个限制的地方,不能放置任何物体。 Packing example

当然,我不是第一个遇到这种问题的人,我希望有人已经为它开发了一个好的解决方案。什么都好:书籍参考、文章、代码 sn-ps 等。 形式算法在神经网络和这类事物上更受欢迎。

【问题讨论】:

  • 根据基本算法,只需稍作调整即可将其从“普通矩形”更改为“带孔的矩形”。你想用什么?
  • 实际上我还没有选择一个,因为我不知道哪一个可以以最好的方式适应我的目的。对我来说,似乎可以使用修改后的最大矩形算法来完成任务,但我不确定。

标签: algorithm bin-packing


【解决方案1】:

解决它的一种可能方法是使用整数线性规划。有不同的模型,但这里是一个简单的模型(有一点问题,但如果需要,您可以改进)。

将问题拆分为主问题和子问题,主问题如下所示:

minimize sum(p)
s.t.
for all i: sum[j] p[j]*count[j,i] >= n[i]
p[i] >= 0 (and integer, don't add this constraint)

地点:

  • p 是决策变量,决定使用多少实例将可用项目的特定“包装”到容器中。显然有太多这些无法提前列出,但它们可以动态生成。
  • count[j,i] 是包装 j 包含项目 i 的次数。
  • n[i] 是我们想要项目 i 的次数。
  • 约束是>=,因为打包几个额外的项目是可以的,它让我们可以使用更少的不同打包(否则主要问题需要特殊的“故意不理想”打包才能满足约束)。
  • 如果您使用求解器,则不应显式添加整数约束,因为整数解决方案可能需要小数解决方案中尚不需要的列。

从每个项目的几个愚蠢的包装开始,这样肯定会有一些解决方案,尽管它可能很糟糕。您甚至可以将 一个 项放在容器中,即使不使用求解器解决子问题,这也是微不足道的,但无论如何都必须解决子问题,因此您不妨在这里重用它。

子问题是找出可以改进主问题的当前解决方案的包装。所以取master问题C的行的对偶成本(有多少种类就有多少)解决

maximize y.C
s.t.
1) for all i: y[i] <= n[i]
2) for all i: y[i] = sum[j] P[j] if j is a placement of item i
3) for all cells (a,b): sum[j] P[j] (if j covers a,b) <= 1
4) for all existing packings e: e.y <= sum(e) - 1
y >= 0 and integer
P boolean

在哪里,

  • y 是隐含变量,从 P 的选择中得出,y[i] 是项目 i 在包装中出现的次数。
  • P 是真正的决策变量,决定是否使用特定项目的特定位置。您的示例问题中有 62 个不同的项目放置,包括轮换。
  • 约束 1 确保包装实际上可以用于主要问题的整数解决方案(使用过多的项目会使相应的变量注定为小数或零)。
  • 约束 2 将 y 链接到 P
  • 约束 3 确保解决方案是有效的包装,即项目不会相互重叠。
  • 约束 4 是必要的,以避免重新创建已添加到主问题的列。

如果主问题是常规线性程序,则不会重新创建列,但它是整数程序,并且在分支约束 4 后需要明确防止重新创建。例如,在“低”分支上(回想一下,这意味着我们取了一些变量k,它有一个小数值f,并将其限制为&lt;= ⌊f⌋),子问题尝试做的第一件事是重新创建与k 完全相同的包装,以便可以将其添加到主问题中以“撤消损坏”。这与我们需要的完全相反。所以必须禁止重新创建一个列。

约束 4 不是一个很好的方法,因为现在子问题将尝试生成所有 等效 包装,这要归功于对称性。例如,对这个包装的变量进行四舍五入后:

它会生成类似这样的等效包装:

等等。这些有很多,而且它们都毫无意义,因为这并不重要(对于主问题的客观价值,当考虑整数约束时)在哪里 1x3 块,重要的是包装包含一个 1x3 件和 14 个 1x1 件。

因此,理想情况下,约束 4 将被更复杂的东西取代,它禁止包装 等效 与以前的任何东西相同,但其他最有效的方法是首先尝试高分支。至少在这个例子中,效果很好。

在此示例中,在添加允许主问题最优的列之后(但仍然是分数,在任何分支之前),目标值为 5.5882352941176467。这已经意味着我们知道我们至少需要 6 个容器,因为这是最佳的小数值证明它不能用 5 来完成,并且小数容器不是一个选项。

很快找到了一个6个容器的解决方案,即

其中三个:

以下各一个:

其中包含所有部件以及额外的 1x4 部件和 3 个额外的 1x1 部件。

这个算法不太依赖碎片或容器的形状,除了它们必须可以表示为网格上的单元格。容器可以到处都有孔,碎片可以更像俄罗斯方块,甚至有不连贯的部分。一个缺点是它需要的展示位置列表会随着容器的大小而严重扩展。

【讨论】:

  • 从阅读到正确理解它需要一些时间。谢谢。
  • @Dmytro 运气好吗?如果需要,我可以解释更多
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-30
  • 2013-08-16
  • 2023-04-01
  • 2018-07-03
  • 2022-12-12
相关资源
最近更新 更多