随机数(新标准)

随机数

一、概念

1、在新标准出现之前,c和c++都依赖于一个简单的c库函数rand来生成随机数,此函数生成均匀分布的伪随机函数。
2、有很多程序需要不同范围的随机数,一些应用需要浮点数,一些程序需要非均匀分布的数,对于这些,程序员需要转换rand生成的范围。
3、定义在random中的随机数库通过一组协作的类来解决这些问题,随机数引擎类和**随机数分布类。**一个引擎类生成unsigned随机数序列,一个分布类使用一个引擎类生成指定类型的,在给定范围内的、服从特定概率分布的随机数。

二、随机数引擎和分布

1、导言

通过调用一个随机数引擎对象来生成原始随机数。
c++程序不应该使用库函数rand,而应使用default_random_engine类和恰当的分布类对象。

default_random_engine e;  //生成随机数无符号数

2、随机数引擎操作

Engine e默认构造函数,使用该引擎类型默认的种子
Engine e(s)使用整数值s作为种子
e.seed(s)使用种子s重置引擎状态
e.min()该引擎生成最小值
e.max()改引擎生成最大值
Engine::result_type该引擎生成的unsigned整型类型
e.discard(u)将引擎器推进u步,u的类型为unsigned long long

对于大多数情况下,随机数引擎的输出是不能直接使用的。

3、分布类型和引擎

为了得到在一个指定范围内的数,我们使用一个分布类型的对象

uniform_int_distribution<unsigned> u(0,9); //此类型生成均匀分布的unsigned值
default_random_engine e;  //生成无符号随机数
for(size_t i=0;i<10;++i)
cout<<u(e)<<" ";
cout<<endl;

分布类型定义了一个调用运算符,它接受一个随机数引擎作为参数,分布对象使用它的引擎参数生成随机数,并将其映射到指定的分布。

4、引擎生成一个数值序列

一个给定的随机数发生器一直会生成相同的随机数序列,一个函数如果定义了局部的随机数发生器,应该将其定义为static的,否则每次调用函数都会生成相同的序列。

#include<iostream>
#include<random>
using namespace std;
void noStatic()
{
	uniform_int_distribution<unsigned> u(0, 9); //此类型生成均匀分布的unsigned值
	default_random_engine e;  //生成无符号随机数
	for (size_t i = 0; i < 10; ++i)
		cout << u(e) << " ";
	cout << endl;
}
void Static() {
  static uniform_int_distribution<unsigned> u(0, 9); //此类型生成均匀分布的unsigned值
  static default_random_engine e;  //生成无符号随机数
	for (size_t i = 0; i < 10; ++i)
		cout << u(e) << " ";
	cout << endl;
}
int main() {
	cout << "调用noStatic版本:" << endl;
	noStatic();
	cout << "再次调用noStatic版本:" << endl;
	noStatic();
	cout << "调用Static版本:" << endl;
	Static();
	cout << "再次调用Static版本:" << endl;
	Static();

}

在这里插入图片描述
定义在函数外面,就不用担心这种情况。

5、设置随机数发生器种子

5.1、我们通常希望每次运行程序都会生成不同的随机结果,可以通过提供一个种子来达到这个目的,种子就是一个数值,引擎可以利用他从序列中一个新位置重新开始生成随机数。

default_random_engine e1;  //使用默认种子
default_random_engine e2(1235565);  //使用给定种子
default_random_engine e3;  
e3.seed(32767);   //调用seed设置一个新种子
default_random_engine e4(32767);

e3和e4具有相同的种子,它们会生成相同的序列。

5.2、选择一个好的种子,是极其困难的,最常用的方法是调用系统函数time,这个函数定义在头文件ctime中。

default_random_engine e1(time(0));  //稍微随机些的种子

6、其他随机数分布

6.1、生成随机实数
uniform_real_distribution 类型  //生成随机实数
default_random_engine e;
uniform_real_distribution<>u(0,1);  //生成0~1之间的随机实数
uniform_real_distribution<double>u(0,1);  //生成0~1之间的随机实数
cout<<u(e)<<endl;

默认类型为double类型

6.2、非均匀分布
default_random_engine e;
normal_distribution<>u(4,1.5);  //均值为4,标准差1.5
cout<<u(e)<<endl;
6.3、bernoulli_distribution类

此分布总是返回一个bool值,返回true的概率是一个常数,此概率为0.5

default_random_engine e;
bernoulli_distribution<>u;  
cout<<u(e)<<endl;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值