how to initialize boost::mt19937 with multiple values without using C++11 - c++

I can use:
boost::mt19937 gen(43);
this works just fine, but what if I want more than 32-bits of seed before using the random number generator? Is there an easy way to put 64-bits or 128-bits of seed into the Mersenne Twister?
I found a few examples of loading multiple values before generating results, but none of the code works.
There are a couple of problems with this code:
std::vector<unsigned int> seedv(1000, 11);
std::vector<unsigned int>::iterator i=seedv.begin();
boost::mt19937 gen2(i, seedv.end());
First, calling gen2() always returns the same value. I don't know how I screwed that up.
Second, I don't want 1,000 seeds, but when I lower it to 600 it "throws an instance of std::invalid_argument with note enough elements in call to seed"
Can this method be shortened to a handful of seeds?
Here is another code example that looks easy:
std::string seedv("thisistheseed");
std::seed_seq q(seedv.begin(),seedv.end());
boost::mt19937 gen2(q);
but it won't compile. I finally figured out that std::seed_seq is only available in c++11. I am stuck with gcc 4.7 until the libraries I depend on are stable.
I suppose I can just stick with a 32-bit seed, but I wanted a little bit more.
I did read this article:
Boost Mersenne Twister: how to seed with more than one value?
I like the idea of initializing the whole vector from:
mersenne_twister(seed1) ^ mersenne_twister(seed2)
but I don't see a way to do that without modifying Mersenne_Twister.hpp
Any suggestions?
UPDATE: one more way not to do it!
unsigned long seedv[4];
seedv[0]=1;
seedv[1]=2;
seedv[2]=3;
seedv[3]=4;
boost::mt19937 gen2(seedv,4);
With the right casting, this should work, but every cast I have tried still won't get past the compiler. I can cast anything in C, but C++ still stumps me at times...

Use boost::seed_seq instead of std::seed_seq.
Update: Use
boost::random_device rd;
boost::mt19937 eng(rd);
boost::mt19937 allows you to seed it with either a single value up to 32 bits in width (the w parameter of the underlying boost::mersenne_twister_engine), or with a sequence of 624 values (the n parameter of the underlying template). 624 is the number of elements in mt19937's internal state.
If you read the documentation you'll see that these two mechanisms seed the state of the engine differently.
seeding with a single value sets every element of the engine's state using a complicated function of that single value.
seeding with a sequence of 624 values sets each element of the engine state to exactly the corresponding seed value.
The point is that boost::mt19937 does not itself include a mechanism to map an arbitrary number of seed values to the fixed number of elements in its internal state. It allows you to set the state directly (using 624 values), and for convenience it offers a built-in mapping from single 32-bit values to complete, 624 element states.
If you want to use an arbitrary number of input seed values then you will need to implement a mapping from arbitrarily sized sequences to 624 element states.
Keep in mind that the mapping should be designed such that the resulting internal state is a 'good' state for the mersenne twister algorithm. This algorithm is shift-register based and can be subject to internal states which produce relatively predictable output. The built-in mapping for single values was designed to minimize this issue and whatever you implement should be as well.
Probably the best way to implement such a mapping, rather than doing the mathematical analysis yourself, is to simply use the standard mersenne twister warmup algorithm. According to a comment on this answer the C++11 std::seed_seq is specified to perform such a warmup. Boost includes boost::seed_seq, which presumably does the same thing.
Update: Instead of using some arbitrary number of values to compute a sequence of 624 values you can simply use exactly 624 random values. If the values are unbiased and evenly distributed over the range of 32-bit values then you won't need any warm-up (well, unless you're astronomically unlucky).
The boost <random> library supports this very directly:
boost::random_device rd;
boost::mt19937 eng(rd);
Note that the C++11 <random> library does not support seeding this way.

