我正在寻找一种算法,该算法将允许我快速访问(不一定要打印)300个项目集中的每个X项目子集,当该子集中的项目值为加起来等于Y。允许重复且顺序很重要。这300个项目集的所有值均为正。
例如,
300个项目集:[1.5、1.34、3,.25、2.333、1.75,.125,.675、2、4..75 ... ...]
X = 5
Y = 6
算法生成:
[2,2,1.5,.25,.25]
[2,2,.25,1.5,.25]
[2,1.5,2,.25,.25]
[1.5,2,2,.25,.25]
[2,1.75,.5,.5,1.25]
[2,1.75,.5,1.25,.5]
[2,1.75,1.25,.5,.5]
[2,1.25,.5,.5,1.75]
[1.25,2,.5,.5,1.75]
[.5,2,.5,1.25,1.75]
[3,1,1,.5,.5]
[1、3、1,.5,.5]
[1,1,3,.5,.5]
[1,1,.5,3,.5]
[1,1,.5,.5,3]
以此类推。...
[2,2,1.5,.25,.25]是允许的,并且
[2,1.75,.5,.5,1.25]与[1.25,.5,.5,1.75,2]不同。
我意识到这是子集总和问题的一种变体,但是我似乎无法在任何在线位置找到任何有用的变体示例。现在,我当前的解决方案实现了嵌套循环(嵌套循环的数量由X的值确定),当X很小时效果很好,但是当X开始上升时很快变得非常慢。任何输入将不胜感激!
答案 0 :(得分:0)
一种方法是收集子集,并检查子集的长度和总和是否合适。
如有必要,您可以对子集进行排列。
function subsetSum(array, sum, items) {
function iter(taken, index, subsum) {
if (taken.length === items && subsum === sum) return result.push(taken);
if (taken.length === items || subsum === sum || index === array.length) return;
iter([...taken, array[index]], index, subsum + array[index]);
iter(taken, index + 1, subsum);
}
var result = [];
iter([], 0, 0);
return result;
}
var result = subsetSum([1.5, 1.34, 3, .25, 2.333, 1.75, .125, .675, 2, 4, .75], 6, 5);
console.log(result.map(a => a.join(' ')));
.as-console-wrapper { max-height: 100% !important; top: 0; }