1

I have written a dynamic programming algorithm that finds the total amount of subsets that sum up to a target value. However, I am having trouble developing a function to recover the solution (that is, print out the actual subsets).

For example, let's take the set [1,3,5,7,9,10] with the target 13. My algorithm calculates that there are 3 subsets. The output table is shown in the image below.

output table for my subset sum algorithm

Because this is a simple set, I can manually determine which three subsets make up the target. That is:

[3,10]
[1,3,9]
[1,5,7]

But, with more complicated solutions, how would I use my output table to recursively recover a solution? Any assistance is appreciated.

Joe Balin
  • 177
  • 2
  • 17
  • If your algorithm already gives you how many sum-subsets exists, you must calculate each possible subset somewhere in that algorithm no? Why not just use the same formula? – pingul Feb 23 '17 at 13:43

1 Answers1

3

Caveat

Without seeing your algorithm and any input restrictions for it (for example, are duplicate values allowed in the set?) it might not be possible to devise a method that will work for all possible cases.

It appears, however, that the following will work for all cases listed in the results table of your example. If you find that this does not work for other cases, please add those examples to your question. (I am disregarding target = 0 as a special case.)

Algorithm Sketch

Iterate through the results of the target column in ascending order.

When the result increments, you have identified another subset and have found the largest value in that subset.

To find the remaining values in the subset, "make change" the way a store clerk would. In other words, walk back down the set values, subtracting from the remaining total as you can.

Sample Run

For your given example of target sum = 13 for subsets within set [1,3,5,7,9,10]:

resultCount = 0

result(13,1) is 0; this result - resultCount = 0, so no new subsets

result(13,3) is 0; this result - resultCount = 0, so no new subsets

result(13,5) is 0; this result - resultCount = 0, so no new subsets

result(13,7) is 1; this result - resultCount = 1, so resultCount = 1
                                                     and new subset = [7]
                                                     and remaining = 13 - 7 = 6
    5 < 6, so subset = [7,5] and remaining = 6 - 5 = 1
    3 > 1, so remaining is still 1
    1 = 1, so subset = [7,5,1] and remaining = 0 (subset complete)

result(13,9) is 2; this result - resultCount = 1, so resultCount = 2
                                                     and new subset = [9]
                                                     and remaining = 13 - 9 = 4
    7 > 4, so remaining is still 4
    5 > 4, so remaining is still 4
    3 < 4, so subset = [9,3] and remaining = 4 - 3 = 1
    1 = 1, so subset = [9,3,1] and remaining = 1 - 1 = 0 (subset complete)

result(13,10) is 3; this result - resultCount = 1, so resultCount = 3
                                                      and new subset = [10]
                                                      and remaining = 13 - 10 = 3
    9 > 3, so remaining is still 3
    7 > 3, so remaining is still 3
    5 > 3, so remaining is still 3
    3 = 3, so subset = [10,3] and remaining = 3 - 3 = 0 (subset complete)

End of run with 3 subsets identified:

[7,5,1]
[9,3,1]
[10,3]
  • Ah! This logic helped me out a lot. However, it seems to be a bit... greedy with recovering the solution. Let's say we found a new result for the target of, say, 20, in the list [15,6,6,8,16]. If you start looking at the set from either end and just subtracting from 20 where possible, you will end up in a weird place. And we would need some way to "flag" values if we find 2 or more new subsets at a time. But, nevertheless, this was very helpful! I think I can figure it out from here. – Joe Balin Feb 24 '17 at 00:32
  • Yes, I was assuming that the values in your result table are sorted ascending, so [6,6,8,15,16] in the new example. I am guessing that with a target of 20, your algorithm would have, in column 20, results of 0, 0, 1, 1, 1. But maybe your comment has a typo and you meant [1,5,6,6,8,16] in which case I would guess column 20 would show 0, 0, 0, 0, 3, 3 and, as you say, you would need to address finding multiple subsets at the same time. Starts to look like Cribbage scoring. In any case, glad this was helpful! – James Droscha Feb 24 '17 at 15:00