【问题标题】:1-dimensional nesting algorithm一维嵌套算法
【发布时间】: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. 确定所有可能的切割组合
  2. 确定可以从每个库存中提取哪些组合
  3. 找到切割组合的最佳组合。

第 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


【解决方案1】:

实际上,还有一个更具体的问题适用:cutting stock problem

裁切问题是一个 优化问题,或更多 具体来说,一个整数线性 编程问题。它源于 工业中的许多应用。想象 你在造纸厂工作,你 有几卷纸 固定宽度等待切割,然而 不同的客户想要不同的 各种尺寸的卷数 宽度。你打算怎么剪 滚动,以便您最大限度地减少浪费 (剩余的数量)?

这比装箱问题更适用的原因是因为您正在尝试尽量减少浪费,而不是尽量减少“箱”的数量。从某种意义上说,装箱问题是切料问题的逆问题:如何将一定长度的钢材重新组装成一定尺寸的尽可能少的钢筋?

【讨论】:

    【解决方案2】:

    【讨论】:

    • 嘿底座,很好的答案。编辑您的答案以显示它而不是留在 cmets 中可能值得编辑
    【解决方案3】:

    感谢您提出垃圾箱包装问题底座的建议。这导致我到以下帖子, Calculating a cutting list with the least amount of off cut waste。这似乎很好地涵盖了我的问题

    【讨论】:

      【解决方案4】:

      解决了与几年前类似的问题。我最终使用了遗传算法。对于小问题,这将是矫枉过正。回到 16 位时代,这个程序写起来有些有趣,但同时也不好玩。

      首先,它列出了使用给定长度切割 10 英尺原材料的所有方法。记录每一种材料的浪费量。 (虽然它是快速数学,但存储这些以供以后查找更快。)然后它查看了所需部分的列表。在一个循环中,它将从切割方式列表中选择一种切割方式,该方式不会切割超过所需尺寸的任何尺寸。贪心算法会选择一个浪费最少的算法,但有时可以通过放松这一点找到更好的解决方案。最终,遗传算法做出了选择,“DNA”是一些在过去的解决方案中表现良好的切割方法。

      所有这一切都可以追溯到互联网出现之前的时代,是通过聪明和实验破解的。这些天来,可能有一些 .NET 或 java 库的东西已经被黑盒化了——但这会少一些乐趣和少一些教育,不是吗?

      【讨论】:

      • 你能指出我正确的方向吗...因为我想实施这个解决方案(遗传)...我尝试了蛮力方式...但有时需要很长时间。 ..
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-22
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多