[英]Find all combinations of a list of numbers with a given sum
I have a list of numbers, eg我有一个数字列表,例如
numbers = [1, 2, 3, 7, 7, 9, 10]
As you can see, numbers may appear more than once in this list.如您所见,数字可能在此列表中出现多次。
I need to get all combinations of these numbers that have a given sum, eg 10
.我需要获得具有给定总和的这些数字的所有组合,例如
10
。
The items in the combinations may not be repeated, but each item in numbers
has to be treated uniquely, that means eg the two 7
in the list represent different items with the same value.组合中的项目可能不会重复,但
numbers
中的每个项目都必须唯一对待,这意味着例如列表中的两个7
代表具有相同值的不同项目。
The order is unimportant, so that [1, 9]
and [9, 1]
are the same combination.顺序并不重要,因此
[1, 9]
和[9, 1]
是相同的组合。
There are no length restrictions for the combinations, [10]
is as valid as [1, 2, 7]
.组合没有长度限制,
[10]
与[1, 2, 7]
一样有效。
How can I create a list of all combinations meeting the criteria above?如何创建满足上述条件的所有组合的列表?
In this example, it would be [[1,2,7], [1,2,7], [1,9], [3,7], [3,7], [10]]
在这个例子中,它将是
[[1,2,7], [1,2,7], [1,9], [3,7], [3,7], [10]]
You could use itertools to iterate through every combination of every possible size, and filter out everything that doesn't sum to 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
Result:结果:
[(1, 2, 7), (1, 2, 7), (1, 9), (3, 7), (3, 7), (10,)]
Unfortunately this is something like O(2^N) complexity, so it isn't suitable for input lists larger than, say, 20 elements.不幸的是,这有点像 O(2^N) 复杂度,所以它不适合大于 20 个元素的输入列表。
The solution @kgoodrick offered is great but I think it is more useful as a generator: @kgoodrick 提供的解决方案很棒,但我认为它作为生成器更有用:
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)
list(subset_sum([1, 2, 3, 7, 7, 9, 10], 10))
yields [[1, 2, 7], [1, 2, 7], [1, 9], [3, 7], [3, 7], [10]]
. list(subset_sum([1, 2, 3, 7, 7, 9, 10], 10))
产生[[1, 2, 7], [1, 2, 7], [1, 9], [3, 7], [3, 7], [10]]
。
This question has been asked before, see @msalvadores answer here .这个问题已经被问过,看到@msalvadores回答这里。 I updated the python code given to run in python 3:
我更新了在 python 3 中运行的 python 代码:
def subset_sum(numbers, target, partial=[]):
s = sum(partial)
# check if the partial sum is equals to target
if s == target:
print("sum(%s)=%s" % (partial, target))
if s >= target:
return # if we reach the number why bother to continue
for i in range(len(numbers)):
n = numbers[i]
remaining = numbers[i + 1:]
subset_sum(remaining, target, partial + [n])
if __name__ == "__main__":
subset_sum([3, 3, 9, 8, 4, 5, 7, 10], 15)
# Outputs:
# sum([3, 8, 4])=15
# sum([3, 5, 7])=15
# sum([8, 7])=15
# sum([5, 10])=15
@qasimalbaqali @qasimalbaqali
This may not be exactly what the post is looking for, but if you wanted to:这可能不是该帖子正在寻找的内容,但如果您想:
Find all combinations of a range of numbers [lst], where each lst contains N number of elements, and that sum up to K: use this:找到一系列数字 [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)
Results:结果:
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),
The idea/question behind this was "how much can we charge per month if we give x number of months free and still meet revenue targets".这背后的想法/问题是“如果我们免费提供 x 个月的费用并且仍然满足收入目标,我们每月可以收取多少费用”。
This works...这工作...
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
Append: including zero.
Append:包括零。
import random as rd
def combine(soma, menor, maior):
"""All combinations of 'n' sticks and '3' plus sinals.
seq = [menor, menor+1, ..., maior]
menor = min(seq); maior = max(seq)"""
lista = []
while len(set(lista)) < 286: # This number is defined by the combination
# of (sum + #summands - 1, #summands - 1) -> choose(13, 3)
zero = rd.randint(menor, maior)
if zero == soma and (zero, 0, 0, 0) not in lista:
lista.append((zero, 0, 0, 0))
else:
# You can add more summands!
um = rd.randint(0, soma - zero)
dois = rd.randint(0, soma - zero - um)
tres = rd.randint(0, soma - zero - um - dois)
if (zero + um + dois + tres == soma and
(zero, um, dois, tres) not in lista):
lista.append((zero, um, dois, tres))
return sorted(lista)
>>> result_sum = 10
>>> combine(result_sum, 0, 10)
Output Output
[(0,0,0,10), (0,0,1,9), (0,0,2,8), (0,0,3,7), ...,
(9,1,0,0), (10,0,0,0)]
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 导入itertools编号= [1、2、3、7、7、9、10]结果= [itertools.combinations(numbers,i)中seq的范围为s的范围为len(len(numbers,0,-1) sum(seq)== 10]打印结果
Sorry I am new to Stack Flow and cannot comment to a post. 抱歉,我是Stack Flow的新手,无法评论帖子。 Kevin, Can I please ask if I want to replace numbers = [1, 2, 3, 7, 7, 9, 10] with a csv file, how would I write this code?
凯文(Kevin),请问我是否要用csv文件替换数字= [1、2、3、7、7、9、10],我将如何编写此代码? Thank you in advance
先感谢您
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.