在 Python 中生成所有可能的长度为 N 且总和为 S 的列表

Generate all possible lists of length N that sum to S in Python(在 Python 中生成所有可能的长度为 N 且总和为 S 的列表)
本文介绍了在 Python 中生成所有可能的长度为 N 且总和为 S 的列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我正在尝试生成所有可能的长度为 N 且总和为 S 的列表.我已经编写了一些代码来执行此操作,但是对于任何大的(特别是,我想要 N=5,S=100),我遇到内存溢出错误.

I'm trying to generate all possible lists of Length N that sum to S. I've written some code to do so, but on anything large (in particular, I want N=5, S=100), I run into memory overflow errors.

我正在寻找更好的解决方案或改进代码的方法,以便我可以在 N=5、S=100 上运行它.下面这两个程序协同工作以在嵌套列表中创建所有可能的数字组合,然后将它们重新加工成正确的格式.下面复制了一些示例输出.

I'm looking for either a better solution to the problem, or a way to improve my code so I can run it on N=5, S=100. These two programs below work in tandem to create all the possible number combinations in nested lists, and then re-work them to be the right format. Some sample output is reproduced below.

我知道我的代码不是最好的.我是一名工程师(我知道,我知道),所以编码并不是我的专长.感谢您提供的任何帮助.

I know my code isn't the best. I'm an engineer by trade (I know, I know), so coding isn't exactly my forte. I appreciate any help you can provide.

我只是想澄清一些事情.首先,列表中可以有零,列表可以包含相同数字的倍数,并且列表中数字的顺序很重要.

I just wanted to clarify a few thing. First, it's ok to have zero in the lists, the lists can contain multiples of the same number, and the order of the numbers in the lists matters.

def nToSum(N,S):
    ''' Creates a nested list of all possible lists of length N that sum to S'''
    if N <= 1: #base case
        return [S]
    else:
        L = []
        for x in range(S+1):   #create a sub-list for each possible entry of 0 to S 
            L += [[x,nToSum(N-1,S-x)]]  #create a sub-list for this value recursively
        return L

def compress(n=[],L): #designed to take in a list generated by nToSum
    '''takes the input from nToSum as list L, and then flattens it so that each list is a
       top level list.  Leading set n is the "prefix" list, and grows as you climb down the 
       sublists'''
    if type(L[0]) == int:  #base case:  you have exposed a pure integer
        return [n+L]       #take that integer, and prepend the leading set n
    else:
        Q = []
        for x in L:  # look at every sublist
            Q += compress(n+[x[0]],x[1])  # for each sublist, create top level lists recursively
        return Q                          # note:  append x[0] to leading set n

>>> nToSum(3,3)
[[0, [[0, [3]], [1, [2]], [2, [1]], [3, [0]]]], [1, [[0, [2]], [1, [1]], [2, [0]]]], [2, [[0, [1]], [1, [0]]]], [3, [[0, [0]]]]]

>>> compress([],nToSum(3,3))
[[0, 0, 3], [0, 1, 2], [0, 2, 1], [0, 3, 0], [1, 0, 2], [1, 1, 1], [1, 2, 0], [2, 0, 1], [2, 1, 0], [3, 0, 0]]

推荐答案

使用生成器可以节省内存(如果使用 Python 2,则使用 xrange 而不是 range).这就是我想出的.它与您的 nToSum 非常相似,无需 compress.

Using a generator saves on memory (usexrange instead of range if using Python 2). This is what I came up with. It is very similar to your nToSum without the need for compress.

def sums(length, total_sum):
    if length == 1:
        yield (total_sum,)
    else:
        for value in range(total_sum + 1):
            for permutation in sums(length - 1, total_sum - value):
                yield (value,) + permutation

L = list(sums(5,100))
print('total permutations:',len(L))

# First and last 10 of list
for i in L[:10] + L[-10:]:
    print(i)

输出

total permutations: 4598126
(0, 0, 0, 0, 100)
(0, 0, 0, 1, 99)
(0, 0, 0, 2, 98)
(0, 0, 0, 3, 97)
(0, 0, 0, 4, 96)
(0, 0, 0, 5, 95)
(0, 0, 0, 6, 94)
(0, 0, 0, 7, 93)
(0, 0, 0, 8, 92)
(0, 0, 0, 9, 91)
(98, 0, 2, 0, 0)
(98, 1, 0, 0, 1)
(98, 1, 0, 1, 0)
(98, 1, 1, 0, 0)
(98, 2, 0, 0, 0)
(99, 0, 0, 0, 1)
(99, 0, 0, 1, 0)
(99, 0, 1, 0, 0)
(99, 1, 0, 0, 0)
(100, 0, 0, 0, 0)

这篇关于在 Python 中生成所有可能的长度为 N 且总和为 S 的列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

patching a class yields quot;AttributeError: Mock object has no attributequot; when accessing instance attributes(修补类会产生“AttributeError:Mock object has no attribute;访问实例属性时)
How to mock lt;ModelClassgt;.query.filter_by() in Flask-SqlAlchemy(如何在 Flask-SqlAlchemy 中模拟 lt;ModelClassgt;.query.filter_by())
FTPLIB error socket.gaierror: [Errno 8] nodename nor servname provided, or not known(FTPLIB 错误 socket.gaierror: [Errno 8] nodename nor servname provided, or not known)
Weird numpy.sum behavior when adding zeros(添加零时奇怪的 numpy.sum 行为)
Why does the #39;int#39; object is not callable error occur when using the sum() function?(为什么在使用 sum() 函数时会出现 int object is not callable 错误?)
How to sum in pandas by unique index in several columns?(如何通过几列中的唯一索引对 pandas 求和?)