产生随机数的能力可以在某些类型的节目是有用的,尤其是在游戏中,统计建模程序,科学的模拟,需要模型的随机事件。以游戏为例,无随机事件,怪物会攻击你,同样的方式,你总是会找到这些宝藏,地牢的布局不会改变,等。这不会使一个很好的游戏。
那么我们如何产生随机数?在现实生活中,我们经常会产生随机的结果做事情像掷硬币,滚动骰子,或洗牌的。这些项目涉及许多物理变量(如重力,摩擦力,空气阻力,动量,等等),他们变得几乎不可能预测或控制,和产生的结果是所有意图和目的随机。
然而,计算机不设计利用物理变量-你的电脑不能投掷一个硬币,掷骰子,或是将房卡。电脑生活在一个控制电的世界里,一切都是二进制(或真或假),没有中间。就其本质而言,计算机的设计产生的结果是可预见性。当你告诉计算机来计算2 + 2,你总是希望答案是4。不是3或5次。
因此,计算机一般不能产生随机数。相反,他们必须模拟的随机性,这是最经常使用的伪随机数发生器。
伪随机数生成器(PRNG)是一个程序,以启动数(称为种子),并进行数学运算,它转化成一些,似乎是无关的种子。它然后将产生的数字和执行相同的数学运算上转化为出现的数量是无关的一个新产生的数量。通过不断的应用算法,最后生成的数字,它可以产生一系列新的号码,如果算法是足够复杂的出现是随机的。
写一个PRNG真是很容易的。这里是一个简短的程序,生成100个随机数:
#include <stdafx.h>
#include <iostream>
using namespace std;
unsigned int PRNG()
{
// our initial starting seed is 5323
static unsigned int nSeed = 5323;
// Take the current seed and generate a new value from it
// Due to our use of large constants and overflow, it would be
// very hard for someone to predict what the next number is
// going to be from the previous one.
nSeed = (8253729 * nSeed + 2396403);
// Take the seed and return a value between 0 and 32767
return nSeed % 32767;
}
int main()
{
// Print 100 random numbers
for (int nCount=0; nCount < 100; ++nCount)
{
cout << PRNG() << "\t";
// If we've printed 5 numbers, start a new column
if ((nCount+1) % 5 == 0)
cout << endl;
}
}
每个数字似乎是相当随机相对于前一个。事实证明,我们的算法其实并没有很好的理由,我们稍后会讨论。但它确实有效地说明的PRNG数生成原理。
在C + +生成随机数
C(通过扩展C + +)带有一个内置的伪随机数发生器。它是作为两个独立的功能,生活在cstdlib头实现:
srand()设置初始种子值。srand()应该只被调用一次。
rand()生成序列中的下一个随机数(从由srand()种子)。
这里有一个使用这些功能的示例程序:
#include <stdafx.h>
#include <iostream>
#include <cstdlib> // for rand() and srand()
using namespace std;
int main()
{
srand(5323); // set initial seed value to 5323
// Print 100 random numbers
for (int nCount=0; nCount < 100; ++nCount)
{
cout << rand() << "\t";
// If we've printed 5 numbers, start a new column
if ((nCount+1) % 5 == 0)
cout << endl;
}