这些是我使用的行,它生成一个列表,列出了总和为输入的整数,然后说明了组合的数量。
import itertools
val = int(input())
r = range(val)[1:]
res = []
for i in range(len(r)+1):
res += [list(x) for x in itertools.combinations(r, i) if sum(list(x)) == val]
print("Solution : %s " % res)
print("Combinations : %s" % len(res))
答案 0 :(得分:1)
看起来您正在计算每个可能的组合,然后只保留满足您的总和条件的组合。它正在搜索的组合池以2 ^(n-1)的速度增长,您可以通过注释条件部分来查看:
import itertools
import time
startTime = time.time()
val = 21
r = range(val)[1:]
res = []
for i in range(len(r)+1):
res += [list(x) for x in itertools.combinations(r, i)]# if sum(list(x)) == val]
#print("Solution : %s " % res)
print("Combinations : %s" % len(res))
print(time.time() - startTime, 'seconds')
试试这个:
def a(lst, target, with_replacement=False):
def _a(idx, l, r, t, w):
if t == sum(l): r.append(l)
elif t < sum(l): return
for u in range(idx, len(lst)):
_a(u if w else (u + 1), l + [lst[u]], r, t, w)
return r
return _a(0, [], [], target, with_replacement)
val = 50
s = range(1, val)
solutions = a(s, val)
print(solutions)
print(len(solutions))
由thefourtheye代码修改: Finding Combinations to the provided Sum value
计时: 原始代码:val = 24, t = 6.5917372703552253 seconds
val = 25, t = 13.705767631530762 seconds
val = 26, t = 27.934977531433105 seconds
val = 50, t = 459889248.39282094 seconds
上述方法:
val = 24, t = 0.0084612369537353 seconds
val = 25, t = 0.0069310665130615 seconds
val = 26, t = 0.0085859298706054 seconds
val = 50, t = 0.4947729110717773 seconds
答案 1 :(得分:1)
可能有很多方法可以提高速度。我试过(并注意到它有很大的不同)一个简单的方法:摆脱生成器和列表之间的重复转换。这是您的代码,已修改:
import time
import itertools
#val = int(input("val:"))
#r = range(val)[1:]
def simple_time_func(func):
def wrapper(*args, **kwargs):
start = time.time()
r = func(*args, **kwargs)
print("{} took {:.3f} seconds.".format(func.__name__, time.time() - start))
return r
return wrapper
@simple_time_func
def original(val, r):
res = list()
for i in range(len(r) + 1):
res += [list(x) for x in itertools.combinations(r, i) if sum(list(x)) == val]
return res
@simple_time_func
def improved0(val, r):
res = list()
for i in range(len(r) + 1):
res += [x for x in itertools.combinations(r, i) if sum(x) == val]
return res
for val in range(21, 28):
r = range(val)[1:]
print("\nval: {}".format(val))
for func in (original, improved0):
res = func(val, r)
#print(" Solution : %s " % res)
#print(" Combinations : %s" % len(res))
备注强>:
for
循环)并将其封装在一个函数(original
)中以便计时improved0
)<强>输出强>:
(py35x64_test) c:\Work\Dev\StackOverflow\q46853086>"c:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" a.py val: 21 original took 0.573 seconds. improved0 took 0.325 seconds. val: 22 original took 1.185 seconds. improved0 took 0.633 seconds. val: 23 original took 2.388 seconds. improved0 took 1.300 seconds. val: 24 original took 4.880 seconds. improved0 took 2.609 seconds. val: 25 original took 9.796 seconds. improved0 took 5.243 seconds. val: 26 original took 19.701 seconds. improved0 took 10.489 seconds. val: 27 original took 39.314 seconds. improved0 took 21.559 seconds.
正如输出显示的那样,这种明显微不足道的变化几乎将时间缩短了一半 下一步包括真实优化(因为计算复杂性仍然看起来是指数级的),关于数学和编程技巧的有效使用,更进一步提高速度(不幸的是我已经没时间了)