伪随机数生成算法及性能检验

本文介绍了伪随机数的概念及其在计算机仿真、密码学等领域的应用。讨论了平方取中法和线性同余法这两种常见的伪随机数生成算法,通过实例展示了它们的性能。平方取中法计算快但易产生周期性,而线性同余法具有更好的均匀性,但随机性相对较弱。

本文永久链接为http://johnhany.net/2013/11/random-algorithm-and-performance/ 转载请注明出处

什么叫伪随机数

        在一些问题中,比如计算机仿真和模拟、密码学等应用中,需要产生一个随机数数列来解决问题。

        随机数数列分为真随机数数列和伪随机数数列。真随机数数列是完全不可预测的,可以通过放射性衰变、电子设备的热噪音、宇宙射线的触发时间等物理过程得到,但无法通过单纯的软件方式获得;伪随机数数列是可预测的,严格意义上不具有随机性质,通常用数学公式的方法获得。

        由于很多应用当中对“随机”数列的要求并不十分严格,而且伪随机数的产生较真随机数更为廉价、高效,所以在大多数情况下只要产生统计分布较好的伪随机数数列就能够满足应用要求。早期的伪随机数生成算法以平方取中法为主,现在则以线性同余法为主要方式。下面我会就两种方式分别给出实例,并以数据统计和图形化的方式对伪随机数生成算法的性能进行检验。


种子

    正如数列需要有首项,产生伪随机数需要一个初值用来计算整个序列,这个初值被称为“种子”。种子可以是一个固定的值,也可以是根据当前系统状态确定的值。C语言用来产生伪随机数的库函数rand()的种子是固定的值,因此每次调用该函数产生的随机数数列都是相同的。所以为了获得随机性更好的数列,种子应为一个变量,该变量可以与当前系统时间、用户对键盘或鼠标操作情况有关。这里我将根据系统时间获得种子。

代码如下:

   #include <time.h>
   unsigned long ssecond,nowtime;
    unsigned long seed;
   long gettime()          //获得当前时间
   {
       time_t t;
       time(&t);
       struct tm *local;
       local=localtime(&t);
       local->tm_mon++;
       ssecond=(long)local->tm_sec*100+local->tm_sec+36923;
       nowtime=local->tm_sec + local->tm_min*100 + local->tm_hour*10000 + local->tm_mday*1000000 + local->tm_mon*100000000;
       return nowtime;
   }

在调用伪随机数生成函数之前通过seed=gettime();语句就完成了种子的初始化。


平方取中法

平方取中法是由冯·诺依曼在1946年提出的,其基本思想为:将数列中的第a(i)项(假设其有m位)平方,取得到的2m位数(若不足2m位,在最高位前补0)中间部分的m位数字,作为a(i)的下一项a(i+1),由此产生一个伪随机数数列。即:


x(i+1)=(10^(-m/2)*x(i)*x(i))mod(10^m)


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值