用线性同余法生成“伪”随机数

线性同余方法(LCG)是个产生伪随机数的方法。

它是根据递归公式:

N_{j+1} \equiv (A \times N_j + B ) \pmod{M}

其中A,B,M是产生器设定的常数。

LCG的周期最大为M,但大部分情况都会少于M。要令LCG达到最大周期,应符合以下条件:

  1. B,M互质
  2. M的所有质因子的能整除A-1
  3. M是4的倍数A-1也是;
  4. A,B,N_0都比M小;
  5. A,B是正整数。

    线性同余算法有m 、a 、c 和X0 4个参数,通过置Xn + 1 ≡aXn + c (mod m) ,求得随机数序列< Xn > , 这个序列称作线性同余序列。m、a 、c 和X0 分别称做模数、乘数、增量和初始值。线性同余方法速度快,如果对乘数和模数进行适当的选择,可以满足用于评价一个随机数产生器的3 种准则:
1.这个函数应该是一个完整周期的产生函数。也就是说,这个函数应该在重复之前产生出0 到m之间的所有数;
2.产生的序列应该看起来是随机的;
3.这个函数应该用32bit 算术高效实现。

在我的算法中,a=7^5;c=0;m=2^31-1; x0为系统时间;

我的代码如下:

#include <stdio.h>
#include <time.h>
static unsigned long rand_seed;
void mysrand (unsigned long int);
void myrand ();
int
main (void)
{
    int i;

    mysrand (time (NULL));
    for (i = 0; i < 100; i++)
      {
          myrand ();
      }
    return 0;
}

void
mysrand (unsigned long seed)
{
    rand_seed = seed;
}

void
myrand ()
{
    rand_seed = (rand_seed * 16807L) % ((1 << 31) - 1);
    printf ("%ld ", rand_seed);
}

===============PS==================

产生随机种子的方法很多,目前用得比较多的是使用系统时间为种子。我觉得这种方法也不妥当。假如我批量执行程序,程序执行的时间是几个ms,那么几个相邻程序的种子就是一样的,产生的结果因此也是一样的。(因为系统时间是按照秒来计算的,一秒内执行多少次,产生的随机种子就有多少相同的。)

刚在网上发现这个方法:随便创建一个非全局的非静态的变量,然后不初始化,直接访问,把这个变量的值作为随机数种子。不知道可行不?找空试一下。不知道未定义变量的值在不同时间执行时规律性是不是很强,很强的话,又要KO掉。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值