使用mersenne twister c ++生成数字(0,1)

时间:2014-04-07 21:34:31

标签: c++ mersenne-twister

我正在努力将R代码实现到C ++中,以便它运行得更快,但我在实现mersenne twister方面遇到了困难。我只想生成(0,1)之间的值。以下是我对此问题的看法。

#include <random>

std::mt19937 generator (123);

std::cout << "Random value: " << generator() << std:: endl;

我尝试除以RAND_MAX,但这并没有产生我想要的值。

提前致谢。

3 个答案:

答案 0 :(得分:16)

在C ++ 11中,“(伪)随机生成器”和“概率分布”的概念是分开的,并且有充分的理由。

您可以通过以下方式实现您的目标:

  std::mt19937 generator (123);
  std::uniform_real_distribution<double> dis(0.0, 1.0);

  double randomRealBetweenZeroAndOne = dis(generator);

如果你想了解为什么这种分离是必要的,以及为什么在生成器的输出上使用标准的除法/范围操作是个坏主意,请注意这个video

答案 1 :(得分:6)

您可能需要考虑以下代码:

// For pseudo-random number generators and distributions
#include <random> 

...

// Use random_device to generate a seed for Mersenne twister engine.
std::random_device rd{};    

// Use Mersenne twister engine to generate pseudo-random numbers.
std::mt19937 engine{rd()};

// "Filter" MT engine's output to generate pseudo-random double values,
// **uniformly distributed** on the closed interval [0, 1].
// (Note that the range is [inclusive, inclusive].)
std::uniform_real_distribution<double> dist{0.0, 1.0};

// Generate pseudo-random number.
double x = dist(engine);

有关在C ++中生成伪随机数的更多详细信息(包括rand() 好的原因),请参阅此视频 Stephan T. Lavavej (来自Going Native 2013):

  

rand() Considered Harmful

答案 2 :(得分:1)

std :: mt19937不会像0和RAND_MAX一样生成rand(),而是介于0和2 ^ 32-1之间

顺便说一下,这个类提供了min()和max()值!

您需要将值转换为double,减去min()并除以max() - min()

uint32_t val;
val << generator;
double doubleval = ((double)val - generator::min())/(generator::max()-generator::min());

或(不太通用)

uint32_t val;
val << generator;
double doubleval = (double)val * (1.0 / std::numeric_limits<std::uint32_t>::max());