使用boost :: random并获得相同的数字序列

Set*_*eth 3 c++ random

我有以下代码:

Class B {

void generator()
{
    // creating random number generator
    boost::mt19937 randgen(static_cast<unsigned int>(std::time(0)));
    boost::normal_distribution<float> noise(0,1);
    boost::variate_generator<boost::mt19937, 
        boost::normal_distribution<float> > nD(randgen, noise);


    for (int i = 0; i < 100; i++)
    {
        value = nD();
        // graph each value
    }
}
};

Class A {

void someFunction()
{
    for(int i = 1; i <=3; i++)
    {
        std::shared_ptr<B> b;
        b.reset(new B());
        b->generator();
    }
}
};
Run Code Online (Sandbox Code Playgroud)

我希望快速连续多次执行上面的代码,以生成多个图形.我还回顾了这个类似的stackoverflow问题,但有一点需要注意,当使用time(0)并快速连续调用成员函数时,你仍然可能得到相同的数字序列.

我怎么能克服这个问题?

编辑:我已经尝试在B类中制作randgen静态,也尝试使它成为A类中的全局变量,但每次3个图形仍然相同.我也试过从GetSystemTime毫秒播种.我肯定错过了什么.

pax*_*blo 6

一种方法是每次执行代码时不重新设置随机数生成器.

创建生成器并将其播种一次,然后继续使用它.

假设您在同一次运行中多次调用该代码.如果您正在进行多次运行(但仍在同一秒内),则可以使用其他不同的属性(例如进程ID)来更改种子.

或者,您可以使用Windows GetSystemTime()返回SYSTEMTIME结构,其中一个元素为毫秒,或者Linux getTimeOfDay返回自纪元以来的微秒数.

视窗:

#include <windows.h>
SYSTEMTIME st;
GetSystemTime (&st);
// Use st.wSecond * 100 + st.wMillisecs to seed (0 thru 59999).
Run Code Online (Sandbox Code Playgroud)

Linux的:

#include <sys/time.h>
struct timeval tv;
gettimeofday (&tv, NULL);
// Use tv.tv_sec * 100 + (tv.tv_usec / 1000) to seed (0 thru 59999).
Run Code Online (Sandbox Code Playgroud)


pdu*_*sen 6

使用Boost.Random,您可以保存随机数生成器的状态 - 例如,您可以将其保存到文本文件中.这是通过流完成的.

例如,使用代码,在为生成器设定种子并运行一次后,可以使用输出流保存状态,如下所示:

std::ofstream generator_state_file("rng.saved");
generator_state_file << randgen;
Run Code Online (Sandbox Code Playgroud)

然后,当您创建新生成器时,可以使用相反的流从该文件加载状态:

std::ifstream generator_state_file("rng.saved");
generator_state_file >> randgen;
Run Code Online (Sandbox Code Playgroud)

然后使用状态生成一些更随机的数字,然后重新保存状态,依此类推.

如果您不想使用文件,也可以将状态保存为std::string使用状态std::stringstream,但我没有亲自尝试过.