Java 生成N个和为1的数字
给定一个大小为Java 生成N个和为1的数字,java,math,random,probability,Java,Math,Random,Probability,给定一个大小为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个随机数,计算它们的和,并通过将每个数除以和将和标准化为1。您
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个随机数,计算它们的和,并通过将每个数除以和将和标准化为1。您试图完成的任务相当于从n维单位单纯形中绘制一个随机点 也许对你有帮助 简单的解决方案可能如下所示:
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;
}
publicstaticdouble[]getArray(intn)
{
双a[]=新双[n];
双s=0.0d;
随机=新随机();
对于(int i=0;i
为了从N维单位单纯形中均匀地画出一个点,我们必须取一个指数分布的随机变量向量,然后用这些变量的和来规范化它。为了得到指数分布的值,我们取均匀分布值的负
log
。如果您想有效地从正态分布生成值,请尝试。这相对较晚,但要展示对@Kobi在这篇文章中给出的简单而直接的答案的修正,@dreeves指出了这一点,这使得采样是一致的。方法(如果我理解清楚的话)是
得到n个随机数,计算它们的和,并将和标准化为1 将每个数除以和 ,这里有一个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;
}
公共静态双[]数组(int n){
双精度[]a=新双精度[n];
双标志=0;
因为(inti=0;iNice:)没有想到……תהה!这引入了偏差。你不能用这种方法从单纯形中统一采样。@dreeves-你能详细说明一下吗?本文的图2--给出了你提出的标准化方法的n=3情况下的偏差的视觉描述。我相信kohomologie的答案是正确的(虽然我没有检查它们包含的代码)。在大多数语言中,你应该只创建一次Random
,否则你将不会得到随机结果(在许多情况下,重复相同的数字)。我还担心log
-你能解释一下为什么会有吗?+1作为参考,但我认为nextDouble()
已经为均匀分布进行了调整:Kobi,谢谢你指出了新的Random()
东西。至于日志
——我编辑了我的帖子,包括更全面的解释。垃圾神,nextDouble()从[0,1]返回均匀分布的值所以当我们取n个这样的值时,我们得到一个平行面上的随机点。如果我们将这个点的坐标除以这个点和原点之间的曼哈顿距离,我很不确定我们会得到一个单位单纯形中的均匀分布点。谢谢你的澄清;算法假定均匀分布,并使用-ln来得到re所需的指数分布。西格玛是指标准偏差?我希望你意识到,只要你说标准偏差,你就自动暗示你是从正态分布中提取随机数。大多数计算机RNG从均匀分布中提取数字。你可以通过意识到中心极限来回避这个问题定理可以帮助你:也就是说,你想从正态分布中抽取一个数字,就是从RNG均匀分布中抽取N个数字,取其平均值,生成一个随机的“正态”值,其中N足够大,可以满足你的需要(最好是N>1,这就是你现在所做的)。@gmatt:不,他的意思是“和”看看他的例子
[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<n;i++){
a[i] = Math.random();
flag += a[i];
}
for(int i=0;i<n;i++) a[i] /= flag;
return a;
}