如何获取N个随机整数,它们的总和等于M

6

我希望生成一个长度为N的随机整数序列,其总和为M。

我尝试使用Python中的numpy和dirichlet函数,但是它们生成的是双精度浮点数数组,而我需要生成随机整数。

import numpy as np 
np.random.dirichlet(np.ones(n))*m

解决方案可以使用其他分发方式,即解决问题的方法。

有没有整数的分布? - Julian Solarte
我撤回了我的评论,因为我看到你正在乘以“m”,所以你最终确实会得到可以被截断的东西,但事实仍然是,根据定义,狄利克雷是一个实数分布。二项式分布和泊松分布是两种常见的离散分布,但它们不具有您所需的求和属性。 - RishiG
1
哦——看看这个。看起来多项式分布是一个好选择。虽然分布不同于狄利克雷分布,但是生成的数字总和可以保证与给定值相等,而使用狄利克雷分布则不能保证。 - RishiG
非常感谢,它解决了我的问题。我已经编辑了问题,这样你就可以回答我的问题了。 - Julian Solarte
没关系。我并不是非常在意这个问题的接受度,我更多地是对找到答案感兴趣。我写了一个答案只是因为我有相关信息。 - RishiG
3个回答

7
使用dirichlet的问题在于它是实数分布。它将产生一个范围在(0,1)内、总和为1的数字向量,但截断或舍入可能会删除特定总和的保证。根据这篇文章,我们可以使用multinomial分布(使用np.random.multinomial)来获得所需的效果,方法如下:
from numpy.random import multinomial

np.random.multinomial(m, np.ones(n)/n)

这将生成n个介于0m之间的整数,它们的总和为m,在抽取给定位置时具有相等的概率。最简单的方式是将结果视为从一组固定对象(例如,掷骰子从1到6的整数)中进行抽取的一组绘画,其中最终数组是相应对象被抽取的次数。总数将始终汇总到给定的总绘制数(掷骰子)。

1
这是一个示例解决方案:

import numpy as np

M = 50 # The fixed sum
N = 5 # The amount of numbers

array = np.random.multinomial(M, np.ones(N) / N)[0]
print(array)

1
请注意,Dirichlet分布可用于参数化多项式,从而控制箱子的平滑度或“均匀性”,例如:
import numpy as np 

m = 50
n = 5
s = 0.1

np.random.multinomial(m, np.random.dirichlet(np.ones(n) * s))

大多数时候被参数化为@Bonfire,但更大的值(例如尝试s = 100)使得bin趋近于具有平均值= m/n 的泊松分布,而较小的值则导致更大的方差。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接