zoukankan      html  css  js  c++  java
  • C++11 随机数

    C++11带来诸多特性,random就是其一.

    随机数由生成器和分布器结合产生

      生成器generator:能够产生离散的等可能分布数值(需要种子,不然每次生存的随机数都一样)
      分布器distributions: 能够把generator产生的均匀分布值映射到其他常见分布,如均匀分布uniform,正态分布normal,二项分布binomial,泊松分布poisson
      种子:相当于外部传给随机数生成器的诱因,如果每次传入的种子一样,则每次生成的随机数还是一样
     
    1.default_random_engine 
    //std::default_random_engine engine();  //没有设置种子,每次生存的随机数都一样
    std::default_random_engine engine(time(nullptr));  //设置了种子,每次种子都不一样
    std::uniform_int_distribution<> dis(1, 10);
    for (int n = 0; n < 10; n++)
        std::cout << dis(engine) << " " << std::endl;
    注:default_random_engine 结合uniform_int_distribution生成的随机数是闭环[begin, end]
    如果嫌每次调用都要传入generator对象麻烦,可以使用std::bind,要包含头文件functional,以后就可以直接调用dice()产生复合均匀分布的随机数。
    //std::default_random_engine engine();  //没有设置种子,每次生存的随机数都一样
    std::default_random_engine engine(time(nullptr));
    std::uniform_int_distribution<> dis(1, 10);
    auto dice = std::bind(dis,generator);
    for (int n = 0; n < 10; n++) std::cout << dice() << " " << std::endl;

    2. random_device

      标准库提供了一个非确定性随机数生成设备.在Linux的实现中,是读取/dev/urandom设备;Windows的实现居然是用rand_s,在这里强烈谴责一下.

      random_device提供()操作符,用来返回一个min()到max()之间的一个数字.如果是Linux(Unix Like或者Unix)下,都可以使用这个来产生高质量的随机数,可以理解为真随机数.

    #include <iostream>
    #include <random>
    int main()
    {
      std::random_device rd;
      for(int n=0; n<20000; ++n)
        std::cout << rd() << std::endl;
      return 0; 
    }
    
    //结合:default_random_engine使用生成指定范围内的真随机数
    int main()
    {
        std::random_device rd; 
        std::default_random_engine engine(rd());
        std::uniform_int_distribution<> dis(10, 20); 
        auto dice = std::bind(dis, engine); 
        for (int n = 0; n < 10; n++) 
            std::cout << dice() << " " << std::endl;
     }

    2. random number engine

      标准把随机数抽象成随机数引擎和分布两部分.引擎用来产生随机数,分布产生特定分布的随机数(比如平均分布,正太分布等).

      标准提供三种常用的引擎:linear_congruential_engine,mersenne_twister_engine和subtract_with_carry_engine.第一种是线性同余算法,第二种是梅森旋转算法,第三种带进位的线性同余算法.第一种是最常用的,而且速度也是非常快的; 第二种号称是最好的伪随机数生成器;第三种没用过....

      随机数引擎接受一个整形参数当作种子,不提供的话,会使用默认值. 推荐使用random_device来产生一个随机数当作种子.(windows下爱咋整咋整,谁叫windows的random_device是调用rand_s)

    #include <iostream>
    #include <random>
    
    int main()
    {
        std::random_device rd;
        std::mt19937 mt(rd());
        for(int n = 0; n < 10; n++)
            std::cout << mt() << std::endl;
        return 0;
    }

    3. random number distributions

      标准提供各种各样的分布,不过我们经常用的比较少,比如平均分布,正太分布...使用也很简单

    //平均分布
    #include <random>
    #include <iostream>
    int main()
    {
        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_int_distribution<> dis(1, 6);
        for(int n=0; n<10; ++n)
            std::cout << dis(gen) << ' ';
        std::cout << '
    ';
    }

    //正太分布
    #include <iostream>
    #include <iomanip>
    #include <string>
    #include <map>
    #include <random>
    #include <cmath>
    int main()
    {
        std::random_device rd;
        std::mt19937 gen(rd());
     
        // values near the mean are the most likely
        // standard deviation affects the dispersion of generated values from the mean
        std::normal_distribution<> d(5,2);
     
        std::map<int, int> hist;
        for(int n=0; n<10000; ++n) {
            ++hist[std::round(d(gen))];
        }
        for(auto p : hist) {
            std::cout << std::fixed << std::setprecision(1) << std::setw(2)
                      << p.first << ' ' << std::string(p.second/200, '*') << '
    ';
        }
    }
     
  • 相关阅读:
    【jQuery】清空表单内容
    【jQuery】remove()和empty()的使用
    【ajax 提交表单】多种方式的注意事项 ,serialize()的使用
    【Gson】互相转化
    yum安装nginx详解
    linux find命令
    nginx实战
    java判断是否为汉字
    分布式存储 CentOS6.5虚拟机环境搭建FastDFS-5.0.5集群(转载)
    Java应用程序实现屏幕的"拍照"
  • 原文地址:https://www.cnblogs.com/DswCnblog/p/5624869.html
Copyright © 2011-2022 走看看