Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
153 views
in Technique[技术] by (71.8m points)

c++ - How to generate the same random number sequence over multiple types of compilers and kernels with <random>?

The problem

I need to produce the same (pseudo) random number sequence on different machines and compilers. If I use the same kernel, it seems that the implementetion of mersenne twister (MT) in g++ works well: regardless if I compile my program on a newer machine, with g++ 4.9 or 4.7, I get the same random numbers. But I get different ones if I use older kernel or if I change to Visual Studio's compiler. That's ok, because there's no gurantee that mersenne_twister_engine::seed sets the internal state to the same over different compilers.

What I've already tried

I tought that applying operator<< on the generator produces a unique result that can be used to set the generators on other machines with the operator>>, but in case of mt19937, it seems it is not working. To make it clear, on a computer A I had the code

mt19937 generator1A;
uniform_int_distribution<int> distribution(0, 1000);

cout << "Generating random numbers with seed 1000" << endl;

generator1A.seed(1000);
generator1A(); //to advance the state by one so operator>> will give a longer output; this is not necessary indeed
ofstream test("testseed1000.txt");
test << generator1A << endl;

for (int i = 0; i < 10; ++i)
    cout << distribution(generator1A) << endl;

And it produces 252, 590, 893, ..., and a long file. I transfer the file to the other machine B, and run the following code:

mt19937 generator1B, generator2B;
uniform_int_distribution<int> distribution(0, 1000);

cout << "Generating random numbers with seed 1000, and with operator>>" << endl;
generator2B.seed(1000);
generator2B(); // to advance the state by one here as well

ifstream test("testseed1000.txt");

test >> generator1B;
cout << "************************" << endl;
cout << generator1B << endl;
cout << "************************" << endl;
cout << "With seedwith operator>>" << endl;

for (int i = 0; i < 10; ++i)
    cout << distribution(generator2B) << "" << distribution(generator1B) << endl;

And it produces

654     205
205     115
115     610

The question

Can you give advices how to generate the same (pseudo) random numbers with at least VC++ on Windows and g++ on Debian and Ubuntu? I'd like to use std if it is possible and I wouldn't like to implement my own MT engine.

Notes:

  • creating millions of random numbers and then reading in is not a solution
  • I have to use MSVS for code developing and unix servers for simulation
  • other than MT engines are also welcomed but I prefer MT
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To remove a variable from the problem, try looking at the outputs from your random number engine, rather than feeding it into a distribution.

I just looked at a few documentation pages for uniform_int_distribution, and it does not give any statement about how the outputs from the uniform random number generator are used. I'm not sure what the standard says.

I predict that you are getting the same outputs from your mersenne twister, but you're feeding those outputs into two inequivalent implementations of uniform_int_distribution.

If this is true, then to get the same random number sequence, you're going to have to use an external implementation of the distribution functions to ensure that you get the same results on all systems.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...