使用Box-Muller方法生成随机标准正态分布数

时间:2019-01-09 20:34:37

标签: c# gaussian

我需要生成均值0和Standard dev 1都包含在0和1之间的随机标准正态分布数。问题是,尽管代码正在运行,但生成的随机数不在0和1之间。

这是使用Box-muller算法的方法:

public double NextGaussian()
    {
            double u1 = r.NextDouble();
            double u2 = r.NextDouble();
            double left = Math.Cos(2.0 * Math.PI * u1);
            double right = Math.Sqrt(-2.0 * Math.Log(u2));
            double z = left * right;
            return this.mean + (z * this.standardDeviation);          
    }

然后在主要方法中:

Gaussian g = new Gaussian(0.0, 1.0);
double a = g.NextGaussian();

我希望变量a的值都在0到1之间,但实际输出都是数字

1 个答案:

答案 0 :(得分:0)

I think you problen lies in a missunderstanding of the normal distribution. A normal distribution gives you numbers in range (-inf, inf). Although the larger the absolute value the less probable the number is (not linear). You can see that on every picture of a normal distribution. To put it simple the mean is the value of the hightest probability and the standard deviation defines how peaky the curve is,

Since you want only values in [mean, mean + standard dev] i recommend to tweak the distribution a little and use the absolute value of the random number (in relation to the mean) and cut that at the standard deviation treating this value as the value of mean + standart dev.

public static double NextRandomWithinStandardDeviation(this Gaussian gaussian)
{
    return Math.Min(
        Math.Abs(gaussian.NextRandom() - gaussian.Mean) + gaussian.Mean,
        gaussian.Mean + gaussian.StandardDeviation
    );
}

However this will not be truely normal distributed. In fact 21.73% of all generated random numbers will be outside of your interval, witch raises the probability to get mean + standard deviation significantly.

An other approach could be to generate random number, until the generated number is within the interval. This could theoretically take forever, but probability to get a number outside of the interval after the fifth iteration is less than 0.01%.

public static double NextRandomWithinStandardDeviation(this Gaussian gaussian)
{
    double randomNumer;
    do
    {
        randomNumber = Math.Abs(gaussian.NextRandom() - gaussian.Mean) + gaussian.Mean;
    }while(randomNumber > gaussian.Mean + gaussian.StandardDeviation);

    return randomNumber;
}
相关问题