【问题标题】:Priming the Mersenne twister PRNG启动梅森捻线机 PRNG
【发布时间】:2012-10-29 01:20:58
【问题描述】:

似乎有一些关于使用 mt19937 的神话,特别是一旦播种生成器产生的“某些”比特数应该被忽略,以便尽可能接近伪随机性。

我见过的代码示例如下:

boost::mt19937::result_type seed = 1234567; //taken from some entropy pool etc
boost::mt19937 prng(seed);
boost::uniform_int<unsigned int> dist(0,1000);
boost::variate_generator<boost::mt19937&,boost::uniform_int<unsigned int> > generator(prng,dist);

unsigned int skip = 10000;
while (skip--)
{
   generator();
}

//now begin using for real.
....

我的问题是:

  1. 这是神话还是有一些真实性?

  2. 如果可行,应该忽略多少位?正如我所看到的数字
    似乎很随意

【问题讨论】:

  • 这家伙似乎暗示这不是神话:math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html——如果我没看错的话,捻线机需要“一些时间”才能清除起始状态的初始零,并且如果您使用大部分为零的初始状态进行初始化(例如,使用单个 32 位值,将扭曲器的大部分状态保留为零),则这些值将是“不够随机的”(或者,太类似于与种子的汉明距离较低的其他值)。这仅略高于维基百科的研究水平,因此请谨慎对待。
  • @Yakk 很有趣,所以我一直看到的所有这些恶作剧似乎都有“东西”。
  • 无论真实性或所需的迭代次数如何,正确的解决方案不是用熵池中的随机位填充整个种子,而不是仅填充前 32 位或其他任何位吗?
  • Gilly:这个问题和 Java 有什么关系?

标签: c++ math random boost-random


【解决方案1】:

第一条评论中引用的论文 Mersenne Twister with improved initialization 不仅仅是某个人,他还是 Boost 实现所依据的论文的两位合著者之一。

根据Boost documentation,使用单个 32 位整数(4 字节)作为此生成器的种子的问题是生成器的内部状态为 2496 字节。这么小的种子需要一段时间才能传播到生成器的其余内部状态,这并不奇怪,特别是因为 Twister 并不意味着加密安全。

为了解决您对需要运行生成器一段时间才能开始的担忧,您需要备用(和显式)构造函数。

template<typename SeedSeq> explicit mersenne_twister_engine(SeedSeq &);

这就是第三条评论的精神,在这里你用比单个整数更长的东西进行初始化。序列提供来自某个生成器。要使用熵池,请将生成器编写为熵池中的适配器,并根据需要从池中返回值。

【讨论】:

    猜你喜欢
    • 2011-08-16
    • 2011-03-10
    • 2013-07-12
    • 2013-04-11
    • 2014-10-28
    • 2013-12-02
    • 2015-10-15
    • 2020-02-03
    • 1970-01-01
    相关资源
    最近更新 更多