A seed-sequence generator helper exists for this reason:
The class seed_seq stores a sequence of 32-bit words for seeding a pseudo-random number generator . These words will be combined to fill the entire state of the generator. http://www.boost.org/doc/libs/1_57_0/doc/html/boost/random/seed_seq.html
#include <boost/random.hpp>
#include <boost/random/seed_seq.hpp>
int main()
{
boost::random::seed_seq ss({1ul, 2ul, 3ul, 4ul});
boost::mt19937 gen2(ss);
}
You can also pass a pair of iterators to an existing range.
Live On Coliru

The standard Mersenne Twister is the following typedef:
typedef mersenne_twister_engine<uint32_t,32,624,397,31,0x9908b0df,
11,0xffffffff,7,0x9d2c5680,15,0xefc60000,18,1812433253> mt19937;
The first template type is called UintType and is used as the argument for the seed method:
void seed(UIntType value);
You could therefore use the pre-defined boost::mt19937_64 to have a 64-bit seed. You can also create your own mersenne_twister_engine if you want to customize it more.

It's not pretty, but it should be possible to do:
std::vector<unsigned int> seedv(1000);
seedv[0] = 1;
seedv[1] = 2;
seedv[2] = 3;
seedv[3] = 4;
// etc.
boost::mt19937 gen2(seedv.begin(), seedv.end());
That is, still pass in 1000 seeds, even though most of them are 0's. However, as #bames53 mentions in a comment, this isn't a good idea. It's legal, and compiles, but doesn't make for a good seed.
By the way, the array approach should work (at least, it should compile):
unsigned long seedv[4];
seedv[0]=1;
seedv[1]=2;
seedv[2]=3;
seedv[3]=4;
boost::mt19937 gen2(seedv, seedv + 4);
This is an example of using pointers as iterators. 4 isn't an iterator (generally), but seedv + 4 is (it's the address of the element just after the end of seedv)..

Related

Forking a random number generator deterministically?

I'm using std::mt19937 to produce deterministic random numbers. I'd like to pass it to functions so I can control their source of randomness. I could do int foo(std::mt19937& rng);, but I want to call foo and bar in parallel, so that won't work. Even if I put the generation function behind a mutex (so each call to operator() did std::lock_guard lock(mutex); return rng();), calling foo and bar in parallel wouldn't be deterministic due to the race on the mutex.
I feel like conceptually I should be able to do this:
auto fooRNG = std::mt19937(rng()); // Seed a RNG with the output of `rng`.
auto barRNG = std::mt19937(rng());
parallel_invoke([&] { fooResult = foo(fooRNG); },
[&] { barResult = bar(barRNG); });
where I "fork" rng into two new ones with different seeds. Since fooRNG and barRNG are seeded deterministically, they should be random and independent.
Is this general gist viable?
Is this particular implementation sufficient (I doubt it)?
Extended question: Suppose I want to call baz(int n, std::mt19937&) massively in parallel over a range of indexed values, something like
auto seed = rng();
parallel_for(range(0, 1 << 20),
[&](int i) {
auto thisRNG = std::mt19937(seed ^ i); // Deterministically set up RNGs in parallel?
baz(i, thisRNG);
});
something like that should work, right? That is, provided we give it enough bits of state?
Update:
Looking into std::seed_seq, it looks(?) like it's designed to turn not-so-random seeds into high-quality seeds: How to properly initialize a C++11 std::seed_seq
So maybe what I want something like
std::mt19937 fork(std::mt19937& rng) {
return std::mt19937(std::seed_seq({rng()}));
}
or more generally:
//! Represents a state that can be used to generate multiple
//! distinct deterministic child std::mt19937 instances.
class rng_fork {
std::mt19937::result_type m_seed;
public:
rng_fork(std::mt19937& rng) : m_seed(rng()) {}
// Copy is explicit b/c I think it's a correctness footgun:
explicit rng_fork(const rng_fork&) = default;
//! Make the ith fork: a deterministic but well-seeded
//! RNG based off the internal seed and the given index:
std::mt19937 ith_fork(std::mt19937::result_type index) const {
return std::mt19937(std::seed_seq({m_seed, index}));
}
};
then the initial examples would become
auto fooRNG = fork(rng);
auto barRNG = fork(rng);
parallel_invoke([&] { fooResult = foo(fooRNG); },
[&] { barResult = bar(barRNG); });
and
auto fork_point = rng_fork{rng};
parallel_for(range(0, 1 << 20),
[&](int i) {
auto thisRNG = fork_point.ith_fork(i); // Deterministically set up a RNG in parallel.
baz(i, thisRNG);
});
Is that correct usage of std::seed_seq?
I am aware of 3 ways to seed multiple parallel pseudo random number generators (PRNGs):
First option
Given a seed, initialize the first instance of the PRNG with seed, the second with seed+1, etc. The thing to be aware of here is that the state of the PRNGs will be initially very close in case the seed is not hashed. Some PRNGs will take a long time to diverge. See e.g. this blog post for more information.
For std::mt19937 specifically, however, this was never an issue in my tests because the initial seed is not taken as is but instead gets "mangled/hashed" (compare the documentation of the result_type constructor). So it seems to be a viable option in practice.
However, notice that there are some potential pitfalls when seeding a Mersenne Twister (which has an internal state of 624 32-bit integers) with a single 32 bit integer. For example, the first number can never be 7 or 13. See this blog post for more information. But if you do not rely on the randomness of only the first few drawn numbers but draw a more reasonable number of numbers from each PRNG, it is probably fine.
Second option
Without std::seed_seq:
Seed one "parent" PRNG. Then, to initialize N parallel PRNGs, draw N random numbers and use them as seeds. This is your initial idea where you draw 2 random numbers rng() and initialize the two std::mt19937:
std::mt19937 & rng = ...;
auto fooRNG = std::mt19937(rng()); // Seed a RNG with the output of `rng`.
auto barRNG = std::mt19937(rng());
The major issue to look out for here is the birthday problem. It essentially states that the probability to draw the same number twice is more likely than you'd intuitively think. Given a type of PRNG that has a value range of b (i.e. b different values can appear in its output), the probability p(t) to draw the same number twice when drawing t numbers can be estimated as:
p(t) ~ t^2 / (2b) for t^2 << b
(compare this post). If we stretch the estimate "a bit", just to show the basic issue:
For a PRNG producing a 16 bit integer, we have b=2^16. Drawing 256 numbers results in a 50% chance to draw the same number twice according to that formula. For a 32 bit PRNG (such as std::mt19937) we need to draw 65536 numbers, and for a 64 bit integer PRNG we need to draw ~4e9 numbers to reach the 50%. Of course, this is all an estimate, so you want to draw several orders of magnitude less numbers than that. Also see this blog post for more information.
In case of seeding the parallel std::m19937 instances with this method (32 bit output and input!), that means you probably do not want to draw more than a hundred or so random numbers. Otherwise, you have a realistic chance of drawing the same number twice. Of course, you could ensure that you do not draw the same seed twice by keeping a list of already used seeds. Or use std::mt19937_64.
Additionally, there are still the potential pitfalls mentioned above regarding the seeding of a Mersenne Twister with 32 bit numbers.
With seed sequence:
The idea of std::seed_seq is to take some numbers, "mix them" and then provide them as input to the PRNG so that it can initialize its state. Since the 32 bit Mersenne Twister has a state of 624 32-bit integers, you should provide that many numbers to the seed sequence for theoretically optimal results. That way you get b=2^(624*32), meaning that you avoid the birthday problem for all practical purposes.
But in your example
std::mt19937 fork(std::mt19937& rng) {
return std::mt19937(std::seed_seq({rng()}));
}
you provide only a single 32 bit integer. This effectively means that you hash that 32 bit number before putting it into std::mt19937. So you do not gain anything regarding the birthday problem. And the additional hashing is unnecessary because std::mt19937 already does something like this.
std::seed_seq itself is somewhat flawed, see this blog post. But I guess for practical purposes it does not really matter. A supposedly better alternative exists, but I have no experience with it.
Third option
Some PRNG algorithms such as PCG or xoshiro256++ allow to jump over a large number of random numbers fast. For example, xoshiro256++ has a period of (2^256)-1 before it repeats itself. It allows to jump ahead by 2^128 (or alternatively 2^192) numbers. So the idea would be that the first PRNG is seeded, then you create a copy of it and jump ahead by 2^128 numbers, then create a copy of that second one and jump ahead again by 2^128, etc. So each instance works in a slice of length 2^128 from the total range of 2^256. The slices are stochastically independent. This elegantly bypasses the problems with the above methods.
The standard PRNGs do have a discard(z) method to jump z values ahead. However, it is not guaranteed that the jumping will be fast. I don't know whether std::mt19937 implements fast jumping in all standard library implementations. (As far as I know, the Mersenne Twister algorithm itself does allow this in principle.)
Additional note
I found PRNGs to be surprisingly difficult to use "right". It really depends on the use case how careful you need to be and what method to choose. Think about the worst thing that could happen in your case if something goes wrong, and invest an according amount of time in researching the topic.
For ordinary scientific simulations where you require only a few dozens or so parallel instances of std::mt19937, I'd guess that the first and second option (without seed sequence) are both viable. But if you need several hundreds or even more, you should think more carefully.

