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