鉴于:
m
个列表的数量(m
可能会有所不同)。arange()
个数字。需要:
sum()
到N
的m-tuple(每个列表一个数字)。我有什么:
我可以在静态列表中找到所有组合。
import numpy as np
for a in np.arange(0,1,0.01):
for b in np.arange(0,1,0.01):
for c in np.arange(0,1,0.01):
for d in np.arange(0,1,0.01):
if (a+b+c+d) == 1.0:
print a,b,c,d
我也希望找到一种最佳的计算方法。
答案 0 :(得分:5)
正如评论中所讨论的那样,范围都是相同的,我们应该使用整数。这是一种非常好的方式。
生成三个数字,而不是生成四个数字并测试它们是否加起来为10,而是将区间[0,10]的分区定义为四个区间。例如,当我们在(3,4,8)处进行切割时,我们添加端点0和10,那么我们就有边界(0,3,4,8,10)。相邻边界之间的差异是(3-0,4-3,8-4,10-8)=(3,1,4,2)。这四个数字加起来为10.这里的代码就是这样做的:
n = 10
import itertools, operator
for cuts in itertools.combinations_with_replacement(range(n+1), 3):
combi = list(map(operator.sub, cuts + (n,), (0,) + cuts))
if max(combi) < n:
print(combi)
打印:
[0, 0, 1, 9]
[0, 0, 2, 8]
[0, 0, 3, 7]
[0, 0, 4, 6]
[0, 0, 5, 5]
[0, 0, 6, 4]
[0, 0, 7, 3]
[0, 0, 8, 2]
[0, 0, 9, 1]
[0, 1, 0, 9]
[0, 1, 1, 8]
[0, 1, 2, 7]
...
...
[7, 2, 0, 1]
[7, 2, 1, 0]
[7, 3, 0, 0]
[8, 0, 0, 2]
[8, 0, 1, 1]
[8, 0, 2, 0]
[8, 1, 0, 1]
[8, 1, 1, 0]
[8, 2, 0, 0]
[9, 0, 0, 1]
[9, 0, 1, 0]
[9, 1, 0, 0]
它非常有效,因为它可以非常直接地生成组合。 if max(combi) < n
仅过滤掉[0, 0, 0, 10]
,[0, 0, 10, 0]
,[0, 10, 0, 0]
和[10, 0, 0, 0]
。
这是你的原版,我的和@ Mijamo之间的速度比较,其中包含100个数字,例如你的例子:
drum: 21.027 seconds
Stefan: 0.708 seconds
Mijamo: 62.864 seconds
该测试的完整代码:
import itertools, operator
from timeit import timeit
def drum(n):
out = []
for a in range(n):
for b in range(n):
for c in range(n):
for d in range(n):
if a + b + c + d == n:
out.append((a, b, c, d))
return out
def Stefan(n):
combinations = (map(operator.sub, cuts + (n,), (0,) + cuts)
for cuts in itertools.combinations_with_replacement(range(n+1), 3))
return [c for c in combinations if max(c) < n]
def Mijamo(n):
combinations = itertools.product(range(n), repeat=4)
return [tuple for tuple in combinations if sum(tuple) == n]
for func in drum, Stefan, Mijamo:
print '%6s: %6.3f seconds' % (func.__name__, timeit(lambda: func(100), number=1))
答案 1 :(得分:2)
可以通过以下方式检索所有组合:
combinations = itertools.product(np.arange(0,1,0.01), repeat = m)
https://docs.python.org/3.5/library/itertools.html#itertools.product
因为它是一个生成器,你可以创建一个新的生成器来返回总和为n的tupples
results = (tuple for tuple in combinations if sum(tuple) == N)
答案 2 :(得分:1)
如何使用&#34;产品&#34;从itertools获得所有可能的m长度元组。然后你只需按元组和== N
的条件进行过滤