欢迎访问宙启技术站
智能推送

nextGaussian()函数生成正态分布的伪随机数的方法?

发布时间:2023-06-26 09:01:58

nextGaussian()函数是Java中Random类中一个常用的方法,其可以生成服从标准正态分布(均值为0,标准差为1)的伪随机数。它的产生方式是基于Box-Muller转换或Marsaglia-Polar转换的。

Box-Muller转换:

Box和Muller于1958年提出的一个方法。我们把生成服从均值为0,方差为1的两个独立随机变量的方法称为Box-Muller转换,它利用两个均匀分布的随机变量U1和U2 产生了两个服从标准正态分布的独立随机变量Z0和Z1。

具体实现方法如下:

1. 产生两个均匀分布随机变量u1和u2,它们的范围是[0,1]

2. 根据以下公式计算两个独立的标准正态分布随机变量z0和z1: 

    z0 = sqrt(-2 * ln(u1)) * cos(2 * pi * u2)

    z1 = sqrt(-2 * ln(u1)) * sin(2 * pi * u2)

3. z0和z1就是服从标准正态分布的伪随机数

Marsaglia-Polar转换:

此方法是由George Marsaglia于1964年提出的,相比于Box-Muller转换,它只需要产生一个均匀分布随机变量。

具体实现方法如下:

1. 产生两个均匀分布随机变量u1和u2,范围是[-1,1]

2. 计算s = u1^2 + u2^2

3. 如果s>=1,则返回步骤1重新计算,否则进入下一步

4. 根据以下公式计算标准正态分布随机变量z:

    z = u1 * sqrt(-2 ln(s) / s)

5. z就是服从标准正态分布的伪随机数

在Java中,nextGaussian()函数采用的是Box-Muller转换,其基本代码实现如下:

public double nextGaussian() {

  if (haveNextNextGaussian) {

   haveNextNextGaussian = false;

   return nextNextGaussian;

  } else {

   double v1, v2, s;

   do {

    v1 = 2 * nextDouble() - 1; //产生[-1,1)范围内的随机数

    v2 = 2 * nextDouble() - 1;

    s = v1*v1 + v2*v2;

   } while (s >= 1 || s == 0);

   double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s);

   nextNextGaussian = v2 * multiplier;

   haveNextNextGaussian = true;

   return v1 * multiplier;

  }

}

该函数首先判断是否之前已经生成了一个服从标准正态分布的伪随机数,如果有,则直接返回;如果没有,则执行Box-Muller转换计算出两个相互独立的标准正态分布随机变量,并将其中一个缓存下来,以备下次调用。最后返回其中一个随机变量作为函数结果。

在实际的编程应用中,我们经常需要生成不同均值和标准差的正态分布的伪随机数。此时可以将生成的标准正态分布随机变量z乘以标准差,再加上均值即可得到服从期望为均值,方差为标准差的正态分布随机变量。

综上所述,nextGaussian()函数通过Box-Muller转换来生成服从标准正态分布的伪随机数,其原理简单,易于实现,因此在Java中得到了广泛的应用。