返回介绍

随机数的产生

发布于 2025-02-26 23:20:00 字数 3627 浏览 0 评论 0 收藏 0

随机数有着广泛的用途。比如测试、游戏、仿真以及安全等领域都需要用到随机数。标准库所提供的多种可供选择的随机数产生器也恰恰反应了随机数应用范 围的多样性。随机数产生器由引擎(engine)和分布(distribution)两部分组成。其中,engine 用于产生一个随机数序列或者伪随机数 序列;distribution 则将这些数值映射到位于固定范围的某一数学分布中。关于分布的例子有:unifrom_int (所有的整数倍都被以相等的概率产生) 以及 normal_distribution (分布的概率密度函数曲线呈钟形);每一种分布都处于某一特定的范围之内。例如:

//distribution 将产生的随机数映射到整数 1..6
uniform_int_distribution<int> one_to_six {1,6}; 

default_random_engine re {};        //默认的 engine

如果想获得一个随机数,你可以用一个随机引擎为参数调用 distribution 来产生一个随机数:

int x = one_to_six(re); // x 是 [1:6]这个范围内的一个随机数

在每次调用的时候都需要提供一个引擎作为参数非常繁琐,所以我们可将引擎和 distribution 邦定成一个函数对象,然后直接通过这个函数对象的调用来产生随机数,而不用每次调用都提供参数了。

auto dice {bind(one_to_six,re)}; //  产生一个新的随机数生成器
int x = dice(); // 调用 dice 函数对象,x 是一个分布在 [1:6]范围的随机数

多亏在设计它是对一般性和性能的关注。在这方面,一位专家曾在评价标准库中随机数模块时说道:“在扩充的过程中,每一个随机数库想变成什么”。然而,它很 难真正让一个新手感觉到容易上手。在性能方面,我从没有见过随机数的接口成为性能的瓶颈。另外,我也一直会使用一个简单的随机数生器来教新手(具有一定的 基础)。下面的就是这样的一个可以说明问题的例子。

int rand_int(int low, high);   //按照均匀分布在区间[low: high]中产生一个随机数

然而我们如何实现 rand_int()?我们必须在 rand_int() 中使用 dice() 之类的函数:

int rand_int(int low, int high)
{   
     static default_random_engine re {};
     using Dist = uniform_int_distribution<int>;
     static Dist uid {};
     return uid(re, Dist::param_type{low,high});
}

关于 rand_int() 的定义依然是属于“专家级”的,但是应该把关于它的使用安排在 C++课程的第一周。

在这里,我们举一个不太琐碎的关于随机数生成器的例子。这个例子中代码的功能是生成和打印一个正态分布。

default_random_engine re;   //默认引擎

normal_distribution<double> nd(31 /* mean */,
      8 /* sigma */);

auto norm = std::bind(nd, re);

vector<int> mn(64);

int main()
{
    for (int i = 0; i<1200; ++i) 
               ++mn[round(norm())]; // 产生随机数

    for (int i = 0; i<mn.size(); ++i) 
           {
        cout << i << '\t';
        for (int j=0; j<mn[i]; ++j) 
                    cout << '*';

                cout << '\n';
    }
}

我运行了一个支持 boost::random 的版本并把它编辑到 C++0x 中,然后得到了下面的结果。

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 ******************************************************************
30 **********************************************
31 *********************************************************************
32 **********************************************
33 *************************************************************
34 **************************************************************
35 ***************************************
36 ***********************************************
37 **********************************************
38 *********************************************
39 ********************************
40 ********************************************
41 ***********************
42 **************************
43 ******************************
44 *****************
45 *************
46 *********
47 ********
48 *****
49 *****
50 ****
51 ***
52 ***
53 **
54 *
55 *
56
57 *
58
59
60
61
62
63

另外,可以参考以下文献:

  • Standard 26.5: Random number generation

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文