• C++随机数


    伪随机数

    int rand(void)函数通常用来当做随机函数来使用,殊不知这其实是一个伪随机函数。按照某种顺序生成的随机函数,这是什么意思呢?我们来测试一下,

    第一次:

         cout << "first:" << endl;
        cout << rand() << endl;
        cout << rand() << endl;
        cout << rand() << endl;

    第一次结果
    第二次
    第二次结果
    发现,只要程序重复运行每次生成的随机数都是一样的!!这就是伪随机数的概念。如何改进呢?

    种子

    我们力求每次都要随机成功,引入一个随机数种子的概念,种子和随机数的产生是有因果关系的,同一个种子,只会产生同一种随机数,随机数种子是由一个种子函数来指定的,它就是void srand(unsigned int seed),当没有设置的时候,系统默认是1,我们要保证每次进入系统种子都会改变,通常的习惯是用时间来定为种子,因为时间一直在流逝,time(NULL)返回一个1970-1-1 00:00:00到当前时间的秒数。可以做为种子。
    srand(time(NULL))
    就像这样

    int _tmain(int argc,TCHAR* argv[])
    {
        srand((unsigned)time(NULL));
        cout << rand() << endl;
        cout << rand() << endl;
        cout << rand() << endl;
        cin.get();
        return 0;
    } 
    • 先指定再使用。严格的说这个还是一个伪随机函数 ,但也基本达到了完全随机的效果。

    获得两个区间之间的随机值,普遍想到的方法是:
    要取得[a,b)的随机整数,使用(rand() % (b-a))+ a;
    要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a;
    要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1;

    这个办法很好理解,但是我喜欢先得到0-1之间的随机值,再乘以b-a,最后再加上a。

    double dVal = ((double)rand()/RAND_MAX)
    return  iMin + dVal *  (iMax - iMin)  

    确定区间的方法都是一样的,理解哪个用哪个!


    思考

    我们虽然写出了相对随机的随机数函数,但是细心的人会发现一个问题,就是随机数区间的概率问题,假如我们需要求1到3之间的随机数,我们期望是等概率的,但是事实却不是。
    

    我们知道,rand()函数获得的区间是[0,RAND_MAX),假若用求余数的方法,RAND_MAX的值是0x7fff,可得(0x7fff-1)%3=0,看上去好像每个数出现的次数一致,别忘了我们还包含一个0,也就是说0出现的次数多,不是等概率的。

    • 具体怎么办留给大家思考,欢迎在评论区探讨
  • 相关阅读:
    MySQL 5.7.18 zip 文件安装过程
    Mysql 自定义随机字符串
    JAVA基本类型和引用类型
    初识JSP
    Java导出错误数据
    时序图的使用习惯
    Redis踩坑
    ES踩坑
    代码规范
    Git在公司的使用流程
  • 原文地址:https://www.cnblogs.com/pzqu/p/9457624.html
Copyright © 2020-2023  润新知