我编写了以下函数来生成双精度的随机向量:
void getrands(vector<double> *x)
{
int N=(*x).size();
uniform_real_distribution<double> unif(0.0,1.0);
mt19937 re(time(NULL));
auto generator = bind(unif,re);
generate_n((*x).begin(),N,generator);
}
在我的main()程序中,如果我尝试在几个向量上调用此函数(假设我想生成10个随机向量),我最终得到的所有向量都包含相同的随机数,因为没有足够的时间过去得到一个好的重播种子。有什么更好的方法呢?我应该创建一个随机数组然后将其转换为向量?我习惯了matlab,我可以调用X = rand(n,m)......
谢谢!
答案 0 :(得分:5)
更好的方法是使用std::random_device
为随机数生成器播种。
mt19937 re(std::random_device{}());
你应该将RNG作为参数传递给函数,而不是每次迭代都创建一个新实例。
另外,请注意std::bind
复制其参数,因此您可能希望将RNG包装在std::ref
中,然后将其作为参数传递给bind
。
我将你的功能重写为
template<typename Generator>
void getrands(vector<double>& x, Generator& gen, unsigned num)
{
generate_n(std::back_inserter(x), num, std::ref(gen));
}
并将其命名为
uniform_real_distribution<double> unif(0.0,1.0);
mt19937 re(std::random_device{}());
auto generator = bind(unif, std::ref(re));
vector<double> vs;
getrands(vs, generator, 10);
这允许您重用相同的RNG,在调用函数之前不需要将向量设置为正确的大小,并且如果需要,可以向向量添加值。
答案 1 :(得分:1)
您应该将std::mt19937
的定义移出到全局范围内,以便只初始化一次。随机数生成是全局变量更有意义的罕见情况之一。此外,播种的最佳做法是使用std::random_device
而不是当前时间。