• C++库的随机数生成


    C++库为我们提供了很多生成随机数的方法。

    使用C的随机数生成法

    先学过C语言,或者仅仅用C++做算法的人。对rand()是非常熟悉了。这个函数没有参数,生成0到RAND_MAX的随机数(RAND_MAX随环境可能是16位范围或32位范围)。

    #include <stdlib.h>
    #include <stdio.h>
    #include <time.h>
    
    main() {
    	srand(time(0)); // 以当前时间初始化随机数种子
    
    	for (int i = 0; i < 12; i++)
    		printf("%d ", rand());
    	printf("\n%d", RAND_MAX);
    }
    
    /* output:
    54662053 670906658 1153043822 1421129869 1473191568 431426198 458863543 103837017 1196255552 740286342 625267246 1994847783 
    2147483647
    */
    

    一般我们用当前unix时间(即time(0)的值)初始化随机种子,这样每次运行时种子都可以不同,保证每次运行得到不同的随机数结果。在我的机器上,RAND_MAX值为2147483647,即所有31位正数的范围。

    使用C++的随机数生成法

    C语言的rand函数功能还是太局限。在生成特定范围的数或者实数的时候很不方便。

    C++提供了全新的方式使用随机数。首先,使用random头文件,可以定义一个default_ranbdom_engine

    #include <random>
    #include <iostream>
    using namespace std;
    
    main(){
    	default_random_engine a;
    
    	cout << "min: " << a.min() << endl;
    	cout << "max: " << a.max() << endl;
    	for (int i = 0; i < 12; i++)
    		cout << a() << ' '; //! 生成下一个数
    }
    /*
    min: 1
    max: 2147483646
    16807 282475249 1622650073 984943658 1144108930 470211272 101027544 1457850878 1458777923 2007237709 823564440 1115438165 
    */
    

    这个“随机数引擎”是一个可调用对象,与rand()非常相似,不过在多线程时可以定义很多个一起用。同时也需要在构造时(或使用成员函数seed赋值种子,否则默认构造下种子相同,每次都会生成相同的随机数)。一般来讲,最好把它定义成静态或全局变量。如果作为局部变量的话,则每次都会从相同的种子重新开始。

    //C++ Primer上的例子
    auto random_vector() {
    	default_random_engine eng;
    
    	vector<int> a(12);
    	for (int i = 0; i < 12; i++) a[i] = eng();
    }
    /*
    这个函数返回一个填充随机值的vector,但是他每次运行都会使用相同种子,生成完全一样的值。
    
    把eng定义为static就可以解决这个问题。
    
    或者也可以使用time(0),但time(0)是以秒为单位的,若调用太快仍会得到相同的结果
    */
    

    除了随机数引擎,我们还可以使用随机数分布对象。分布对象可以用调用引擎生成随机数,再调整出适当范围内的随机数,比如下面这个:

    main(){
    	default_random_engine a;
    
    	uniform_int_distribution<short> x(12, 90); //整数生成器
    
    	cout << "min: " << x.min() << endl;
    	cout << "max: " << x.max() << endl;
    	for (int i = 0; i < 12; i++)
    		cout << x(a) << ' '; //! 生成下一个数
    }
    /*
    min: 12
    max: 90
    12 22 71 48 54 29 15 65 65 85 42 53
    */
    

    uniform_int_distribution可以指定任意整数类型和上下界值(闭区间),在范围内均匀生成对应的随机整数,不过他每次生成数据时要代一个引擎作为参数,也就是说,他是根据引擎生成的值再调整出来的,自己不具有生成随机数的功能,所以叫做“随机数分布对象”。再介绍些其他分布对象:

    uniform_real_distribution<double> eng(min, max);// 浮点数均匀分布
    normal_distribution<int> eng(average, SD); // 整数正态分布,需要方差和中间值
    bernoulli_distribution eng(pro) //伯努利分布,生成true和false,可以指定true的概率
    

    把真正生成随机数的东西和调整分布的东西分开是有好处的。因为随机数生成必须使用外部变量,占用额外空间。而调整阶段是不用的。因此,即使程序各个地方都在用随机数,也只需要一个default_random_engine

  • 相关阅读:
    ActiveReport换页的判断(当设置了repeatstyle为OnPage)
    创建与删除SQL约束或字段约束。 http://www.cnblogs.com/hanguoji/archive/2006/11/17/563871.html
    在SQL Server 2005中实现表的行列转换
    ActiveReport,Detail隐藏的问题
    SQL Server identity列的操作方法
    「預り」の意味
    POJ 1595 Prime Cuts
    Hdu Graph’s Cycle Component
    POJ 3250 Bad Hair Day
    Hdu 1548 A strange lift(BFS)
  • 原文地址:https://www.cnblogs.com/ofnoname/p/16422725.html
Copyright © 2020-2023  润新知