为什么<random>库在使用 std::uniform_int_distribution 时每次都产生相同的结果

Why is <random> library producing the same results every time when using std::uniform_int_distribution

本文关键字:结果 distribution uniform gt random lt 为什么 std int      更新时间:2023-10-16

备注:

  1. 我的编译器是g++5.1.0-2,采用c++14语言标准
  2. 我的IDE是Code::Blocks(我也在Dev-C++上尝试过代码)
  3. 我测试代码的在线IDE是http://cpp.sh/(C++外壳)和https://www.codechef.com/ide(CodeChef.com的IDE)均运行c++14
  4. 当使用在线IDE时,代码运行良好,这让我更加困惑

这是代码:

#include <iostream>
#include <random>
#include <cstdlib>
#include <ctime>
#include <chrono>
int main() {
    srand(time(0));
    long long seed = rand();
    std::default_random_engine rand_num(seed);
    std::uniform_int_distribution<long long> range(0, 10);
    long long a = range(rand_num);
    long long b = rand_num();
    std::cout<<seed<<"n"; // the seed is different every time (tested)
    std::cout<<a<<"n";
    std::cout<<b<<"n";
    system("pause");
    return 0;
}

在我自己的计算机上运行代码时,带有std::uniform_int_distribution(a)的不是随机的,但工作正常,并在在线IDE上创建了一个随机数。

没有std::uniform_int_distribution(b)的可以与在线IDE和我自己的计算机一起工作。

怎么了?我该怎么修?

更新:该代码与mt19937引擎(std::mt19937和std::mt 19937_64)配合良好

这似乎是Windows上g++实现的一个已知问题。请参阅类似问题的公认答案:为什么每次使用std::random_device和mingw gcc4.8.1运行时,我都会得到相同的序列?

为了避免这个问题,您可以使用<chrono>设施来为随机数生成器种子:

#include <iostream>
#include <random>
#include <cstdlib>
#include <ctime>
#include <chrono>
int main() {
    srand(time(0));
    long long seed = rand();
    std::default_random_engine rand_num{static_cast<long unsigned int>(std::chrono::high_resolution_clock::now().time_since_epoch().count())};
    //                                  ^ ^ ^ ^ ^ ^^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
    std::uniform_int_distribution<long long> range{1,10};
    long long a = range(rand_num);
    long long b = rand_num();
    std::cout<<seed<<"n"; // the seed is different every time (tested)
    std::cout<<a<<"n";
    std::cout<<b<<"n";
    system("pause");
    return 0;
}

这在每次运行时都给了我不同的结果(在Windows上使用g++)。

您的代码在Visual C++中运行良好,但在g++5.2.0中失败了。在我看来,它就像是gcc标准库中的一个bug。

然而,更多的证据表明,使用default_random_engine通常是个坏主意,而使用time(0)作为种子也相当糟糕(尽管快速检查表明,将其更改为使用random_device作为种子仍然会产生坏结果)。