zoukankan      html  css  js  c++  java
  • (c++11)随机数------c++程序设计原理与实践(进阶篇)

      随机数既是一个实用工具,也是一个数学问题,它高度复杂,这与它在现实世界中的重要性是相匹配的。在此我们只讨论随机数哦最基本的内容,这些内容可用于简单的测试和仿真。在<random>中,标准库提供了复杂的方法来产生适应不同数学分布的随机数。这一随机数标准库基于下面两个基础概念:

    • 发生器(engine,随机数发生器):发生器是一个可以产生均匀分布整形值序列的函数对象。
    • 分布(distribution):分布是一个函数对象,给定一个发生器产生的序列作为输入,分布可以按照相应数学公式产生一个值的序列。

      例如 http://www.cnblogs.com/goudanli/p/7856623.html 中的 random_vector()函数。调用random_vector(n)就会生成一个Matrix<double,1>类型的矩阵对象,它包含n个元素,元素值都是[0:n)之间的随机数。

    Vector random_vector(Index n) {
        Vector v(n);
        default_random_engine ran{(unsigned int)(time(0)+2)};
        uniform_int_distribution<> ureal{ 0,max0 };
        for (Index i = 0; i < n; ++i)
        {
            v(i) = ureal(ran);
        }
     
        return v;
    }
    

      默认发生器(default_random_engine)简单、代价底、容易运行。对日常应用,它已经足够了。对于更专业的应用,标准库提供了其他发生器,它们有着更好的随机性和不同的执行代价。例如,linear_congurential_engine、mersenne_twidter_engine和random_device等。

      std_lib_facilities.h中的两个随机数发生器定义如下

    int randint(int min,int max){
    	static default_random_engine ran;
    	return uniform_int_distribution<>{min,max}(ran);
    }
    int randint(int max){
    	return randint(0,max);
    }
    

      这些函数经常会被用到,当然还有其他的,让我们看看正态分布如何产生:

    auto gen=bind(normal_distribution<double>{15,4.0},
    		default_random_engine{});
    

      <functional>中的标准库函数bind()构造了一个函数对象,当调用它时,它会调用它的第一个参数,并将第二个参数作为这次调用的参数。因而在本例中,gen()返回一个正态分布序列,其均值为15,方差为4.0,使用的是default_random_engine。示例:

    vector<int>hist(2*15);
    	for(int i=0;i<500;++i)
    	++hist[int(round(gen()))];
    
    for(int i=0;i!=hist.size();++i){
    	cout<<i<<'	';
    	for(int j=0;j!=hist[i];++j)
    	cout<<'*';
    	cout<<'
    ';
    }
    

      完整程序:

    #include<iostream>
    #include<random>
    #include<functional>
    using namespace std;
    auto gen=bind(normal_distribution<double>{15,4.0},
    				default_random_engine{});
    
    int main(){
    
    	vector<int>hist(2*15);
    	for(int i=0;i<500;++i)
    	++hist[int(round(gen()))];
    
    	for(int i=0;i!=hist.size();++i){
    		cout<<i<<'	';
    		for(int j=0;j!=hist[i];++j)
    			cout<<'*';
    		cout<<'
    ';
    	}
    }
    

      输出:

    0       *
    1
    2
    3       *
    4       **
    5       *
    6       ***
    7       **********
    8       *************
    9       *******************
    10      ***************
    11      **********************************
    12      *********************************
    13      **************************************
    14      *********************************************************
    15      ***************************************************
    16      **********************************************
    17      ******************************************
    18      *************************************
    19      ********************************
    20      ****************************
    21      ****************
    22      ********
    23      *******
    24      ****
    25      **
    26
    27
    28
    29
    

      正态分布经常被用到,其他分布包括 bernoulli_distribution,exponential_distribution和chi_distribution。在《The C++ Programming Language》中能找到详细介绍。整数分布的返回值是闭区间[a:b],而实数(浮点)分布的返回值是开区间[a:b)。

      默认情况下,程序的每次运行中,发生器(除了random_device)产生同样的序列。这非常有利于程序调试。如果希望同一发生器产生不同的序列,我们需要设定不同的初值。这一初始化过程被称为“种子”。例如:

    auto gen1= bind(uniform_int_distribution<>{0,9},
                    default_random_engine{});    
    auto gen2= bind(uniform_int_distribution<>{0,9},
                    default_random_engine{10});  
    auto gen3= bind(uniform_int_distribution<>{0,9},
                    default_random_engine{5});  
    

      为了获得不可预测的序列,我们经常使用当前时间(以纳秒为单位)或其他类似的事物作为种子。

    c++程序设计原理与实践(进阶篇)

  • 相关阅读:
    Warning: Cannot modify header information
    curl_setopt(): CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set in
    PHP Warning: strtotime(): It is not safe to rely on the system's timezone settings.
    出现Deprecated: Function ereg_replace() is deprecated in 的原因及解决方法
    APMServ5.2.6 升级PHP版本 到高版本 5.3,5.4
    Apache无法启动解决 the requested operation has failed
    用json获取拉钩网的信息
    json
    如何用组件组装一个简单的机器人
    vue-组件
  • 原文地址:https://www.cnblogs.com/l2017/p/7859538.html
Copyright © 2011-2022 走看看