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是指2^{19937}-1

常用下面的语句生成一个随机数引擎

mt19937 gen{random_device {}()};

mt19937是c++11新特性,它是一种随机数算法,用法与rand()函数类似,但是与其它已使用的伪随机数发生器相比,mt19937具有速度快,周期长的特点,周期可达到2^{19937}-1

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)); //初始化随机数种子

参考文献

C++如何生成随机数_fenxinzi557的博客-CSDN博客_c++生成一个随机数

C++11 随机数_何处微尘的博客-CSDN博客_c++11 随机数

  • 18
    点赞
  • 111
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值