XorShift可以返回零吗?

时间:2017-06-26 05:14:18

标签: c++ random

我一直在阅读有关XorShift PRNG的文章,尤其是论文here

一个人here声明

  

数字位于[1,2 ** 64]的范围内。请注意,它永远不会是0。

查看有意义的代码:

uint64_t x;
uint64_t next(void) {
   x ^= x >> 12; // a
   x ^= x << 25; // b
   x ^= x >> 27; // c
   return x * UINT64_C(2685821657736338717);
}

如果x为零,则每个下一个数字也为零。但是不会让它变得不那么有用吗?如果只需要min + rand() % (max - min),通常的使用模式可能是int或将64位转换为32位。但是,如果永远不会返回0,那可能是一个严重的问题。此外,这些位不是01,但显然0缺失的概率相同,因此零或稍差。我甚至无法在维基百科上找到任何提及,所以我错过了什么?

那么在给定范围内从XorShift64 *生成随机,均匀分布的数字的好/适当方法是什么?

2 个答案:

答案 0 :(得分:2)

简短回答:不,它不能归零。

根据Numeric Recipes&#34;它产生一整段2^64-1 [...]缺失值为零&#34;。

本质上是仔细选择那些移位值来制作非常长的序列(完全可能的一个w / 0),因此可以确定每个数字都是产生的。零确实是这个生成器的固定点,因此它产生2个序列:零,另一个包含所有其他数字。

因此,对于足够小的范围max-min,IMO足以使函数(next() - 1) % (max - min) + min或甚至完全省略减法,因为模将返回零。 如果想要更好的质量平等分配,应该使用通常的&#39;使用next()作为范围为[1, 2^64)

的基础生成器的方法

答案 1 :(得分:-1)

我几乎可以肯定有一个x,xorshift操作返回0。

证明:

首先,我们有这些方程式:

a = x ^ (x >> 12);
b = a ^ (a << 25);
c = b ^ (b >> 27);

代替他们:

b = (x ^ x >> 12) ^ ((x ^ x >> 12) << 25);

c = b ^ (b >> 27) = ((x ^ x >> 12) ^ ((x ^ x >> 12) << 25)) ^ (((x ^ x >> 12) ^ ((x ^ x >> 12) << 25)) >> 27);

正如您所看到的,虽然c是一个复杂的等式,但它完全是阿贝尔的。

这意味着,您可以将c的位表示为x的位的完全布尔表达式。

因此,您可以简单地为位b0b1b2构建一个方程式系统,......所以:

(注意:系数只是示例,我没有计算它们,但看起来也是如此):

c0 = x1 ^ !x32 ^ x47 ...
c1 = x23 ^ x45 ^ !x61 ...
...
c63 = !x13 ^ ...

从那时起,你有64个方程和64个未知数。您只需使用Gauss-elimination解决问题,您将始终拥有一个独特的解决方案。

除了一些罕见的情况,即方程系统的系数的行列式为零,但这种大矩阵的大小不太可能。

即使它发生了,也意味着你在每次迭代中都有信息丢失,即你无法获得{{1}的所有2^64个可能值只有其中一些。

现在考虑更可能的可能性,系数矩阵是非零的。在这种情况下,对于x的所有可能2^64值,您的所有x值均为2^64,这些值都不同。

因此,你可以为零。

扩展名:实际上你得零为零...对不起,证明更有用的是表明它不像第一个地方那么简单。重要的是,您可以将c的位表示为c的位的布尔函数。

这个随机数生成器还有另一个问题。这就是即使你以某种方式修改函数 not 也有这样的问题(例如,通过在每次迭代中添加1):

  1. 您仍然无法保证它不会因x的任何可能值而进入短循环*。如果有值为345234523452345的5长度循环怎么办?你能证明所有可能的初始值吗?我不能。

  2. 实际上,拥有真正的伪随机迭代函数,您的系统可能会在x次迭代后循环。它有一个几乎无足轻重的组合理由,但不幸的是,这个边距很小,不能包含它。&#34; ; - )

  3. 所以:

    • 如果您的PRNG的2^32循环长度没问题,那么请使用从网上某处收集的经过验证的迭代函数。
    • 如果不是,请将位长升级到至少2^32。这将导致大约2^128循环长度,这并不是那么糟糕。
    • 如果您仍想要64位输出,则在内部使用128位数字,但返回2^64(即,将内部状态(x>>64) ^ (x&(2^64-1))的上半部分和下半部分对齐)。 / LI>