歐幾里得算法和擴展歐幾里得算法

  歐幾里得算法即輾轉相除法,是求兩個數的最大公因數的有效算法。而擴展歐幾里得算法則可以求出等式sa+tb=gcd(a,b)中的s和t,該算法可以被用於求解模p運算的逆元,也是一個很有效的算法。

約定和解釋

  1. 文章中所說的數除非特殊說明爲非負整數
  2. (a,b)(a,b)表示aabb的最大公因數

歐幾里得算法(輾轉相除法)

算法描述

有兩個整數aabb, 並且a>ba > b, 則aabb有如下關係(歐幾里得除法)(aa爲被除數,bb爲除數,求出餘數rr):
a=qb+r(0r<b) a=qb+r \quad (0 \leq r < b)
我們令a2=b, b2=ra_2=b, \ b_2=r則類似的有(把除數bb和餘數rr作爲被除數和除數再次執行上述運算)
a2=q2b2+r2(0r2<b2<b) a_2=q_2 b_2 + r_2 \quad (0 \leq r_2 < b_2 < b)
依次類推, 必然存在an, bn, rna_n, \ b_n, \ r_n滿足
an=qnbn+rn(rn=0) a_n = q_n b_n + r_n \quad (r_n = 0)

an=qnbn a_n = q_n b_n
理由是r>r1>r2...>rnr > r_1 > r_2...>r_nri(i=1,2,3...,n)r_i (i = 1,2,3...,n)爲大於等於0的整數,rir_i依次減小最終必然會到0

此時的bnb_n就是aabb的最大公因數

算法的正確性

歐幾里得算法之所以有效,基於這樣一個事實
a=qb+r(0r<b)abbr 若a=qb+r \quad (0 \leq r < b),則a和b的最大公因數與b和r的最大公因素相同
證明如下:
d=(a, b),d1=(b, r)d  (aqb)d1  (qb+r)d  r,d1  ad  dd1  dd=d1 設d = (a, \ b),\quad d_1=(b, \ r) \\ 則有d \ | \ (a-qb), \quad d_1 \ | \ (qb + r) \\ 即d \ | \ r , 即 d_1 \ | \ a \\ 所以有 d \ | \ d^` 且 d_1 \ | \ d \\ 所以 d = d_1
我們利用這個性質,把求較大的兩個數aabb的公因數的問題不斷轉換成求兩個較小的數(除數和餘數)最大公因數的問題,直到這兩個較小的數中有一個爲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)

擴展歐幾里得算法

算法描述

根據定理,對於任意整數aabb,必然存在整數sstt使得如下等式成立
sa+tb=(a,b) sa+tb=(a,b)
要求出其中的sstt可以利用歐幾里得算法求最大公因數的過程

在這裏,爲了更好的說明算法,我們使用a1a2a_1和a_2(a1>a2)(a_1 > a_2)來表示歐幾里得算法中的aba和b,按照歐幾里得算法,有如下求a1a2a_1和a_2最大公因數(a1,a2)(a_1,a_2)的過程
a1=q1a2+a3a2=q2a3+a4a3=q3a4+a5...an3=qn3an2+an1an2=qn2an1+anan1=qn1an a_1=q_1a_2+a_3 \\ a_2=q_2a_3+a_4 \\ a_3=q_3a_4+a_5 \\ ... \\ a_{n-3}=q_{n-3}a_{n-2}+a_{n-1} \\ a_{n-2}=q_{n-2}a_{n-1}+a_n \\ a_{n-1} = q_{n-1}a_n
ana_n就是a1a2a_1和a_2的最大公因數

首先根據歐幾里得算法的求解過程,我們容易得到
(a1,a2)=an=an2qn2an1 (a_1,a_2) = a_n = a_{n-2} - q_{n-2}a_{n-1}
根據上式子,可以得到對於an2an1a_{n-2}和a_{n-1}來說使等式
(a1,a2)=sn2  an2+tn2  an11 (a_1, a_2) = s_{n-2} \ \cdot \ a_{n-2} + t_{n-2} \ \cdot \ a_{n-1} \qquad 式1
成立的sn2tn2s_{n-2}和t_{n-2}的值,即
sn2=1tn2=qn2 s_{n-2} = 1 \\t_{n-2} = -q_{n-2}
現在我們想要計算對於an3an2a_{n-3}和a_{n-2}來說等式
(a1,a2)=sn3  an3+tn3  an22 (a_1, a_2) = s_{n-3} \ \cdot \ a_{n-3} + t_{n-3} \ \cdot \ a_{n-2} \qquad 式2
成立的sn3tn3s_{n-3}和t_{n-3}的值

根據歐幾里得算法的求解過程,有如下等式對n>3都成立
an1=an3qn3an23 a_{n-1} = a_{n-3} - q_{n-3}a_{n-2} \qquad 式3
將式3中an1a_{n-1}的表達式帶入式1得到
(a1,a2)=tn2  an3+(sn2qn3tn2)  an24 (a1, a2) = t_{n-2} \ \cdot \ a_{n-3} + (s_{n-2}-q_{n-3} \cdot t_{n-2}) \ \cdot \ a_{n-2} \qquad 式4
可以看到,我們在式2中需要求的sn3tn3s_{n-3}和t_{n-3}求出來了,且這個關係也對n>3都成立
sn3=tn2tn3=sn2qn3  tn2 s_{n-3} = t_{n-2} \\ t_{n-3} = s_{n-2} - q_{n-3} \ \cdot \ t_{n-2}
按照這個關係,我們可以一直向前推,直到s1t1s_1和t_1滿足
(a1,a2)=s1 a1+t1  a2 (a_1,a_2)=s_1 \ \cdot a_1 + t_1 \ \cdot \ a_2
從而解出了想要求出的sstt

注: sstt不唯一的(只考慮絕對值不同),例如:
6720×46480+(19713)×39423=1(22703)×46480+26767×39423=1 6720 \times 46480 + (-19713) \times 39423 = 1 \\ (-22703) \times 46480 + 26767 \times 39423 = 1
這似乎說明39423模46480的逆元有兩個,但實際上有(19713)+46480=26767(-19713) + 46480 = 26767
1971326767 (mod 46480)-19713 \equiv 26767 \ (mod \ 46480), 對於aabb不互質的情況,暫不清楚。

算法的應用

該算法可以在aapp互質時被用來快速求aapp逆元aa^`

因爲若
s  a+t  p=1 s \ \cdot \ a + t \ \cdot \ p = 1 \\
則有
s  a1 (mod p) s \ \cdot \ a \equiv 1 \ (mod \ p)
其中ss就是aa的逆元aa^`

python實現

# 參數爲兩個數,大數在前小數在後
# 返回值爲s,t和兩個數的最大公因數
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版)陳恭亮【清華大學出版社】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章