|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?我要加入
x
数论基础算法
原创:怒火之袍 2003年7月24日
一、引言
数论曾经被视为数学领域中华而不实的一个分支,然而现在它已经得到了广泛的应用,这其中的部分原因应归结为以大素数为基础的密码体系的建立。这种体系的可行性在于我们可以轻松地找到一些大素数,而体系的安全性则在于将大素数的乘积重新分解因数往往十分困难。本文将介绍数论中比较基本的一些算法,面向的读者应具有代数结构的基础知识。
二、求最大公约数
我们首先要介绍的是能够有效计算两个整数的最大公约数的欧几里得算法(Euclid's algorithm,又称辗转相除法)(下文中用gcd(a,b)来表示整数a与b的最大公约数,由于gcd(a,b)=gcd(|a|,|b|),我们将参数的范围限定在非负整数的范围内)。
将a、b分别分解质因数后即可求得二者的最大公约数,然而即使是最好的算法也不能使位操作意义下的时间复杂度达到多项式级(数论算法的时间复杂度分析常常指在位操作的意义下)。高校的欧几里德算法是建立在下面的定理上的:
对于任何的非负整数a和正整数b,有gcd(a,b)=gcd(b,a mod b)。欧几里得算法的流程为:
- EUCLID(a,b)
- if b=0
- then return a
- else return EUCLID(b,a mod b)
复制代码
比如我们要求31和20的最大公约数,则EUCLID的运行过程为:
- EUCLID(30,21)=EUCLID(21,9)=EUCLID(9,3)=EUCLID(3,0)=3。
复制代码
关于该算法的效率分析,有如下定理阐述:
对任何k>=1,若a>b>=1且b<Fk+1(Fx为Fibonacci数列的第x项),那么EUCLID(a,b)的递归调用必小于k次。
连续的Fibonacci数是EUCLID输入的最坏情况,因为对任何k>2有Fk+1 mod Fk=Fk-1,所以gcd(Fk+1,Fk)=gcd(Fk,(Fk+1 mod Fk))=gcd(Fk,Fk-1),而CLID(F3,F2)=EUCLID(2,1)的计算是需要进行一次递归调用的。
现在我们来改写欧几里得算法以计算附加的有用信息,使得我们可以在算法结束时获得两个整数(可能为0或负数)x、y使等式d=gcd(a,b)=ax+by成立。如下所示的EXTENDED-EUCLID过程接收一对非负整数,返回满足上述等式的三元组(d,x,y):
- EXTENDED-EUCLID(a,b)
- if b=0
- then return (a,1,0)
- (d',x',y')←EXTEND-EUCLID(b,a mod b)
- (d,x,y)=(d',y',x'-floor(a/b)*y')
- return (d,x,y)
复制代码
EXTENDED-EUCLID过程与EUCLID过程的时间复杂度在渐近意义下相同,差别仅在于常数因子,而由此得出的x、y却对解决一些问题十分有用。
三、求解同余线性方程
在一些重要的应用中常会涉及到求解如下同余线性方程的问题:a*x模n余b,求x。这个问题有解的条件是d=gcd(a,n)|b,在已知有解x0的情况下,可以推出其在模n意义下的全部解,即xi=x0+i*(n/d)(i=0,1...d-1),具体过程如下:
- MODULAR-LINEAR-EQUATION-SOLVER(a,b,n)
- (d,x',y')←EXTENDED-EUCLID(a,n)
- if d|b
- then x0←x'(b/d) mod n
- for i←0 to d-1
- do print (x0+i(n/d)) mod n
- else print "no solutions"
复制代码 |
|