随机数算法——线性同余产生随机数

在互联网时代,经常有产生一个不重复的随机数的应用场景。

比如点击领用优惠券,产生一个10000 以内的随机数。该数字发到用户手机上,作为验证凭证。

每次该数字需要有如下要求:

1:每次都是随机产生,用户不能轻易猜测到下一个验证码。

2:同一个数字,只会出现一次。不会存在多个用户领用同一个验证码的情况。

基于上述类似场景,可以采用《线性同余产生随机数》算法,每次生成一个不重复的随机数。

 

线性同余产生随机数算法解析:

Xn+1 = ( aXn + c ) mod  m ,n >= 0

其中:  0 < m ;0 <= a<m ;  0 <=c<m 

开始指定一个X0( 0<=X0<m ),依赖上次的值Xn,每次得到一个数Xn+1。根据这个算法所求的随机数序列{X0,X1,...Xn},称作线性同余序列。 

同余序列总是进入一个循环,它最终必定在n个数之间无休止的重复循环。它的最大循环周期为m。 

得到最大的周期m的条件如下: 
(1)c与m为互质数。
(2)对于整除m的每个素数p,b=a-1是p的倍数。
(3)如果m是4的倍数,则b也是4的倍数。 

 

以取10000个 随机数为例,m = 10000;按最大的周期条件设定c = 3; a = 21; x0=4。

代码如下:

1         public static void RandomGenerator(ref long previousVaule)

2         {

3             //Xn+1 = ( aXn + c ) mod  m ,n >= 0 

4             long m = 10000L;

5             long c = 3L;

6             long a = 21L;

7 

8             previousVaule = (a * previousVaule + c) % m;

9         }
            long ab = 4;

            HashSet<long> hash = new HashSet<long>();



            for (int i = 0; i < 10000; i++)

            {

                RandomGenerator(ref ab);

                hash.Add(ab);

                Console.WriteLine(ab);

            }

            Console.WriteLine("总数:"+hash.Count);

运行结果:

随机数算法——线性同余产生随机数

经测试可以验证,10000次随机穷举所有<10000的数字现。现实应用中,还要解决分布式情况下,对上次的值Xn依赖的争用问题。

 

 算法参考:http://www.asmedu.net/algorithm.jsp?index=46

 

你可能感兴趣的:(随机数)