c++ 11中的随机数生成:如何生成,如何工作

Random number generation in C++11: how to generate, how does it work?

本文关键字:何生成 何工作 工作 随机数 c++      更新时间:2023-10-16

我最近遇到了在c++ 11中生成随机数的新方法,但无法消化我读过的关于它的论文(引擎是什么,数学术语,如分布,"所有生成的整数等可能")。

谁能解释一下

  • 它们是什么?
  • 它们是什么意思?
  • 如何生成?
  • 它们是如何工作的?

关于随机数生成的常见问题解答

这个问题太宽泛了,不可能给出一个完整的答案,但让我挑选几个有趣的点:

为什么"等可能"

假设你有一个简单的随机数生成器,它生成数字0,1,…,每10个都有相同的概率(把它想象成经典的rand())。现在你想要一个在0,1,2范围内的随机数,每个随机数的概率是相等的。你的本能反应是选择rand() % 3。但是等等,余数0和1比余数2出现的次数更多,所以这是不正确的!

这就是为什么我们需要合适的分布,它采用一致随机整数的源并将它们转换为我们想要的分布,如示例中的Uniform[0,2]。最好把这个问题留给一个好的图书馆!

<

引擎/h3>

因此,在所有随机性的核心是一个好的伪随机数生成器,它生成在一定间隔内均匀分布的数字序列,并且理想情况下具有很长的周期。rand()的标准实现通常不是最好的,因此最好有一个选择。线性同余和Mersenne twister是两个不错的选择(实际上rand()也经常使用LG);还是那句话,最好让库来处理。

工作原理

简单:首先,设置一个引擎并播种它。种子完全决定了"随机"数字的整个序列,所以a)每次使用不同的一个(例如从/dev/urandom中取出),b)如果您希望重新创建随机选择序列,则存储种子。

#include <random>
typedef std::mt19937 MyRNG;  // the Mersenne Twister with a popular choice of parameters
uint32_t seed_val;           // populate somehow
MyRNG rng;                   // e.g. keep one global instance (per thread)
void initialize()
{
  rng.seed(seed_val);
}

现在我们可以创建发行版:

std::uniform_int_distribution<uint32_t> uint_dist;         // by default range [0, MAX]
std::uniform_int_distribution<uint32_t> uint_dist10(0,10); // range [0,10]
std::normal_distribution<double> normal_dist(mean, stddeviation);  // N(mean, stddeviation)

…并使用引擎创建随机数!

while (true)
{
  std::cout << uint_dist(rng) << " "
            << uint_dist10(rng) << " "
            << normal_dist(rng) << std::endl;
}

并发

选择<random>而不是传统的rand()的另一个重要原因是,现在如何使随机数生成线程安全非常清楚和明显:要么为每个线程提供自己的线程本地引擎,在线程本地种子上播种,要么同步访问引擎对象。

Misc

    一篇关于TR1随机的有趣文章。维基百科有一个很好的总结(谢谢,@Justin)。
  • 原则上,每个引擎都应该定义一个result_type类型,这是种子使用的正确的整型。我认为我曾经有一个错误的实现,迫使我在x64上强制std::mt19937uint32_t的种子,最终这应该是固定的,你可以说MyRNG::result_type seed_val,从而使引擎非常容易更换。

随机数生成器是一个方程,给定一个数字,它会给你一个新数字。通常,您要么提供第一个数字,要么从系统时间等内容中提取。

每次请求一个新数字时,它都会使用前一个数字来执行方程。

如果一个随机数生成器倾向于比其他数字更频繁地产生相同的数字,那么它就不被认为是非常好的。例如,如果你想要一个1到5之间的随机数,并且你有这样的数字分布:

  • 1:1 %
  • 2: 80%
  • 3:5 %
  • 4:5 %
  • <
  • 5: 9%/gh>

2比其他任何数字产生的频率都要高,因此它比其他数字更有可能产生。如果所有的数字都是相等的你每次都有20%的机会得到每个数字。换句话说,上述分布非常不均匀,因为2更受青睐。所有20%的分布都是均匀的。

通常,如果你想要一个真正的随机数,你会从天气或其他自然来源中提取数据,而不是从随机数生成器中提取数据。