将数组放入等长的'n'组中

时间:2014-02-05 08:02:24

标签: arrays algorithm

创建“n”数组的最佳方法是什么,所有数组的总长度尽可能接近相等?

寻找可能输出如下内容的算法:

Data Set (L=array length): [L:3],[L:1],[L:7],[L:4],[L:2] 

n=2: 
[L:3],[L:4],[L:1] = 8 total
[L:7],[L:2] = 9 total

n=3
[L:7]
[L:4],[L:1]
[L:3],[L:2]

在创建上面的示例后,我意识到“接近相等”这个短语可能有点模棱两可,具体取决于你如何定义“相等”。

我有一个n列的布局。每个数组都是一个原子组项,必须一起显示。我目前正在为列提供相同数量的数组,我的结果通常看起来像这样:

7 total arrays: 3 columns

_ _ _
. . .
_ . .
. . .
. . .
  . _
  . .
  .
  _
  .
  .

我确信在谷歌上有大量与之相关的大量资源可以用我想要的东西,但我不确定它是什么。

2 个答案:

答案 0 :(得分:2)

您基本上面临Bin-packingSubset Sum个问题的变体,即NP-Hard

这是从partition problem(子集和的特殊情况,也是NP完全)减少到你的问题:

分区问题:
给定输入集S,找到两个不同子集S1,S1的分区,以便S1 [union] S2 = SS1 [intersection] S2 = {}以及sum(S1)=sum(S2)

现在,给定分区S={s1,...,s_n}的实例,创建数据集[L:s1],...[L:s_n]n=2

现在,很容易看出问题的解决方案是分区问题的解决方案,反之亦然 - 因此解决问题的方法可以有效地解决分区问题。
由于分区问题是NP-Hard-所以这个问题 - 因此没有已知的有效(多项式)解决方案,并且大多数人认为不存在。

关于与binpacking的关系 - 请注意,您的问题基本上是使用size(bin) = sum(lengths)/n进行binpacking


注意:在这里我假设你只使用长度,如果你正在使用实际元素,这个减少不是输入大小的多项式,证明就会下降。

答案 1 :(得分:0)

出于我的目的,我想我可能会这样做:

var arrays = [[1,2,3,4,5],[1,2],[1,2,3,4],[1,2,3]];
//number of bins
var n = 3;
var bins = [];
//init bins
for(var i=0; i<n; i++){
  bins.push(new Array());
}
var i = 0;
while(arrays.length > 0){
  var array = elements.remove[0];
  var smallBin=0;
  var smallLength;
  for(var i=0; i<n; i++){
    if(smallLength){
       if(bin[i].length < smallLength){
         smallLength = bin[i].length;
         smallBin = i;
       }
    }else{
       smallLength = bin[i].length;
    }
  }
  bins[smallBin].push(array);
}

我只是在SO中键入了这个并且还没有测试过它。

我确信有些组合会产生不太完美的结果,但出于我的目的,它应该有用。