将n的和的所有可能分布打印到m个空间

时间:2018-10-14 21:07:56

标签: python algorithm permutation

例如,想要将3加到4个空格中将是:

3 0 0 0, 
0 3 0 0,
0 0 3 0,
0 0 0 3,
0 1 1 1,
1 0 1 1,
1 1 0 1,
1 1 1 0,
2 1 0 0,
... 

或3之和等于2的空格将是:

2 1
1 2
0 3
3 0

2 个答案:

答案 0 :(得分:3)

您要查找的序列称为compositions

查找数字 n 的组成等同于选择从0到 n 的间隔中的索引。您可以通过获取连续选定的索引之间的距离来恢复构图。

示例

给出数字 n = 3 ,我们想要一个长度为 4 的组合。

前两个索引必须 0 3 ,因为这是我们的范围。然后,我们在间隔 [0,1,2,3] 中选择另外三个索引,以精确地生成 4 间隙。

[0, 1, 2, 3]
 ^     ^  ^
       ^  ^

因此,我们选择了 0、2、2、3、3 。我们通过获取连续索引之间的距离来恢复组成。即是 [2,0,1,0]

这对应于将数字替换为从 0到3 的组合。因此,我们可以使用itertools.combinations_with_replacement并将每个这样的组合转换为相应的组合。

代码

def compositions(sum_, n):
    for indices in combinations_with_replacement(range(sum_ + 1), n - 1):
        yield [b - a for a, b in zip([0, *indices], [*indices, sum_])]

print(*compositions(3, 4))

输出

[0, 0, 0, 3]
[0, 0, 1, 2]
[0, 0, 2, 1]
[0, 0, 3, 0]
[0, 1, 0, 2]
[0, 1, 1, 1]
[0, 1, 2, 0]
[0, 2, 0, 1]
[0, 2, 1, 0]
[0, 3, 0, 0]
[1, 0, 0, 2]
[1, 0, 1, 1]
[1, 0, 2, 0]
[1, 1, 0, 1]
[1, 1, 1, 0]
[1, 2, 0, 0]
[2, 0, 0, 1]
[2, 0, 1, 0]
[2, 1, 0, 0]
[3, 0, 0, 0]

答案 1 :(得分:1)

使用itertools.productfilter创建所有可能性,然后过滤总和为3的可能性

from itertools import product

lst = [0, 1, 2, 3]
print(list(filter(lambda x: sum(x) == 3, product(lst, repeat = 4))))
print(list(filter(lambda x: sum(x) == 3, product(lst, repeat = 2))))