在求解最大公約數的幾種方法中,輾轉相除法最為出名。輾轉相除法是仍然在使用的歷史最悠久的算法之一。它首次出現于幾何原本(卷7命題1–2、卷10命題2–3)(大約公元前300年)。在卷7中用于整數,在卷10中用于線(xiàn)段的長(cháng)度(也就是所說(shuō)的實(shí)數,但是當時(shí)未有實(shí)數的概念)。卷10中出現的算法是幾何的,兩段線(xiàn)段a和b的最大公約數是準確測量a和b的最大長(cháng)度。 這個(gè)算法可能并非歐幾里得發(fā)明,而僅僅是將先人的結果編進(jìn)他的幾何原本。數學(xué)家、歷史學(xué)家范德瓦爾登認為卷7的內容可能來(lái)自畢達哥拉斯學(xué)院出身的數學(xué)家寫(xiě)的關(guān)于數論的教科書(shū)。輾轉相除法是被大約公元前375年的歐多克斯發(fā)現的,但也有可能更早之前就已經(jīng)存在,因為歐幾里得和亞里士多德的這兩位歷史名人著(zhù)作中都出現了?νθυφα?ρεσι?一詞(anthyphairesis, 意為“輾轉相減”), 幾個(gè)世紀之后,輾轉相除法又分別被中國人和印度人獨立發(fā)現,主要用來(lái)解天文學(xué)中用到的丟番圖方程以及指定準確的歷法。5世紀末,印度數學(xué)家、天文學(xué)家阿里亞哈塔可能是因為輾轉相除法在解丟番圖方程時(shí)的高效率而稱(chēng)它為“粉碎機”。因為在中國,孫子算經(jīng)中出現了此算法的一個(gè)特例中國剩余定理,但是輾轉相除法的完整表述直到1247年秦九韶的數學(xué)九章中才出現。在歐洲,輾轉相除法首次出現于克勞德·巴希特(英語(yǔ):Claude Gaspard Bachet de Méziriac)的著(zhù)作Problèmes plaisants et délectables的第二版在歐洲,輾轉相除法廣泛使用于丟番圖方程和連分數。后來(lái),英國數學(xué)家桑德森(英語(yǔ):Nicholas Saunderson)將擴展歐幾里得算法作為羅杰科茨(英語(yǔ):Roger Cotes)對計算連分數的方法的研究發(fā)表。 19世紀,輾轉相除法孕育出了一些新的數系,如高斯整數和艾森斯坦整數。1815年,高斯用輾轉相除法證明高斯整數的分解是惟一的,他的研究發(fā)表于1832年。高斯在他的《算數研究》(published 1801)中,作為處理連分數的方法提到了這個(gè)算法。約翰·狄利克雷是第一個(gè)將輾轉相除法作為數論的基礎的數學(xué)家。狄利克雷提出,數論中的很多結論,如分解的惟一性,在任何使輾轉相除法成立的數系中有效。狄利克雷的觀(guān)點(diǎn)被理查德·戴德金修改和推廣,他用輾轉相除法研究代數整數。戴德金是第一個(gè)用高斯整數的分解惟一性證明費馬平方和定理的數學(xué)家。戴德金還率先定義了歐幾里得整環(huán)的概念。19世紀末,輾轉相除法的輝煌逐漸被戴德金的理想取代。 輾轉相除法的其他應用發(fā)展于19世紀。1829年,施圖姆將輾轉相除法用于施圖姆序列(用于確定多項式的不同實(shí)根的個(gè)數的方法)。
輾轉相除法是歷史上第一個(gè)整數關(guān)系算法(英語(yǔ):integer relation algorithm),即尋找兩數的整數關(guān)系的算法。近年來(lái),出現了一些新穎的整數關(guān)系算法,如埃拉曼·弗格森(英語(yǔ):Helaman Ferguson)和福爾卡德于1979年發(fā)表的弗格森-福爾卡德算法、以及與它相關(guān)的LLL算法(英語(yǔ):Lenstra–Lenstra–Lovász lattice basis reduction algorithm)、HJLS算法以及PSLQ算法(英語(yǔ):PSLQ algorithm)。
1969年,科爾(Cole)和戴維(Davie)基于輾轉相除法創(chuàng )造了一種二人游戲,叫做歐幾里得游戲。這個(gè)游戲有最優(yōu)策略。游戲開(kāi)始于兩列分別為a和b個(gè)棋子組成的序列,玩家輪流從較長(cháng)一列中取走較短一列棋子數量的m倍的棋子。如果兩列棋子a和b分別由x和y個(gè)棋子組成,其中x大于y,那么玩家可以序列a的棋子數量減少為自然數x ? my。最后率先將一列棋子清空的玩家勝出。 擴展歐幾里得算法
擴展歐幾里德算法:擴展歐幾里得算法(又稱(chēng)擴充歐幾里得算法)是用來(lái)解某一類(lèi)特定的不定方程的一種方法,常用用來(lái)求解模線(xiàn)性方程及方程組。擴展的歐幾里得算法可以用來(lái)計算模逆元,而模逆元在公鑰密碼學(xué)中占有舉足輕重的地位。 基本算法:對于不完全為 0 的非負整數 a,b,gcd(a,b)表示 a,b 的最大公約數,必然存在整數對 x,y ,使得 gcd(a,b)=ax+by。 證明:設 a>b。
1,顯然當 b=0,gcd(a,b)=a。此時(shí) x=1,y=0;
2,ab≠0 時(shí)
設 ax1+by1=gcd(a,b);
bx2+(a mod b)y2=gcd(b,a mod b);
根據樸素的歐幾里德原理有 gcd(a,b)=gcd(b,a mod b);
則:ax1+by1=bx2+(a mod b)y2;
即:ax1+by1=bx2+(a-(a/b)*b)y2=ay2+bx2-(a/b)*by2;
根據恒等定理得:x1=y2; y1=x2-(a/b)*y2;
這樣我們就得到了求解 x1,y1 的方法:x1,y1 的值基于 x2,y2.
上面的思想是以遞歸定義的,因為 gcd 不斷的遞歸求解一定會(huì )有個(gè)時(shí)候 b=0,所以遞歸可以結束。
歐幾里德算法是計算兩個(gè)數最大公約數的傳統算法,無(wú)論從理論還是從實(shí)際效率上都是很好的。但是卻有一個(gè)致命的缺陷,這個(gè)缺陷在素數比較小的時(shí)候一般是感覺(jué)不到的,只有在大素數時(shí)才會(huì )顯現出來(lái)。 Stein算法由J. Stein 1961年提出,這個(gè)方法也是計算兩個(gè)數的最大公約數。和歐幾里德算法算法不同的是,Stein算法只有整數的移位和加減法,這對于程序設計者是一個(gè)福音。
Stein算法:
設置A1=A、B1=B和C1=1
1、如果An=0,Bn*Cn是最大公約數,算法結束
2、如果Bn=0,An*Cn是最大公約數,算法結束
3、如果An和Bn都是偶數,則An+1=An/2,Bn+1=Bn/2,Cn+1=Cn*2(注意,乘2只要把整數左移一位即可,除2只要把整數右移一位即可)
4、如果An是偶數,Bn不是偶數,則An+1=An/2,Bn+1=Bn,Cn+1=Cn (很顯然啦,2不是奇數的約數)
5、如果Bn是偶數,An不是偶數,則Bn+1=Bn/2,An+1=An,Cn+1=Cn (很顯然啦,2不是奇數的約數)
6、如果An和Bn都不是偶數,則An+1=|An-Bn|,Bn+1=min(An,Bn),Cn+1=Cn
7、n加1,轉步驟1
考慮歐幾里德算法,最?lèi)毫拥那闆r是,每次迭代a=2b-1,這樣,迭代后,r=b-1。如果a小于2N,這樣大約需要4N次迭代。而考慮Stein算法,每次迭代后,顯然A(n+1)B(n+1)≤AnBn/2,最大迭代次數也不超過(guò)4N次。也就是說(shuō),迭代次數幾乎是相等的。但是,需要注意的是,對于大素數,試商法將使每次迭代都更復雜,因此對于大素數Stein將更有優(yōu)勢。