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

    随机数

    • C++ 随机数库定义在 random 头文件中。
    • C++ 随机数库由一组协作类构成:随机数引擎类、随机数分布类
      • 引擎:类型,生成随机 unsigned 整数序列
      • 分布:类型,使用引擎返回特定概率分布的随机数

    随机数引擎和分布

    随机数引擎

    操作 说明
    Engine e; 默认构造函数;使用该引擎类型默认的种子
    Engine e(s); 使用整型值 s 作为种子
    e.seed(s); 使用种子 s 重置引擎的状态
    e.min(); 此引擎生成的最小值
    e.max(); 此引擎生成的最大值
    Engine::result_type 此引擎生成的 unsigned 整型类型
    e.discard(u) 将引擎推进 u 步;u的类型为unsigned long long

    分布类型和引擎

    为了得到在一个指定范围内的数,需要使用一个分布类型的对象:

    default_random_engine  e;
    uniform_int_distribution<unsigned> dis(0, 9);
    for (int i = 0; i < 10;i++)
    	cout << dis(e) << endl;
    

    注意,传递给分布对象的是引擎对象本身,如果传递的是 u(e()) ,含义就变成将 e 生成的下一个值传递给 u,会导致编译错误。

    一个给定的随机数发生器一直会生成相同的随机数序列,一个函数如果定义了局部的随机数发生器,应将引擎和分布对象定义成 static 类型,否则每次调用函数都会生成相同的序列。

    vector<unsigned> bad_randVec()
    {
    	default_random_engine e;
    	uniform_int_distribution<unsigned> dis(0,9);
    	vector<unsigned> res;
    	for (size_t i = 0; i < 100; i++)
    		res.push_back(dis(e));
    
    	return res;
    }
    
    vector<unsigned> good_randVec()
    {
    	static default_random_engine e;
    	static uniform_int_distribution<unsigned> dis(0, 9);
    	vector<unsigned> res;
    	for (size_t i = 0; i < 100; i++)
    		res.push_back(dis(e));
    
    	return res;
    }
    
    int main()
    {	
    	vector<unsigned> vec1 = bad_randVec();
    	vector<unsigned> vec2 = bad_randVec();
    	cout << (vec1 == vec2) << endl; //@ true
    
    	vector<unsigned> vec3 = good_randVec();
    	vector<unsigned> vec4 = good_randVec();
    	cout << (vec3 == vec4) << endl; //@ false
    
        return 0;
    }
    

    设置随机数发生器种子

    随机数发生器会生成相同的随机数序列这一特性在调试中很有用。

    如果我们希望每次程序运行都会产生不同的随机结果,可以提供种子来达到这一目的,种子就是一个数值,引擎可以利用它从序列中一个新位置重新开始生成随机数。

    设置种子有两种方式:

    • 在创建引擎对象时提供种子。
    • 调用 seed 设置种子。
    default_random_engine e1;			//@ 使用默认的种子 
    default_random_engine e2(32767);	//@ 使用给定的种子
    default_random_engine e3;
    e3.seed(100);						//@ 使用 seed 设置种子
    default_random_engine e4(time(0));	//@ 使用 time() 产生随机种子
    

    其它随机数分布

    生成随机实数

    default_random_engine e;
    uniform_real_distribution<double> u(0,1); //@ 指明数据的范围
    for (size_t i = 0; i < 10; i++)
    	cout << u(e) << endl;
    

    生成非均匀分布的随机数

    新标准库定义了20种分布类型:

    正太分布

    default_random_engine e;
    normal_distribution<> n(4, 1.5);	//@ 均值4,标准差1.5
    vector<unsigned> vals(9);
    for (size_t i = 0; i != 200; i++)
    {
        unsigned v = lround(n(e));
        if (v < vals.size())
        ++vals[v];
    }
    
    for (size_t j = 0; j != vals.size(); ++j)
    {
    	cout << j << ": " << string(vals[j], '*') << endl;
    }
    

    伯努利分布

    default_random_engine e;
    bernoulli_distribution b;
    for (size_t i = 0; i < 5; i++)
    	cout << b(e) << endl;
    
  • 相关阅读:
    windows 按时自动化任务
    Linux libusb 安装及简单使用
    Linux 交换eth0和eth1
    I.MX6 GPS JNI HAL register init hacking
    I.MX6 Android mmm convenient to use
    I.MX6 GPS Android HAL Framework 调试
    Android GPS GPSBasics project hacking
    Python windows serial
    【JAVA】别特注意,POI中getLastRowNum() 和getLastCellNum()的区别
    freemarker跳出循环
  • 原文地址:https://www.cnblogs.com/xiaojianliu/p/12391011.html
Copyright © 2011-2022 走看看