c++随机数random的使用
C库<cstdlib>中的rand()可以很方便地生成随机数但也存在一些弊端,C++11标准引入了头文件<random>来提供更加完备地随机数功能。主要分为两个部分:随机数引擎(random-number engines)和随机数分布类(random-number distribution)其中,一个引擎类可以生成 unsigned 随机数列,一个分布使用一个引擎类生成指定类型的,在给定范围内的,服从指定概率分布的随机数。
随机数引擎
random_device
标准库提供了一个真随机数生成设备random_device,在UNIX和LINUX中是真随机数,在Windows中使用的是操作系统来生成加密安全的伪随机数。由于各种原因,我们通常使用random_device来产生随机数种子,而不是直接用其产生随机数。
常用随机数算法模板
linear_congruential_engine线性同余法,这种速度最快、最常用mersenne_twister_engine梅森旋转法,这种生成的随机数质量比较高substract_with_carry_engine滞后Fibonacci
参考C++ Reference如果自己实例化模版类很麻烦,需要很强的数序知识,所以有几个常用的几个模版实例化生成器。
实例化的生成器
default_random_engine
它是一个实例化的类。之所以不归入那三种算法,是因为它的实现是由编译器厂家决定的,有的可能用linear_congruential_engine实现,有的可能用mersenne_twister_engine实现。这种现象在C/C中见多了。不过,对于其他的类,C11是有明确规定用哪种算法和参数实现的。
线性同余法
minstd_rand()minstd_rand0
利用适配器变种后
knuth_b:minstd_rand0withshuffle_order_engine
梅森旋转法
mt19937mt19937_64
滞后Fibonacci法
ranlux24_baseranlux48_base
利用适配器变种后的滞后Fibonacci法:
ranlux24:ranlux24_basewithdiscard_block_engineranlux48:ranlux48_basewithdiscard_block_engine
三个适配器
discard_block_engine shuffle_order_engine independent_bits_engine
随机数分布模板
均匀分布:
uniform_int_distribution整数均匀分布uniform_real_distribution浮点数均匀分布
注意,
uniform_int_distribution的随机数的范围不是半开范围[ ),而是[ ],对于uniform_real_distribution却是半开范围[ )。
伯努利类型分布:(仅有yes/no两种结果,概率一个p,一个1-p)
bernoulli_distribution伯努利分布binomial_distribution二项分布geometry_distribution几何分布negative_biomial_distribution负二项分布
Rate-based distributions:
poisson_distribution泊松分布exponential_distribution指数分布gamma_distribution伽马分布weibull_distribution威布尔分布extreme_value_distribution极值分布
正态分布相关:
normal_distribution正态分布chi_squared_distribution卡方分布cauchy_distribution柯西分布fisher_f_distribution费歇尔F分布student_t_distributiont分布
分段分布相关:
discrete_distribution离散分布piecewise_constant_distribution分段常数分布piecewise_linear_distribution分段线性分布
这些模板类都是定义好了的、可以直接使用的。
使用方法实例
1 |
|
直接使用default_random_engine作为生成器产生随机数,通过多次运行这段程序我们发现生成的随机数都是一样的,随机数发生器会生成相同的随机数序列,这种特性在调试程序的时候可能会非常有用,但如果想要生成完全随机的序列,我们需要在初始化生成器的时候指定一个随机数种子。可以通过random_device来获得一个真随机数种子。
1 | #include <iostream> |
当需要特定随机数分布模板的时候,可以通过随机数分布模板(生成器引擎)的方式获得。
1 | #include <iostream> |
当我们需要在函数调用中获得不同的随机数,我们可以通过把生成器和分布模板设置为static来保存状态,这样每次调用的时候都能获得下一个随机数。




