algorithm - 关于Xorshift随机数生成算法

标签 algorithm language-agnostic random

以下是 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 是返回值,xyz 是状态 ("内存”)变量。但是,我无法理解多个内存变量的用途。谁能向我解释这一点?

此外,我尝试将上面的代码复制到 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')

这是绘图的输出:

plot

当生成 10000 个(而不是 100 个)数字时会发生以下情况: plot

总体趋势非常明显。不要忘记 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/

相关文章:

algorithm - DFS策略修正

algorithm - 匈牙利算法将一组与自身匹配

language-agnostic - 最好的图书馆做网络抓取

c++ - 单位半球表面上快速均匀分布的随机点

java - 如何调用此递归最长递增子序列函数

algorithm - 一种绘制等距曲线的方法

string - 如何通过迭代地从字符串中删除所有出现的某些指定单词来最小化字符串的长度

多维空间中的随机单位向量

android - 以随机顺序获取从 1 到 4 的数字

arrays - 将对象数组转换为集合