• C++下随机数的生成


    C++ 下生成随机数的方法有很多种,各有优缺点。

    1. 利用rand()生成随机数

    这是最传统的方法,也是在算法竞赛中最广为人知的方法。

    优点:简单、快速。

    缺点:生成的随机数“不够好”(当然算法竞赛中够用),并且受到srand()的制约。

    rand()的用法不必多说,所以重点讲的是随机种子初始化——srand()。

    1.1 直接使用srand(time(0))

    这也是最简单的方法。但这有一个显而易见的缺陷——1秒内,由于time(0)不会改变,所以生成的随机序列完全一样。

    比如,在对拍时,你以为你风驰电掣地对拍了数十万组数据,实际上生成的不同的数据也就几百组而已,严重拖累了效率。

    1.2 使用标准库

    既然time(0)不太好,换个随机种子不就行了?并且,这个随机种子必须变化得足够快。

    #include <sys/time.h>
    
    timeval ti;
    gettimeofday(&ti,NULL);
    srand(ti.tv_usec);
    

    其中,ti.tv_usec每微秒变化一次,已经很快了。

    1.3 使用chrono (C++11)

    这种就稍微麻烦一点,但比上一种方法好。

    #include <chrono>
    
    srand(chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count());
    

    2. 使用random库(C++11)

    一个十分强大的库,限于篇幅不可能介绍完,因此选一些常用的介绍。

    2.1 使用random_device (推荐)

    它用法较为简单,在Linux与Windows下均可用,生成unsigned int范围内的整数,若要int范围内的非负整数需要稍作转换。(无需考虑随机种子)(其实本质是用系统中的随机数生成器,Linux下为/dev/(u)random,Windows为rand_s)

    #include <random>
    
    random_device rd;
    unsigned int myrand_uint(){
        return rd();
    }
    
    int myrand_int(){
        return rd()>>1;
    }
    
    

    2.2 使用mt19937

    循环节极长,比rand()要好,但同样需要设置随机种子,生成int内的整数(包括负数)。

    mt19937 rd(...); //...内为随机种子
    int myrand(){
        return rd();
    }
    

    3. 利用系统资源

    3.1 shell的环境变量

    Linux下为$RANDOM,Windows为%RANDOM%,范围 [0,32767]。

    echo $RANDOM
    

    3.2 /dev/(u)random (Linux)

    /dev/random与/dev/urandom均为块设备文件,直接打开是一堆乱码(其实是生成的随机串以ASCII方式显示),可以直接在程序中用fopen打开,用fread读取指定字节并转换为整数。

    注意:/dev/random在生成大量随机数时效率会降低,推荐/dev/urandom。

    FILE* rd=fopen("/dev/urandom","r");
    int myrand(){
        unsigned int val;fread(&val,sizeof(val),1,rd);
        return val>>1;
    }
    
    long long myrand_ll(){
        unsigned long long val;fread(&val,sizeof(val),1,rd);
        return val>>1ll;
    }
    
    

    完结撒花~~

  • 相关阅读:
    HTML基础
    JVM内存和JVM调优(五)--分代垃圾回收详述
    JVM内存和JVM调优(四)--如何区分垃圾
    JVM内存和JVM调优(三)--基本GC垃圾回收算法
    JVM内存和JVM调优(二)--引用类型
    JVM内存和JVM调优(一)--堆栈概念
    isAssignableFrom和instanceof
    spring学习(三十九)--自定义注解
    SPRING学习(三十八)--SPRING集成MYBATIS之数据库连接池和多种数据源配置方式(三)
    SPRING学习(三十七)--SPRING集成MYBATIS(二)
  • 原文地址:https://www.cnblogs.com/acceptedzhs/p/14766471.html
Copyright © 2020-2023  润新知