8

根据这个 Stack Overflow 线程,JavaScript 中的 Math.random() 取决于浏览器或操作系统。基本上,这意味着 JavaScript 没有生成统一随机变量的标准算法。这个线程似乎表明 Chrome 的统一随机数算法特别糟糕。

在我的程序中,我尝试根据一些信息和随机噪声来了解用户的行为。我对 Math.random() 生成的数字使用 Box-Muller 变换来生成高斯随机数。这是否意味着使用一种浏览器的用户会遇到与其他浏览器不同类型的噪音?注意我使用 Box Muller 是因为我不关心速度,但我知道它可能对伪随机数的生成方式特别敏感。似乎有很多关于为什么 Math.random() 不好的线程,但在线程中并没有那么多关于实际使用什么的线程。最佳做法是什么?有什么我应该特别注意的,因为我使用 Box-Muller 转换为高斯数?

4

2 回答 2

2

在http://en.wikipedia.org/wiki/Xorshift有一个基于 xor-shift 的 RNG,它具有良好的随机性属性,应该很容易移植到 JavaScript:

编辑完成:

(function () {
    var x = 123456789;
    var y = 362436069;
    var z = 521288629;
    var w = 88675123;
    var f = Math.pow(2, -32);

    Object.defineProperty(Math, 'xor128', {
        value: function () {
            var t = x ^ (x << 11);
            x = y;
            y = z;
            z = w;
            w = w ^ (w >>> 19) ^ (t ^ (t >>> 8));

            return (w >>> 0) * f;  // convert to floating point          
        }
    });

})();

注意:这仅使用生成的 128 位中的 32 位来产生浮点结果。理论上,您可以将来自其他状态变量之一的另外 20 位组合起来以产生 52 位结果。

我能看到的最重要的问题是它不支持播种——它总是会生成相同的序列。

于 2013-10-22T14:26:14.560 回答
1

Box-Muller变换仅适用于均匀分布的输入。根据MDN(最后一个示例),Math.random()不会生成均匀分布的数字。

ECMAScriptMath.random()规范对:

返回一个带正号的数值,大于或等于 0 但小于 1,随机或伪随机选择,在该范围内具有近似均匀的分布,使用依赖于实现的算法或策略。此函数不接受任何参数。

所以,这取决于浏览器。浏览器可能但不必实现完美均匀分布的随机数生成器。

因此,您无法在浏览器端使用 Javascript 可靠地实现跨浏览器 Box-Muller 转换Math.random()

于 2013-10-22T14:18:17.843 回答