First - note that even finding if there is any subset that sums to the desired number is NP-Complete and is known as the subset sum problem, so there is no known polynomial solution for it.
Now, regarding the specific issue, here are some options:
First there is of course the obvious "generate all subsets and check the sum" way. Note that if your elements are all non-negative, you can use branch and bound and terminate a large portion of the possibilities before you actually develop them (If you found a subset X
with sum(X) == s
, and you are looking for the number n < s
- you can be sure any set containing X
will NOT find the solution). Something along the lines of:
findSubsets(list,sol,n):
if (list.empty() and n == 0): #found a feasible subset!
print sol
return
else if (n < 0): #bounding non feasible solutions
return
else if (list.empty()): #a solution that sums to a smaller number then n
return
e <- list.removeAndReturnFirst()
sol <- sol.add(e)
findSubsets(list,sol,n-e)
sol <- sol.removeLast()
findSubsets(list,sol,n)
list.addFirst(e) #cleanup, return the list to original state
Invoke with findSubsets(list,[],n)
where list
is your list of items, n
is the desired number and []
is an empty list.
Note that it can be easily parallelized if needed, there is no real syncrhonization needed between two subsets explored.
Another alternative if the list contains only integers is using Dynamic Programming for solving the subset sum problem. Once you have the matrix you can re-create all the elements from the table by going back in the table. This similar question discusses how to get a list from the knapsack DP solution. The principles of the two problems are pretty much the same.