创建“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
_ _ _
. . .
_ . .
. . .
. . .
. _
. .
.
_
.
.
我确信在谷歌上有大量与之相关的大量资源可以用我想要的东西,但我不确定它是什么。
答案 0 :(得分:2)
您基本上面临Bin-packing和Subset Sum个问题的变体,即NP-Hard。
这是从partition problem(子集和的特殊情况,也是NP完全)减少到你的问题:
分区问题:
给定输入集S
,找到两个不同子集S1,S1
的分区,以便S1 [union] S2 = S
和S1 [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中键入了这个并且还没有测试过它。
我确信有些组合会产生不太完美的结果,但出于我的目的,它应该有用。