jeudi 18 janvier 2018

How can I use mt19937 in a class without getting the same random sequence in each instance? [duplicate]

This question already has an answer here:

I'm writing code for initializing particle positions in a phase space using a density function. I would like to randomly sample their locations according to an arbitrary distribution, and the easiest way to do this that I found was to make a small class with everything needed to sample according to an array of probabilities that I give it. However, I've found that I get the same sequence of numbers every time I run the code.

vose *sampler = new vose(density, init_grid_count);

for (unsigned int i=0; i<20; i++)
{
    unsigned int index = sampler->alias_method();
    cout << index << '\t';
}

This is the definition of the function I use

unsigned int vose::alias_method()
{
    double x = uniform(mt);

    unsigned int i = floor(array_size*x)+1;
    double y = array_size*x+1-i;

    if (y<distribution[i])
        return i;

    else
        return alias[i];
}

I found that if I do the same loop in the constructor for the class so that it runs when I initialize the vose object, it behaves as expected. This means that it generates a different random sequence each time. So why is it that when I do this in the constructor it works right, but when I use it in a member function it outputs the same sequence every time?

The problem is not that my compiler doesn't support the seed generation. I'm using the <chrono> library and when I print out the seed in the constructor, it is different every time. In case you think there could be something off in the constructor, here it is.

vose::vose(double *array, unsigned int size)
{
    //Initialize
    auto seed = chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937 mt(seed); // Seeds Mersenne Twister with Device RNG

    uniform_real_distribution<double> uniform(0, 1);

    distribution = array;
    array_size = size;

    alias = new unsigned int[size];
    for (unsigned int i = 0; i<size; i++)
    {
        alias[i] = i+1;
    }
}




Aucun commentaire:

Enregistrer un commentaire