vendredi 11 novembre 2016

Seeding the mt19937 with same seed is giving different results after changing structure of the project

I had the following file a.h where I had defined the following:

extern std::random_device rd;
extern const size_t MT19937_SEED;
extern std::mt19937 gen;

// declare functions that are going to use gen

and in the corresponding source file a.cpp I had:

std::random_device rd;
const size_t MT19937_SEED = rd();
std::mt19937 gen(MT19937_SEED);

// define and implement the functions which use gen
// these functions every time they need to create a random number
// they create on the stack either a std::uniform_int_distribution(some_range)
// or a std::uniform_real_distribution(some_range)

and I used to seed the random number generator as follows in my main.cpp (which contains the main method), before calling one of the functions that used the random number generator gen declared in a.h and defined in a.cpp

#include "a.h"

int main(...) {
    ...
    gen.seed(some_seed);

    // call one of the functions that use gen
    ...
}

Now, this seemed to work, since when I inserted the same seed I had always the same output. Since I'm working on a project where the seeds are important, I had already found a few seeds that I had memorized, but in the meantime I had also to change the structure of my program, but the seeds I searched for a while do not produce the same output anymore.

So, my new structure of the project is as follows. I've a file util.h and the corresponding source file util.cpp. In the first, I've

struct random_numbers {

    static std::random_device rd;

    static size_t seed;

    static std::mt19937 gen;

    static double zero_one();

    static int one_100();

    static int zero_last(const int n);

    static void set_seed(size_t new_seed);

};

and in the second I've:

size_t random_numbers::seed = random_numbers::rd();
std::mt19937 random_numbers::gen(random_numbers::seed);

void random_numbers::set_seed(size_t new_seed){
    random_numbers::seed = new_seed;
    random_numbers::gen.seed(random_numbers::seed);
}


double random_numbers::zero_one() {
    std::uniform_real_distribution<double> dist(0.0, 1.0);
    return dist(random_numbers::gen);
}

int random_numbers::one_100() {
    std::uniform_int_distribution<int> dist(1, 100);
    return dist(random_numbers::gen);
}

int random_numbers::zero_last(const int n) {
    std::uniform_int_distribution<int> dist(0, n - 1);
    return dist(random_numbers::gen);
}

Now, as you can see, I'm creating the uniform_int_distributions and the uniform_real_distributions inside a few functions which I call from the functions in a.h and a.cpp. I'm setting the seeds of course before calling these functions from a.h as:

random_numbers::set_seed(some_seed);

but of course I'm getting different results. How can I solve this problem?




Aucun commentaire:

Enregistrer un commentaire