随机化正态分布数字的偏差(javascript)

Bias in randomizing normally distributed numbers (javascript)

本文关键字:javascript 正态分布 数字 随机化      更新时间:2023-09-26

我在生成正态分布随机数(mu=0 sigma=1)时遇到问题使用JavaScript .

我尝试了Box-Muller的方法和ziggurat,但生成的一系列数字的平均值为0.0015或-0.0018 -离零很远!!超过50万个随机生成的数字是个大问题。它应该接近于零,比如0.000000000001。

我不知道这是一个方法问题,还是JavaScript的内置Math.random()生成不完全均匀分布的数字。

有没有人发现类似的问题?

这里可以找到ziggurat函数:

http://www.filosophy.org/post/35/normaldistributed_random_values_in_javascript_using_the_ziggurat_algorithm/

下面是Box-Muller的代码:
function rnd_bmt() {
    var x = 0, y = 0, rds, c;
    // Get two random numbers from -1 to 1.
    // If the radius is zero or greater than 1, throw them out and pick two
    // new ones. Rejection sampling throws away about 20% of the pairs.
    do {
        x = Math.random()*2-1;
        y = Math.random()*2-1;
        rds = x*x + y*y;
    }
    while (rds === 0 || rds > 1) 
    // This magic is the Box-Muller Transform
    c = Math.sqrt(-2*Math.log(rds)/rds);
    // It always creates a pair of numbers. I'll return them in an array. 
    // This function is quite efficient so don't be afraid to throw one away
    // if you don't need both.
    return [x*c, y*c];
}

如果生成n独立正态随机变量,则平均值的标准差将为sigma / sqrt(n)

在你的例子中n = 500000sigma = 1,所以平均值的标准误差大约是1 / 707 = 0.0014。95%置信区间,给定0均值,大约是这个的两倍或(-0.0028, 0.0028)。你们的抽样平均数正好在这个范围内。

您获得0.000000000001 (1e-12)的期望不是基于数学的。为了达到这个精度范围,您需要生成大约10^24个样本。以每秒10,000个样本的速度,这仍然需要3千万亿年的时间来完成……这就是为什么在可能的情况下最好避免模拟计算。

另一方面,你的算法似乎是正确实现的:)