使用<random>和函数</random>生成随机双向量

时间:2014-02-11 06:51:35

标签: c++ c++11 random

我编写了以下函数来生成双精度的随机向量:

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)......

谢谢!

2 个答案:

答案 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,在调用函数之前不需要将向量设置为正确的大小,并且如果需要,可以向向量添加值。

Live demo

答案 1 :(得分:1)

您应该将std::mt19937的定义移出到全局范围内,以便只初始化一次。随机数生成是全局变量更有意义的罕见情况之一。此外,播种的最佳做法是使用std::random_device而不是当前时间。