可能重复:
Algorithm to find which number in a list sum up to a certain number
问题:
有一个列表:[1,2,3,4,6,8,10,12],我想用这些数字总结一个新的数字16。
规则:
1)不需要使用所有数字,6 + 10就可以了。
2)一个数字可以多次使用,12 + 2 + 1 + 1就可以了。
3)订单事项,12 + 6和6 + 12是两种不同的组合。
我看到algorithm to sum up a list of numbers for all combinations,但这不一样。
对算法了解不多,如果这个算法适合某些算法,请告诉我,否则会对一些python代码/伪代码表示赞赏。
答案 0 :(得分:4)
首先 - 请注意,即使查找是否有任何与所需数字相加的子集为NP-Complete,也称为subset sum problem,因此没有已知的多项式解决方案。
现在,关于具体问题,以下是一些选项:
首先,当然有明显的“生成所有子集并检查总和”的方式。请注意,如果您的元素都是非负数,则可以在实际开发之前使用分支和绑定并终止大部分可能性(如果您找到了X
的子集sum(X) == s
,那么您正在寻找数字n < s
- 您可以确定任何包含X
的集合都找不到解决方案。有点像:
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
使用findSubsets(list,[],n)
进行调用,其中list
是您的项目列表,n
是所需的数字,[]
是一个空列表。
请注意,如果需要,它可以很容易地并行化,在探索的两个子集之间不需要真正的同步化。
如果列表仅包含整数,则另一种方法是使用Dynamic Programming for solving the subset sum problem。获得矩阵后,您可以通过返回表格重新创建表格中的所有元素。 This similar question讨论了如何从背包DP解决方案中获取列表。这两个问题的原理几乎相同。