我正在尝试找到一种方法来显示加起来给定整数的所有可能的X整数集。例如,获取所有2个整数集,使我得到5:
1, 4
2, 3
或者对于产生6的3个整数:
1, 1, 4
1, 2, 3
2, 2, 2
我只需要不包括0的整数,并且它只需要在一组中最多约15个并且最多30个。号。
我甚至不确定这是否有数学术语。它与我想的因子化相似吗?
答案 0 :(得分:19)
以下是解决此问题的一种方法:
def sum_to_n(n, size, limit=None):
"""Produce all lists of `size` positive integers in decreasing order
that add up to `n`."""
if size == 1:
yield [n]
return
if limit is None:
limit = n
start = (n + size - 1) // size
stop = min(limit, n - size + 1) + 1
for i in range(start, stop):
for tail in sum_to_n(n - i, size - 1, i):
yield [i] + tail
你可以这样使用它。
for partition in sum_to_n(6, 3):
print partition
[2, 2, 2]
[3, 2, 1]
[4, 1, 1]
答案 1 :(得分:9)
有一个代码段here:
from itertools import combinations, chain
def sum_to_n(n):
'Generate the series of +ve integer lists which sum to a +ve integer, n.'
from operator import sub
b, mid, e = [0], list(range(1, n)), [n]
splits = (d for i in range(n) for d in combinations(mid, i))
return (list(map(sub, chain(s, e), chain(b, s))) for s in splits)
像这样使用:
for p in sum_to_n(4):
print p
输出:
[4] [1, 3] [2, 2] [3, 1] [1, 1, 2] [1, 2, 1] [2, 1, 1] [1, 1, 1, 1]
答案 2 :(得分:0)
这些被称为整数的分区。其他人提供了定义它们的链接。
执行这些操作的技巧通常是递归地执行。例如,假设我想形成所有不同的方法来构建10作为正好三个整数的总和,其中没有一个出现多次。
查看该总和中可能的最大组件。可以10吗?不,因为如果最大的组件是10,那还剩下什么?即,10 - 10 = 0.事实证明,如果总和中的最大元素是7,那么剩下的,被分成两个正整数之和的是3.并且我们可以将3分成两个的总和完全一种方式的不同整数。所以{7,2,1}就是这样一个分区,也是唯一一个涉及7个元素的分区。
6可以用作最大的元素吗?如果是这样,那么我们将剩下4个。我们可以用一种方式打破4,产生分区{6,3,1}。进一步搜索将产生10的其他分区为{5,4,1},{5,3,2}。没有其他人可以存在。
关键是,此操作可以很容易地定义为递归函数。通过仔细编码,人们甚至可以使用记忆,以避免重新计算我们以前见过的那些。
答案 3 :(得分:0)
你的问题可以这样改写:
给定数字N,找到所有集合[S1,S2,S3 .....],其中每个集合的总和等于N.集合的大小由数字L给出。
首先让我们考虑L=2
的情况。这意味着您可以拥有以下集合
(9,1) , (8,2), (7,3) , (6,4) , (5,5)
我将此称为基础解决方案,您很快就会明白为什么。
现在让我们将L改为3并重新回答:
那么让我们考虑数字9.是否存在L
这样的列表sum(L) + 9 = 10
?显而易见的答案是否定的,但这里有趣的不是答案而是问题本身。我们基本上要求一组2
元素,这些元素可以概括为数字1
。这与基础解决方案解决的问题相同。
因此,对于x
中的每个号码[9,8,7,6,5,4,3,2,1]
,您尝试找到[a,b]
的{{1}}集合。
这不是一个完整的答案,但想法是你在这里看到模式,并使用递归来计算基本情况,如上所述,然后找出将完成你的解决方案的递归调用。祝你好运!