1

我的教授正在模拟客户到银行。它表示客户遵循具有 3.5 均值和 1.3 标准偏差的正态分布到达。

问题是我在理解为什么使用此代码时遇到了一些困难。我相信他提供的代码是接收流、均值和标准来生成随机数

代码

public class Random {

    private static double second=0;

    static double normal(int stream, double mean, double std){
        double v1=0, v2=0, y1, y2, x1, x2, w=2;

        if (second!=0 ){
            return second;
        }

        while(w>1){
            v1=2*RandomGenerator.rand(stream)-1;
            v2=2*RandomGenerator.rand(stream)-1;
            w=Math.pow(v1,2)+Math.pow(v2,2);
        }

        y1=v1*Math.pow((-2*Math.log(w))/w, 0.5);
        y2=v2*Math.pow((-2*Math.log(w))/w, 0.5);
        x1=mean+y1*std;
        x2=mean+y2*std;
        second=x2;
        return x1;
    }

} 

我的数学课是很多年前的,所以理解这个正态分布有点困难,在网上搜索了如何计算正态分布后,我找不到任何类似于给定代码的公式。

所以,这些是我的问题。

  1. 做什么second?是某种保护吗?
  2. 这段代码如何使用正态分布?好像想不通...
4

1 回答 1

2

我将按相反的顺序回答问题。该方法的核心部分是一种标准技术,用于将从 [0, 1] 上的均匀分布中抽取的两个随机变量转换为从具有给定均值和标准差的正态分布中抽取的两个随机变量。(称为Box-Muller 变换。)while循环使用生成和测试技术从单位圆上的二维均匀分布生成随机点 (v1, v2)。从 (v1, v2) 到 (y1, y2) 的映射将均匀分布转换为具有零均值和单位标准偏差的二维正态分布。然后将其移动和缩放以获得具有所需均值和标准偏差的 (x1, x2)。

现在有了一种生成正态分布变量对的方法,其余代码的工作方式如下: if second == 0,这是一个需要生成新值的信号,因此它通过if并生成一对值。然后它保存其中一个值second并返回另一个。下次调用该方法时,它会注意到其中有一个有效值second并立即返回,而不是生成更多值。

代码中存在一个主要错误:在second返回值之前应该重置为零;否则它将始终继续返回第二个随机值(在第二次调用后看起来不会那么随机)。即使这个缺陷得到了纠正,还有第二个问题。每个其他返回值的值为 0 的概率为零。理论上这并不算太糟糕,因为正态分布的随机样本的值恰好为零的概率是……零!但是,这仍然是一个缺陷。

我将代码重写如下:

public class Random {

    private static double second;
    private static boolean secondValid = false;

    static double normal(int stream, double mean, double std) {
        double v1, v2, y1, y2, x1, x2, w;

        if (secondValid) {
            secondValid = false;
            return second;
        }

        do {
            v1 = 2 * RandomGenerator.rand(stream) - 1;
            v2 = 2 * RandomGenerator.rand(stream) - 1;
            w = v1 * v1 + v2 * v2;
        } while (w > 1);

        y1 = v1 * Math.sqrt(-2 * Math.log(w) / w);
        y2 = v2 * Math.sqrt(-2 * Math.log(w) / w);
        x1 = mean + y1 * std;
        x2 = mean + y2 * std;
        second = x2;
        secondValid = true;
        return x1;
    }

}
于 2012-05-02T15:27:59.167 回答