依赖PRNG

我对函数rand(x, y, seed)感兴趣,该函数根据参数返回(伪)随机数,具有以下属性:

  • 返回的值应该依赖于它的3个参数, 而不依赖于迄今为止调用rand的次数。 例如,假设这些调用按以下顺序进行:

    rand(0, 0, 123) = 1
    rand(0, 1, 123) = 2
    rand(0, 2, 123) = 3
    

    然后用相同的参数调用rand ,但以不同的顺序,我们应该得到相同的值。 例如:

    rand(0, 1, 123) = 2
    rand(0, 2, 123) = 3
    rand(0, 0, 123) = 1
    
  • 这个函数应该具有一个很好的正常特性(体面的,我并不需要任何特别的东西)。PRNG:大周期,均匀分布等。返回符合int的正整数很好。 如果你愿意,它也可以更高。

  • 假设这些数字将用于生成矩阵。 然后改变种子应确保生成的矩阵看起来与其他种子产生的矩阵看起来尽可能不同。 这应该发生尽可能多的种子:我不希望矩阵重复。
  • 如果有帮助,我的种子将永远是以毫秒为单位的unix时间戳(如果这使得它以某种方式更容易,也可以以秒为单位)。 所有参数可以高达32位signed int,但在函数内部使用64位值不是问题。

    我可以使用什么功能?

    我想到的是:

    佩林噪音似乎做了我想要的一些,但我不知道它是如何适合它作为一个PRNG,特别是分布明智。 我也不确定它有多高效,因为我的(x, y)参数是相当随机的,我不能为它们预先计算它。

    我还研究了以下功能:

    p = 1400328593
    rand(x, y, seed) = (x * x * seed + y * seed * seed + seed * x * y + seed) mod p
                     = (seed * (x * x + y * seed + x * y + 1)) mod p
    

    似乎产生了足够好的数字。 基于我的(非常薄弱的​​)测试,它们似乎分配得很好。 测试期限比较困难,但我没有这样做。

    更新:

    这里是上述函数的Ent的输出,其中C中的time(NULL)作为它的种子,以及(x, y) in {0 ... 999} x {0 ... 999}(x, y) in {0 ... 999} x {0 ... 999}生成的值:

    熵=每字节3.312850比特。

    最佳压缩将使此9207076字节文件的大小减少58%。

    9207076样本的卡方分布为229710872.43,随机超过这个值的时间不到0.01%。

    数据字节的算术平均值是52.3354(127.5 =随机)。 Pi的Monte Carlo值为4000000000(误差为27.32%)。 序列相关系数为0.036131(完全不相关= 0.0)。

    在实践中这是否足够好(理论上,上述测试表明它不是很好),还是有一些我应该使用的知名度?


    这听起来像你想要一个哈希函数。 如果SHA1的效率不是太低,就选择一个安全的,因为它保证了良好的分布特性; 否则,您可以使用常见的散列函数,如FNV。 只需使用您的种子和坐标作为输入数据,并使用散列作为随机值。


    你可以尝试使用Blum Blum Shub。 它具有可以直接计算系列的第n个值的属性,这看起来适合于您的情况。 它需要三个参数,p,q和x0。 p和q是素数,x0与p和q都相关。 所以你的论点x和y可以用来找到x和y的素数,然后它们将适用于p和q,然后你可以使用你的第三个参数为x0找到合适的值。 这有点乏味,Blum Blum Shub速度慢,因为它是一个密码RNG,但如果你真的不需要速度,那么它就可以工作,而且实施起来也不是很难。

    另一种方法是采用像CMWC这样的RNG,并用x + y ^ i + seed ^(2i)来填充发生器的第i个位置,运行一段时间的发生器(可能是一些次数等于它存储的值的数量),然后从中取出一个值。

    如果你想使用CMWC,你可以看看我在github上的实现,以及在这里用已知时间构造发生器的值。

    链接地址: http://www.djcxy.com/p/37301.html

    上一篇: dependent PRNG

    下一篇: random number generator for cluster environment