歐幾里得算法與不定方程

本文主要介紹數論中的歐幾里得算法,線性方程及它們之間的關係。本文主要參考了《數論概論》,因此將本文當成這本書的讀書筆記也未嘗不可。

(本文正被完善中……)


歐幾里得算法


問題:求60和22的最大公約數(兩個數的最大公約數a, b是能夠整除它們的最大數,記爲gcd(a, b))。


因爲這兩個數比較小,所以我們完全可以通過肉眼觀察出其最大公約數:2 。那麼對於(225,120 )這一組數呢?我們可以分解兩個數的因子:

225=32×52

120=23×3×5

然後求出所有數的約數(a 的約數divisor(a) 表示能夠整除a 的數):

divisor(225)={1,3,5,9,15,25,45,75,225}

divisor(120)={1,2,3,4,5,6,8,10,12,15,20,24,30,40,60,120}

它們的公約數

commonDivisor(225,120)={1,3,5,15}

其中最大的15 就是它們的最大公約數(根據最大公約數的定義)。大功告成,總算讓人鬆了一口氣。按照這個方法,不論來什麼樣的一組數,我們都可以輕鬆的求它們的最大公約數了。等等,真的是這樣嗎?那麼來看看這一組數:

(1160718174,316258250)

我的天,這題誰愛算誰算吧(溜~)。

下面介紹歐幾里得算法,只要掌握了這種算法,就可以用極其快的速度算出兩個數的最大公約數,就算是上面那兩個天文數字也OK 。不僅如此,歐幾里得算法還很容易通過編程實現,那麼就可以利用計算機的計算能力迅速的解決大多數(指的是有機會碰上的)最大公約數的問題,其代碼量只有三行。

在介紹算法的具體過程之前,我打算先用文字描述一下這個算法,即使無法很好的說清楚這個算法,也讓先有一個大體的概念。

歐幾里得算法:可以用以下方法求a, b的最大公約數gcd(a, b)

  1. 計算r=amodb ,然後令a=b,b=r
  2. 重複步驟1 ,直到r=0 ,此時b 就是答案。

下面我們將利用歐幾里得算法計算gcd(1160718174,316258250)

1160718174=3  ×316258250+211943424

316258250  =1  ×211943424+104314826

211943424  =2  ×104314826+3313772

104314826  =31×3313772    +1587894

3313772      =2  ×1587894    +137984

1587894      =11×137984      +70070

137984        =1  ×70070        +67914

70070          =1  ×67914        +2156

67914          =31×2156          +1078 (最大公約數)

2156            =2  ×1078          +0

我們只用了10 次計算就將這兩個天文數字的最大公約數計算出來了。下面用一種不嚴謹的方法證明這種計算方法是對的(爲了證明的方便,這裏僅以上面的數據爲例,不做一般性的證明):

先證明10781160718174316258250 的公約數:
1078 能夠整除2156 (最後一個式子)

因爲1078 能夠整除10782156 ,所以1078 能夠整除67914 (倒數第二個式子)

……(以此類推)

因爲1078 能夠整除104314826211943424 ,所以1078 可以整除316258250 (第二個式子)

因爲1078 能夠整除316258250211943424 ,所以1078 可以整除1160718174 (第一個式子)

再證明1078 是兩數的公約數中最大的那個:

假設d 爲兩數的任意公約數

因爲d 能夠整除1160718174316258250 ,所以d 能夠整除211943424 (第一個式子)

因爲d 能夠整除316258250211943424 ,所以d 能夠整除104314826 (第二個式子)

……(以此類推)

因爲d 能夠整除679142156 ,所以d 能夠整除1078 (倒數第二個式子)

那麼1160718174316258250 的任意公約數都能整除1078 ,那麼1078 是兩數的最大公約數。

簡潔而神奇,這就是歐幾里得算法。




擴展歐幾里得算法


問題:求方程60x + 22y = gcd(60, 22)的一組解


