【问题标题】:What is the theory behind this PRNG?这个 PRNG 背后的理论是什么?
【发布时间】:2011-10-27 13:01:11
【问题描述】:
__forceinline static int Random()
{
    int x = 214013, y = 2531011;
    seed = (x * seed + y);
    return ((seed >> 16) & 0x7FFF) - 0x3FFF; 
}

上面的代码返回的 PRNG 分布均匀。

现在将 x 更改为 x + 1 - 生成的序列不能再称为 PRNG。

那么(这个)PRNG 背后的理论是什么? “x 和 y 是经过精心挑选的”,但它们是如何选择的?

【问题讨论】:

  • Normal distribution?你确定这就是你的意思吗?
  • Fred Larson:我编辑了我的帖子,抱歉我的“错字”。我写正态分布是因为(如果我认为正确的话)正态分布是从现实世界中观察到的,所以一个好的 PRNG 应该复制正态分布的行为以生成一个好的随机序列?我是对的吗?顺便说一句,生成器来自这里software.intel.com/en-us/articles/…
  • 一些自然现象被很好地建模为正态分布。其他的,例如掷骰子,则不是。
  • André Caron、Fred Larson:好的,谢谢,我刚刚从 wiki 阅读了关于统一分发的内容,现在我明白了!

标签: c++ random theory


【解决方案1】:

这看起来像Linear congruential generator。当乘数 x 可以被模数减一的所有质因数整除时,LCG 会更好(这里是 0x3FFFFFFFF,由于 return 语句中的数学运算,它有点隐藏)。

【讨论】:

  • 这里的模数实际上是 0x80000000。它是 x - 1 可被 m 的素因子整除,而不是 x 可被 m - 1 的素因子整除(这里是素数)
【解决方案2】:

它是一个 32 位的 LCG,它丢弃了最低的 16 位。我怀疑这个生成器是否适合有趣的目的。对于简单的游戏,这应该足够了。

我发布的链接回答了您的具体问题:当且仅当 x - 1 是 4 的倍数(在维基百科的符号中,a 是 x,c 是 y 和 m 是2^31)。

因此,当 x 为偶数时,生成器不是最优的。

【讨论】:

    【解决方案3】:

    这是一个线性全等生成器。还应该有一个模数;这 经典公式是:

    seed = (a * seed + b) % m;
    

    在这种情况下,m 只是 2^n,其中 n 是 seed 中的位数 (它可能有一个无符号类型,因为模算术是 需要)。关于如何选择abm;一般来说,根据参考文件(随机数 发电机:很难找到好的发电机,Park 和 Miller,CACM,10 月。 1988),m应该是质数,b一般可以为0;这 生成器违反了这两个规则。 (违反第一个往往 使低位非常非随机,这解释了为什么结果 被转移了。)

    据我所知,只有这样才能保证am的选择 好的是做广泛的统计测试,虽然有办法 找出一些不好的。对于初学者,am 应该没有 共同因素。 (在最好的生成器中,两者通常都是素数。) 这里,m 是 2 的幂,x 加一可以被 2 整除 同样,因此您或多或少可以保证生成的生成器 不会很好。

    有关详细信息,我建议您阅读这篇文章。

    【讨论】:

    • 没有办法选择 a 和 m 以使 LCG 通过,例如。顽固的测试。应该不惜一切代价避免 LCG。
    • @AlexandreC。有更好的 PRN 生成器,至少对于更好的通常定义而言。然而,对于许多应用程序来说,精心挑选am 的 LCG 就足够了,而且它通常比其他替代方案快很多。 (对于其他应用程序,当然不是,必须使用其他一些算法。例如,LCG 不是密码安全的。)
    • James Kanze:感谢您的链接和文章。 Alexandre C.:特别是现在我使用此 PRNG 为我的音频应用程序生成白噪声。我真的需要非常快速的解决方案,这个 PRNG 就是这种情况,我也没有抱怨它产生的噪音 - 对我来说似乎很好。
    • @Vadim:这取决于你如何处理噪音。 LCG 的统计特性很差,并且有现代统计上更好的替代方案至少表现得一样好(例如 XOR-shift,参见 Marsaglia 的工作)。对于数值应用,我避免 LCG 之类的瘟疫,因为从 LCG 中提取的随机向量往往是完全非随机的。
    • Alexandre C.:我想过滤噪声以获得一堆本身有一定宽度的谐波 - 因此是噪声。然后我将从谐波中重建波形。这个 PRNG 就足够了吗?我暂时没有尝试这样做,所以我不知道这个 PRNG 是否会起作用。我现在还要检查异或移位。如果您有任何建议或您知道性能更好更快的源代码,如果您发布它会很高兴。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-08
    • 2015-06-09
    • 2013-01-22
    • 2011-02-06
    • 2021-02-15
    • 2018-03-19
    相关资源
    最近更新 更多