是否有一种有效的算法将几组数字打包到几个桶中?

时间:2012-11-04 15:01:18

标签: java algorithm set

例如,您有几个double的列表,您需要在几个"桶中分发"固定大小(桶大小也是double)。还有两个附加限制:

  • 某些列表中的值只能转到某些(预先指定的)存储桶:

    bucket1 <-\
               |--- list1
              /
             /
    bucket2 <--\
    bucket3 <---- list2
    bucket4 <--/
    
    bucket5 <--- list3
    
  • 生成的分布必须尽可能均匀(以便所有存储桶的加载因子为0.5)。

此类问题的具体示例:想象一下,如果您有多个电源单元(&#34;桶和#34;)和几个灯板。每个供电单元连接到一个或多个板,每个供电单元具有不同的容量,灯消耗不同的能量。如果某个电路板连接到多个电源单元,那么您可以指定&#34;分配&#34;一些灯首先供电,一些 - 第二,等等。

对于大量元素,使用强力执行此操作很快就变得不可行。

有一种有效的方法吗?

编辑:我设计了以下方法 - 这似乎很快就会收集到所需的结果。这个想法如下:

  • 首先,对于每个列表,我使用最小负载桶启发式将项目分配到允许的桶中。
  • 然后,我执行以下操作:
      每个列表
      • 从分组中删除与列表对应的项目
      • 使用相同的负载最小的启发式
      • 再次分发它们
      • 计算最大装载铲斗尺寸与最小装载(允许铲斗)的比率
    • 如果比率小于某个常数(我用了1.02),或者如果步数太多,则终止循环。

一般的想法是&#34;顺利&#34;桶直到分布变得足够平坦,这通常意味着我们达到了所需的目标。

这是一个好的算法吗?

2 个答案:

答案 0 :(得分:2)

听起来像bin packing problem或带有附加约束的背包问题(某些列表只能转到特定的存储桶),您希望解决方案将所有存储桶填充到至少一个特定的加载因子。说到“有效”,我会说你所描述的应该是NP难的(“应该”因为我没有时间考虑从NP问题减少到你的具体问题但我很确定有一个)。

您可以尝试的方法:首先解决约束问题并确定哪些线路可以进入哪些存储桶,然后贪婪地填充存储桶。如果您的约束很难,您可以进行回溯。

答案 1 :(得分:1)

简答:不。它是NP-Complete。有关更多信息,请阅读这些wikipedias:

http://en.wikipedia.org/wiki/Bin_packing_problem

http://en.wikipedia.org/wiki/Knapsack_problem