1、在新标准出现之前,c和c++都依赖于一个简单的c库函数rand来生成随机数,此函数生成均匀分布的伪随机函数。
2、有很多程序需要不同范围的随机数,一些应用需要浮点数,一些程序需要非均匀分布的数,对于这些,程序员需要转换rand生成的范围。
3、定义在random中的随机数库通过一组协作的类来解决这些问题,随机数引擎类和**随机数分布类。**一个引擎类生成unsigned随机数序列,一个分布类使用一个引擎类生成指定类型的,在给定范围内的、服从特定概率分布的随机数。
通过调用一个随机数引擎对象来生成原始随机数。
c++程序不应该使用库函数rand,而应使用default_random_engine类和恰当的分布类对象。
default_random_engine e; //生成随机数无符号数
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 |
对于大多数情况下,随机数引擎的输出是不能直接使用的。
为了得到在一个指定范围内的数,我们使用一个分布类型的对象
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;
分布类型定义了一个调用运算符,它接受一个随机数引擎作为参数,分布对象使用它的引擎参数生成随机数,并将其映射到指定的分布。
一个给定的随机数发生器一直会生成相同的随机数序列,一个函数如果定义了局部的随机数发生器,应该将其定义为static的,否则每次调用函数都会生成相同的序列。
#include
#include
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.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)); //稍微随机些的种子
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类型
default_random_engine e;
normal_distribution<>u(4,1.5); //均值为4,标准差1.5
cout<<u(e)<<endl;
此分布总是返回一个bool值,返回true的概率是一个常数,此概率为0.5
default_random_engine e;
bernoulli_distribution<>u;
cout<<u(e)<<endl;