Кажется, вам подойдёт такой простой алгоритм: перебрать все числа в двоичной записи от 1 до 2
n, и брать те элементы строки, которым соответствует 1.
Набросал функцию, подбирающую из данных элементов комбинацию, дающую наиболее близкую сумму к заданной:
function nearest(arr, total) {
var len = arr.length
, i
, bit
, sum
, n = Math.pow(2, len)
, currDist
, index = undefined
, dist = undefined
, result = []
;
for( i = 1; i < n; i++) {
sum = 0;
for( bit = 0; bit < len; bit++) {
if( i & (1 << bit)) sum += arr[bit];
}
currDist = Math.abs(total - sum);
if( typeof dist === 'undefined' || dist > currDist) {
index = i;
dist = currDist;
if( dist === 0) break;
}
}
for(bit = 0; bit < len; bit++) {
if( index & (1 << bit)) result.push(arr[bit]);
}
return result;
}
nearest([1,3,4,6,8], 12) // [1,3,8]
nearest([1,2,4,6,8], 12) // [2,4,6]
nearest([7,9,13,19,28], 12) // [13] dist = 1
nearest([7,9,13,19,28], 28) // [9,19] не [28] т.к. останавливается на первом найденном варианте