假设我们有n
个投掷箱,我们投掷k
球。什么是快速(即使用numpy / scipy而不是python代码)的方式来生成所有可能的结果作为矩阵?
例如,如果n = 4
和k = 3
,我们需要以下numpy.array
:
3 0 0 0
2 1 0 0
2 0 1 0
2 0 0 1
1 2 0 0
1 1 1 0
1 1 0 1
1 0 2 0
1 0 1 1
1 0 0 2
0 3 0 0
0 2 1 0
0 2 0 1
0 1 2 0
0 1 1 1
0 1 0 2
0 0 3 0
0 0 2 1
0 0 1 2
0 0 0 3
如果错过任何排列,请道歉,但这是一般的想法。生成的排列不必具有任何特定的顺序,但上面的列表便于在心理上明确地迭代它们。
更好的是,有没有办法将每个从1到multiset number的整数(此列表的基数)直接映射到给定的排列?
这个问题与以下问题有关,这些问题在R中实现,具有非常不同的设施:
还有相关参考文献:
答案 0 :(得分:1)
这是使用itertools.combinations_with_replacement
的生成器解决方案,不知道它是否适合您的需求。
def partitions(n, b):
masks = numpy.identity(b, dtype=int)
for c in itertools.combinations_with_replacement(masks, n):
yield sum(c)
output = numpy.array(list(partitions(3, 4)))
# [[3 0 0 0]
# [2 1 0 0]
# ...
# [0 0 1 2]
# [0 0 0 3]]
这个函数的复杂性呈指数级增长,因此在可行和不可行之间存在着一个独立的边界。
请注意,虽然numpy数组需要在构造时知道它们的大小,但这很容易实现,因为很容易找到多重编号。 下面可能是一个更好的方法,我没有做任何时间。
from math import factorial as fact
from itertools import combinations_with_replacement as cwr
nCr = lambda n, r: fact(n) / fact(n-r) / fact(r)
def partitions(n, b):
partition_array = numpy.empty((nCr(n+b-1, b-1), b), dtype=int)
masks = numpy.identity(b, dtype=int)
for i, c in enumerate(cwr(masks, n)):
partition_array[i,:] = sum(c)
return partition_array
答案 1 :(得分:1)
出于参考目的,以下代码使用Ehrlich's algorithm来迭代C ++,Javascript和Python中多集的所有可能组合:
可以使用this method将其转换为上述格式。具体地,
for s in multichoose(k, set):
row = np.bincount(s, minlength=len(set) + 1)
这仍然不是纯粹的numpy,但可以很快用于填充预分配的numpy.array
。
答案 2 :(得分:0)
这是一个带有列表推导的天真实现,与numpy
相比,不确定性能judgeScoreList = judgeScores.split()
答案 3 :(得分:0)
这是我为此提出的解决方案。
import numpy, itertools
def multinomial_combinations(n, k, max_power=None):
"""returns a list (2d numpy array) of all length k sequences of
non-negative integers n1, ..., nk such that n1 + ... + nk = n."""
bar_placements = itertools.combinations(range(1, n+k), k-1)
tmp = [(0,) + x + (n+k,) for x in bar_placements]
sequences = numpy.diff(tmp) - 1
if max_power:
return sequences[numpy.where((sequences<=max_power).all(axis=1))][::-1]
else:
return sequences[::-1]
注1:最后的[:: - 1]只是反转顺序以匹配您的示例输出。
注2:找到这些序列相当于找到排列n个星和k-1个条的所有方法(填充n + k-1个点)(见stars and bars thm 2)。
注3:max_power参数是为您提供仅返回所有整数低于某个最大值的序列的选项。