生成概率分布
给定一个大小为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,2,…,M-1]范围生成n-1个不同的值。
- 对结果向量进行排序
- 添加0和M作为结果向量的第一个和最后一个元素。
- 通过计算x i -x i-1生成新的向量,其中i = 1,2,… n。 也就是说,新向量由旧向量的连续元素之间的差异组成。
- 将新矢量的每个元素除以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循环中生成的数字将被标志分割,最后数组将具有概率分布中的随机数。