Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 生成N个和为1的数字_Java_Math_Random_Probability - Fatal编程技术网

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指出了这一点,这使得采样是一致的。方法(如果我理解清楚的话)是

  • 从范围[1,2,…,M-1]中生成n-1个不同的值
  • 对结果向量进行排序
  • 添加0和M作为结果向量的第一个和最后一个元素
  • 通过计算席-X-1生成一个新的向量,其中i= 1,2,…N也就是说,新向量由旧向量的连续元素之间的差异组成
  • 将新向量的每个元素除以M,就得到了均匀分布 我很想知道生成不同的随机值并通过除以它们的和将它们归一化为1是否也会产生均匀分布


    得到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;
    }