0

I have a coding question that I am try to solve. I haven't been able to come up with a good algorithm yet.

Given a number X (e.g. 200), determine which numbers from a list (e.g.: 4,5,10, 10, 23,67,889, 150, 50) will when summed up will be equal to X. In this case the answer is (50, 150). So far I thought about first sorting the the list (lowest to highest) then loop through adding the numbers until I get to a value greater than X. Discard all the remaining numbers in the list since they are not needed (e.g. 889). Now I have the list of numbers required to produce a sum of 200. Now I need to determine which are the numbers that sum up to 200.

Currently stuck at this point.

Any thoughts very much appreciated.

3
  • I don't think you can discard numbers after you've reached the total: what if no combinations of them work? I think you have to keep going with all numbers less than the desired total., and probably work highest to lowest from there. Commented Jul 10, 2015 at 23:32
  • 1
    There is a very well known dynamic programming algorithm for this problem. It's called subset sum. Commented Jul 11, 2015 at 0:17
  • You want to count the number of subsets whose sum is equal to X or you want to find if there is a subset whose is ` X`? Commented Jul 11, 2015 at 4:20

3 Answers 3

2

This is a knapsack problem. Refer here https://en.m.wikipedia.org/wiki/Knapsack_problem

Sign up to request clarification or add additional context in comments.

2 Comments

It's actually the subset sum problem.
It's only knapsack when there's no negative number.
2

Depends. If you want it fast, you can use a greedy(ish) algorithm: (pseudo code)

n = answer; // what you want the numbers to add up to be. 
numbers = [1, 2, 40, 39,....]; //the candidates. 
addList = Array[][];
addList[0] = numbers;
level = 0;
while(true){
    for (number in numbers){
         currnum = addlist[level][i] + number;
         if(currnum == n){
             return true; // or what ever you want to return
         } else if (currnum < n){
              addlist[level+1].append(currnum);
         }
    }
    if (addlist[level+1].length ==0){
          return false; // it will never add up to the value n. 
    }
    level++;
}

This is strictly pseudo code, I'm mixing arraylist and array a bit just for readability.

Comments

0

The only numbers that can be discarded are the ones bigger than the goal number, as any other combination of smaller numbers might sum up to the desired amount.

To find which ones (if any) you will have to check all possible combinations of remaining numbers.

The most simple approach would be to recursively traverse the list, once adding the current number and once leaving it out, pruning the current branch if the sum already exceeds the goal value.

An example (perl) implementation for your problem instance is given in the snippet below:

my @numbers = (4, 5, 10, 10, 23, 67, 889, 150, 50);
my $length = scalar @numbers; # length of the list


sub visit {
  my ($i, $sum, $goal, $items) = @_;
  # i: current index, sum: sum of numbers currently selected
  # goal: goal value to reach, items: list of numbers currently selected 

  # we found a solution !
  print join (", ", @$items) . "\n" if $sum == $goal;

  return if $i >= $length || $sum >= $goal;

  # continue without adding
  visit ($i+1, $sum, $goal, $items);

  # continue with adding
  visit ($i+1, $sum + $numbers[$i], $goal, [$numbers[$i], @$items]);
}

visit (0, 0, 200, []); it will report the pair 50, 150 as expected.

Note, that no attempt to remove duplicates was made, so calling with goal value of 77 visit (0, 0, 77, []); besides the triple 50, 23, 4 the pair 67, 10 will be listed twice, since there are two instances of 10s there.

Oh, and don't trust any greedy algorithms suggested in other posts, as they are doomed to fail solving knapsack problems.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.