Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

I want to have two independent random distributions of integers in a configurable range. What I had originally is illustrated by the following program:

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

This turns out to always generate equal values when argv[1] and argv[2] are equal, and has less obvious dependencies when they are different as well. For in case I used different engine instances, and even seeded them differently.

What is going on here? I noticed that the problem goes away if I replace the default_random_engine by the mt19937, but that is something I never would have guessed. Also, is the other engine supposed to be able to produce independent samples?

EDIT I am working on Ubuntu 16.04.2, with g++ 7.3.0 from the standard repositories.

EDIT 2 As François Andrieux speculated in the comments, this seems to be a peculiarity of the specific default random generator of my environment: the seeds 0 and 1 seem to generate the same sequence of random numbers. All other combinations generate seemingly independent samples.

like image 874
doetoe Avatar asked Mar 26 '19 17:03

doetoe


2 Answers

libstdc++ seems to use minstd_rand0 for default_random_engine.

In visual studio (and presumably other implementations) a seed of 0 is explicitly converted to a seed of 1.

Either use a different seed value or explicitly choose the engine you want to use. You have no control over what default_random_engine produces and different standard libaries will choose generators with differing properties. For example visual studio uses mt19937.

like image 143
Alan Birtles Avatar answered Nov 14 '22 23:11

Alan Birtles


Some pseudo random number engines can have multiple seeds with correlating, or even an identical sequence. This is particularly true for Linear congruential generators.

To avoid correlation of engines with different seed:

  1. Use a better engine, such as Mersenne Twister.
  2. Avoid using identity elements as seed (0, 1, empty sequence, generator.modulus, ...) for all engines.
  3. Instead of using a singular seed, use a seed sequence:

-

template< class Sseq >
void seed( Sseq& seq );
like image 35
eerorika Avatar answered Nov 14 '22 23:11

eerorika