将任意数据数组分组为N个bin

时间:2012-03-02 23:47:44

标签: python algorithm sorting

我想将任意大小的随机值数组分组到n组中,这样任何一个组/ bin中的值之和尽可能相等。

因此,对于值[1, 2, 4, 5]n = 2,输出存储区应为[sum(5+1), sum(4+2)]

我遇到的一些可能性:

  • 完全无穷无尽的广度优先搜索
  • 具有硬编码的停止条件的随机过程
  • 从排序数组的一端开始,分组直到总和等于全局平均值,并移至下一组,直到达到n

似乎是最优解(在给定输入数组的情况下,二进制位的内容之和尽可能相等)可能是非平凡的;所以目前我倾向于最后一个选项,但感觉我可能错过了更优雅的解决方案?

1 个答案:

答案 0 :(得分:4)

这是一个NP难题。换句话说,在不探索所有组合的情况下找不到最佳解决方案是不可能的,组合的数量是n ^ M(其中M是数组的大小,n是bean的数量)。这是一个非常类似于 clustering 的问题,它也是NP难的。

如果您的数据集足够小,可以使用强力算法(探索所有组合)。

但是,如果您的数据集很大,那么您需要一个多项式时间算法,它不会为您提供最佳解决方案,但需要很好的近似。在这种情况下,我建议您使用与 K-Means ...

类似的内容

步骤1.计算每箱的预期总和。让 A 成为你的数组,然后每个bin的预期总和是 SumBin = SUM(A)/ n (数组中所有元素的总和超过数量的bin) 。

步骤2.将数组的所有元素放在一些我们称之为 The Bag 的集合(例如另一个数组)中(这只是概念性的,所以你理解下面的步骤)。< / p>

步骤3.将 The Bag 分区为 n 组(最好是随机的,这样每个元素最终都会以某个bin i 结束,概率为1 / 名词的)。此时,您的垃圾箱中包含所有元素,并且 The Bag 为空。

步骤4.计算每个bin的总和。如果结果与上次迭代相同,则退出。 (这是 K-Means 期望步骤)

步骤5.对于每个bin i ,如果其总和大于 SumBin ,请选择大于 SumBin 的第一个元素并将其放入回到 The Bag ;如果其总和小于 SumBin ,则选择小于 SumBin 的第一个元素并放回 The Bag 。这是 K-Means 的梯度下降步骤(又名最大化步骤。)

步骤6.转到步骤3.

这个算法只是一个近似值,但它很快并且保证收敛。

如果您对如上所述的随机算法持怀疑态度,在第一次迭代后返回步骤3时,您可以通过运行 Hungarian algorithm <来最佳地执行此操作,而不是随机分配元素。 / em>,但我不确定这会保证更好的结果。