【问题标题】:Is there an efficient algorithm to pack several sets of numbers into several buckets?是否有一种有效的算法可以将多组数字打包到几个桶中?
【发布时间】:2012-11-05 01:11:20
【问题描述】:

例如,您有多个doubles 列表,您需要将它们分布在几个固定大小的“桶”中(桶大小也是double)。还有两个额外的限制:

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

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

此类问题的具体示例:假设您有多个电源单元(“桶”)和几块灯板。每个供电单元连接到一个或多个板,每个供电单元的容量不同,灯消耗的能量不同。如果某个板子连接到多个电源单元,那么您可以将一些灯“分配”到第一个电源,一些 - 到第二个,等等。

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

有没有有效的方法?

编辑:我设计了以下方法 - 它似乎很快就收敛到所需的结果。思路如下:

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

一般的想法是“平滑”桶,直到分布变得足够平坦,这通常意味着我们达到了所需的目标。

这是一个好的算法吗?

【问题讨论】:

    标签: java algorithm set


    【解决方案1】:

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

    你可以尝试什么:首先解决约束问题并确定哪些行可以进入哪些桶,然后贪婪地填充桶。如果你的约束很难,你可以做回溯。

    【讨论】:

    • 我想我做了一些关于“贪婪地填满水桶”的事情,但做了一些修改 - 请参阅我的编辑。你怎么看?
    • 我认为这听起来是一个很好的初始方法。不过,我会做以下事情: 1. 对列表进行分类并确定它们可以放在哪些桶中; 2. 用最不完整的启发式填充桶,并用适用的最大列表填充它; 3.当所有list都分发完毕后,对于每个未填充到指定负载因子的bucket,从最大bucket中添加一个list。
    • 遗憾的是,没有指定的负载因子 - 我需要最小化跨桶的最大负载因子。
    • 啊,我明白了;那么你可以在 3 内把桶里的东西弄平。祝你好运!
    【解决方案2】:

    简短的回答:不。这是NP完全的。如需更多信息,请阅读以下维基百科:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-17
      • 2019-10-21
      相关资源
      最近更新 更多