C/C++生成随机数
1. rand函数
只要产生随机数而不需要设定范围的话,只要用rand()就可以了,rand()会返回一随机数值,范围在0至RAND_MAX 间。RAND_MAX定义在stdlib.h,其值为2147483647。
# include <iostream>
using namespace std;
int main()
{
for (int i=0; i<10; i++)
{
cout << rand() << endl;
}
}
运行结果生成10个随机数:
41
18467
6334
26500
19169
15724
11478
29358
26962
24464
2. srand函数
##include <time.h>
#include <stdlib.h>
srand((unsigned int)time(NULL));//在main函数里调用srand函数以实现真正随机
3. random库
3.1. 头文件
#include <random>
3.2. 随机数类常⽤函数介绍
- default_random_engine
随机⾮负数(不建议单独使⽤)。是⼀个随机数引擎类。它定义的调⽤运算符返回⼀个随机的 unsigned 类型的值。
- uniform_int_distribution
指定范围的随机⾮负数。是⼀个随机数分布类,也是个模板类,模板参数为⽣成随机数的类型(不过只能是 int、unsigned、short、unsigned short、long、unsigned long、long long、unsigned long long 中的⼀种)。它的构造函数接受两个值,表⽰随机数的分布范围(闭区间)。
- uniform_real_distribution
指定范围的随机实数。是⼀个随机数分布类,它也是模板类,参数表⽰随机数类型(可选类型为 float、double、long double)。构造函数也需要最⼤值和最⼩值作为参数。(左闭右开区间)
- bernoulli_distribution
指定概率的随机布尔值。是⼀个分布类,但它不是模板类。它的构造函数只有⼀个参数,表⽰该类返回 true 的概率,该参数默认为 0.5,即返回 true 和 false 的概率相等。
3.3. 示例
//随机数生成引擎
//利用了真随机数 random_device()
default_random_engine e{random_device{}()};
mt19937_64 eng{random_device{}()};
//随机数分布引擎
uniform_real_distribution<double> dis1(0, 20);
uniform_int_distribution<int> dis2(20, 40);
bernoulli_distribution u;
for(int i = 0;i < 4; ++i){
cout<<e()<<" ";
}
cout<<endl; //370521601 1801455354 1835679272 1511451702
for(int i = 0;i < 4; ++i){
cout<<dis1(eng)<<" ";
}
cout<<endl; //6.65994 0.0263284 0.0570728 17.9504
for(int i = 0;i < 4; ++i){
cout<<dis2(e)<<" ";
}
cout<<endl; //23 36 25 30
for(int i = 0;i < 4; ++i){
cout<<u(e)<<" ";
}
cout<<endl; //0 0 1 0
4. 随机数引擎
C++11提供了下面三种随机数生成算法可供选择:
linear_congruential_engine线性同余法
mersenne_twister_engine梅森旋转法
substract_with_carry_engine滞后Fibonacci
这三种算法,在C++11里面都是用模板的方式实现的。C++11标准预定义了一些随机数类,这些随机数类都是用比较好的参数实例化上面那三个模板类得到的。
注意:在C++11里面,把这些随机数生成器叫做引擎(engines)。
下图列出了一些实例化的随机数类:
当然具体用了哪些参数,我们是不用管的,直接用就行了。
4.1. default_random_engine类
上图左上角的default_random_engine的类,也是一个实例化的类。之所以不归入那三种算法,是因为它的实现是由编译器厂家决定的,有的可能用linear_congruential_engine实现,有的可能用mersenne_twister_engine实现。不过,对于其他的类,C++11是有明确规定用哪种算法和参数实现的。
default_random_engine 是⼀个随机数引擎类。它定义的调⽤运算符返回⼀个随机的 unsigned 类型的值。
#include<iostream>
#include<random>
int main(){
default_random_engine e;
//也可为随机数引擎加随机数发生器的参数:
//default_random_engine random(time(NULL));
//default_random_engine random{random_device{}()};
for(int i = 0; i < 20; ++i)
cout<<e()<<' ';
cout<<endl;
return 0;
}
//gcc编译器需要加上 –std=c++11 选项。
4.2. default_random_engine类
上图左上角的default_random_engine的类,也是一个实例化的类。之所以不归入那三种算法,是因为它的实现是由编译器厂家决定的,有的可能用linear_congruential_engine实现,有的可能用mersenne_twister_engine实现。不过,对于其他的类,C++11是有明确规定用哪种算法和参数实现的。
default_random_engine 是⼀个随机数引擎类。它定义的调⽤运算符返回⼀个随机的 unsigned 类型的值。
#include<iostream>
#include<random>
int main(){
default_random_engine e;
//也可为随机数引擎加随机数发生器的参数:
//default_random_engine random(time(NULL));
//default_random_engine random{random_device{}()};
for(int i = 0; i < 20; ++i)
cout<<e()<<' ';
cout<<endl;
return 0;
}
//gcc编译器需要加上 –std=c++11 选项。
4.3. mt19937 随机数引擎
mt19937又叫梅森旋转算法,用于生成随机数的,他也不是梅森发明的,是俩日本人发明的。它的循环节是 2 19937 − 1 2^{19937}-1 219937−1,这是一个梅森素数,所以叫mt19937,也就是说:
mt是指maxint(整型int最大值的缩写)
19937是指
常用下面的语句生成一个随机数引擎
mt19937 gen{random_device {}()};
mt19937是c++11新特性,它是一种随机数算法,用法与rand()函数类似,但是与其它已使用的伪随机数发生器相比,mt19937具有速度快,周期长的特点,周期可达到。
rand()在windows下生成的数据范围为0-32726
mt19937所生成的数据范围大概为(-maxint, +maxint)(maxint整型int最大值的缩写)
4.4. 真随机数 random_device()
random_device()函数目的就是产生生成真随机数。它并不是由某一个数学算法得到的随机序列,而是通过读取文件,读什么文件看具体的实现(Linux可以通过读取/dev/random文件来获取)。文件的内容是随机的,因为文件内容是计算机系统的熵(熵指的是一个系统的混乱程度)。也是当前系统的环境噪声,系统噪音可以通过很多参数来评估,如内存的使用,文件的使用量,不同类型的进程数量等等。Linux的熵来自键盘计时、鼠标移动等。
然而randm_device()只在Linux下有效,在Windows下无效。
#include <random>//随机数
random_device rd;//随机数发生器
mt19937 g(rd());//随机数引擎
或者写为下面一句:
mt19937 g{random_device{}()};
//类似于srand()和rand()的效果
srand(time(NULL)); //初始化随机数种子
参考文献
更多推荐
所有评论(0)