Why is library producing the same results

2019-07-01 17:55发布

问题:

Notes:

  1. My compiler is g++ 5.1.0-2 with c++14 language standards
  2. My IDE is Code::Blocks (I tried the code on Dev-C++ too)
  3. The online IDEs I tested the code on were http://cpp.sh/ (C++ shell) and https://www.codechef.com/ide (CodeChef.com's IDE) both running c++14
  4. The code runs ok when using an online IDE, which puzzles me even more.

Here is the code:

#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;
}

The one with std::uniform_int_distribution (a) isn't random when running the code on my own computer but works ok and creates a random number on the online IDEs.

The one without std::uniform_int_distribution (b) works ok with both online IDEs and my own computer.

What's the problem? How can I fix it?

UPDATE: The code works ok with mt19937 engine (std::mt19937 and std::mt19937_64)

回答1:

It seems to be a known problem of g++ implementation on Windows. See the accepted answer to a similar question: Why do I get the same sequence for every run with std::random_device with mingw gcc4.8.1?

To avoid the problem you can use <chrono> facilities to seed the random number generator:

#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;
}

This gave me different results at every run ( with g++ on Windows).



回答2:

Your code works fine with Visual C++, but fails for me with g++ 5.2.0. It looks to me like a bug in gcc's standard library.

Yet more evidence that using the default_random_engine is just a bad idea in general, and using time(0) as a seed is pretty awful as well (though a quick check indicates that changing it to use random_device for the seed still produces broken results).