【发布时间】:2008-10-06 13:47:22
【问题描述】:
将一维长度嵌套到预定义的库存长度中的有效算法是什么?
例如,如果您需要以下数量和长度的钢筋,
- 5 x 2 米
- 5 x 3 米
- 5 x 4 米
这些可以从 10 米长的钢筋上切割下来。 您如何计算切割 10m 钢筋的模式,以便使用最少的钢筋?
此外,您如何将多个库存长度合并到算法中?
我有一些时间来解决这个问题,所以我将写下我是如何解决它的。我希望这对某人有用。我不确定这样回答我自己的问题是否可以。如果更合适,版主可以将其更改为答案。
首先感谢所有回答的人。这为我指出了适当的算法; the cutting stock problem.
这篇文章也很有用; "Calculating a cutting list with the least amount of off cut waste".
好的,继续解决。
我将在我的解决方案中使用以下术语;
- 库存:将被切成小块的一段材料
- 剪切:从库存中剪切的一段材料。可以从同一个库存中进行多次切割
- 浪费:所有切割完成后留在一块库存中的材料长度。
解决问题主要分为三个阶段,
- 确定所有可能的切割组合
- 确定可以从每个库存中提取哪些组合
- 找到切割组合的最佳组合。
第 1 步
有 N 个切割,有 2^N-1 个独特的切割组合。这些组合可以表示为二进制真值表。
其中 A、B、C 是独特的切割;
A B C | Combination
-------------------
0 0 0 | None
0 0 1 | C
0 1 0 | B
0 1 1 | BC
1 0 0 | A
1 0 1 | AC
1 1 0 | AB
1 1 1 | ABC
带有一些位运算符的 for 循环可用于快速创建每个剪切组合的分组。
对于较大的 N 值,这可能会非常耗时。
在我的情况下,同一剪辑有多个实例。这产生了重复的组合。
A B B | Combination
-------------------
0 0 0 | None
0 0 1 | B
0 1 0 | B (same as previous)
0 1 1 | BB
1 0 0 | A
1 0 1 | AB
1 1 0 | AB (same as previous)
1 1 1 | ABB
我能够利用这种冗余来减少计算组合的时间。我将重复的剪辑组合在一起,并计算了该组的独特组合。然后,我将此组合列表附加到第二组中的每个唯一组合以创建一个新组。
以AABBC为例,流程如下。
A A | Combination
-------------------
0 1 | A
1 1 | AA
呼叫此组 X。
将 X 附加到 B 的唯一实例,
B B X | Combination
-------------------
0 0 1 | A
| AA
0 1 0 | B
0 1 1 | BA
| BAA
1 1 0 | BB
1 1 1 | BBA
| BBAA
将此组称为 Y。
将 Y 附加到 C 的唯一实例,
C Y | Combination
-----------------
0 1 | A
| AA
| B
| BA
| BAA
| BB
| BBA
| BBAA
1 0 | C
1 1 | CA
| CAA
| CB
| CBA
| CBAA
| CBB
| CBBA
| CBBAA
此示例生成 17 个唯一组合,而不是 31 个 (2^5-1)。节省了将近一半。
一旦确定了所有组合,就该检查它是否适合库存。
第 2 步
此步骤的目的是将步骤 1 中确定的切割组合映射到可用的库存尺寸。
这是一个相对简单的过程。 对于每个剪切组合,
calculate the sum of all cut lengths.
for each item of stock,
if the sum of cuts is less than stock length,
store stock, cut combination and waste in a data structure.
Add this structure to a list of some sort.
这将产生一个有效嵌套剪切组合的列表。 存储废料并不是绝对必要的,因为这可以根据切割长度和库存长度计算得出。但是,储存废物会减少第 3 步所需的处理。
第 3 步
在此步骤中,我们将确定产生最少浪费的切割组合。这基于步骤 2 中生成的有效嵌套列表。
在理想世界中,我们会计算所有可能性并选择最好的一个。对于任何非平凡的削减集,都需要永远计算它们。我们只需要对非最优解决方案感到满意。 有多种算法可以完成这项任务。
我选择了一种方法,可以寻找浪费最少的巢穴。它将重复此操作,直到计算完所有削减。
从三个列表开始
- cutList:所有必需剪辑的列表(包括重复剪辑)。
- nestList:在第 2 步中生成的巢列表。这是从最低废物到最高废物排序的。
- finalList:最初为空,这将存储将输出给用户的剪切组合列表。
方法
pick nest from nestList with the least waste
if EVERY cut in the nest is contained in cutList
remove cuts from cutList
copy this nest into the finalList
if some cuts in nest not in cutList
remove this nest from nestList
repeat until cutlist is empty
使用这种方法,我设法将一些典型的测试数据总共浪费了大约 2-4%。希望我能在某个时候重新审视这个问题,并尝试实施Delayed column generation 算法。这应该会产生更好的结果。
我希望这可以帮助其他遇到此问题的人。
大卫
【问题讨论】:
-
这读起来很像家庭作业问题......
-
也许这不是家庭作业——这很像一个实际的工业问题,我在 1990 年左右编写了一个程序
-
我使用了不同的算法。它的结果可以在wood-cut.rhcloud.com 看到。它没有给出最佳解决方案,因为它需要枚举方法,但给出了可接受的解决方案。我见过一些软件以超过 50 美元的价格提供此功能并使用遗传算法,并且不保证最佳解决方案,有时甚至给出比 wood-cut.rhcloud.com 更差的结果。我正在努力优化我的网站,并会在有时间时编写该算法。
标签: algorithm