![](/img/trans.png)
[英]Is there a more efficient way to find all combinations of 10 items in 10% increments?
[英]Is there an efficient way to find all integer tuples of length 10 that sum to 100
我正在尝试查找仅包含加到 100 的正整数(允许为 0)的所有元组。我对每个索引的最大值有一些限制。 我有包含这些约束的列表最大值
maxs = [3, 9, 14, 21, 21, 35, 31, 49, 42, 38]
到目前为止,我只是在运行这个 10 维嵌套 for 循环
combinations = []
for s1 in range(maxs[0]+1):
for s2 in range(maxs[1]+1):
for s3 in range(maxs[2]+1):
for s4 in range(maxs[3]+1):
for s5 in range(maxs[4]+1):
for s6 in range(maxs[5]+1):
for s7 in range(maxs[6]+1):
for s8 in range(maxs[7]+1):
for s9 in range(maxs[8]+1):
for s10 in range(maxs[9]+1):
if s1 +s2+s3+s4+s5+s6+s7+s8+s9+s10 == 100:
combinations.append([s1,s2,s3,s4,s5,s6,s7,s8,s9,s10]
如果有帮助的话,我知道只有不到 10 ^ 11 种组合。 可能这个问题太大了
谢谢
这不是性能最好的,但它是最简单的。
from itertools import combinations
maxs = [3, 9, 14, 21, 21, 35, 31, 49, 42, 38]
combination = [
tuple(filter(lambda x: 0 <= x <= 100, item))
for r in range(1, len(maxs))
for item in combinations(maxs, r)
]
result = [item for item in combination if sum(item) == 100]
print(result)
递归方法。 示例仅使用三个第一个条目。 早期的不良分支切割可能会加速 - 例如,当 cursum 超过目标时
maxs = [3, 9, 14, 21, 21, 35, 31, 49, 42, 38]
def sum100(n, target, maxs, level, cursum, curlist):
if level == n:
if cursum == target:
print(curlist)
return
for i in range(maxs[level]+1):
sum100(n, target, maxs, level + 1, cursum + i, curlist + [i])
sum100(3, 15, maxs, 0, 0, [])
[0, 1, 14]
[0, 2, 13]
...
[1, 3, 11]
[1, 4, 10]
[1, 5, 9]
...
[3, 1, 11]
[3, 2, 10]
[3, 3, 9]
我知道有一个公认的解决方案。
但这里有一个可以让你解决这样的各种问题。 它允许您计算解决方案,按字典顺序生成解决方案,或生成任何随机解决方案。 它通过使用动态编程为所有解决方案构建结构来做到这一点,您可以根据需要使用它。
这是一个演示:
import random
def summer (target, choices_list, i=0, cache=None):
if cache is None:
cache = {}
key = (target, i)
if key not in cache:
if i == len(choices_list):
if target == 0:
cache[key] = {0: [1, None]}
else:
cache[key] = None
elif len(choices_list) < i:
cache[key] = None
else:
answer = {}
for choice in choices_list[i]:
next_target = target - choice
next_summer = summer(next_target, choices_list, i+1, cache)
if next_summer is not None:
count = sum([v[0] for v in next_summer.values()])
answer[choice] = [count, next_summer]
if 0 == len(answer.keys()):
cache[key] = None
else:
cache[key] = answer
return cache[key]
def max_summer(target, maxes):
return summer(target, [list(range(0, m+1)) for m in maxes])
def count_solutions(this_summer):
if this_summer is None:
return 0
else:
answer = 0
for v in this_summer.values():
answer += v[0]
return answer
def solution (this_summer, i, answer = None):
if answer is None:
answer = []
if this_summer is None:
answer.pop() # Remove trailing 0
return answer
for choice, info in this_summer.items():
if info[0] < i:
i -= info[0]
else:
answer.append(choice)
return solution(info[1], i, answer)
return None
s = max_summer(100, [3, 9, 14, 21, 21, 35, 31, 49, 42, 38])
print(count_solutions(s))
for x in range(10):
i = x
print(i, solution(s, i))
for x in range(10):
i = random.randrange(0, count_solutions(s))
print(i, solution(s, i))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.