歐幾里得算法即輾轉相除法,是求兩個數的最大公因數的有效算法。而擴展歐幾里得算法則可以求出等式sa+tb=gcd(a,b)中的s和t,該算法可以被用於求解模p運算的逆元,也是一個很有效的算法。
約定和解釋
- 文章中所說的數除非特殊說明爲非負整數
- (a,b)表示a和b的最大公因數
歐幾里得算法(輾轉相除法)
算法描述
有兩個整數a和b, 並且a>b, 則a和b有如下關係(歐幾里得除法)(a爲被除數,b爲除數,求出餘數r):
a=qb+r(0≤r<b)
我們令a2=b, b2=r則類似的有(把除數b和餘數r作爲被除數和除數再次執行上述運算)
a2=q2b2+r2(0≤r2<b2<b)
依次類推, 必然存在an, bn, rn滿足
an=qnbn+rn(rn=0)
即
an=qnbn
理由是r>r1>r2...>rn且ri(i=1,2,3...,n)爲大於等於0的整數,ri依次減小最終必然會到0
此時的bn就是a和b的最大公因數
算法的正確性
歐幾里得算法之所以有效,基於這樣一個事實
若a=qb+r(0≤r<b),則a和b的最大公因數與b和r的最大公因素相同
證明如下:
設d=(a, b),d1=(b, r)則有d ∣ (a−qb),d1 ∣ (qb+r)即d ∣ r,即d1 ∣ a所以有d ∣ d‘且d1 ∣ d所以d=d1
我們利用這個性質,把求較大的兩個數a和b的公因數的問題不斷轉換成求兩個較小的數(除數和餘數)最大公因數的問題,直到這兩個較小的數中有一個爲0了,由於0和任何一個數x$的最大公因數就是x$,因爲就求出了最大公因數。
python實現
def gcd(big_num, small_num):
remainder = big_num % small_num
if remainder == 0:
return small_num
return gcd(small_num, remainder)
擴展歐幾里得算法
算法描述
根據定理,對於任意整數a和b,必然存在整數s和t使得如下等式成立
sa+tb=(a,b)
要求出其中的s和t可以利用歐幾里得算法求最大公因數的過程
在這裏,爲了更好的說明算法,我們使用a1和a2(a1>a2)來表示歐幾里得算法中的a和b,按照歐幾里得算法,有如下求a1和a2最大公因數(a1,a2)的過程
a1=q1a2+a3a2=q2a3+a4a3=q3a4+a5...an−3=qn−3an−2+an−1an−2=qn−2an−1+anan−1=qn−1an
an就是a1和a2的最大公因數
首先根據歐幾里得算法的求解過程,我們容易得到
(a1,a2)=an=an−2−qn−2an−1
根據上式子,可以得到對於an−2和an−1來說使等式
(a1,a2)=sn−2 ⋅ an−2+tn−2 ⋅ an−1式1
成立的sn−2和tn−2的值,即
sn−2=1tn−2=−qn−2
現在我們想要計算對於an−3和an−2來說等式
(a1,a2)=sn−3 ⋅ an−3+tn−3 ⋅ an−2式2
成立的sn−3和tn−3的值
根據歐幾里得算法的求解過程,有如下等式對n>3都成立
an−1=an−3−qn−3an−2式3
將式3中an−1的表達式帶入式1得到
(a1,a2)=tn−2 ⋅ an−3+(sn−2−qn−3⋅tn−2) ⋅ an−2式4
可以看到,我們在式2中需要求的sn−3和tn−3求出來了,且這個關係也對n>3都成立
sn−3=tn−2tn−3=sn−2−qn−3 ⋅ tn−2
按照這個關係,我們可以一直向前推,直到s1和t1滿足
(a1,a2)=s1 ⋅a1+t1 ⋅ a2
從而解出了想要求出的s和t。
注: s和t不唯一的(只考慮絕對值不同),例如:
6720×46480+(−19713)×39423=1(−22703)×46480+26767×39423=1
這似乎說明39423模46480的逆元有兩個,但實際上有(−19713)+46480=26767
即−19713≡26767 (mod 46480), 對於a和b不互質的情況,暫不清楚。
算法的應用
該算法可以在a和p互質時被用來快速求a模p的逆元a‘
因爲若
s ⋅ a+t ⋅ p=1
則有
s ⋅ a≡1 (mod p)
其中s就是a的逆元a‘
python實現
def gcd_ext(big_num, small_num):
remainder = big_num % small_num
iq = int(big_num / small_num)
if small_num % remainder == 0:
s = remainder
t = -iq
return (s, t, remainder)
s_last, t_last, gcd = gcd_ext(small_num, remainder)
s = t_last
t = s_last - t_last * iq
return (s, t, gcd)
參考資料
信息安全數學基礎(第2版)陳恭亮【清華大學出版社】