__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被精心选择”,但它们是如何被选择的?
__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被精心选择”,但它们是如何被选择的?
这看起来像是一个线性同余生成器。当乘数x
可以被模数减一的所有质因数整除时(这里的模数是0x3FFFFFFFF
,由于返回语句中的数学运算有点隐晦,因此有些隐藏),LCG会更好。
这是一个32位的LCG,它会舍弃最低16位。我怀疑这个生成器对于有趣的目的来说并不好。对于简单的游戏,这应该已经足够了。
你的具体问题可以通过我发布的链接得到答案:当且仅当x - 1是4的倍数(在维基百科的符号表示中,a是x,c是y,m是2 ^ 31),该生成器才能实现完整周期。
因此,当x为偶数时,该生成器并不是最佳选择。
seed = (a * seed + b) % m;
m
简单地是 2^n,其中 n 是 seed
的位数(假设它具有无符号类型,因为需要模算术)。有大量文献介绍如何选择 a
、b
和 m
;一般来说,根据参考文献(《随机数生成器:好的生成器很难找到》,Park 和 Miller,CACM,1988 年 10 月),m
应该是一个质数,而 b
通常可以为 0;这个生成器违反了这两个规则。(违反第一个规则倾向于使低位非常不随机,这就解释了为什么结果会被移位。)a
和m
的唯一方法是进行广泛的统计测试,尽管有一些方法可以识别出一些不好的选择。首先,a
和m
不应该有任何公共因子。(在最佳生成器中,两者通常都是质数。)在这里,m
是2的幂,并且将1添加到x
使其能够被2整除,因此您可以更或多少保证生成器的结果不会很好。