给定一个大小为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首选。
答案 0 :(得分:22)
获取n个随机数,计算它们的总和,并通过将每个数除以总和来将总和标准化为1。
答案 1 :(得分:16)
您要完成的任务无异于从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
。
答案 2 :(得分:1)
这是相对较晚的,但是为了表明对@ Kree的简单直截了当的答案的修正,@ {@ 3%}指出@dreeves使得采样均匀。该方法(如果我清楚地理解的话)是
我很想知道生成不同随机值并通过除以它们将它们归一化为1也会产生均匀分布。
答案 3 :(得分:0)
如果您想有效地从正态分布中生成值,请尝试Box Muller Transformation。
答案 4 :(得分:0)
获取n个随机数,计算它们的总和并将总和标准化为1 用每个数字除以总和。
Expanding on Kobi's answer,这是一个完全正确的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]
答案 5 :(得分:0)
public static double[] array(int n){
double[] a = new double[n];
double flag = 0;
for(int i=0;i<n;i++){
a[i] = Math.random();
flag += a[i];
}
for(int i=0;i<n;i++) a[i] /= flag;
return a;
}
这里,首先 a 存储随机数。并且 flag 将保留所有生成的数字的总和,以便在下一个for循环中将生成的数字除以 flag ,该数字最后将包含概率分布中的随机数。