java 生成概率分布
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2171074/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Generating a probability distribution
提问by Yuval Adam
Given an array of size nI want to generate random probabilities for each index such that Sigma(a[0]..a[n-1])=1
给定一个大小的数组,n我想为每个索引生成随机概率,使得Sigma(a[0]..a[n-1])=1
One possible result might be:
一种可能的结果可能是:
0 1 2 3 4
0.15 0.2 0.18 0.22 0.25
Another perfectly legal result can be:
另一个完全合法的结果可以是:
0 1 2 3 4
0.01 0.01 0.96 0.01 0.01
How can I generate these easily and quickly? Answers in any language are fine, Java preferred.
如何轻松快速地生成这些?任何语言的答案都很好,首选 Java。
采纳答案by viaclectic
The task you are trying to accomplish is tantamount to drawing a random point from the N-dimensional unit simplex.
你试图完成的任务无异于从 N 维单元单纯形中抽取一个随机点。
http://en.wikipedia.org/wiki/Simplex#Random_samplingmight help you.
http://en.wikipedia.org/wiki/Simplex#Random_sampling可能会对您有所帮助。
A naive solution might go as following:
一个简单的解决方案可能如下:
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;
}
To draw a point uniformlyfrom the N-dimensional unit simplex, we must take a vector of exponentiallydistributed random variables, then normalize it by the sum of those variables. To get an exponentially distributed value, we take a negative logof uniformly distributed value.
为了从 N 维单位单纯形中均匀地绘制一个点,我们必须取一个指数分布的随机变量向量,然后通过这些变量的总和对其进行归一化。为了得到一个指数分布的值,我们取一个log均匀分布值的负数。
回答by Kobi
Get n random numbers, calculate their sum and normalize the sum to 1 by dividing each number with the sum.
获取 n 个随机数,计算它们的总和,并通过将每个数字除以总和将总和归一化为 1。
回答by ayePete
This is relatively late, but to show the ammendment to @Kobi's simple and straightforward answer given in this paperpointed to by @dreeves which makes the sampling uniform. The method (if I understand it clearly) is to
这是相对较晚的,但为了显示对@dreeves 指出的@Kobi在本文中给出的简单而直接的答案 的修正,这使得采样统一。方法(如果我理解清楚的话)是
- Generate n-1 distinctvalues from the range [1, 2, ... , M-1].
- Sort the resulting vector
- Add 0 and M as the first and last elements of the resulting vector.
- Generate a new vector by computing xi- xi-1where i = 1,2, ... n. That is, the new vector is made up of the differences between consecutive elements of the old vector.
- Divide each element of the new vector by M. You have your uniform distribution!
- 从范围 [1, 2, ... , M-1]生成 n-1 个不同的值。
- 对结果向量进行排序
- 添加 0 和 M 作为结果向量的第一个和最后一个元素。
- 通过计算 x i- x i-1生成一个新向量,其中 i = 1,2, ... n。也就是说,新向量由旧向量的连续元素之间的差异组成。
- 将新向量的每个元素除以 M。你有你的均匀分布!
I am curious to know if generating distinctrandom values and normalizing them to 1 by dividing by their sum will also produce a uniform distribution.
我很想知道生成不同的随机值并通过除以它们的总和将它们归一化为 1 是否也会产生均匀分布。
回答by Stevoisiak
Get n random numbers, calculate their sum and normalize the sum to 1 by dividing each number with the sum.
获取 n 个随机数,计算它们的总和,并通过将每个数字除以总和将总和归一化为 1。
Expanding on Kobi's answer, here's a Java function that does exactly that.
扩展 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;
}
In a test run, getRandDistArray(5)returned the following
在测试运行中,getRandDistArray(5)返回以下内容
[0.1796505603694718, 0.31518724882558813, 0.15226147256596428, 0.30954417535503603, 0.043356542883939767]
回答by srihari krishna
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;
}
Here, at first astores random numbers. And the flagwill keep the sum all the numbers generated so that at the next for loop the numbers generated will be divided by the flag, which at the end the array will have random numbers in probability distribution.
在这里,首先a存储随机数。并且flag将保留所有生成的数字的总和,以便在下一个 for 循环中生成的数字将除以flag,最后数组将具有概率分布的随机数。
回答by James McLeod
If you want to generate values from a normal distribution efficiently, try the Box Muller Transformation.
如果您想有效地从正态分布生成值,请尝试Box Muller 变换。

