The algorithm is in Python. Seems correct to me, ideas how to prove it? And what would be its time complexity?
from bisect import bisect
# Implements the decision version of subset sum.
# The subset sum problem: given a set and a number find a subset of the set which sums to the given number.
# Inputs: an ordered list of integers xs, and an integer n which is the target sum.
def subset_sum(xs, n):
if n < sum(filter(lambda x: x < 0, xs)):
return False
if n > sum(filter(lambda x: x >= 0, xs)):
return False
xs = xs[:]
u = {}
def rec(i, n):
if not (i, n) in u:
u[i, n] = False
k = bisect(sums[:i], n)
while k > 0:
k -= 1
u[i, n] = u[i, n] or sums[k] == n
u[i, n] = u[i, n] or rec(k, n - sums[k])
return u[i, n]
sums = xs
return rec(len(sums), n)
It has been answered below that the above algorithm is exponential time.
That being so, I have a follow up question: Is the algorithm still exponential time if the rec sub-routine above is changed into the following?
def rec(i, n):
if not (i, n) in u:
u[i, n] = False
k = bisect(sums[:i], n)
k -= 1
if k >= 0 and n >= sums[0]::
u[i, n] = sums[k] == n or rec(k, n - sums[k]) or rec(k, n)
return u[i, n]
The recurrence $T(i, n) = T(i - 1, n - 1) + log_2(i)$ is what I came up with for worst case running time. Maybe that's far off. But from that it seems it is $|S|log(|S|)$.
New information: I have been able to solve a problem instance involving a set of 8192 integers equal to the range (1, 9, ... 65537) and the target n = 65525 in one and a half minute on my laptop. The resulting list consists of 125 integers. That makes the algorithm (with the above changes applied) sub-exponential, certainly not $2^{|S|}$ . The time taken is for the search version which applies the decision version discussed here $|S|$ times.
Here is a link to the full source code of my test set-up:
i
. Eg. you can first look for whether there is a sum equal toN
and only after that try to do other manipulations onN
... In other words, do you need to know the complexity of this algorithm, or maybe algorithm can be altered to work faster? – wvxvw Oct 04 '15 at 22:44