Search code examples
c++randommersenne-twister

C++ Calling Pseudo-Random Number Generator Function within a Loop - Constant Seed Issue


I'm new to programming and learning C++ by myself. I managed to write a pseudo-random number generator which uses "Mersenne Twister" engine.

double gen_rand()
{
 std::mt19937 generator (time(0));
 std::uniform_real_distribution<double> dis(0.0, 1.0);

 return dis(generator);
}

When I call this function from a loop within main(), the output is always the same. I'm sure this is because of the seed I'm using in the function body, time(0). Since I'm supplying the same seed everytime I call gen_rand(), I get the same result.

One way I could find to overcome this problem is to embed the function body into main() instead of using a separate function. But since I might need random numbers elsewhere, an outside function is more useful for me. I saw some people have created headers to achieve similar results but such solutions are well beyond my current level of knowledge.

Is there a way to start the seed before calling an outside function and have the function use this process to generate random numbers?

Below is the loop I use:

#include <iostream>
#include <vector>
#include <random> 
#include <ctime>

int main()
{
 std::vector<double> r_num;

 for (int i = 0; i<leg; ++i)
 {
     r_num.push_back(gen_rand());
     std::cout << r_num[i] << std::endl;
 }
}

Solution

  • I am using this (which is similar to yours):

    #include <random>
    std::mt19937 rng(time(NULL));
    int random(int n) {
      std::uniform_int_distribution<int> distribution(0, n);
      return distribution(rng);
    }
    

    as you can see here: Uniformly random numbers ∈[min, max].


    Also, as tobi303 mentioned, you could just do:

    #include <iostream>
    #include <random>
    
    std::mt19937 rng(time(NULL));
    int n = 5;
    std::uniform_int_distribution<int> distribution(0, n);
    
    int main() {
            std::cout << distribution(rng) << std::endl;
            std::cout << distribution(rng) << std::endl;
            std::cout << distribution(rng) << std::endl;
            return 0;
    }
    

    Multiple outputs:

    gsamaras@gsamaras:~$ g++ -Wall -std=c++0x px.cpp 
    gsamaras@gsamaras:~$ ./a.out 
    3
    1
    0
    gsamaras@gsamaras:~$ ./a.out 
    5
    2
    0
    gsamaras@gsamaras:~$ ./a.out 
    5
    2
    1
    gsamaras@gsamaras:~$ pico px.cpp
    gsamaras@gsamaras:~$ g++ -Wall -std=c++0x px.cpp 
    gsamaras@gsamaras:~$ ./a.out 
    5
    4
    3