我发现了一个问题,即找到一种算法来优化将一段管道切割成更小的不同长度。 例如,您有10米的标准管道,您需要切割以下部分: 4件0.7米 3件2.1米 7米中的7米 等等 目标是尽可能找到最佳的订单,以便将废物保持在最低限度。
我有一个解决方案,但我不确定它是最好的。 首先,我创建一个具有所有长度的堆栈(stack1),按大小排序,顶部的值越大。 我定义了一个空的辅助堆栈stack2 数组管[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
总结一下:它总是试图削减所需的最大部分。如果它不能进入下一个项目,依此类推。当试用完的物品耗尽时,它会以一个新的"处女"标准的管道长度。
这似乎有效,但我想知道它是否可以改进。有没有办法确定最佳解决方案是什么?
答案 0 :(得分:3)
这与Bin Packing Problem完全相同,您选择的算法“有时称为第一次拟合递减算法” 1 。该算法专为速度而设计,但并不总能产生最佳解决方案。
答案 1 :(得分:2)
这是切割库存问题。用户3386109指出,您的算法不会产生最佳解决方案。它也是NP难的,因为箱子包装可以减少到切割库存。
作为您的算法不是最优的原因的一个示例,假设您的管道长度为100,您需要切割四个34长管道和八个33长管道。正确的做法是将三个管道分成两个33和34个。然而,你的第一个方法是将两个管道分成两个34,两个管道分成三个33,一个管道分成两个33。
如果没有很多有用的方法来切割管道(比如说,最多只有几千个),你可以全部枚举它们,你会得到一个通常不太难解决的不平等背包问题。如果有更多有用的方法来切割管道,有一种着名的柱生成方法,因为Gilmore和Gomory在实践中很有用。