Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is boost's random number generation (on a normal distribution) always giving the same values?

Tags:

c++

random

boost

I am doing some random number generation and getting fishy behaviour. Here is my code:

    // initialized earlier... in the constructor of a class
    boost::mt19937 *rng = new boost::mt19937();
    rng->seed(time(NULL));

    // actual use here.
    for (int i = 0; i < 10; ++i)
    {
        test();
    }


    void test()
    {
       boost::normal_distribution<> distribution(10, 10);
       boost::variate_generator< boost::mt19937, boost::normal_distribution<> > resampler(*rng, distribution);

       const double sample = (resampler)(); // always the same value.
    }

Am I misusing the random sampling in boost? What have I done wrong to make that always be the same value. I initialize the random number generator in the constructor so it should always spit out a different value (not getting reinitialized)

like image 294
zebra Avatar asked Jan 14 '23 18:01

zebra


1 Answers

The problem is with the line boost::variate_generator< boost::mt19937, boost::normal_distribution<> > resampler(*rng, distribution);. This constructor take its parameters by value (see the documentation). So each resampler starts off with an identical copy of the generator and calls it once.


Edit: Shafik noticed the same thing just a little after I did. If you really can't hoist the initialization out of the loop, you can also re-seed the generator. There are many ways to accomplish this depending on your application. Below is just one example:

void test()
{
   static unsigned int seed = 0
   rng->seed((++seed) + time(NULL));

   boost::normal_distribution<> distribution(10, 10);
   boost::variate_generator< boost::mt19937, boost::normal_distribution<> > resampler(*rng, distribution);

   const double sample = (resampler)(); // always the same value.
}

Note: do not re-seed rng with just time(NULL), as that may return the same value several times if you call test() in a tight loop.

like image 98
jerry Avatar answered Jan 16 '23 07:01

jerry