C++中伪随机数类的实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baickl/article/details/554575

随机数,在很多地方都有具体的用处:
扑克,测验飞行员对飞机意外变故的反应的飞行模拟器,市场研究时假设客流的波动 ……等等
计算机用随机数发生器来产生均匀分布在一定范围之内的随机数,该发生器用确定的算法从称为
种子的初始值开始产生随机数,算法对种子加工,产生一个数的序列,其实这个序列是固定的,
因为它使用初始值执行固定的命令集,输出由指令和数据唯一决定。
因此我们可以这么说,这么得来的随机数并不是真正的随机数,而是一个伪随机数。
多数编译器提供实现随机数发生器的库函数,但是不幸的是,并不是每个库函数都一样。
但是我们可以自己定义一个随机数类来实现随机数,下面我们先分析一下过程。

首先我们要确定有下面变量:
unsigned long randSeed;随机数的种子
还有与种子操作产生随机数的相关数据:
const unsigned long maxshort=65536L;
const unsigned long multiplier=1194122693L;
const unsigned long adder=12345L;
上面的这些数据都可以自己更改,到后面再具体来介绍为什么这么设定这些数据作为相关数据。

第二步:我们确定相关函数
种子生成器(即构造函数):
RandomNumber(unsigned long s);
随机整数发生器:
unsigned short Random(unsigned long n);
浮点数发生器:
double fRandom(void);

确定了这些,我们可以声明随机数类了:
#include
//用当前种子产生随机数
const unsigned long maxshort=65536L;
const unsigned long multiplier=1194211693L;
const unsigned long adder=12345L;

class RandomNumber
{
private:
//存放种子的私有成员
unsigned long randSeed;
public:
//构造函数 。缺省值0表示系统自动给出种子
RandomNumber(unsigned long s=0);
//产生0<=value中,用参数0调用时,
它反回一个无符号长整数(32位),表示从基准时间(1970.1.1.午夜或者1904.1.1午夜)至今已经过去的秒数。
任何情况下产生的数都是巨大的无符号型长整数.基于两者的选择,我们很理所当然地用一个选择语句来描述:
RandomNumber::RandomNumber(unsigned long s)
{
if(s==0)
randSeed=time(0);//系统时间作种子
else
randSeed=s; //用户提供种子
}
上面的就是种子生成器的代码。

到这,我们得到了种子。这只是没有加工的种子,其实每次迭代,都是用常量来产生新的无符号的种子:
randSeed=multiplier*randSeed+adder;
通过上面的表达式,我们得到了更新后的种子,这就是我们在下面的用到的原理,通过更新新种子,再将其
右移16位(不知道各位是否发现一直到现在我们得到的都是32位的种子),这时得到的结果就是在0至65535的随机数
,不急,我们再用除法把这个数映射到0……n-1。这就是Random(n)的结果,看下面代码:
unsigned short RandomNumber::Random(unsigned long n)
{
randSeed=multiplier*randSeed+adder;
return (unsigned short)((randSeed>>16)%n);
}

这里就得到随机整数了。

怎么得到随机浮点数呢?我们通过随机整数来实现:
首先调用整数Random(maxshort),大家都知道他的范围了吧,再用double(maxshort)除,这样就得到了0<=fRandom()<=1.0
的实数随机数:
double RandomNumber::fRandom(void)
{
return Random(maxshort)/double(maxshort);
}


至此,完成

下面一步是怎么写成头文件:
先把以上代码按顺序写放在一起,编不编成库存文件就随各位了,我是不会编的,直接放头文件也一样。
然后在开头加上:
#ifndef RANDOMNUMBER_INCLUDE
#define RANDOMNUMBER_INCLUDE
未尾加上:
#endif就行了

然后保存为random.h就可以了,至于扩展大家自己看吧,我还没有想到,
到此我先感谢以前帮助的朋友们,他们是:无情公子,陈灵君(我不知道你在网易的名字,SORRY!)这两位
一直以来对我的帮助。非常感谢,没有你们的指引我真的不知道 后面的路如何走,
也希望你们能像以前那样的帮助我。我不能做什么,只能说感谢了!!~~
也祝大家在网易越玩越开心,天天进步。。:)
QQ:49448699

参考资料:Data Structures With C++(William Ford &William Topp著)

没有更多推荐了,返回首页