随机数生成设备
随机数生成设备random_device
,生成非确定性随机数,在Linux中通过读取/dev/urandom
设备,Windows中使用rand_s
重载了()
运算符,每次调用会生成一个min()
到max()
之间的高质量随机数种子,若在Linux(Unix Like)下,可以使用这个生成高质量的随机数,可以理解为真随机数,windows下就无所谓了
随机数引擎类
- 由编译器厂家实现
default_random_engine
- 线性同余引擎算法
linear_congruential_engine
- 梅森旋转算法
mersenne_twister_engine
- 带进位的线性同余算法
subtract_with_carry_engine
- 基于梅森旋转算法
生成周期更长的伪随机数,质量高,但是速度较慢
std::mt19937
std::mt19937_64
64 bit 版本
除了使用random_device
,还可以用time()
生成随机数种子
default_random_engine dre(time(NULL));
由于time()
返回以秒计的时间,该方式只适用于生成种子的间隔为秒级或更长的场景
随机数分布类
将随机数引擎生成的随机数序列映射到常见的分布
- 均匀分布
std::uniform_int_distribution<>
整数均匀分布,若使用无参构造,则范围为[0,numberic_limits::max()]
std::uniform_real_distribution<>
浮点数均匀分布,默认为double
,若使用无参构造,则范围为[0,1)
- 伯努利类型
伯努利分布std::bernoulli_distribution
二项分布std::binomial_distribution
几何分布std::geometry_distribution
负二项分布std::negative_biomial_distribution
- 正态分布相关
正态分布std::normal_distribution<>
卡方分布chi_squared_distribution
柯西分布cauchy_distribution
费歇尔F分布fisher_f_distribution
t分布student_t_distribution
- 分段分布
离散分布discrete_distribution
分段常数分布piecewise_constant_distribution
分段线性分布piecewise_linear_distribution
- 其他分布
泊松分布poisson_distribution
指数分布exponential_distribution
伽马分布gamma_distribution
威布尔分布weibull_distribution
极值分布extreme_value_distribution
如下函数,用于生成随机数
vector<unsigned> bad_randVec() {
default_random_engine engine;
uniform_int_distribution<unsigned> ui_distr(0,9);
vector<unsigned> ret;
for(size_t i = 0;i<100;i++)
ret.push_back(ui_distr(engine));
return ret;
}
每次调用bad_randVec()
函数时,都会生成相同的随机数,若想每次调用该函数能获取到不同的随机数,应将engine
和ui_distr
定义为static
,保持变量状态,从而每次调用都生成新的随机数,如下good_randVec()
vector<unsigned> good_randVec() {
static default_random_engine engine;
static uniform_int_distribution<unsigned> ui_distr(0,9);
vector<unsigned> ret;
for(size_t i = 0; i<100;i++)
ret.push_back(ui_distr(engine));
return ret;
}
示例如下
#include<random>
#include<ctime>
#include<functional>
int main() {
// std::random_device rd;
// std::default_random_engine eng(rd());
// std::default_random_engine eng(1);
std::default_random_engine eng(time(NULL));
std::uniform_int_distribution<int> distr(1,10);
auto func= bind(distr, eng);
for(int i=0; i<10; ++i){
std::cout<<func()<<std::ends; // distr(eng);
}
return 0;
}
注:若想在类中初始化uniform_int_distribution
,可在构造函数初始化列表中进行