获得总和为M的N个随机数

mar*_*den 40 language-agnostic random sum

我想得到N个随机数,它们的总和是一个值.

例如,假设我想要5个随机数,它们的和为1

那么,一个有效的可能性是:

0.2 0.2 0.2 0.2 0.2
Run Code Online (Sandbox Code Playgroud)

其他可能性是:

0.8 0.1 0.03 0.03 0.04
Run Code Online (Sandbox Code Playgroud)

等等.我需要这个来创建模糊C均值的所有物矩阵.

Gui*_*ume 55

简答:

只需生成N个随机数,计算它们的总和,将每个除以总和并乘以M.

更长的答案:

上述解决方案并不能产生均匀分布取决于什么是用于这些随机数字,这可能是一个问题.Matti Virkkunen提出的另一种方法:

生成介于0和1之间的N-1个随机数,将数字0和1自身添加到列表中,对它们进行排序,并获取相邻数字的差异.

我不确定这是否会产生均匀分布

  • 然后乘以M(除非M在示例中为1). (22认同)
  • 这不是一个好的随机化,因为增加N会给出一个趋于零的方差 (11认同)
  • 这是一个糟糕的答案.看到这个答案证明使用漂亮的图表这个解决方案是错误的:http://stackoverflow.com/a/8068956/88821 (7认同)
  • 我想跳上"这个解决方案确实提供了良好的分布式答案"banwagon (3认同)

Mat*_*nen 42

生成介于0和1之间的N-1个随机数,将数字0和1自身添加到列表中,对它们进行排序,并获取相邻数字的差异.

  • @chovy:要获得"0在8之间",在算法中使用8而不是1,并使用3作为N.它的工作原理是它就像拿一根带有设定长度的字符串,在随机位置标记然后切割它是标记的位置.你最终得到N个字符串,必须加起来原始长度. (2认同)

Acc*_*dae 26

我认为值得注意的是,目前接受的答案并没有给出统一的分布:

"只需生成N个随机数,计算它们的总和,将每个数除以总和"

为了看到这一点,我们来看看N = 2和M = 1的情况.这是一个简单的情况,因为我们可以通过在范围(0,1)中统一选择x来生成列表[x,1-x].所提出的解决方案生成一对[x /(x + y),y /(x + y)],其中x和y在(0,1)中是均匀的.为了分析这个,我们选择一些z,使得0 <z <0.5并计算第一个元素小于z的概率.如果分布是均匀的,那么这个概率应该是z.但是,我们得到了

Prob(x /(x + y)<z)= Prob(x <z(x + y))= Prob(x(1-z)<zy)= Prob(x <y(z /(1-z) ))= z /(2-2z).

我做了一些快速的计算,似乎到目前为止唯一能够产生均匀分布的解决方案是由Matti Virkkunen提出的:

"生成介于0和1之间的N-1个随机数,将数字0和1自身添加到列表中,对它们进行排序,并获取相邻数字的差异."


cgn*_*utt 7

不幸的是,如果您想要统一的随机数,这里的许多答案都是不正确的。保证均匀随机数的最简单(在许多语言中也是最快)的解决方案就是

# This is Python, but most languages support the Dirichlet.
import numpy as np
np.random.dirichlet(np.ones(n))*m
Run Code Online (Sandbox Code Playgroud)

其中n是要生成的随机数的数量,m是结果数组的总和。此方法会产生正值,对于生成总和为 1 的有效概率(令 m = 1)特别有用。