考虑以下解决子集总和问题的方法:
def subset_summing_to_zero (activities): subsets = {0: []} for (activity, cost) in activities.iteritems(): old_subsets = subsets subsets = {} for (prev_sum, subset) in old_subsets.iteritems(): subsets[prev_sum] = subset new_sum = prev_sum + cost new_subset = subset + [activity] if 0 == new_sum: new_subset.sort() return new_subset else: subsets[new_sum] = new_subset return []
我从这里得到它:
http://news.ycombinator.com/item?id=2267392
还有一条评论说有可能使其“更有效”。
怎么样?
另外,还有其他解决问题的方法至少与上述方法一样快吗?
编辑
我对任何会加快速度的想法都很感兴趣。我发现:
https://zh.wikipedia.org/wiki/Subset_sum_problem#cite_note- Pisinger09-2
其中提到了线性时间算法。但是我没有纸,亲爱的人们,也许您知道它是如何工作的?一个实现也许?也许完全不同的方法?
\
虽然我以前的答复介绍了polytime近似算法对这个问题,要求被 专门_为一个实现方式制成Pisinger的polytime动态规划的解决方案时,所有的_X 我_在 _X 是积极的:
from bisect import bisect def balsub(X,c): """ Simple impl. of Pisinger's generalization of KP for subset sum problems satisfying xi >= 0, for all xi in X. Returns the state array "st", which may be used to determine if an optimal solution exists to this subproblem of SSP. """ if not X: return False X = sorted(X) n = len(X) b = bisect(X,c) r = X[-1] w_sum = sum(X[:b]) stm1 = {} st = {} for u in range(c-r+1,c+1): stm1[u] = 0 for u in range(c+1,c+r+1): stm1[u] = 1 stm1[w_sum] = b for t in range(b,n+1): for u in range(c-r+1,c+r+1): st[u] = stm1[u] for u in range(c-r+1,c+1): u_tick = u + X[t-1] st[u_tick] = max(st[u_tick],stm1[u]) for u in reversed(range(c+1,c+X[t-1]+1)): for j in reversed(range(stm1[u],st[u])): u_tick = u - X[j-1] st[u_tick] = max(st[u_tick],j) return st
哇,真令人头疼。这需要进行校对,因为在实现的同时balsub,我无法定义正确的比较器来确定是否存在针对此SSP子问题的最佳解决方案。
balsub