问题
I have the following piece of code:
unsigned int randomInt()
{
mt19937 mt_rand(time(0));
return mt_rand();
};
If I call this code, for example 4000 times in a for loop, I don't get random unsigned integers, instead I get for example 1000 times one value and the next 1000 times I get the next value.
What am I doing wrong?
回答1:
This happens because you call f
4000 times in a loop, which probably takes less than a mili second, so at each call time(0)
returns the same value, hence initializes the pseudo-random generator with the same seed. The correct way is to initialize the seed once and for all, preferably via a std::random_device
, like so:
#include <random>
#include <iostream>
static std::random_device rd; // random device engine, usually based on /dev/random on UNIX-like systems
// initialize Mersennes' twister using rd to generate the seed
static std::mt19937 rng(rd());
int dice()
{
static std::uniform_int_distribution<int> uid(1,6); // random dice
return uid(rng); // use rng as a generator
}
int main()
{
for(int i = 0; i < 10; ++i)
std::cout << dice() << " ";
}
回答2:
A source of randomness is a resource that belongs to your entire program, not to a single function. You should pretty much never create a source of randomness inside a routine used to return a random value.
Good options include:
- Pass a source of randomness into your function
- Make your source of randomness a global variable
- Make your source of randomness a static variable, so that initialization happens once.
One thing you might think to try that you should not do is to replace time(0)
with a similar function that has a higher resolution; while you will get different results, this will still generate poor quality random numbers, and may even be much slower than generating random numbers properly. (I believe there are random number generators that can work properly with such usage, but those have to be designed for that purpose)
来源:https://stackoverflow.com/questions/29549873/stdmt19937-doesnt-return-random-number