一种算法,用于将值列表分类为n个组,以便每个组的总和尽可能接近

时间:2011-03-09 16:35:10

标签: algorithm language-agnostic mathematical-optimization

基本上我有很多值需要分成n个不同的组,以便每组的总和尽可能接近其他组的总和?值列表并不是非常长,所以我可能只是暴力强迫它,但我想知道是否有人知道这样做更有效的方法。感谢。

5 个答案:

答案 0 :(得分:7)

如果近似解是足够的,那么将数字降序排序,循环遍历它们并将每个数字分配给具有最小总和的组。

groups = [list() for i in range(NUM_GROUPS)]
for x in sorted(numbers, reverse=True):
    mingroup = groups[0]
    for g in groups:
        if sum(g) < sum(mingroup):
           mingroup = g
    mingroup.append(x)

答案 1 :(得分:3)

这个问题被称为“多路分区问题”,实际上计算难度很大。谷歌搜索它返回了一篇有趣的论文"Multi-Way Number Paritioning,其中作者提到larsmans建议的启发式,并提出了一些更高级的算法。如果上述启发式还不够,你可以查看论文或者可能联系作者,他似乎正在那个领域进行研究。

答案 2 :(得分:1)

蛮力可能不会像你想象的那样有效......

假设您有100个变量和20个群组:

  • 您可以将1变量放入20个不同的组中,这样可以20组合。
  • 您可以将2个变量分别放入20个不同的组中,这样就可以20 * 20 = 20^2 = 400组合。
  • 您可以将3个变量分别放入20个不同的组中,这样就可以20 * 20 * 20 = 20^3 = 8000组合。
  • ...
  • 您可以将100个变量分别放入20个不同的组中,这会产生20^100个组合,这超过了已知Universe中的最小原子数(10^80 )。

好的,你可以做得更聪明一点(无论你把第一个变量放在哪里,......)都可以得到像分支和绑定这样的东西,但是那个仍然可以扩展

因此要么使用快速确定性算法,如larsman提议。 或者,如果您需要更优化的解决方案并有时间实现它,请查看元启发式算法和实现它们的软件(例如Drools Planner)。

答案 3 :(得分:1)

您可以将数字相加并除以组数。这为您提供了总和的目标值。对数字进行排序,然后尝试获取子集以合计所需的总和。从可能的最大值开始,因为它们将导致总和中的最大变化。一旦您确定了一个不是最佳总和(但接近)的组,您可以重新计算剩余数字的预期总和(超过n-1组),以最小化其余组的最优RMS偏差(如果这是一个度量标准)你关心的)。将这个“预期总和”概念与larsmans答案结合起来,你应该有足够的信息来得出一个快速的近似答案。没有什么是最佳的,但远比随机和运行时间有限。

答案 4 :(得分:1)

您是否知道需要多少组才能提前将其拆分?

您对组的最大大小有限制吗?

针对此问题的变体的一些算法: