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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With