How to properly seed a 64 bit random generator with time [duplicate]

I'm working on a program that runs Monte Carlo simulation; specifically, I'm using a Metropolis algorithm. The program needs to generate possibly billions of "random" numbers. I know that the Mersenne twister is very popular for Monte Carlo simulation, but I would like to make sure that I am seeding the generator in the best way possible.
Currently I'm computing a 32-bit seed using the following method:
mt19937_64 prng; //pseudo random number generator
unsigned long seed; //store seed so that every run can follow the same sequence
unsigned char seed_count; //to help keep seeds from repeating because of temporal proximity
unsigned long genSeed() {
return ( static_cast<unsigned long>(time(NULL)) << 16 )
| ( (static_cast<unsigned long>(clock()) & 0xFF) << 8 )
| ( (static_cast<unsigned long>(seed_count++) & 0xFF) );
}
//...
seed = genSeed();
prng.seed(seed);
I have a feeling there are much better ways to assure non-repeating new seeds, and I'm quite sure mt19937_64 can be seeded with more then 32-bits. Does anyone have any suggestions?
Use std::random_device to generate the seed. It'll provide non-deterministic random numbers, provided your implementation supports it. Otherwise it's allowed to use some other random number engine.
std::mt19937_64 prng;
seed = std::random_device{}();
prng.seed(seed);
operator() of std::random_device returns an unsigned int, so if your platform has 32-bit ints, and you want a 64-bit seed, you'll need to call it twice.
std::mt19937_64 prng;
std::random_device device;
seed = (static_cast<uint64_t>(device()) << 32) | device();
prng.seed(seed);
Another available option is using std::seed_seq to seed the PRNG. This allows the PRNG to call seed_seq::generate, which produces a non-biased sequence over the range [0 ≤ i < 232), with an output range large enough to fill its entire state.
std::mt19937_64 prng;
std::random_device device;
std::seed_seq seq{device(), device(), device(), device()};
prng.seed(seq);
I'm calling the random_device 4 times to create a 4 element initial sequence for seed_seq. However, I'm not sure what the best practice for this is, as far as length or source of elements in the initial sequence is concerned.
Let's recap (comments too), we want to generate different seeds to get independent sequences of random numbers in each of the following occurrences:
The program is relaunched on the same machine later,
Two threads are launched on the same machine at the same time,
The program is launched on two different machines at the same time.
1 is solved using time since epoch, 2 is solved with a global atomic counter, 3 is solved with a platform dependent id (see How to obtain (almost) unique system identifier in a cross platform way?)
Now the point is what is the best way to combine them to get a uint_fast64_t (the seed type of std::mt19937_64)? I assume here that we do not know a priori the range of each parameter or that they are too big, so that we cannot just play with bit shifts getting a unique seed in a trivial way.
A std::seed_seq would be the easy way to go, however its return type uint_least32_t is not our best choice.
A good 64 bits hasher is a much better choice. The STL offers std::hash under the functional header, a possibility is to concatenate the three numbers above into a string and then passing it to the hasher. The return type is a size_t which on 64 machines is very likely to match our requirements.
Collisions are unlikely but of course possible, if you want to be sure to not build up statistics that include a sequence more than once, you can only store the seeds and discard the duplicated runs.
A std::random_device could also be used to generate the seeds (collisions may still happen, hard to say if more or less often), however since the implementation is library dependent and may go down to a pseudo random generator, it is mandatory to check the entropy of the device and avoid to a use zero-entropy device for this purpose as you will probably break the points above (especially point 3). Unfortunately you can discover the entropy only when you take the program to the specific machine and test with the installed library.
As far as I can tell from your comments, it seems that what you are interested in is ensuring that if a process starts several of your simulations at exactly the same time, they will get different seeds.
The only significant problem I can see with your current approach is a race condition: if you are going to start multiple simulations simultaneously, it must be done from separate threads. If it is done from separate threads, you need to update seed_count in a thread-safe manner, or multiple simulations could end up with the same seed_count. You could simply make it an std::atomic<int> to solve that.
Beyond that, it just seems more complicated than it has to be. What do you gain by using two separate timers? You could do something as simple as this:
at program startup, grab the current system time (using a high resolution timer) once, and store that.
assign each simulation a unique ID (this could just be an integer initialized to 0, (which should be generated without any race conditions, as mentioned above) which is incremented each time a simulation starts, effectively like your seed_count.
when seeding a simulation, just use the initially generated timestamp + the unique ID. If you do this, every simulation in the process is assured a unique seed.
How about...
There is some main code that starts the threads and there are copies of a function run in those threads, each copy with it's own Marsenne Twister. Am I correct? If it is so, why not use another random generator in the main code? It would be seeded with time stamp, and send it's consecutive pseudorandom numbers to function instances as their seeds.
From the comments I understand you want to run several instances of the algorithm, one instance per thread. And given that the seed for each instance will be generated pretty much at the same time, you want to ensure that these seeds are different. If that is indeed what you are trying to solve, then your genSeed function will not necessarily guarantee that.
In my opinion, what you need is a parallelisable random number generator (RNG). What this means, is that you only need one RNG which you instantiate with only one seed (which you can generate with your genSeed) and then the sequence of random numbers that would normally be gerenated in a sequential environment is split in X non-overlapping sequences; where X is the number of threads. There is a very good library which provides these type of RNGs in C++, follows the C++ standard for RNGs, and is called TRNG(http://numbercrunch.de/trng).
Here is a little more information. There are two ways you can achieve non-overlapping sequences per thread. Let's assume that the sequence of random numbers from a single RNG is r = {r(1), r(2), r(3),...} and you have only two threads. If you know in advance how many random numbers you will need per thread, say M, you can give the first M of the r sequence to the first thread, ie {r(1), r(2),..., r(M)}, and the second M to the second thread, ie {r(M+1), r(M+2),...r(2M)}. This technique is called blocksplitting since you split the sequence in two consecutive blocks.
The second way is to create the sequence for the first thread as {r(1), r(3), r(5), ...} and for the second thread as {r(2), r(4), r(6),...}, which has the advantage that you do not need to know in advance how many random numbers you will need per thread. This is called leapfroging.
Note that both methods guarantee that the sequences per thread are indeed non-overlapping. The link I posted above has many examples and the library itself is extremely easy to use. I hope my post helps.
The POSIX function gettimeofday(2) gives the time with microsecond precision.
The POSIX thread function gettid(2) returns the ID number of the current thread.
You should be able to combine the time in seconds since the epoch (which you are already using), the time in microseconds, and the thread ID to get a seed which is always unique on one machine.
If you also need it to be unique across multiple machines, you could consider also getting the hostname, the IP address, or the MAC address.
I would guess that 32 bits is probably enough, since there are over 4 billion unique seeds available. Unless you are running billions of processes, which doesn't seem likely, you should be alright without going to 64 bit seeds.

rand() and srand() functions in c++

I have been learning recently how to program games in c++ from a beginner book, and i reached a lesson where i have to make a game in where i have to guess the computer's random picked number, and i have to use this line of code:
srand(static_cast<unsigned int>(time(0)));
variable=rand();
I obviously use iostream cstdlib and ctime.I don't really understand how this works.How is it picking the time and date, and by what rules is it converting into an unsigned int. Basically, how those functions work.
Thank you!
1. About time()
time (or better std::time in C++) is a function that returns some integer or floating point number that represents the current time in some way.
Which arithmetic type it actually returns and how it represents the current time is unspecified, however, most commonly you will get some integer type that holds the seconds since begin of the Unix epoch.
2. About srand()
srand is a function that uses its argument (which is of type unsigned int), the so called seed, to set the internal state of the pseudo number generator rand. When I write random in the rest of this answer, read pseudo random.
Using a different seed will in general result in a different sequence of random numbers produced by subsequent calls to rand, while using the same seed again will result in the exactly same sequence of random numbers.
3. Using time() to seed rand()
If we do not want to get the same random numbers every time we run the program, we need some seed that is different on each run. The current time is a widely used source for such a seed as it changes constantly.
This integer (or whatever else time returned) representing the current time is now converted to unsigned int with a static_cast. This explicit cast is not actually needed as all arithmetic types convert to unsigned int implicitly, but the cast may silence some warnings. As time goes by, we can expect the resulting unsigned int and thus the sequence of random numbers produced by rand to change.
4. Pitfalls
If, as is common, time returns the number of seconds since the beginning of the Unix epoch, there are three important things to note:
The sequence you produce will be different only if at least a second has passed between two invocations.
Depending on the actual implementation, the resulting sequences may start of kind of similar if the time points used to seed rand are close to each other (compared to time since Epoch). Afaik, this is the case in MSVC's implementation. If that is problematic, just discard the first couple of hundred or thousand values of the sequence. (As I have learned by now, this does not really help much for poor RNGs as commonly used for rand. So if that is problematic, use <random> as described below.)
Your numbers are not very random in the end: If someone knows when your call to srand occurred, they can derive the entire sequence of random numbers from that. This has actually led to a decryption tool for a ransom ware that used srand(time(0)) to generate its "random" encryption key.
Also, the sequence generated by rand tends to have poor statistical properties even if the seed was good. For a toy program like yours, that is probably fine, however, for real world use, one should be aware of that.
5. The new <random>
C++11 introduced new random number facilities that are in many ways superior to the old rand based stuff. They provided in the standard header <random>. It includes std::random_device which provides a way to get actually random seeds, powerful pseudo random number generators like std::mt19937 and facilities to map the resulting random sequences to integer or float ranges without introducing unnecessary bias.
Here is an example how to randomly roll a die in C++11:
#include <random>
#include <iostream>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 6);
for (int n=0; n<10; ++n)
std::cout << dis(gen) << ' ';
std::cout << '\n';
}
(Code from cppr) Note: std::random_device does not work properly with MinGW, at least in the version (Nuwen MinGW5.3) I tested!
It should also be noted that the state space of a mt19937 is much larger than the 32 bit we (commonly) get out of a single call to random_device. Again, this will most likely not matter for toy programs and homework, but for reference: Here is my attempt to properly seed the entire state space, plus some helpful suggestions in the answers.
If you are interested in more details about rand vs <random>, this is an interesting watch.
First line:
srand() is a pseudo-random number generator. In your case it is initialized with the current time (execution time) on your system.
Second line:
After the pseudo-random number generator is configured, you can retrieve random numbers by calling rand().

Best way to seed mt19937_64 for Monte Carlo simulations

I'm working on a program that runs Monte Carlo simulation; specifically, I'm using a Metropolis algorithm. The program needs to generate possibly billions of "random" numbers. I know that the Mersenne twister is very popular for Monte Carlo simulation, but I would like to make sure that I am seeding the generator in the best way possible.
Currently I'm computing a 32-bit seed using the following method:
mt19937_64 prng; //pseudo random number generator
unsigned long seed; //store seed so that every run can follow the same sequence
unsigned char seed_count; //to help keep seeds from repeating because of temporal proximity
unsigned long genSeed() {
return ( static_cast<unsigned long>(time(NULL)) << 16 )
| ( (static_cast<unsigned long>(clock()) & 0xFF) << 8 )
| ( (static_cast<unsigned long>(seed_count++) & 0xFF) );
}
//...
seed = genSeed();
prng.seed(seed);
I have a feeling there are much better ways to assure non-repeating new seeds, and I'm quite sure mt19937_64 can be seeded with more then 32-bits. Does anyone have any suggestions?
Use std::random_device to generate the seed. It'll provide non-deterministic random numbers, provided your implementation supports it. Otherwise it's allowed to use some other random number engine.
std::mt19937_64 prng;
seed = std::random_device{}();
prng.seed(seed);
operator() of std::random_device returns an unsigned int, so if your platform has 32-bit ints, and you want a 64-bit seed, you'll need to call it twice.
std::mt19937_64 prng;
std::random_device device;
seed = (static_cast<uint64_t>(device()) << 32) | device();
prng.seed(seed);
Another available option is using std::seed_seq to seed the PRNG. This allows the PRNG to call seed_seq::generate, which produces a non-biased sequence over the range [0 ≤ i < 232), with an output range large enough to fill its entire state.
std::mt19937_64 prng;
std::random_device device;
std::seed_seq seq{device(), device(), device(), device()};
prng.seed(seq);
I'm calling the random_device 4 times to create a 4 element initial sequence for seed_seq. However, I'm not sure what the best practice for this is, as far as length or source of elements in the initial sequence is concerned.
Let's recap (comments too), we want to generate different seeds to get independent sequences of random numbers in each of the following occurrences:
The program is relaunched on the same machine later,
Two threads are launched on the same machine at the same time,
The program is launched on two different machines at the same time.
1 is solved using time since epoch, 2 is solved with a global atomic counter, 3 is solved with a platform dependent id (see How to obtain (almost) unique system identifier in a cross platform way?)
Now the point is what is the best way to combine them to get a uint_fast64_t (the seed type of std::mt19937_64)? I assume here that we do not know a priori the range of each parameter or that they are too big, so that we cannot just play with bit shifts getting a unique seed in a trivial way.
A std::seed_seq would be the easy way to go, however its return type uint_least32_t is not our best choice.
A good 64 bits hasher is a much better choice. The STL offers std::hash under the functional header, a possibility is to concatenate the three numbers above into a string and then passing it to the hasher. The return type is a size_t which on 64 machines is very likely to match our requirements.
Collisions are unlikely but of course possible, if you want to be sure to not build up statistics that include a sequence more than once, you can only store the seeds and discard the duplicated runs.
A std::random_device could also be used to generate the seeds (collisions may still happen, hard to say if more or less often), however since the implementation is library dependent and may go down to a pseudo random generator, it is mandatory to check the entropy of the device and avoid to a use zero-entropy device for this purpose as you will probably break the points above (especially point 3). Unfortunately you can discover the entropy only when you take the program to the specific machine and test with the installed library.
As far as I can tell from your comments, it seems that what you are interested in is ensuring that if a process starts several of your simulations at exactly the same time, they will get different seeds.
The only significant problem I can see with your current approach is a race condition: if you are going to start multiple simulations simultaneously, it must be done from separate threads. If it is done from separate threads, you need to update seed_count in a thread-safe manner, or multiple simulations could end up with the same seed_count. You could simply make it an std::atomic<int> to solve that.
Beyond that, it just seems more complicated than it has to be. What do you gain by using two separate timers? You could do something as simple as this:
at program startup, grab the current system time (using a high resolution timer) once, and store that.
assign each simulation a unique ID (this could just be an integer initialized to 0, (which should be generated without any race conditions, as mentioned above) which is incremented each time a simulation starts, effectively like your seed_count.
when seeding a simulation, just use the initially generated timestamp + the unique ID. If you do this, every simulation in the process is assured a unique seed.
How about...
There is some main code that starts the threads and there are copies of a function run in those threads, each copy with it's own Marsenne Twister. Am I correct? If it is so, why not use another random generator in the main code? It would be seeded with time stamp, and send it's consecutive pseudorandom numbers to function instances as their seeds.
From the comments I understand you want to run several instances of the algorithm, one instance per thread. And given that the seed for each instance will be generated pretty much at the same time, you want to ensure that these seeds are different. If that is indeed what you are trying to solve, then your genSeed function will not necessarily guarantee that.
In my opinion, what you need is a parallelisable random number generator (RNG). What this means, is that you only need one RNG which you instantiate with only one seed (which you can generate with your genSeed) and then the sequence of random numbers that would normally be gerenated in a sequential environment is split in X non-overlapping sequences; where X is the number of threads. There is a very good library which provides these type of RNGs in C++, follows the C++ standard for RNGs, and is called TRNG(http://numbercrunch.de/trng).
Here is a little more information. There are two ways you can achieve non-overlapping sequences per thread. Let's assume that the sequence of random numbers from a single RNG is r = {r(1), r(2), r(3),...} and you have only two threads. If you know in advance how many random numbers you will need per thread, say M, you can give the first M of the r sequence to the first thread, ie {r(1), r(2),..., r(M)}, and the second M to the second thread, ie {r(M+1), r(M+2),...r(2M)}. This technique is called blocksplitting since you split the sequence in two consecutive blocks.
The second way is to create the sequence for the first thread as {r(1), r(3), r(5), ...} and for the second thread as {r(2), r(4), r(6),...}, which has the advantage that you do not need to know in advance how many random numbers you will need per thread. This is called leapfroging.
Note that both methods guarantee that the sequences per thread are indeed non-overlapping. The link I posted above has many examples and the library itself is extremely easy to use. I hope my post helps.
The POSIX function gettimeofday(2) gives the time with microsecond precision.
The POSIX thread function gettid(2) returns the ID number of the current thread.
You should be able to combine the time in seconds since the epoch (which you are already using), the time in microseconds, and the thread ID to get a seed which is always unique on one machine.
If you also need it to be unique across multiple machines, you could consider also getting the hostname, the IP address, or the MAC address.
I would guess that 32 bits is probably enough, since there are over 4 billion unique seeds available. Unless you are running billions of processes, which doesn't seem likely, you should be alright without going to 64 bit seeds.

Priming the Mersenne twister PRNG

There seems to be some mythology around the use of mt19937, specifically that once seeded 'some' number of bits produced by the generator should be ignored so as to have only as near as is possible to pseudo randomness.
Examples of code I've seen are as follows:
boost::mt19937::result_type seed = 1234567; //taken from some entropy pool etc
boost::mt19937 prng(seed);
boost::uniform_int<unsigned int> dist(0,1000);
boost::variate_generator<boost::mt19937&,boost::uniform_int<unsigned int> > generator(prng,dist);
unsigned int skip = 10000;
while (skip--)
{
generator();
}
//now begin using for real.
....
My questions are:
Is this myth or is there some truth to it all?
If it's something viable, how many bits should be ignored? as the numbers I've seen
seem to be arbitrary
The paper referenced in the first comment, Mersenne Twister with improved initialization, isn't just some guy, he's one of the two co-authors of the paper upon which the Boost implementation is based.
The problem with using a single 32-bit integer (4 bytes) as a seed for this generator is that the internal state of the generator is 2496 bytes, according to the Boost documentation. It's not too surprising that such a small seed takes a while to propagate into the rest of the internal state of the generator, particular since the Twister isn't meant to be cryptographically secure.
To address your concern about needing to run the generator for a while to get started, you want the alternate (and explicit) constructor.
template<typename SeedSeq> explicit mersenne_twister_engine(SeedSeq &);
This is the spirit of the third comment, where you initialize with something longer than a single integer. The sequence provide comes from some generator. To use an entropy pool, write a generator as an adapter from an entropy pool, returning values from the pool as needed.