C++,为什么我不能使用两个默认随机引擎生成独立的随机整数样本

In C++, why can't I generate independent random integer samples using two default random engines

本文关键字:随机 引擎 默认 独立 样本 整数 两个 不能 为什么 C++      更新时间:2023-10-16

我想在一个可配置的范围内有两个独立的整数随机分布。我最初拥有的内容由以下程序说明:

#include <random>
#include <cstdio>
#include <cstdlib>
using namespace std;
int main(int argc, char* argv[])
{
default_random_engine generator1;
default_random_engine generator2;
uniform_int_distribution<int> dist1(0,atoi(argv[1]));
uniform_int_distribution<int> dist2(0,atoi(argv[2]));
generator1.seed(0);
generator2.seed(1);
for (int i = 0; i < 60; i++)
printf("(%d, %d)n", dist1(generator1), dist2(generator2));
return 0;
}

事实证明,当 argv[1] 和 argv[2] 相等时,这总是生成相等的值,当它们不同时,它们也有不太明显的依赖关系。以防万一我使用不同的引擎实例,甚至以不同的方式播种它们。

这是怎么回事?我注意到如果我用 mt19937 替换default_random_engine,问题就会消失,但这是我永远不会猜到的。另外,另一个引擎是否应该能够产生独立的样品?

编辑我正在开发 Ubuntu 16.04.2,使用标准存储库中的 g++ 7.3.0。

编辑 2正如弗朗索瓦·安德里厄在评论中推测的那样,这似乎是我环境中特定默认随机生成器的一个特点:种子 0 和 1 似乎生成相同的随机数序列。所有其他组合都会生成看似独立的样本。

libstdc++似乎使用minstd_rand0default_random_engine

在Visual Studio(可能还有其他实现)中,0种子被显式转换为1种子。

使用不同的种子值或显式选择要使用的引擎。您无法控制default_random_engine产生什么,不同的标准库将选择具有不同属性的生成器。例如,Visual Studio使用mt19937

某些伪随机数引擎可以有多个具有相关甚至相同序列的种子。对于线性全等生成器尤其如此。

要避免引擎与不同种子的关联,请执行以下操作:

  1. 使用更好的引擎,例如Mersenne Twister。
  2. 避免将标识元素用作所有引擎的种子(0、1、空序列、generator.modulus、...)。
  3. 不要使用单个种子,而是使用种子序列:

-

template< class Sseq >
void seed( Sseq& seq );