5.9 随机数生成

from http://www.learncpp.com/cpp-tutorial/59-random-number-generation/

通常在游戏,统计模型程序和科学模拟中会用到随机事件。

而由于计算机的本质结构决定计算机只能生成伪随机数据。

伪随机生成器,设定一个初始值(seed),对它进行操作形成不同的数值,让它看上去与初始值没有联系。如果算法足够复杂,将同样的算法用到最后生成的数字,这样就能够产生一些列看上去随机的数值。

下面是一个产生100个伪随机数的程序:

1.

1: #include <stdafx.h>
2: #include <iostream>
3: using namespace std;
4:
5: unsigned int PRNG()
6: {
7:     // our initial starting seed is 5323
8:     static unsigned int nSeed = 5323;
9:
10:     // Take the current seed and generate a new value from it
11:     // Due to our use of large constants and overflow, it would be
12:     // very hard for someone to predict what the next number is
13:     // going to be from the previous one.
14:     nSeed = (8253729 * nSeed + 2396403);
15:
16:     // Take the seed and return a value between 0 and 32767
17:     return nSeed  % 32767;
18: }
19:
20: int main()
21: {
22:     // Print 100 random numbers
23:     for (int nCount=0; nCount < 100; ++nCount)
24:     {
25:         cout << PRNG() << "\t";
26:
27:         // If we've printed 5 numbers, start a new column
28:         if ((nCount+1) % 5 == 0)
29:             cout << endl;
30:     }
31: }

事实上我们这个例子并不是很好,但是它足够用来说明伪随机数是如何产生的。

C++产生伪随机数

语言中有内置的随机数生成器,它需要两个独立的函数组合使用。

srand() 用来设置初始seed。srand()通常只调用一次。

rand()生成序列中的下一个随机值。

2.

1: #include <iostream>
2: #include <cstdlib> // for rand() and srand()
3: using namespace std;
4:
5: int main()
6: {
7:     srand(5323); // set initial seed value to 5323
8:
9:     // Print 100 random numbers
10:     for (int nCount=0; nCount < 100; ++nCount)
11:     {
12:         cout << rand() <<“\t”;
13:
14:         // If we've printed 5 numbers, start a new column
15:         if ((nCount+1) % 5 == 0)
16:         cout << endl;
17:     }
18: }

rand()产生的伪随机数的范围在0到RAND_MAX之间,通常它的值在cstdlib中为32767.

通常我们并不想要这个范围内的随机值。我们想要两个nLow和nHigh范围内。如1-6.

3.

1: // Generate a random number between nLow and nHigh (inclusive)
2: unsigned int GetRandomNumber(int nLow, int nHigh)
3: {
4:     return (rand() % (nHigh - nLow + 1)) + nLow;
5: }

当我们反复运行第2个程序的时候,发现每次的结果都是相同的。由于我们每次设置的seed都是相同的。因此我们使用了time()函数来产生seed。

1: #include <stdafx.h>
2: #include <iostream>
3: #include <cstdlib> // for rand() and srand()
4: #include <ctime> // for time()
5: using namespace std;
6:
7: int main()
8: {
9:
10:     srand(time(0)); // set initial seed value to system clock
11:     for (int nCount=0; nCount < 100; ++nCount)
12:     {
13:         cout << rand() << "\t";
14:
15:         if ((nCount+1) % 5 == 0)
16:             cout << endl;
17:     }
18: }

怎样的伪随机生成器算是好的呢?

1)生成器会以相同的概率产生每一个数值。

2)随机序列的下一个数字不能明显、容易被预测

3)随机数生成器产生的数值有一个好的分布,忽而小,忽而大,让人感觉是随机的。

4)所有的伪随机生成器都是周期性的

rand()函数只是一个普通的伪随机生成器

大多数rand()都是使用Linear Congruential Generator方法实现的。

由于RAND_MAX通常是32767,意味着如果我们想要更大的范围就会不适合了。同时,rand()也不适合产生浮点型随机值如0.0-1.0. 同时rand()相对于其他算法拥有一个短的周期。

可以使用Mersenne Twister,它具有更好的结果,同时使用相对简单。
原文链接: https://www.cnblogs.com/grass-and-moon/archive/2012/05/22/2513829.html

欢迎关注

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

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

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

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

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

(0)
上一篇 2023年2月9日 上午2:26
下一篇 2023年2月9日 上午2:27

相关推荐