【问题标题】:Custom linear congruential generator in JavaScriptJavaScript 中的自定义线性同余生成器
【发布时间】:2013-07-11 14:31:31
【问题描述】:

我正在尝试在 JavaScript(glibc 中使用的那个)中创建一个自定义 linear congruential generator (LCQ)。

它的属性on Wikipedia 是:m=2^31a=1103515245c=12345

现在我正在获得下一个种子价值

x = (1103515245 * x + 12345) % 0x80000000 ; // (The same as &0x7fffffff)

虽然生成器似乎可以工作,但是在画布上测试数字时:

cx = (x & 0x3fffffff) % canvasWidth; // Coordinate x (the same for cy)

他们似乎有可怕的偏见:http://jsfiddle.net/7VmR9/3/show/

为什么会这样?通过选择不同的模数,视觉测试的结果看起来会更好。

测试 JSFiddle 在这里:http://jsfiddle.net/7VmR9/3/

更新

最后我将转换固定为画布坐标,如下公式:

var cx = ((x & 0x3fffffff)/0x3fffffff*canvasWidth)|0

现在像素坐标不像使用模运算时那样畸形了。

更新小提琴:http://jsfiddle.net/7VmR9/14/

【问题讨论】:

  • 对我来说,这个值好像减了 1?也许应该是 2^31 +1?我制作了一个动画来显示不同的值。 jsfiddle.net/cHbXk

标签: javascript canvas random functional-testing lcg


【解决方案1】:

是的,看起来你已经解决了。我也做过同样的事情。

线性同余生成器的形式为:

seed = (seed * factor + offset) % range;

但是,最重要的是,在从中获取实际随机数时,以下 起作用:

random = seed % random_maximum;

这不起作用,因为第二个模数似乎抵消了生成器的影响。相反,您需要使用:

random = floor (seed / range * random_maximum);

(这将是一个随机整数;删除floor 调用以获得随机浮点数。)


最后,我会警告你:在 JavaScript 中,当处理超过 dword 限制的数字时,会损失精度。因此,您的 LCG 的随机结果可能是随机的,但它们很可能与用 C++ 或其他实际支持双字数学的低级语言实现的同一 LCG 的结果不匹配。

同样由于不精确,LCG的周期极易被大大缩短。因此,例如,您引用的 glibc LCG 的循环可能是 40 亿(也就是说,它会在重新开始并重新生成完全相同的一组数字之前生成超过 40 亿个随机数)。这个 JavaScript 实现可能只会得到 10 亿,或者可能更少,因为当乘以因子时,这个数字会超过 40 亿,并且这样做会失去精度。

【讨论】:

    【解决方案2】:

    对于生成器,公式是(您在第一部分忘记了模数):

    current = (multiplier * current * modul + addend) % modulus) / modulus
    

    我意识到您尝试对其进行优化,因此我用它更新了小提琴,以便您可以将其用作优化的基础:

    http://jsfiddle.net/AbdiasSoftware/7VmR9/12/

    【讨论】:

    • 嗨,Ken,你说得对,我错误地生成了两个画布坐标。最后我用了这个转换:var cx = ((x & 0x3fffffff)/0x3fffffff*canvasWidth)|0;jsfiddle.net/7VmR9/14谢谢你的帮助!最好的问候
    猜你喜欢
    • 1970-01-01
    • 2015-08-22
    • 2013-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-29
    • 2016-07-03
    • 1970-01-01
    相关资源
    最近更新 更多