以下是 Xorshift RNG 的基本实现(从维基百科复制):
uint32_t xor128(void) {
static uint32_t x = 123456789;
static uint32_t y = 362436069;
static uint32_t z = 521288629;
static uint32_t w = 88675123;
uint32_t t;
t = x ^ (x << 11);
x = y; y = z; z = w;
return w = w ^ (w >> 19) ^ (t ^ (t >> 8));
}
我理解 w
是返回值,x
、y
和 z
是状态 ("内存”)变量。但是,我无法理解多个内存变量的用途。谁能向我解释这一点?
此外,我尝试将上面的代码复制到 Python:
class R2:
def __init__(self):
self.x = x = 123456789
self.y = 362436069
self.z = 521288629
self.w = 88675123
def __call__(self):
t = self.x ^ (self.x<<11)
self.x = self.y
self.y = self.z
self.z = self.w
w = self.w
self.w = w ^ (w >> 19) ^(t ^ (t >> 8))
return self.w
然后,我生成了 100 个数字并绘制了它们的 log10
值:
r2 = R2()
x2 = [math.log10(r2()) for _ in range(100)]
plot(x2, '.g')
这是绘图的输出:
当生成 10000 个(而不是 100 个)数字时会发生以下情况:
总体趋势非常明显。不要忘记 Y 轴是实际值的 log10
。
很奇怪的行为,你不觉得吗?
最佳答案
这里的问题当然是您正在使用 Python 来执行此操作。
Python 具有大整数的概念,因此即使您正在复制处理 32 位数字的实现,Python 也只是说“我会继续为您保留所有内容”。
如果您尝试这样做:
x2 = [r2() for _ in range(100)]
print(x2);
您会注意到它会产生越来越长的数字,例如这是第一个数字:
252977563114
这是最后一个:
8735276851455609928450146337670748382228073854835405969246191481699954934702447147582960645
这是已修复的代码来处理这个问题:
...
def __call__(self):
t = self.x ^ (self.x<<11) & 0xffffffff # <-- keep 32 bits
self.x = self.y
self.y = self.z
self.z = self.w
w = self.w
self.w = (w ^ (w >> 19) ^(t ^ (t >> 8))) & 0xffffffff # <-- keep 32 bits
return self.w
...
关于algorithm - 关于Xorshift随机数生成算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4508043/