整除定义:如果 a 和 b 是整数,a 不为零,若有整数 c 使得 b=ac,就说 a 整除 b 。在 a 整除 b 时,a 是 b 的一个因子,b 是 a 的倍数。符号 a | b 表示 a 整除 b 。
带余除法:若 a 为整数,d 为正整数,有唯一的整数 q 和 r, 并且 0≤ r < d,满足 a = dq + r 。
同余定义:若 a 和 b 为整数,m 正整数,如果 m 整除 a - b, 就说 a 模 m 同余 b 。用 a≡b(mod m) 表示。
整数 a 模 m 所有整数同余的集合称为 a 模 m 的同余类。这样的同余类有 m 个(余数分别为 0, ..., m-1),各不相交,这些等价类的并集即是整数集合。
同余和加法乘法有如下关系:
m 为正整数,若 a≡b(mod m),c≡d(mod m),那么,(a+c)≡(b+d)(mod m),ac≡bd(mod m)
以上引自 “离散数学及其应用” Kenneth H. Rosen
线性同余法是最常用的生成伪随机数的算法之一。过程如下:
给定一个模数 m,一个乘数 a,一个增量 c,一个初始值(称为种子)x0
x1= (a*x0+c) mod m
...
xn= (a*xn-1+c) mod m
比如书上给出了一个例子,m=9,a=7,c=4,x0=3
得出的一个序列为:
3, 7, 8, 6, 1, 2, 0, 4, 5, 3, 7 ...
0~8 这些数字依次出现,循环往复,且在整个序列中出现的次数是相等的,其中每一项都只依赖于前面的一项。
如果想要得到0~m-1按某种次序循环,对乘数a,增量c有什么要求呢?
根据上面的例子中可以发现,模数9和乘数7互质,增量c咋一看没啥规律,那是不是只要乘数和模数互质就可以了呢?
可以令 m=9,a=7, c=0, x0=3试试看看会产生什么样的序列:
x0=3
x1=x0*7mod9=3
x2=x1*7mod9=3
x3...
0比较特殊,c换成3试试
x0=3
x1=(x0*7+3) mod 9=6
x2=(x1*7+3) mod 9=0
x3=(x2*7+3) mod 9=3
x4=(x3*7+3) mod 9=6
x5=...
从结果可以看出,很遗憾,c并不是随意取的,也不是无关紧要的
在看上面给出的例子中,当c=4时,和m=9也是互质的,并且c是合数
那么考虑是不是c也应该是和m互质才行,那就看看c=8时的情况
x0=3
x1=(x0*7+8) mod 9=2
x2=(x1*7+8) mod 9=4
x3=(x2*7+8) mod 9=0
x4=(x3*7+8) mod 9=8
x5=(x4*7+8) mod 9=1
x6=(x5*7+8) mod 9=6
x7=(x6*7+8) mod 9=5
x8=(x7*7+8) mod 9=7
x9=(x8*7+8) mod 9=3
x10=...
looks good!当 m=9, a=7, c=8时,也可以产生从0~8的随机序列
所以我们暂时得到的pattern是:m和a互质,m和c互质,且c须是合数
这个规律是具有普遍适用性呢?我们换组数字来验证一下:
m=10, a=7, c=6
x0=3
x1=(x0*7+6) mod 10=7
x2=(x1*7+6) mod 10=5
x3=(x2*7+6) mod 10=1
x4=(x3*7+6) mod 10=3
x5=...
很遗憾,虽然m=10, a=7互质,m=10和c=6也互质,并且c是合数,并不能产生0~9的随机序列
看来适用于m=9的pattern并不适用于m=10
那么线性同余法求伪随机数对于 模数m,乘数a和增量c到底与何要求呢? 留待以后解决和验证!