1

I have an input array, like so:

const dels = [ // up to 50 possible
  {no: 491, weight: 1348},
  {no: 492, weight: 694},
  {no: 1054, weight: 4104},
  {no: 1181, weight: 2636},  // *
  {no: 2096, weight: 4084},
  {no: 2201, weight: 4064},
  {no: 2296, weight: 2364},
  {no: 2365, weight: 1670},
  {no: 2632, weight: 4084},
  {no: 2891, weight: 2424},
  {no: 3051, weight: 2414},  // *
];

I also have an array of sums, like so:

const sums = [5050, 24836]; // up to 4 possible

The structure is fixed, but the numbers are unknown (come from an external source).

I know that each number of the sums array is the sum of some weight members of the other array (each dels item counted exactly once).

So this can be assumed:

const sumDels = dels.reduce((a,i) => a + i.weight, 0);
const sumSums = sums.reduce((a,i) => a + i, 0);
sumDels === sumSums // is true

sumDels.every(x => x.weight > 0) // is true

What algorithm can efficiently give me the possible combinations that lead to the given sums?

A possible result could look like this:

const goodResult = [ // <-- array of possible combinations (theretically, there could be more than one)
  [                  // <-- `dels` array mapped with `sumIdx`
    {no: 491, sumIdx: 1},
    {no: 492, sumIdx: 1},
    {no: 1054, sumIdx: 1},
    {no: 1181, sumIdx: 0},  // *
    {no: 2096, sumIdx: 1},
    {no: 2201, sumIdx: 1},
    {no: 2296, sumIdx: 1},
    {no: 2365, sumIdx: 1},
    {no: 2632, sumIdx: 1},
    {no: 2891, sumIdx: 1},
    {no: 3051, sumIdx: 0},  // *
  ]
];

A naive solution would try all permutations but with sums.length==4 and dels.length==50 that's 1267650600228229401496703205376 possible combinations, if I'm not wrong... ;-)

Udo G
  • 12,572
  • 13
  • 56
  • 89

1 Answers1

0

As suggested in the comments, this is known as the subset sum problem and I've learnt that usually there is no other way to try all combinations, while bailing out early when a combination is already identified as being wrong.

This led me to another Stackoverflow answer with a nice recursive implementation.

It handles only one sum, though (my sums array could reach up to 4 numbers), but it's a good starting point for the full solution.

Udo G
  • 12,572
  • 13
  • 56
  • 89