• 随机数(新标准)


    随机数

    一、概念

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

    二、随机数引擎和分布

    1、导言

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

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

    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

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

    一个给定的随机数发生器一直会生成相同的随机数序列,一个函数如果定义了局部的随机数发生器,应该将其定义为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();
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

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

    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);
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

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

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

    6、其他随机数分布

    6.1、生成随机实数

    uniform_real_distribution 类型  //生成随机实数
    
    • 1
    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;
    
    • 1
    • 2
    • 3
    • 4

    默认类型为double类型

    6.2、非均匀分布

    default_random_engine e;
    normal_distribution<>u(4,1.5);  //均值为4,标准差1.5
    cout<<u(e)<<endl;
    
    • 1
    • 2
    • 3

    6.3、bernoulli_distribution类

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

    default_random_engine e;
    bernoulli_distribution<>u;  
    cout<<u(e)<<endl;
    
    • 1
    • 2
    • 3
  • 相关阅读:
    【多线程】Thread 类 详解
    FlinkSQL 之乱序问题
    WordPress网站,只需一行JS代码,实现一键复制
    CF487C Prefix Product Sequence 题解
    6K star! 100%本地运行LLM的AI助手
    MATLAB算法实战应用案例精讲-【图像处理】Transformer
    iNeuOS工业互联网操作系统,设备运维业务和“低代码”表单开发工具
    【面试题】JSON.stringify()妙用,你真的知道吗?
    MATLAB Coder从入门到放弃
    Web APIs——事件对象
  • 原文地址:https://blog.csdn.net/ccb1372098/article/details/126378687