如何简洁,可移植和彻底播种mt19937 PRNG?
我似乎看到了许多答案,有人建议使用这些答案<random>来生成随机数,通常连同这样的代码一起使用: std::random_device rd; std::mt19937 gen(rd()); std::uniform_int_distribution<> dis(0, 5); dis(gen); 通常,这会代替某种“邪恶可憎”,例如: srand(time(NULL)); rand()%6; 我们可以批评的理由是旧的方式time(NULL)提供了低熵,time(NULL)是可以预测的,而最终的结果是不均匀的。 但是,所有这一切对于新方法都是正确的:它只是饰面更亮。 rd()返回一个unsigned int。它至少有16位,可能是32位。这不足以使MT的19937位状态成为种子。 使用std::mt19937 gen(rd());gen()(用32位播种并查看第一个输出)不能提供良好的输出分布。7和13永远不会是第一个输出。两颗种子产生0。十二颗种子产生1226181350。(链接) std::random_device可以并且有时被实现为带有固定种子的简单PRNG。因此,每次运行可能会产生相同的序列。(链接)甚至比time(NULL)。 更糟糕的是,尽管存在上述问题,但复制并粘贴上述代码片段非常容易。为此,一些解决方案需要获取可能并不适合每个人的大型 库。 有鉴于此,我的问题是,如何能以C ++简洁,可移植,彻底地植入mt19937 PRNG? 鉴于上述问题,一个好的答案是: 必须完全植入mt19937 / mt19937_64。 不能完全依赖std::random_device或time(NULL)作为熵的来源。 不应该依赖Boost或其他库。 应该放在少量的行中,这样看起来很不错,可以粘贴到答案中。 思想 我目前的想法是,std::random_device可以使用time(NULL),从地址空间随机化派生的值和硬编码的常数(可以在分发期间设置)将的输出(可以通过XOR)进行混搭,以尽力而为。 std::random_device::entropy() 不能很好地说明std::random_device可能做什么或可能不会做什么。