所以我有10个号码。让我们说每个数字代表一个人的技能。如果我要创建2支5支球队,我将如何组建2支球队,以便他们的球队总和的差异很小。
答案 0 :(得分:2)
使用10个数字,最简单的方法是检查所有组合并计算差异。
答案 1 :(得分:1)
这与Knapsack problem类似:您尝试将个人放入其中一个团队中,以便该团队的总和是不大于总和的一半的最大值。如果团队规模不受限制,情况就会一样。
答案 2 :(得分:0)
这是我想出的一个疯狂的想法。
时间复杂度: O(N log N)
for(each element q from last element to first element of Q)
{
Find a number p that is not currently used
which if swapped with the current element q
makes the sum closer to T but not more than T.
Remove q from Q
Add p to Q
}
return Q as best set.
虽然for循环看起来好像是O(N 2 ),但是可以进行二分搜索以找到数字p.So它是O(N * log N)
免责声明:我只描述了算法。我不知道如何正式证明它。
答案 3 :(得分:0)
生成5个元素的所有组合。你将在一个团队中拥有这5个,而在另一个团队中拥有剩下的5个。比较所有结果并选择差异最小的结果。您可以使用5个for
循环创建所有这些组合。
答案 4 :(得分:0)
我刚试了一下 - 不幸的是我不得不编程那个排列事物(函数next
)并为每个元素调用result.fit
。
可以做得更好,但为了演示它应该足够好。
var all = [ 3, 4, 5, 8 , 2, 1, 1, 4, 9, 10 ];
function sumArray(a) {
var asum = 0;
a.forEach(function(v){ asum += v });
return asum;
}
var next = function(start, rest, nbr, result) {
if (nbr < 0) {
result.fit(start);
return;
}
for (var i = 0; i < rest.length - nbr; ++i) {
var clone = start.slice(0);
clone.push(rest[i]);
next(clone, rest.slice(i + 1), nbr - 1, result);
}
};
var result = {
target: sumArray(all) / 2,
best: [],
bestfit: Math.pow(2,63), // really big
fit: function(a) {
var asum = sumArray(a);
var fit = Math.abs(asum - this.target);
if (fit < this.bestfit) {
this.bestfit = fit;
this.best = a;
}
}
}
next([], all, all.length / 2, result);
console.log(JSON.stringify(result.best));
答案 5 :(得分:0)
与大多数算法相同 - 比较126种组合。 Haskell中的代码:
inv = [1,2,3,4,5,6,7,8,9,10]
best (x:xs) (a,b)
| length a == 5 = [(abs (sum a - sum (x:xs ++ b)),(a,x:xs ++ b))]
| length b == 5 = [(abs (sum (x:xs ++ a) - sum b),(x:xs ++ a,b))]
| otherwise = let s = best xs (x:a,b)
s' = best xs (a,x:b)
in if fst (head s) < fst (head s') then s
else if fst (head s') < fst (head s) then s'
else s ++ s'
main = print $ best (tail inv) ([head inv],[])
输出:
*Main> main
[(1,([9,10,5,2,1],[8,7,6,4,3])),(1,([10,8,6,2,1],[9,7,5,4,3]))
,(1,([9,10,6,2,1],[8,7,5,4,3])),(1,([9,8,7,2,1],[10,6,5,4,3]))
,(1,([10,8,7,2,1],[9,6,5,4,3])),(1,([9,10,4,3,1],[8,7,6,5,2]))
,(1,([10,8,5,3,1],[9,7,6,4,2])),(1,([9,10,5,3,1],[8,7,6,4,2]))
,(1,([10,7,6,3,1],[9,8,5,4,2])),(1,([9,8,6,3,1],[10,7,5,4,2]))
,(1,([10,8,6,3,1],[9,7,5,4,2])),(1,([9,8,7,3,1],[10,6,5,4,2]))
,(1,([10,7,5,4,1],[9,8,6,3,2])),(1,([9,8,5,4,1],[10,7,6,3,2]))
,(1,([10,8,5,4,1],[9,7,6,3,2])),(1,([9,7,6,4,1],[10,8,5,3,2]))
,(1,([10,7,6,4,1],[9,8,5,3,2])),(1,([9,8,6,4,1],[10,7,5,3,2]))
,(1,([8,7,6,5,1],[9,10,4,3,2])),(1,([9,7,6,5,1],[10,8,4,3,2]))]
答案 6 :(得分:0)
这是Partition problem的一个实例,但对于您的小实例测试,所有组合应该足够快。