這是個關於x,y 的不定方程。我們觀察這個方程。方程中有兩個未知數,並且有一個奇怪的東西:gcd(60,22) 。爲什麼這個方程長得如此奇怪呢?這要從一條叫貝祖定理的定理說起:

貝祖定理:設a,b是不全爲零的整數,則存在整數x,y,使得ax + by = gcd(a,b)

所以是因爲這個方程的解一定存在,所以我們本着一顆“無聊的心”來考察一下這方程的如何求解。哈哈~

事實上ax + by的結果一定是gcd(a, b)的整數倍,所以如果要討論ax + by這種整數線性方程的話,就必然要討論這個方程

首先不管方程的解法如何,求出gcd(60,22) 都是必須的。那我們在複習歐幾里得算法的同時求一下gcd(60,22)

a=60,b=22 (只是爲了簡潔),歐幾里得算法的過程如下:

a=2×b+16

b=1×16+6

16=2×6+4

6=1×4+2 (最大公約數)

4=2×2+0

於是gcd(a,b) 等於2 。現在終於可以來解方程了。首先觀察方程。顯然,我們可以枚舉x,y 來求解,通過觀察可以發現4a+11b=2 。但是對於更一般的ab ,用枚舉的方法來解決問題就不一定有效了。這裏就必須引入擴展歐幾里得算法。同樣,先介紹一下擴展歐幾里得算法的大致步驟:

  1. 將歐幾里得算法過程中的第一個式子中的a, b, r 都用a, b 表示
  2. 將第二個式子中的a2, b2, r2 也用a, b 表示
  3. 依次將第三,第四,…,第m 式子中的am, bm, rma, b 表示
  4. 將倒數第二條式子中的所有量用a, b 表示,此時可以得到方程的解

具體的步驟如下(下面的每條式子同上述歐幾里得算法的每條式子相對應):

16=a2b

6=a+3b

4=3a8b

2=4a+11b

上面的最後一條式子就向我們展示瞭解。這就是擴展歐幾里得算法。因爲其正確性是顯然的,所以這裏就不證明了。


問題:求方程ax + by = gcd(a, b)的通解


如果求60x+22y=2 的解還不夠滿足的話,我們可以將這個問題的更一般的解找出來。將方程一般化後可以得到方程:ax+by=g ,其中g=gcd(a,b) 。我們嘗試求出這條方程的所有解,也就是其通解。

首先,可以通過上述擴展歐幾里得算法求出這條方程的一組解,我們可以將其記爲(x1,y1)

其次,我們可以先嚐試求g=1 的情況,也就是a,b 互質(沒有公共因子)的情況。顯然,如果將ax+by=1 的所有解(x,y) 在平面直角座標系中以點(x,y) 的形式畫出來,那麼這些解一定落在直線ax+by=1 上。以防有人不明白爲什麼這個方程的解集落在直線上,我們將方程變形爲

y=abx+1b

這個“斜截式”的方程就比較顯然的呈現出一條直線了。那麼方程的另一組解就可以表示爲直線上的另一個座標爲整數的點

(x1+t,y1abt)

其中t 爲某個神祕的我們暫時不需要知道是多少的整數。因爲g=gcd(a,b)=1 ,所以 爲了保證“abt 是整數“,必須滿足“t爲b的倍數” 。否則若b 既不能整除a 又不能整除t ,則abt 就 不是整數。

好的,現在tb 的倍數了(之所以先討論g=1 , 目的就在於得到這個結論從而簡化問題),那麼t就可以表示爲k×b ,也就是t=kb ,將t 代入(x1+t,y1abt) 可得方程的通解的形式

(x1+kb,y1ka)

其中k 爲任意整數,每個整數對應了方程的一組解。

然後,我們再討論g>1 的情況。先將方程ax+by=g 變形:

agx+bgy=1

問題就轉化成了上面一種情況,也就是ax+by=1a=ag,b=bg,gcd(a,b)=1 的情況,那麼套用前面的公式,通解就是

(x1+kbg,y1kag)


問題:求方程ax + by = c的通解

問題:求方程ax + by = g的最小非負解

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