繁体   English   中英

有没有一种有效的方法可以找到所有长度为 10 的 integer 元组总和为 100

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM