生成概率分布

给定一个大小为n的数组我想为每个索引生成随机概率,使得Sigma(a[0]..a[n-1])=1

一个可能的结果可能是:

 0 1 2 3 4 0.15 0.2 0.18 0.22 0.25 

另一个完全合法的结果可能是:

 0 1 2 3 4 0.01 0.01 0.96 0.01 0.01 

如何轻松快速地生成这些内容? 任何语言的答案都很好,Java首选。

您要完成的任务等同于从N维单位单纯形中绘制随机点。

http://en.wikipedia.org/wiki/Simplex#Random_sampling可能对您有所帮助。

一个天真的解决方案可能如下:

 public static double[] getArray(int n) { double a[] = new double[n]; double s = 0.0d; Random random = new Random(); for (int i = 0; i < n; i++) { a [i] = 1.0d - random.nextDouble(); a [i] = -1 * Math.log(a[i]); s += a[i]; } for (int i = 0; i < n; i++) { a [i] /= s; } return a; } 

要从N维单位单纯形中均匀地绘制一个点,我们必须采用指数分布随机变量的向量,然后通过这些变量的总和对其进行归一化。 为了获得指数分布的值,我们采用均匀分布值的负log

获得n个随机数,计算它们的总和,并通过将每个数除以总和来将总和标准化为1。

这是相对较晚的,但是为了表明@Kree在本文中给出的简单直接的答案的修正,@ dreeves指出,这使得采样均匀。 方法(如果我清楚地理解的话)是

  1. 从[1,2,…,M-1]范围生成n-1个不同的值。
  2. 对结果向量进行排序
  3. 添加0和M作为结果向量的第一个和最后一个元素。
  4. 通过计算x i -x i-1生成新的向量,其中i = 1,2,… n。 也就是说,新向量由旧向量的连续元素之间的差异组成。
  5. 将新矢量的每个元素除以M.你有均匀的分布!

我很想知道是否生成不同的随机值并通过除以它们将它们归一化为1也将产生均匀分布。

如果要有效地从正态分布生成值,请尝试Box Muller Transformation 。

获得n个随机数,计算它们的总和,并通过将每个数除以总和来将总和标准化为1。

扩展Kobi的答案 ,这是一个完全正确的Java函数。

 public static double[] getRandDistArray(int n) { double randArray[] = new double[n]; double sum = 0; // Generate n random numbers for (int i = 0; i < randArray.length; i++) { randArray[i] = Math.random(); sum += randArray[i]; } // Normalize sum to 1 for (int i = 0; i < randArray.length; i++) { randArray[i] /= sum; } return randArray; } 

在测试运行中, getRandDistArray(5)返回以下内容

 [0.1796505603694718, 0.31518724882558813, 0.15226147256596428, 0.30954417535503603, 0.043356542883939767] 
 public static double[] array(int n){ double[] a = new double[n]; double flag = 0; for(int i=0;i 

这里,首先存储随机数。 并且该标志将保持所有生成的数字的总和,以便在下一个for循环中生成的数字将被标志分割,最后数组将具有概率分布中的随机数。