bin-packing任务的修改版本的最佳解决方案

时间:2012-06-02 00:00:25

标签: algorithm backtracking greedy

问题

假设我们有一组 N 实数 A = {x_1,x_2,...,x_N}

目标是将此集合划分为 A_1,A_2,...,A_L 子集,其限制为 sum(A_i)< = T 最小化这个词:

成本:=总和(abs(sum(A_i) - T))

其中 sum(A_i)表示 A_i 中的数字总和, T 是给定的阈值。

我正在寻找一种非进化的最优算法。

更新: x_i 是真正的正数且不大于 T 0< x_i< = T )。

更新2:修复了费用功能。


很好的尝试,贪心算法!

一个简单的想法是使用Greedy方法来解决问题。这是一个伪代码:

 1. create subset A_1 and set i=1.
 2. remove the largest number x from A.
 3. If sum(A_i) + x <= T
  * put x into A_i
 4. Else
  * create a new subset A_i+1, 
  * put x into A_i+1 
  * set i=i+1
 5. If A is non-empty
  * goto step 2.
 6. Else
  * return all created A_i s

问题是这个解决方案不是最优的。例如,有些情况下最好不要在第一个子集 A_1 中放入两个最大的数字 x1 x2 ,即使他们没有超过 T ,因为没有其他* x_i *可用于添加到该集合并使其总和更接近 T 。另一方面,如果我们将 x1 x2 放在单独的集合中,则可以找到更好的解决方案(具有较小成本的解决方案值)。

可能的解决方案

我曾想过使用Backtracking算法也可以找到最佳解决方案,但我想这个问题的复杂性会很高。

我在维基百科上读过一些文章,如Bin packing problem(NP-hard [叹气......] )和Cutting stock problem,显然我的问题与此标准非常相似问题,但我不确定哪一个符合我的情况。

1 个答案:

答案 0 :(得分:2)

<强>更新 使用校正的成本函数,请注意,总和(A_i) - T将始终为负,因为A_i <= T。 所以我们的目标是尽量减少

sum(abs(sum(A_i)-T))= sum(T-sum(A_i))= L * T-sum(A)

sum(A)是常数,因此任务是尽量减少使用的箱数。因此,您的问题相当于经典的垃圾箱包装。

要解决此问题,您可以使用像this one这样的bin打包解算器。