Python 查找具有给定和的数字列表的所有组合
我有一个数字列表,例如Python 查找具有给定和的数字列表的所有组合,python,algorithm,python-3.x,combinations,subset-sum,Python,Algorithm,Python 3.x,Combinations,Subset Sum,我有一个数字列表,例如 numbers = [1, 2, 3, 7, 7, 9, 10] 如您所见,数字可能会在该列表中出现多次 我需要得到这些数字的所有组合,它们有一个给定的和,例如10 组合中的项目可能不会重复,但编号中的每个项目必须单独处理,这意味着列表中的两个7代表具有相同值的不同项目 顺序并不重要,因此[1,9]和[9,1]是相同的组合 组合没有长度限制,[10]与[1,2,7]一样有效 如何创建符合上述条件的所有组合的列表? 在本例中,它将是[[1,2,7],[1,2,7],[1,
numbers = [1, 2, 3, 7, 7, 9, 10]
如您所见,数字可能会在该列表中出现多次
我需要得到这些数字的所有组合,它们有一个给定的和,例如10
组合中的项目可能不会重复,但编号中的每个项目必须单独处理,这意味着列表中的两个7
代表具有相同值的不同项目
顺序并不重要,因此[1,9]
和[9,1]
是相同的组合
组合没有长度限制,[10]
与[1,2,7]
一样有效
如何创建符合上述条件的所有组合的列表?
在本例中,它将是
[[1,2,7],[1,2,7],[1,9],[3,7],[3,7],[10]
您可以使用itertools对每个可能大小的每个组合进行迭代,并过滤掉不等于10的所有内容:
import itertools
numbers = [1, 2, 3, 7, 7, 9, 10]
result = [seq for i in range(len(numbers), 0, -1) for seq in itertools.combinations(numbers, i) if sum(seq) == 10]
print result
结果:
[(1, 2, 7), (1, 2, 7), (1, 9), (3, 7), (3, 7), (10,)]
不幸的是,这有点像O(2^N)复杂性,因此它不适用于大于(比如)20个元素的输入列表。这个问题以前有人问过,请参阅@msalvadores答案。我更新了在python 3中运行的python代码:
def subset_sum(数字、目标、部分=[]):
s=总和(部分)
#检查部分和是否等于目标值
如果s==目标:
打印(“总和(%s)=%s”%(部分,目标))
如果s>=目标:
return#如果我们达到了这个数字,为什么还要继续呢
对于范围内的i(len(数字)):
n=数字[i]
剩余=数字[i+1:]
子集_和(剩余、目标、部分+[n])
如果名称=“\uuuuu main\uuuuuuuu”:
子集和([3,3,9,8,4,5,7,10],15)
#产出:
#总和([3,8,4])=15
#总和([3,5,7])=15
#总和([8,7])=15
#总和([5,10])=15
虽然它很棒,但我认为它作为一个生成器更有用:
def subset_sum(numbers, target, partial=[], partial_sum=0):
if partial_sum == target:
yield partial
if partial_sum >= target:
return
for i, n in enumerate(numbers):
remaining = numbers[i + 1:]
yield from subset_sum(remaining, target, partial + [n], partial_sum + n)
列表(子集和([1,2,3,7,7,9,10,10])
产生[[1,2,7],[1,2,7],[1,9],[3,7],[3,7],[10]]
这是有效的
from itertools import combinations
def SumTheList(thelist, target):
arr = []
p = []
if len(thelist) > 0:
for r in range(0,len(thelist)+1):
arr += list(combinations(thelist, r))
for item in arr:
if sum(item) == target:
p.append(item)
return p
@卡西马尔巴卡利
这可能不是该帖子所要寻找的,但如果你想:
查找一系列数字[lst]的所有组合,其中每个lst包含N个元素,总计为K:使用此选项:
# Python3 program to find all pairs in a list of integers with given sum
from itertools import combinations
def findPairs(lst, K, N):
return [pair for pair in combinations(lst, N) if sum(pair) == K]
#monthly cost range; unique numbers
lst = list(range(10, 30))
#sum of annual revenue per machine/customer
K = 200
#number of months (12 - 9 = num months free)
N = 9
print('Possible monthly subscription costs that still equate to $200 per year:')
#print(findPairs(lst, K, N))
findPairs(lst,K,N)
结果:
Possible monthly subscription costs that still equate to $200 per year:
Out[27]:
[(10, 11, 20, 24, 25, 26, 27, 28, 29),
(10, 11, 21, 23, 25, 26, 27, 28, 29),
(10, 11, 22, 23, 24, 26, 27, 28, 29),
这背后的想法/问题是“如果我们提供x个月的免费服务,但仍能达到收入目标,我们每月能收取多少费用?”.如果您在理解上述代码时感到困惑,这里是上述代码的一个简单版本,适用于范围(1,len(a)):适用于itertools中的s。组合(a,i):如果总和=sum1:print(s)这个代码有时间复杂度更小的版本吗?@Kevin:对于更多的元素,如何处理它?
itertools。如果number
有重复的元素,组合将创建重复的元素。你能解释一下“从子集的收益率求和(剩余,目标,部分+[n],部分求和+n)”这一行吗@Martin Valgur:它能处理10000个列表元素吗?如果列表中的元素不完全相同,这将创建重复的元素。如果您希望每个输出包含一定数量的数字,比如12,该怎么办。每个列表需要有12个数字,总和为15?@max我正在寻找一个类似于您的解决方案,您找到什么了吗?@qasimalbaqali我找到了。不要介意我的评论,但这是可行的:#Python3程序从itertools导入组合def findPairs(lst,K,N)中查找具有给定和的整数列表中的所有对:返回[pair for pair in compositions(lst,N),如果和(对)=K]#每月成本范围;唯一数字lst=列表(范围(10,30))#每台机器/客户的年收入之和K=200#月数(12-9=免费月数)N=9打印('可能的每月订阅成本仍然等于每年200美元:')#打印(findPairs(lst,K,N))findPairs(lst,K,N)