C++11 随机数生成

       C++ 程序中,在新标准出现之前,C 和 C++ 都依赖一个C 库函数 rand 来产生随机数,然而,这个函数生成的是均匀分布的伪随机数,每个随机数的范围在 0 和一个最大值RAND_MAX(至少为 32767)之间。

  rand 函数存在一些问题:在实际的编程中,很多程序需要不通范围的随机数。一些应用需要随机浮点数。一些程序需要非均匀分布的随机数。所在在编写程序时为了生成满足一定要求的随机数,通常会转换 rand 生成的随机数的范围、类型或者是分布,但是这样会引入非随机性。

       c++11提供的<random>实现了随机数库,它通过随机数引擎类(random_number_engines)产生随机数序列,随机数分布类(random_number_distribution)使用随机数引擎生成服从特定概率分布的随机数。

下面介绍一个C++中生成随机数的例子:

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
//#include "Timer.h"
#include <random>


// const int arraySize = 100000;
int main()
{
    std::default_random_engine e;    // 默认的随机数引擎
    for (int i = 0; i < 15; i++)
    {
        auto rnd = e();
        std::cout << rnd << std::endl;
        std::cout << typeid(rnd).name() << std::endl;   // 返回值的类型
    }
    std::cout << e.max() << " | " << e.min() << std::endl;   // 随机数引擎的范围
    //system("pause");
    return 0;
}

       随机数类是定义在std命名空间的,所以要声明。随机数引擎是函数对象,这就是为什么使用e()去生成随机数。程序每次运行都会生成相同的随机数序列,这在一定程度有利于程序的调试,但我们有时需要每一次运行产生的随机数序列都是不同的。我们可以通过设置随机数引擎的种子来改变引擎的状态,没有改变时是使用默认的随机数种子,这就是为什么每一次都生成同样的随机数序列。从结果我们可以知道,默认的种子生成随机数范围在1-2147483646之间。

可以通过e.seed()方法来设置随机数种子:

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
//#include "Timer.h"
#include <random>


// const int arraySize = 100000;
int main()
{
    std::default_random_engine e;    // 默认的随机数引擎
    e.seed(10);    // 设置生成随机数的种子
    for (int i = 0; i < 15; i++)
    {
        auto rnd = e();
        std::cout << rnd << std::endl;
        //std::cout << typeid(rnd).name() << std::endl;   // 返回值的类型
    }
    std::cout << e.max() << " | " << e.min() << std::endl;   // 随机数引擎的范围
    //system("pause");
    return 0;
}

如果需要改变生成的随机数的范围,需要使用随机数分布类:

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
//#include "Timer.h"
#include <random>


// const int arraySize = 100000;
int main()
{
    std::default_random_engine e;    // 默认的随机数引擎
    std::uniform_int_distribution<int> u(0, 10);    // 随机数分布类,可以确定随机数范围 [0,10]
    e.seed(10);    // 设置生成随机数的种子
    for (int i = 0; i < 15; i++)
    {
        auto rnd = u(e);
        std::cout << rnd << "  ";
        //std::cout << typeid(rnd).name() << std::endl;   // 返回值的类型
    }
    std::cout << std::endl;
    std::cout << e.max() << " | " << e.min() << std::endl;   // 随机数引擎的范围
    //system("pause");
    return 0;
}

在实际的应用中,[0, 1]之间的随机数应用的比较广泛,在C++11中,可以按照如下的方式生成满足要求的随机数:

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
//#include "Timer.h"
#include <random>


// const int arraySize = 100000;
int main()
{
    std::default_random_engine e;    // 默认的随机数引擎
    std::uniform_real_distribution<double> u(0, 1);    // 随机数分布类,可以确定随机数范围 [0,10]
    e.seed(10);    // 设置生成随机数的种子
    for (int i = 0; i < 15; i++)
    {
        auto rnd = u(e);
        std::cout << rnd << "  ";
        //std::cout << typeid(rnd).name() << std::endl;   // 返回值的类型
    }
    std::cout << std::endl;
    std::cout << e.max() << " | " << e.min() << std::endl;   // 随机数引擎的范围
    //system("pause");
    return 0;
}

除此之外,c++11的<random>库还提供了不同的随机数引擎和随机数分布类,例如,要生成满足正态分布的0-1之间的随机数:

// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
#include "Timer.h"
#include <random>


// const int arraySize = 100000;
int main()
{
    std::default_random_engine e;    // 默认的随机数引擎
    // std::normal_distribution的构造函数  可知参数的意义
    // explicit normal_distribution(_Ty _Mean0 = 0.0, _Ty _Sigma0 = 1.0)  
    std::normal_distribution<double> u(0, 1);    // 正态分布 
    e.seed(10);    // 设置生成随机数的种子
    for (int i = 0; i < 15; i++)
    {
        auto rnd = u(e);
        std::cout << rnd << "  ";
        //std::cout << typeid(rnd).name() << std::endl;   // 返回值的类型
    }
    std::cout << std::endl;
    std::cout << e.max() << " | " << e.min() << std::endl;   // 随机数引擎的范围
    //system("pause");
    return 0;
}

C++11 提供的随机数引擎和随机数分布类型如下所示:
http://www.cplusplus.com/reference/random/?kw=random

随机数引擎:

C++11  随机数生成

随机数分布类:
C++11  随机数生成

------------------------------------------------------------------------------------------------------

原文链接: https://www.cnblogs.com/ncepubye/p/12724018.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++11  随机数生成

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/396517

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月6日 上午11:22
下一篇 2023年4月6日 上午11:22

相关推荐