伪随机数生成

来自cppreference.com
< cpp‎ | numeric
 
 
 
 

随机数库提供生成随机和伪随机数的类。这些类包括:

  • 随机数引擎(生成拥有均匀分布整数序列的伪随机数生成器,和若可用则如此的真随机数生成器)。
  • 随机数分布(例如均匀正态泊松分布),它们将随机数引擎的输出转换为各种统计分布。

引擎和分布被设计为相互使用以生成随机值。所有引擎都可以指定地播种、序列化和反序列化,以用于可重复的模拟器。

目录

[编辑] 随机数引擎

随机数引擎以种子数据为熵源生成伪随机数。数种不同类的伪随机数生成算法实现为能定制的模板。

选择使用何种引擎涉及到多次权衡:线性同余引擎一般地块,并对状态的存储要求非常小。延迟斐波那契生成器在无先进算术指令集的处理器上非常快,但状态存储较为庞大,有时有不太想要的光谱特性。梅森缠绕器较慢且拥有较大的状态存储要求,但只要有正确的参数,就会有最长的的不可重复序列,且拥有最想要的光谱特性(对于给定的想要的定义)。

随机数引擎满足均匀随机位生成器 (UniformRandomBitGenerator)

定义于头文件 <random>
实现线性同余算法
(类模板)
实现梅森缠绕器算法
(类模板)
实现带进位减(一种延迟斐波那契)算法
(类模板)

[编辑] 随机数引擎适配器

随机数引擎适配器生成以另一随机数引擎为熵源的伪随机数。它们通常用于改换底层引擎的光坡特性。

定义于头文件 <random>
舍弃随机数引擎的某些输出
(类模板)
打包随机数引擎的输出为指定位数的块
(类模板)
以不同顺序发送随机数引擎的输出
(类模板)

[编辑] 预定义随机数生成器

定义了数个特别的流行算法。

定义于头文件 <random>
类型 定义
minstd_rand0 std::linear_congruential_engine<std::uint_fast32_t, 16807, 0, 2147483647>

由 Lewis 、 Goodman 及 Miller 发现于 1969 ,由 Park 与 Miller 于 1988 接纳为“最小标准”[编辑]

minstd_rand std::linear_congruential_engine<std::uint_fast32_t, 48271, 0, 2147483647>

较新的“最小标准”,为 Park 、 Miller 及 Stockmeyer 于 1993 推荐[编辑]

mt19937

std::mersenne_twister_engine<std::uint_fast32_t, 32, 624, 397, 31,
                             0x9908b0df, 11,
                             0xffffffff, 7,
                             0x9d2c5680, 15,
                             0xefc60000, 18, 1812433253>

32 位梅森缠绕器,由松本与西村发现于 1998[编辑]

mt19937_64

std::mersenne_twister_engine<std::uint_fast64_t, 64, 312, 156, 31,
                             0xb5026f5aa96619e9, 29,
                             0x5555555555555555, 17,
                             0x71d67fffeda60000, 37,
                             0xfff7eee000000000, 43, 6364136223846793005>

64 位梅森缠绕器,由松本与西村设计于 2000[编辑]

ranlux24_base std::subtract_with_carry_engine<std::uint_fast32_t, 24, 10, 24>[编辑]
ranlux48_base std::subtract_with_carry_engine<std::uint_fast64_t, 48, 5, 12>[编辑]
ranlux24 std::discard_block_engine<std::ranlux24_base, 223, 23>

24 位 RANLUX 生成器,由 Martin Lüscher 与 Fred James 设计于 1994[编辑]

ranlux48 std::discard_block_engine<std::ranlux48_base, 389, 11>

48 位 RANLUX 生成器,由 Martin Lüscher 与 Fred James 设计于 1994[编辑]

knuth_b std::shuffle_order_engine<std::minstd_rand0, 256>[编辑]
default_random_engine 实现定义

[编辑] 非确定随机数

std::random_device 是非确定的均匀随机数生成器,尽管若不支持非确定随机数生成,则允许实现用伪随机数引擎实现 std::random_device

用硬件熵源的非确定随机数生成器
(类) [编辑]

[编辑] 随机数分布

随机数分布后处理随机数的发生结果,以使得输出结果按照定义的统计概率密度函数分布。

随机数分布满足随机数分布 (RandomNumberDistribution)

定义于头文件 <random>
均匀分布
产生均匀分布在范围上的整数值
(类模板) [编辑]
产生均匀分布在范围上的实数值
(类模板) [编辑]
伯努利分布
产生伯努利分布上的 bool 值。
(类)
产生二项分布上的整数值。
(类模板)
产生负二项分布上的整数值。
(类模板)
产生几何分布上的整数值。
(类模板)
泊松分布
产生泊松分布上的整数值。
(类模板)
产生指数分布上的实数值。
(类模板)
产生 Γ 分布上的实数值
(类模板)
产生威布尔分布上的实数值。
(类模板)
产生极值分布上的实数值。
(类模板)
正态分布
产生标准正态(高斯)分布上的实数值。
(类模板)
产生对数正态分布上的实数值。
(类模板)
产生 χ2 分布上上的实数值。
(类模板)
产生柯西分布上的实数值。
(类模板)
产生费舍尔 F 分布上的实数值。
(类模板)
产生学生 t 分布上的实数值。
(类模板)
采样分布
产生离散分布上的随机整数。
(类模板)
产生分布在常子区间上的实数值。
(类模板)
产生分布在定义的子区间上的实数值。
(类模板)

[编辑] 工具

定义于头文件 <random>
给定精度的均匀分布在 [0, 1) 上的实数值
(函数模板) [编辑]
(C++11)
通用的偏差消除的混淆种子序列生成器
(类)

[编辑] C 随机库

除了上述的引擎和分布,来自 C 随机库的函数和常量亦可用,尽管不推荐:

定义于头文件 <cstdlib>
生成伪随机数
(函数) [编辑]
初始化伪随机数生成器
(函数) [编辑]
std::rand 生成的最大可能值
(宏常量) [编辑]

[编辑] 示例

#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <random>
#include <cmath>
 
int main()
{
    // 以随机值播种,若可能
    std::random_device r;
 
    // 选择 1 与 6 间的随机数
    std::default_random_engine e1(r());
    std::uniform_int_distribution<int> uniform_dist(1, 6);
    int mean = uniform_dist(e1);
    std::cout << "Randomly-chosen mean: " << mean << '\n';
 
    // 生成围绕平均值的正态分布
    std::seed_seq seed2{r(), r(), r(), r(), r(), r(), r(), r()}; 
    std::mt19937 e2(seed2);
    std::normal_distribution<> normal_dist(mean, 2);
 
    std::map<int, int> hist;
    for (int n = 0; n < 10000; ++n) {
        ++hist[std::round(normal_dist(e2))];
    }
    std::cout << "Normal distribution around " << mean << ":\n";
    for (auto p : hist) {
        std::cout << std::fixed << std::setprecision(1) << std::setw(2)
                  << p.first << ' ' << std::string(p.second/200, '*') << '\n';
    }
}

可能的输出:

Randomly-chosen mean: 4
Normal distribution around 4:
-4 
-3 
-2 
-1 
 0 *
 1 ***
 2 ******
 3 ********
 4 *********
 5 ********
 6 ******
 7 ***
 8 *
 9 
10 
11 
12

[编辑] 参阅

伪随机数生成C 文档