首页 > 解决方案 > 如何理解 C++11 随机数生成器

问题描述

生成随机数的那三行看起来有点棘手。很难永远记住这些台词。有人可以解释一下以使其更容易理解吗?

#include <random>
#include <iostream>

int main()
{
    std::random_device rd;  //1st line: Will be used to obtain a seed for the random number engine

    std::mt19937 gen(rd()); //2nd line: Standard mersenne_twister_engine seeded with rd()

    std::uniform_int_distribution<> dis(1, 6);

    for (int n=0; n<10; ++n)

        std::cout << dis(gen) << ' ';   //3rd line: Use dis to transform the random unsigned int generated by gen into an int in [1, 6]

    std::cout << '\n';
}

以下是我能想到的一些问题:

  1. 第一行代码: 是文档random_devicerandom_device描述的类,所以这行意味着声明一个对象?如果是,为什么在第二行中我们通过构造 mt19937 而不是使用对象(不带括号)?rdrd()rd

  2. 第三行代码:为什么要调用类uniform_int_distribution<>对象dis()?是dis()函数吗?为什么我们要把genobject 传入dis()?

标签: c++

解决方案


random_device 很慢但真正随机,它用于生成随机数序列的“种子”。

mt19937 速度很快,但只是“伪随机”。它需要一个“种子”来开始生成一系列数字。该种子可以是随机的(如您的示例中所示),因此您每次都会获得不同的随机数序列。但它可能是一个常数,所以你每次都会得到相同的数字序列。

uniform_int_distribution 是一种将随机数(可以有任何值)映射到您实际感兴趣的数字的方法,在这种情况下是从 1 到 6 的整数的均匀分布。

与 OO 编程的情况一样,这段代码是关于职责划分的。每个类对整体需求(掷骰子的生成)贡献了一小部分。如果你想做一些不同的事情,这很容易,因为你已经把所有的东西都摆在了你面前。

如果这太多了,那么您需要做的就是编写一个函数来捕捉整体效果,例如

int dice_roll()
{
    static std::random_device rd;
    static std::mt19937 gen(rd());
    static std::uniform_int_distribution<> dis(1, 6);
    return dis(gen);
}

dis函数对象仿函数的示例。它是一个重载的对象,operator()因此可以像调用函数一样调用它。


推荐阅读