zoukankan      html  css  js  c++  java
  • C++利用系统时间产生的随机数

    本文由青松原创并依GPL-V2及其后续版本发放,转载请注明出处且应包含本行声明。

    C++中常用rand()函数生成随机数,但严格意义上来讲生成的只是伪随机数(pseudo-random integral number)。生成随机数时需要我们指定一个种子,如果在程序内循环,那么下一次生成随机数时调用上一次的结果作为种子。但如果分两次执行程序,那么由于种子相同,生成的“随机数”也是相同的。

    在工程应用时,我们一般将系统当前时间(Unix时间)作为种子,这样生成的随机数更接近于实际意义上的随机数。给一下例程如下:

    #include <iostream>
    #include <ctime>
    #include <cstdlib>
    using namespace std;

    int main()
    {
    double random(double,double);
    srand(unsigned(time(0)));
    for(int icnt = 0; icnt != 10; ++icnt)
    cout << "No." << icnt+1 << ": " << int(random(0,10))<< endl;
    return 0;
    }

    double random(double start, double end)
    {
    return start+(end-start)*rand()/(RAND_MAX + 1.0);
    }
    /* 运行结果
    * No.1: 3
    * No.2: 9
    * No.3: 0
    * No.4: 9
    * No.5: 5
    * No.6: 6
    * No.7: 9
    * No.8: 2
    * No.9: 9
    * No.10: 6
    */
    利用这种方法能不能得到完全意义上的随机数呢?似乎9有点多哦?却没有1,4,7?!我们来做一个概率实验,生成1000万个随机数,看0-9这10个数出现的频率是不是大致相同的。程序如下:
    #include <iostream>
    #include <ctime>
    #include <cstdlib>
    #include <iomanip>
    using namespace std;

    int main()
    {
    double random(double,double);
    int a[10] = ;
    const int Gen_max = 10000000;
    srand(unsigned(time(0)));

    for(int icnt = 0; icnt != Gen_max; ++icnt)
    switch(int(random(0,10)))
    {
    case 0: a[0]++; break;
    case 1: a[1]++; break;
    case 2: a[2]++; break;
    case 3: a[3]++; break;
    case 4: a[4]++; break;
    case 5: a[5]++; break;
    case 6: a[6]++; break;
    case 7: a[7]++; break;
    case 8: a[8]++; break;
    case 9: a[9]++; break;
    default: cerr << "Error!" << endl; exit(-1);
    }

    for(int icnt = 0; icnt != 10; ++icnt)
    cout << icnt << ": " << setw(6) << setiosflags(ios::fixed) << setprecision(2) << double(a[icnt])/Gen_max*100 << "%" << endl;

    return 0;
    }

    double random(double start, double end)
    {
    return start+(end-start)*rand()/(RAND_MAX + 1.0);
    }
    /* 运行结果
    * 0: 10.01%
    * 1: 9.99%
    * 2: 9.99%
    * 3: 9.99%
    * 4: 9.98%
    * 5: 10.01%
    * 6: 10.02%
    * 7: 10.01%
    * 8: 10.01%
    * 9: 9.99%
    */
    可知用这种方法得到的随机数是满足统计规律的。

    另:在Linux下利用GCC编译程序,即使我执行了1000000次运算,是否将random函数定义了inline函数似乎对程序没有任何影响,有理由相信,GCC已经为我们做了优化。但是冥冥之中我又记得要做inline优化得加O3才行...

    不行,于是我们把循环次数改为10亿次,用time命令查看执行时间:
    chinsung@gentoo ~/workspace/test/Debug $ time ./test
    0: 10.00%
    1: 10.00%
    2: 10.00%
    3: 10.00%
    4: 10.00%
    5: 10.00%
    6: 10.00%
    7: 10.00%
    8: 10.00%
    9: 10.00%

    real 2m7.768s
    user 2m4.405s
    sys 0m0.038s
    chinsung@gentoo ~/workspace/test/Debug $ time ./test
    0: 10.00%
    1: 10.00%
    2: 10.00%
    3: 10.00%
    4: 10.00%
    5: 10.00%
    6: 10.00%
    7: 10.00%
    8: 10.00%
    9: 10.00%

    real 2m7.269s
    user 2m4.077s
    sys 0m0.025s

    前一次为进行inline优化的情形,后一次为没有作inline优化的情形,两次结果相差不大,甚至各项指标后者还要好一些,不知是何缘由...
  • 相关阅读:
    spring cloud-zuul的Filter详解
    Hibernate day01
    JAVA中几种常用的RPC框架介绍
    乐观锁和悲观锁的区别(最全面的分析)
    Redis、Memcache和MongoDB的区别
    Hessian整合Spring
    Hessian的使用以及理解
    sso单点登录系统原理与实现
    zookeeper原理(转)
    Nginx的负载均衡的几种方式
  • 原文地址:https://www.cnblogs.com/rever/p/4372620.html
Copyright © 2011-2022 走看看