基于总和的排列,不限制排列的项目数

问题描述

import itertools as itt

layer_thickness=[1,2,3,4,5]
permu= itt.permutations(layer_thickness,5)
permu_list=list(permu)
for i in permu_list:
    if sum(i)==15:
        print(i)

在这里,我想要对 layer_thickness 中的元素进行排列,这些排列的总和应该是 5。但是 prmutation 中的元素数量不受任何限制,除非它给出所需的总和。

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1,2 2 2 2 2 2 2 1,etc are 也应该是一个元素。

我应该做哪些修改来实现这一目标?

解决方法

您不能将所有排列创建为任何总数的列表 - 它只会占用太多内存:

  • 假设 [1,2,3,4,5] 为数字,1 是最低元素。
  • 假设您想要达到 total = 15 - 您的“最大”解决方案是 (1,1,1)
  • 要创建超过 15 个位置的 5 个数字的所有可能排列,您需要创建 15**5 个列表条目:15**5 = 2.562.890.625 个可能的数字排列

将每个组合存储为 1 个字节,这将需要 2.56 Terabyte 的内存。怀疑你有那么多。


您能做的最好的事情是只生成有效的数字,并在达到总数后立即退出。要对固定数字集执行此操作,您可以从以下问题开始:Finding all possible combinations of numbers to reach a given sum

使用它并提供可以加起来以实现目标的“最大化”数字列表可能会导致某些结果:

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,partial + [n],partial_sum + n)

信用:https://stackoverflow.com/a/4633515/7505395

def calc_nums_for_permutate(nums,total):
    """Creates a list of numbers from num - each single number is added as
    many times as itself fits into total"""
    return [n for n in nums for _ in range(total//n)]

if __name__ == "__main__":
    nums = [1,5]
    total = 15
    
    print( *subset_sum( calc_nums_for_permutate(nums,total),total))

这不适用于所有和任何输入 - 祝您运行时好运,这对于 total = 10 仍然可以很好地工作 - 对于 total = 15 它将花费比我需要更多的时间来格式化/复制粘贴并在此处制定此答案。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...