【问题标题】:Algorithm for pipe cutting optimization切管优化算法
【发布时间】:2014-05-28 21:57:01
【问题描述】:

我遇到了一个问题,即寻找一种算法来优化将一段管道切割成更小、不同的长度。 例如,您有 10 米的标准管道,您需要切割以下几块: 4片0.7米 3片2.1米 7 米 5 米 等等 目标是不断找到最佳的切割顺序,从而将浪费降至最低。

我有一个解决方案,但我不确定它是否是最好的。 首先,我制作了一个包含所有长度的堆栈(stack1),按大小排序,顶部的值较大。 我定义了一个空的辅助堆栈 stack2 数组 pipe[n][m] 存储结果。 n 是管道编号,m 是要从该管道切割的长度。 然后我执行以下过程(这是伪代码):

i=0
j=0
while(stack1 in not empty or stack2 is not empty)
    a=pop(stack1)
    if(a==null)
        push(stack2,stack1) ;push stack2 into stack1
        sort(stack1)
        i=i+1
        j=0
        a=pop(stack1)
    if(a fits in pipe[i])
        pipe[i][j++]=a   ;this just means that 'a' will be cut from this pipe
    else
        push(a,stack2)   ;if it doesnt fit, save it for later

总而言之:它总是尝试尽可能切割最大的请求部分。当它不能时,它会转到下一个项目,依此类推。当它用完要尝试的项目时,它会从一个新的“原始”标准管道长度开始。

这似乎可行,但我想知道它是否可以改进。有没有办法确定最好的解决方案是什么?

【问题讨论】:

  • 这听起来很像背包问题(计算机科学中的一个 NP 难题)。
  • 如果上述代码有效并且您正在寻找优化它的方法,那么您的问题可能更适合Code Review
  • 更新:我尝试了一种变体,如果超出值不为零,则尝试重复操作,稍后省略第二大块,如果它仍然大于零,则省略第三块最大的,等等。这给出了不同的分布,但总是完全相同的整体性能(除了需要更长的计算时间)。

标签: algorithm optimization


【解决方案1】:

这与Bin Packing Problem 完全相同,您选择的算法是“有时称为首次拟合递减算法”1。该算法是为提高速度而设计的,但并不总是产生最佳解决方案。

1引用自linked wikipedia article

【讨论】:

  • 具体来说,请参阅引用 MTP 的“精确算法”部分。
【解决方案2】:

这是切割库存问题。正如 user3386109 所指出的,您的算法不会产生最佳解决方案。它也是 NP 难的,因为可以将箱包装减少到切割库存。

举例说明您的算法为何不是最优的,假设您的管道长度为 100,您需要切割四根 34 长度的管道和八根 33 长度的管道。正确的做法是将三个管道切割成两个 33 和一个 34。但是,您的第一次拟合方法会将两个管道切割成两个 34,将两个管道切割成三个 33,并将一个管道切割成两个 33。

如果没有很多有用的方法来切割管道(例如,最多几千个),您可以将它们全部列举出来,您会得到一个通常不太难解决的不等式背包问题。如果有更多有用的方法来切割管道,那么 Gilmore 和 Gomory 提出的著名的列生成方法在实践中很有用。

【讨论】:

    猜你喜欢
    • 2011-05-20
    • 1970-01-01
    • 2016-07-30
    • 2023-02-03
    • 1970-01-01
    • 2020-02-09
    • 2015-11-05
    • 2015-10-25
    相关资源
    最近更新 更多