使用梅森扭曲器 C++ 生成数字 (0,1)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22923551/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 00:16:50  来源:igfitidea点击:

Generating number (0,1) using mersenne twister c++

c++mersenne-twister

提问by user3508622

I'm working on implementing R code into C++ so that it runs faster, but I am having difficulties implementing mersenne twister. I only wish to generate values between (0,1). Here is what I have that pertains to this question.

我正在努力将 R 代码实现到 C++ 中,以便它运行得更快,但是我在实现 mersenne twiner 时遇到了困难。我只想在 (0,1) 之间生成值。这是我对这个问题的了解。

#include <random>

std::mt19937 generator (123);

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

I tried dividing by RAND_MAX, but that did not produce the values that I was looking for.

我尝试除以RAND_MAX,但这并没有产生我正在寻找的值。

Thanks in advance.

提前致谢。

回答by sbabbi

In C++11 the concepts of "(pseudo) random generator" and "probability distribution" are separated, and for good reasons.

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

What you want can be achieved with the following lines:

您可以通过以下几行实现您想要的:

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

  double randomRealBetweenZeroAndOne = dis(generator);

If you want to understand why this separation is necessary, and why using a standard division /range manipulation on the output of the generator is a bad idea, watch this video.

如果您想了解为什么这种分离是必要的,以及为什么对生成器的输出使用标准除法/范围操作是个坏主意,请观看此视频

回答by Mr.C64

You may want to consider code like this:

您可能需要考虑这样的代码:

// 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);


For more details on generating pseudo-random numbers in C++ (including reasons why rand()is notgood), see this video by Stephan T. Lavavej(from Going Native 2013):

有关用C产生伪随机数,更多的细节++(包括原因rand()没有好),看到这部影片由斯蒂芬T. Lavavej(从融入本土2013):

rand()Considered Harmful

rand()认为有害

回答by galinette

std::mt19937 does not generate between 0 and RAND_MAX like rand(), but between 0 and 2^32-1

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

And by the way, the class provides min() and max() values!

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

You need to convert the value to a double, substract min() and divide by max()-min()

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

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

or (less generic)

或(不太通用)

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