如何生成具有从 0 到给定上限的正态分布的随机正浮点数?

How to generate random positive floating point numbers with normal distribution from 0 up to a given ceiling?

我需要生成一些 float 数字,这些数字在从 0 到特定上限的范围内近似正态分布。

我搜索了堆栈溢出并发现了其他语言的类似问题,但 none .net 核心。

internal List<float> function(int ceiling, int repetitions)
{
    List<float> list = new List<float>();
    for (int i = 0; i<= repetitions;i++)
    {
         list.Add(Random.nextFloat() * ceiling);
    }
    return list;
}

我希望函数 return list 随机正数 float,范围从 0 到给定的上限,至少近似正态分布。

好吧,您可以使用截断法线和取绝对值来使结果为正。

沿线

double R = 10.0; // upper value of the truncated normal

var seed = 31234567;
Random rng = new Random( seed );

double u1 = rng.NextDouble();
double u2 = rng.NextDouble();

double phi = 2.0*Math.PI*u2;
double r   = Math.Sqrt(-2.0*Math.Log(1.0 - u1*(1.0 - Math.Exp(-R*R/2.0))));

return new Tuple<double,double>(Math.Abs(r*Math.Cos(phi)), Math.Abs(r*Math.Sin(phi)));

上面的代码应 return 从 0 到 R 的区间中的几个采样值,看起来像截断的高斯分布。您可以与标准高斯采样 Box-Muller 进行比较

如果您正在寻找边界为 0 和 ceiling 的东西 "at least approximately normal",将三个制服相加将产生对称、钟形和有界的结果,随后可以重新缩放到你想要的任何范围。我不是 C# 程序员,但如果你有一个名为 prng:

的 PRNG
(prng.NextDouble() + prng.NextDouble() + prng.NextDouble()) * ceiling / 3.0

将产生 [0, ceiling] 范围内的结果。这是 ceiling 设置为 3 的 100,000 个观察结果:

您可以将其概括为对 k 制服求和,并在除数中将 3 替换为 k 以进行重新缩放。 k 越大,中心极限定理越接近正态性,但由于您似乎并不要求快速进入的实际法线(无论如何都没有有界范围)递减 returns.

请注意,虽然此方法使用多个制服,但它在计算上相对有效,因为它避免了超越函数。