Loading AI tools
求2數的最大公因數的算法 来自维基百科,自由的百科全书
在數學中,輾轉相除法,又稱歐幾里得演算法(英語:Euclidean algorithm),是求最大公因數的演算法。輾轉相除法首次出現於歐幾里得的《幾何原本》(第VII卷,命題i和ii)中,而在中國則可以追溯至東漢出現的《九章算術》。
兩個整數的最大公因數是能夠同時整除它們的最大的正整數。輾轉相除法基於如下原理:兩個整數的最大公因數等於其中較小的數和兩數相除餘數的最大公因數。例如,欲求252和105的最大公因數();因為,所以這個最大公因數也是42與105的最大公因數()。在這個過程中,較大的數縮小了,所以繼續進行同樣的計算可以不斷縮小這兩個數直至餘數為零。這時,所剩下的還沒有變成零的數就是兩數的最大公因數。由輾轉相除法也可以推出,兩數的最大公因數可以用兩數的整數倍相加來表示,如。這個重要的結論叫做貝祖定理。
輾轉相除法最早出現在歐幾里得的《幾何原本》中(大約公元前300年),所以它是現行的演算法中歷史最悠久的。這個演算法原先只用來處理自然數和幾何長度(相當於正實數),但在19世紀,輾轉相除法被推廣至其他類型的數學物件,如高斯整數和一元多項式。由此,引申出歐幾里得整環等等的一些現代抽象代數概念。後來,輾轉相除法又擴充至其他數學領域,如紐結理論和多元多項式。
輾轉相除法有很多應用,它甚至可以用來生成全世界不同文化中的傳統音樂節奏。[1]在現代密碼學方面,它是RSA演算法(一種在電子商務中廣泛使用的公鑰加密演算法)的重要部分。它還被用來解丟番圖方程式,比如尋找滿足中國剩餘定理的數,或者求有限體中元素的逆。輾轉相除法還可以用來構造連分數,在史特姆定理和一些整數分解演算法中也有應用。輾轉相除法是現代數論中的基本工具。
輾轉相除法處理大數時非常高效,如果用除法而不是減法實現,它需要的步驟不會超過較小數的位數(十進制下)的五倍。拉梅於1844年證明了這點,同時這也標誌著計算複雜性理論的開端。
歐幾里得的輾轉相除法計算的是兩個自然數和的最大公因數,意思是能夠同時整除和的自然數中最大的一個。兩個數的最大公因數通常寫成,或者簡寫成[2],但是第二種寫法也被使用在其他數學概念,如二維向量的坐標。
如果,則稱和互質。[3]a和b是否互質和它們是否質數無關。[4]如,6和35都不是質數,因為它們都可以分解為多於一個質因數的乘積:6 = 2 × 3,35 = 5 × 7。但是,6和35互質,因為除了1以外沒有自然數同時整除6和35。
令。由於和都是的整數倍,所以可以寫成,並且不存在更大的整數使等式成立。為了使儘可能大,就要使和中所有公因數都提取出來歸入中,所以自然數和一定互質,並且和的最大公因數可以被和的所有其他公因數整除。[5]
我們可以用右圖來解釋最大公因數的概念:[6]設一個長方形的邊長為和。因為和的任何公因數都可以整除和,所以長方形的邊都可以等分為長度為的線段,也就是長方形可以被邊長為的正方形正好填滿。而最大公因數是所有可能的中最大的一個。例如,一個24 × 60的長方形區域可以分成1 × 1、2 × 2、3 × 3、6 × 6或12 × 12的正方形網格。也就是說,12是24和60的最大公因數。
和的最大公因數是兩數共有的質因數的乘積。[7]例如,462可以分解成2 × 3 × 7 × 11;1071可以分解成3 × 3 × 7 × 17。462和1071的最大公因數等於它們共有的質因數的乘積3 × 7 = 21。如果兩數沒有公共的質因數,那麼它們的最大公因數是1,也即這兩個數互質。輾轉相除法的優點就在於它能以有系統的方式求出兩數的最大公因數,而無需分別對它們作因式分解。[8][9]大數的質因數分解被認為是一個困難的問題,即使是現代的電腦也非常難於處理,所以許多加密系統的原理都是建基於此。[10]
在數學中,尤其是抽象代數的環論中,最大公因數有一個更加巧妙的定義:[11]和的最大公因數是[11]和的線性和中的最小正整數,即所有形如(其中和是整數)的數中的最小正整數。可以證明,所有都是的整數倍(,其中是整數)。用現代數學語言來說,和生成的理想即是由生成的主理想。最大公因數的這個定義和其他定義的等價性將在下面描述。
三個數的最大公因數的定義和兩個數的相同,即是它們共有的質因數的積[12],它們或者也可以按下式計算[13]:
所以,歐幾里得的輾轉相除法實際可以計算任意多整數的最大公因數。
下文的論證會用到三種相關的數學方法,分別是數學歸納法、遞迴和無窮遞降。數學歸納法[14]經常用來證明某個定理對所有自然數成立:[15]首先證明定理對一個特定的數成立(通常是1);然後證明如果定理對自然數成立的話,那麼它對自然數成立。這樣,便可證明定理對所有大於的自然數也成立。遞迴[16]是將相關的陣列成一個數列(),[17]當中除初始項外,其中每一項都用前一項或前幾項表示。如費氏數列就是遞迴的,每一項都等於()。輾轉相除法中的一些等式也是遞迴的。最後,無窮遞降[18]是用方程式的一個自然數解匯出比它小的自然數解。[19]但是,這種轉化不能永遠進行下去,因為只有有限個小於原來的自然數解的自然數。所以,要麼方程式無解,不然在有限步內必然能得出最小的自然數解。在下文會用到此法來證明輾轉相除法一定會在有限步內結束。
輾轉相除法是一種遞迴演算法,每一步計算的輸出值就是下一步計算時的輸入值。[20]設表示步驟數(從0開始計數),演算法的計算過程如下。
每一步的輸入是都是前兩次計算的非負餘數和。因為每一步計算出的餘數都在不斷減小,所以,小於。在第步中,演算法計算出滿足以下等式的商和餘數:
其中。也就是要不斷減去直到比小。
為求簡明,以下只說明如何求兩個非負整數和的最大公約數(負數的情況是簡單的)。在第一步計算時(),設和分別等於和,第2步(此時)時計算(即)和(第一步計算產生的餘數)相除產生的商和餘數,以此類推。整個演算法可以用如下等式表示:
如果有,演算法的第一步實際上會把兩個數字交換,因為這時除以所得的商會等於0,餘數則等於。然後,演算法的第二步便是把除以,再計算所得之商和餘數。所以,對於總有,即運算的每一步中得出的餘數一定小於上一步計算的餘數。
由於每一步的餘數都在減小並且不為負數,必然存在第步時等於0,使演算法終止[21],就是和的最大公因數。其中不可能無窮大,因為在和0之間只有有限個自然數。
輾轉相除法的正確性可以分成兩步來證明。[20]在第一步,我們會證明演算法的最終結果同時整除和。因為它是一個公因數,所以必然小於或者等於最大公因數。在第二步,我們證明能整除。所以一定小於或等於。兩個不等式只在時同時成立。
具體證明如下:
例如,計算和的最大公因數的過程如下:從1071中不斷減去462直到小於462(可以減2次,即商),餘數是147:
然後從462中不斷減去147直到小於147(可以減3次,即),餘數是21:
再從147中不斷減去21直到小於21(可以減7次,即),沒有餘數:
此時,餘數是0,所以1071和462的最大公因數是21,這和用質因數分解得出的結果相同(見上文)用表格表示如下:
步驟數 | 算式 | 商和餘數 |
---|---|---|
0 | 、 | |
1 | 、 | |
2 | 、(演算法終止) |
輾轉相除法的計算過程可以用圖形演示。[24]假設我們要在的矩形地面上鋪正方形瓷磚,並且正好鋪滿,其中大於。我們先嘗試用的瓷磚,但是留下了的部分,其中。我們接著嘗試用的正方形瓷磚鋪,又留下了的部分,然後再使用的正方形鋪……直到全部鋪滿為止,即到某步時正方形剛好覆蓋剩餘的面積為止。此時用到的最小的正方形的邊長就是原來矩形的兩條邊長的最大公因數。在圖中,最小的正方形面積是21×21(紅色),而原先的矩形(綠色)邊長是1071×462,所以21是1071和462的最大公因數。
在每個步驟中,輾轉相除法都需要計算兩個數和的商和餘數:
其中。除法的演算法保證這樣的商和餘數總是存在。自然數的除法演算法還指出這樣的商和餘數是惟一的,但這對輾轉相除法而言並非必要。[25]
在歐幾里得最初的描述中,商和餘數是通過連續的減法來計算的,即從中不斷減去直到小於。一個更高效的做法是使用整數除法和模除來計算商和餘數:
function gcd(a, b) while b ≠ 0 t ← b b ← a mod b a ← t return a
C++版本:
int gcd(int m, int n) {
int t = 1;
while(t != 0) {
t = m % n;
m = n;
n = t;
}
return m;
}
Rust版本:
fn gcd(x: isize, y: isize) -> Option<isize> {
match (x,y) {
(0, 0) => None,
(a, 0) => Some(a.abs()),
(mut a, mut b) => {
while b != 0 {
let t = b;
b = a % b;
a = t;
}
Some(a.abs())
},
}
}
Python 3版本:
def gcd(a, b):
while b != 0:
t = a % b
a = b
b = t
return a
在第次迴圈開始時,變數的值是前一次運算的餘數,變數的值是再前一次運算的餘數。步驟的作用等同於遞迴式。變數的功能是在下一個餘數計算過程中臨時性地儲存的值。在一次迴圈結束時,變數的值是前一次運算的餘數,變數的值是再前一次運算的餘數。
在歐幾里得定義的減法版本,取餘運算被減法替換。[27]
function gcd(a, b) if a = 0 return b while b ≠ 0 if a > b a ← a − b else b ← b − a return a
變數和的值分別是前兩次的餘數和。假定第次迴圈開始時大於,那麼等於,因為。在迴圈過程中,重複減去直到比小,此時就是下一個餘數;然後重複減去直到比小,此時就是下一個餘數;重複執行直到。
function gcd(a, b) if b = 0 return a else return gcd(b, a mod b)
C++遞迴版本如下:
int gcd(int n,int m)
{
return m == 0 ? n : gcd(m, n % m);
}
Rust遞迴版本:
fn gcd(x: isize, y: isize) -> Option<isize> {
match (x,y) {
(0, 0) => None,
(a, 0) => Some(a.abs()),
_ => gcd(y, x % y),
}
}
Java版本:
public class MethodOfSuccessiveDivision {
public static void main(String[] args) {
System.out.println(gcd(1071, 462));
}
public static int gcd(int a, int b){
if(b == 0){
return a;
}else{
return gcd(b, a % b );
}
}
}
Python 3版本:
def gcd(a, b):
return a if b == 0 else gcd(b, a % b)
例如的計算過程是:函式的第一次呼叫計算;下一次呼叫計算,在接下來是。
在另一個版本的演算法中,每一步還要把取餘運算時計算出的商增加一後再重新計算餘數(此時計算出的餘數應該是負的),然後取兩個餘數的絕對值較小的數作為下一步運算時使用的餘數。[29][30]取餘運算後,設是計算出的餘數(此時為正),是計算出的商:
即假設。然後使用以下式子計算出一個負的餘數:
如果,那麼用替換進行下一次運算。如利奧波德·克羅內克所指出的,這個版本需要的運算步驟是歐幾里得演算法的所有版本中最少的。[29][30]
輾轉相除法是目前仍然在使用的歷史最悠久的演算法之一。[31]它首次出現於《幾何原本》(卷7命題1–2、卷10命題2–3)(大約公元前300年)。在卷7中用於整數,在卷10中用於線段的長度(以現代的觀點看,線段的長度可視為正實數,也就是說輾轉相除法實際可用於實數上,但是當時未有實數的概念)。卷10中出現的演算法是幾何的,兩段線段a和b的最大公因數是a和b的公度中的最大值。
這個演算法可能並非歐幾里得發明,因為他也有將先前其他數學家的一些成果編進他的《幾何原本》。[32][33]數學家、歷史學家范德瓦爾登認為卷7的內容可能來自畢達哥拉斯學院出身的數學家寫的關於數論的教科書。[34]輾轉相除法在當時很可能已為尤得塞斯(大約公元前375年)所知 [31][35],甚至可能更早之前就已經存在[36][37],因為歐幾里得和亞里斯多德的著作中都出現了ἀνθυφαίρεσις一詞(意為「輾轉相減」)。[38]
幾個世紀之後,輾轉相除法又分別被中國人和印度人獨立發現,[39]主要用來解天文學中用到的丟番圖方程式以及制定準確的曆法。5世紀末,印度數學家、天文學家阿里亞哈塔曾稱輾轉相除法為「粉碎機」,這可能是因為它在解丟番圖方程式時很有效[40]。[41]在中國,《九章算術》中提到了一種類似輾轉相減法的「更相減損術」[42]。《孫子算經》中則出現了中國剩餘定理的一個特例[43],但是直到1247年秦九韶才於其《數學九章》中解答了該定理的一般情況,當中用到了他發明的大衍求一術。此法的其中一部分實際上便是輾轉相除的原理,秦九韶在書中對此有明確表述。[44]在歐洲,輾轉相除法首次出現於克勞德·巴希特的著作《愉悅討喜的問題》(Problèmes plaisants et délectables)的第二版[41]在歐洲,輾轉相除法被用於丟番圖方程式和構建連分數。後來,英國數學家桑德森在其著作中收編了擴充歐幾里得演算法,作為一個有效計算連分數的方法。他將此法的來源歸名於羅傑·科茨。[45]
19世紀,輾轉相除法促成了新數系的建立,如高斯整數和艾森斯坦整數。1815年,高斯用輾轉相除法證明高斯整數的分解是惟一的,儘管他的研究到了1832年才首度發表。[46]高斯在他的《算數研究》(出版於1801年)中實際上也有援引這個演算法,但僅是以連分數方法的形式敘述。[39]約翰·狄利克雷是第一個將輾轉相除法作為數論的基礎的數學家。[來源請求]狄利克雷提出,數論中的很多結論,如分解的惟一性,在任何使輾轉相除法適用的數系中均有效。[47]狄利克雷的數論講義後來經理查·戴德金編輯和推廣,戴德金也有以輾轉相除法來研究代數整數。比如,他是第一個用高斯整數的分解惟一性證明費馬平方和定理的數學家。[48]戴德金還率先定義了歐幾里得整環的概念。19世紀末,戴德金所定義的理想概念使得數論的重心不必建基於輾轉相除法,從而促進了理論的發展。[49]
「歐幾里得演算法是所有演算法的鼻祖,因為它是現存最古老的非凡演算法。」 |
——高德納,《電腦程式設計藝術,第二卷:半數值演算法》,第二版 (1981), p. 318. |
輾轉相除法的其他應用發展於19世紀。1829年,史特姆將輾轉相除法用於史特姆序列(用於確定多項式的不同實根的個數的方法)。[50]
輾轉相除法是歷史上第一個整數關係演算法,即尋找兩個可通約實數的整數關係的演算法。近年來,出現了一些新穎的整數關係演算法,如埃拉曼·弗格森和福爾卡德於1979年發表的弗格森-福爾卡德演算法(Ferguson–Forcade algorithm) [51]、以及與它相關的LLL演算法、HJLS演算法以及PSLQ演算法。[52][53]
1969年,科爾(Cole)和戴維(Davie)基於輾轉相除法創造了一種二人遊戲,叫做「歐幾里得遊戲」。[54]這個遊戲有最佳策略。[55]遊戲開始於兩列分別為a和b個棋子組成的序列,玩家輪流從較長一列中取走較短一列棋子數量的m倍的棋子。如果兩列棋子p和q分別由x和y個棋子組成,其中x大於y,那麼玩家可以將序列p的棋子數量減少為自然數x − my。最後率先將一列棋子清空的玩家勝出。[56][57]
貝祖等式說明,兩個數和的最大公因數可以表示為和的線性和。[58]也就是說,存在整數和使。[59][60]
整數和可以從輾轉相除法算出的商計算出。[61] 從輾轉相除法的最後一步開始,可以表示成前一步的商和前兩步的餘數和:
而前兩步的餘數又分別可以表示成它們前兩步的餘數和商:
將這兩行式子先後代入第一個式子,可以將表示成和的線性和。重複進行迭代直到出現和:
貝祖等式提供了另一種定義和的最大公因數的方法。[11]考慮形如(其中和是整數)的數的集合。因為和都可以被整除,所以這個集合中的所有元素都可以被整除。也就是說這個集合中的數都可以表示成的倍數,或者和的其他公因數的倍數。但是,只有最大公因數才是這個集合的元素。根據貝祖等式,有。換言之,當、時得出。任何其他的公因數都不是這個集合的元素,因為它們都不能被比它們大的整除。相反地,的任何倍數都屬於這個集合,只要令、,便有:
所以,形如的數的集合等於的整數倍的集合。也就是說,任意兩個數的線性和的集合等同於它們最大公因數的整數倍的集合。和的最大公因數叫做和的理想的生成元素。這個最大公因數的定義匯出了兩個現代抽象代數的概念:主理想(由單個元素生成的理想)以及主理想整環(其每一理想都是主理想的整環)。
這個結果可以解決某些實際問題。[62]例如,考慮兩個容積分別為和的量杯,其中和為正整數。通過加入或倒去倍第一個量杯的體積以及倍第二個量杯的體積的液體,任何體積為的液體都可以被量出(只要為正數)。根據貝祖等式,凡是可以被量出的液體,其體積一定是和的最大公因數的倍數。
貝祖等式的整數s和t可以通過擴充歐幾里得演算法算出。這個擴充演算法在原有輾轉相除法的基礎上增加了兩個遞迴等式:[63]
演算法開始時:
加上這兩個遞迴式後,當演算法終止於,貝祖等式的整數和分別由和給出。
這個演算法的正確性可以用數學歸納法來證明。假設遞迴至第步是正確的,也就是假設:
在小於時皆成立。則第步運算得出以下等式:
因為和被假定是正確的,所以可以用和表示:
整理後得到第步的結果,和我們期望值得到的結果一致:
可以寫作2×2的商矩陣乘以一個2維餘數向量:
令表示所有商矩陣的乘積:
這使輾轉相除法化簡為:
如要用和的線性和表示,可將等式兩邊同時乘以矩陣的逆矩陣。[64][65]的行列式等於,因為它等於商矩陣的行列式的乘積,而每一個的行列式都是−1。因為的行列式不為零,最終的餘數向量可以利用的逆矩陣解出:
由上式可以得出。
貝祖等式中的兩個整數分別是、。矩陣法的效率可前文描述的輾轉相除法的遞迴演算法是相同的,每一步都有兩次乘法和兩次加法。
貝祖等式對輾轉相除法的很多應用都很重要,如證明自然數的唯一分解性質[66]假設數字L可以寫成兩個因數和的乘積,即。如果另一個數與互質的數也能整除,那麼必須整除,證明如下:如果和的最大公因數是1,則根據貝祖等式存在和使
兩邊都乘以:
因為整除等式右邊,所以也應整除等式左邊的。這個結果叫做歐幾里得引理。[67]如果一個質數整除那麼它至少整除的一個因數。如果一個數互質於數列 中的每一個數,則w也一定互質於它們的乘積。[67]
歐幾里得引理足以證明每一個自然數的質數分解是惟一的。[68]我們用反證法來證明,假設可以分別分解成個質數和個質數,即:
根據假設,每個質數都能整除,因此它必須能夠整除某個;因為也是一個質數,所以。同理,對於每一個都存在一個與它相等。所以兩種分解除了順序不同以外是完全相同的。整數分解的惟一性在數學證明中有很多應用,下文將會提到。
丟番圖方程式是以亞歷山大數學家丟番圖的名字命名的一類方程式,它的解被限制在整數範圍。[69]關於整數和的線性丟番圖方程式形如:[70]
其中、、是已知整數。這個方程式可以寫成關於的同餘式:
令為和的最大公因數,、都能被整除,故能夠被整除。所以,一定能夠被整除,不然方程式就無解。方程式兩邊若同時除以 ,方程式就變成了貝祖等式:
其中和可以用擴充歐幾里得演算法求解。[71]所以這個丟番圖方程式的一個解即是:
母體而言,丟番圖方程式如果有解,就一定有無數個解。[72]只需要考慮兩個解 和:
或者可以寫成:
所以相鄰兩個解的之間的差是,之間的差是。這樣,所有的解都可以表示成:
當取遍所有整數時,方程式所有的解都可以從計算出來。如果限制為正整數解 (, ) 的話,那麼解的數量就可能是有限的。有時候,這種對解的限制使丟番圖方程式在未知數個數比方程式數更多的情況下仍然能有唯一解[73],而在允許實數解的線性方程組中,這種情況是不可能的。
有限體是一個支援四種運算的數集。這四種運算也通稱為加法、減法、乘法、除法,跟一般的四則運算有相同的性質,如交換律、結合律和分配律。舉例來說,使用同餘可以讓13個數字的集合 構成一個有限體。在這個域中,任何數學運算(加減乘除)都歸約成13的模,例如 。對於任意質數,都可以定義這種有限體;使用更複雜的方法,也可以對質數的次方定義這樣的有限體。有限體也叫做伽羅瓦域,其縮寫為 或。
在這樣一個有個數的域中,任何非零元素都存在惟一乘法逆 使。這可以通過解同餘式得出,[74]或者也可以解與之等價的丟番圖方程式[75]
這個方程式可用擴充歐幾里得演算法解出(參見上文)。在RSA演算法中,尋找乘法逆是非常重要的一步,它決定了使用哪個數來解密資訊。[76]雖然RSA演算法不使用域而是使用環,擴充歐幾里得演算法仍然可以用來求乘法逆。歐幾里得演算法也被應用於糾錯碼,例如,它可以代替伯利坎普-梅西演算法解基於有限體的BCH碼和里德-所羅門碼。[77]
輾轉相除法也可以用來解線性丟番圖方程組。[78]如在中國剩餘定理中,整數可以表示成被個互質的數除留下的餘數:[79]
為了從的個餘數中確定的值,我們將這些式子組合成單個線性丟番圖方程式,其中模數是所有模數的乘積,然後定義如下:
也就是,是除了以外所有模數的乘積。接著是關鍵的一步,尋找個數使:
有了這些數之後,整數可以用下式從餘數中解出:
因為是的乘法逆,所以可以使用擴充歐幾里得演算法求出(見上一節)。
輾轉相除法和連分數有著緊密的關係。[80]計算連分數的過程如下:
其中每個式子的右邊最後一項都等於下一個式子的左邊項的倒數。所以前兩個式子可以組合成:
第三個式子可以代入分母中的:
每一步中,最後一項都可以用下一個式子代換,直至最後一個式子,結果是:
在上文的例子中計算了,其中商分別是2、3、7,所以分數 可以寫成如下連分數形式:
計算最大公因數是很多整數分解演算法的重要步驟[81],如Pollard's rho演算法[82]、Shor演算法[83]、Dixon分解法[84]以及Lenstra橢圓曲線分解[85]。用輾轉相除法算最大公因數效率非常高。而連分數分解法由於用到了連分數,所以也需要使用輾轉相除法[86]。
輾轉相除法的計算效率已經被徹底研究過了。[87]一個演算法的效率可以用計算所需步數乘以每步計算的開銷表示。加百利·拉梅於1884年指出[88],用輾轉相除法計算兩個數的最大公因數所需的步數不會超過其中較小數十進制下的位數的5倍。[89][90]因為每一步的計算開銷通常也是數量級的,所以輾轉相除法的複雜度是。
計算兩個自然數和的最大公因數所需的步數可以表示為。[91]如果和的最大公因數是,,,而和是兩個互質整數,那麼:
這可以通過在輾轉相除法的計算過程中的每一步都除以來證明。[92]同樣,當和同時乘以時,計算步數不變:。所以,對於數值上相近的數,如和,計算步數可能相差很大。
根據輾轉相除法的遞迴性質可以得出另一個公式:
其中,根據定義有。[91]
假設用輾轉相除法求自然數和()的最大公因數需要步,那麼滿足這一條件的和的最小值分別是斐波那契數和。[93]這可以用數學歸納法證明。[94]假設,整除,滿足這一條件的和最小是、,正是和。現在假設這一規律對有效。一個需要步的演算法的第一步是,第二步是。因為演算法是遞迴的,它需要步才能算出,其中和的最小值是和。所以的最小值是當的時候,此時 。1844年,加百利·拉梅發現這個證明標誌著計算複雜性理論的誕生。[95]這也是費氏數列的第一個實際應用。[93]
這個結果也證明了輾轉相除法的運算步驟不會超過較小數十進制下的位數的五倍。[96]因為如果演算法需要步,那麼一定大於或等於,也就是一定大於或等於,其中是黃金分割比。因為,所以。因為,,所以。所以,輾轉相除法不會進行超過O(h)次除法,其中是較小數在十進制下的位數。
輾轉相除法的平均步驟數有三種不同的定義。第一種定義是計算已知自然數和從0到範圍內隨機選取的自然數的最大公因數所需的時間:[91]
但是因為在連續整數間變化非常劇烈,所以的值也會顯得很雜亂。[97]
為了解決這個問題,第二種定義規定只要取遍其中所有和互質的數即可:
在小於的數中,有個數與互質,其中是歐拉函式。在這個定義中,的函式值增長得平穩很多。[98][99]
誤差項的增長率為,其中是無窮小量。公式中的常數等於:
其中是歐拉-馬歇羅尼常數,是黎曼ζ函式的導數。[100][101]公式最左邊的由兩個獨立的方法確定。[102][103]
因為第一種定義可以通過用第二種定義的求和來完成:[104]
所以也可以由以下公式近似:[105]
第三種定義定義為從1到間隨機選取和(均勻分布)時計算它們的最大公因數所需的平均步驟數:[105]
將的近似公式代入,得到的近似:[107]
在輾轉相除法的每一步中,商和餘數都通過和求出:
所以每一步的計算開銷主要與計算商的演算法有關,因為餘數可以很迅速地從、和計算出來:
而計算一個位整數的除法的演算法複雜度是O(h(ℓ+1)),其中ℓ是商的位數。[108]
作為對比,輾轉相除法原先的版本使用的是減法,因此效率要慢很多。進行一次除法等同於進行次減法(其中是商)。如果和的比很大,計算出的商也很大,也就需要進行很多次減法。但在另一方面,計算出來的商在大多數情況下都是非常小的,除法中得出一個確定的商的機率大約是。其中。[109]比如,商是1、2、3、4的可能性分別是大約41.5%、17.0%、9.3%、5.9%。因為電腦計算減法要快於除法,特別是對於很大的數字[110],所以減法版本的輾轉相除法的效能可以比得上除法版本。[111]這也被運用於二進制最大公因數演算法。[112]
綜合考慮演算法需要的步數和每一步的計算開銷,輾轉相除法隨兩個數字和的平均位數成平方級的速度增長()。設表示計算過程中的餘數的位數,因為演算法的步數隨線性增長,所以演算法的運算時間為:
因為輾轉相除法的高效率,它在實踐中被廣泛使用。作為對比,本段中介紹以下輾轉相除法以外的其他最大公因數演算法的效率。
計算兩數和的最大公因數有一個效率很慢的演算法:將除以從2到之間的每一個整數以計算出它們所有的公因數,其中最大的一個即是最大公因數。在這個演算法中,步驟數隨線性增長,也就是隨輸入數字的位數呈指數級增長。另一個很低效的演算法是計算出兩個數的所有質因數(見上文),最大公因數等於所有公共質因數的乘積。[7]但是整數分解演算法效率極低,很多現代的加密系統甚至依靠這種低效率來防止資料被破解。[10]
除了輾轉相除法之外,也有一些高效的演算法存在,如二進制最大公因數演算法將除法操作替換成了二進制的移位,以進一步提高用電腦運算時的效率。[113][114]但是,這種改變並沒有降低演算法的複雜度(仍然是O(h²)),雖然它在電腦上確實比輾轉相除法快些。[115]也可以通過只檢視和的前幾位數來進一步提高效率,不過效果並不明顯。[116][117]二進制版的演算法還可以擴充到其它進制[118],效率最多可以提升五倍。[119]
對於超過25,000位數的大數,有一種改進使演算法複雜度降低至平方級以下[120],如Schönhage[121][122]、Stehlé、Zimmermann等人提出的演算法。[123]這些演算法利用2×2的矩陣(見上文)。這些亞平方級的演算法複雜度通常是。[115][124]
如上文所述,輾轉相除法最早用來尋找兩自然數的最大公因數,但其實它也可以被推廣至實數,甚至是多項式、二次整數和赫爾維茨四元數。在這些數系中,輾轉相除法甚至被用來證明一個重要特性:惟一分解,即這些數系中的數能夠被惟一地分解成不可約元素(質數在這些數系的對應物)。惟一分解是數論中很多證明的基礎。
輾轉相除法可以被應用至實數,如歐幾里得在幾何原本第10卷中所說的那樣。演算法的目的是計算出實數,使已知實數和是它的整數倍:、,其中和是整數。[32]這也就找到了和的整數關係,即找到整數和使。歐幾里得使用輾轉相除法來處理不可通約的長度。[125][126]
實數的輾轉相除法和整數的演算法有兩個區別。第一,餘數是實數,雖然商仍然是整數。第二,演算法不能保證在有限步內結束。如果能在有限步內結束,那麼分數是一個有理數,即:
於是我們可以寫出它的有限連分數形式:。如果演算法無法結束,那麼是無理數,可以寫成無限的連分數形式:。無限連分數的一個例子是:黃金分割比和2的主平方根:。通常,演算法能夠結束的可能性是很低的,因為對於實數和,幾乎所有都是無理數。
如果演算法不結束,也可以在第步時終止計算,得到近似連分數。終止時的越大,則近似越準確。連分數的分子和分母互質並滿足下式:
其中遞迴的初始值是, 。是在分母是的數中最精確的有理數近似值:
只含有一個變數的多項式可以和整數一樣進行加法、乘法和分解為不可約多項式(也就是多項式中的「質數」)。兩個多項式和的最大公因數定義為它們分解之後共有的不可約因式的乘積,這可以用輾轉相除法進行計算。[127]對於多項式的演算法和整數的演算法很相似,在每個步驟,計算出滿足以下遞迴式的商多項式和餘數多項式:
其中,。所選擇的商式必須能使的首項係數和的相等,這樣才能保證每個餘數的次數小於前一個餘數()。因為非零多項式的次數是非負整數,並且在每一步都減小,所以輾轉相除法的計算一定能在有限步內結束。最後一個非零餘數即是兩個多項式和的最大公因數。[128]
例如,有如下兩個四次多項式,都可以分解成兩個二次多項式的乘積:
和
除以得到餘數:
在下一步中,除以得到。最終,除以得到的餘數為0,所以是和的最大公因數,這和它們因式分解的結果相符合。
上文所述的很多應用也適用於多項式。[129]輾轉相除法可以解多項式的線性丟番圖方程式和中國剩餘定理,也可以用來定義多項式的連分數展開式。
多項式的輾轉相除法也有其他應用,如史特姆定理,一個用於計算多項式在給定區間內的實根個數的方法。這被應用於其他領域,如控制論的勞斯-赫爾維茨穩定性判據。
最後,多項式的係數不必局限於整數、實數、甚至複數。這些係數可以是其他域中的元素,如上文所述的有限體。從輾轉相除法得出的結論也可以直接推廣至這類多項式。[127]
高斯整數是滿足的複數,其中和是普通整數,是虛數單位(-1的平方根)。[130]通過在高斯整數中定義輾轉相除法,根據上文貝祖等式可以證明高斯整數的惟一分解。[46]高斯整數的惟一分解性質在很多應用中都很重要,如計算畢氏三元數或者證明費馬平方和定理。[130]輾轉相除法用於這些應用很方便,但並非必不可少,一些定理也可以由其他方式證明。
對於兩個高斯整數和的輾轉相除法和普通整數只有兩個區別。像整數一樣,演算法的第步計算出商和餘數:
其中,,每個餘數都嚴格地小於前一個餘數,。第一個區別即是:商和餘數都是高斯整數,也就是複數,所以商是透過對實際比例(如複數/)的實部和虛部取最近似整數來找出的。第二個區別就是需要定義複數比較大小的方法。所以我們定義一個範數函式,以將高斯整數轉換成普通整數來比較大小。在每個步驟中,餘數的範數必須小於前一個餘數的範數。因為範數是非負整數並且在每一步都減小,所以輾轉相除法在有限步內一定能結束。最後一個非零餘數即是和的最大公因數,即能同時整除和的整數中範數最大的一個。若把乘以或的所得結果考慮在內,那麼可以說和的最大公因數是唯一的。
很多其他應用如線性丟番圖方程式、中國剩餘定理都適用於高斯整數,高斯整數的連分數也可以用輾轉相除法定義。
如果一個支援兩種二元運算(+ 和 ·)的元素的集合形成一個交換環R並且可以使用輾轉相除法求最大公因數,那麼這個集合叫做歐幾里得整環。[131][132]這兩個二元運算不必是平常算數中的加法和乘法,它們可以是更廣泛的概念,如群或么半群中的運算。但是這些運算仍然需要遵守交換律、結合律、分配律。
推廣之後的輾轉相除法需要一個歐幾里得函式,即一個將對映到非負整數集合的函式,使得對於中非零元素和,中存在和滿足,。例如上文中用於高斯整數的範數函式。這個函式可以是數的絕對值或模,也可以是多項式的次數,只要輾轉相除法計算過程中它的值不斷減小就行,這樣演算法便能在有限步內結束。這非常依賴於非負整數的良序性,即每個非空的非負整數集合都有一個最小數。
任何歐幾里得整環都滿足算數基本定理:歐幾里得整環中的數可以惟一分解。所以任何歐幾里得整環都是惟一分解整環,但反之不然。歐幾里得整環是GCD整環(任意兩元素都存在最大公因數的整環)的子類。也就是說,在某些整環中,兩元素存在最大公因數但卻不能用輾轉相除法計算。歐幾里得整環都是主理想環,即其中每一個理想都是主理想,但並不是每個主理想環都是歐幾里得整環。
歐幾里得整環的惟一分解性質在很多場合都非常有用。例如,高斯整數的惟一分解性質可以方便地匯出畢氏三元數的公式,或者證明費馬平方和定理。[130]惟一分解性質也是加百利·拉梅於1847年基於約瑟夫·萊歐維爾的建議發表的證明費馬最後定理的嘗試中的關鍵部分。[133]拉梅的嘗試需要形如的數的惟一分解性質,其中和是整數,是1的次方根,即。雖然這對於某些成立(如時的艾森斯坦整數),但在其他情況下並非總是正確的。惟一分解性質在分圓體的失效使恩斯特·庫默爾發明了理想數的概念,隨後理查·戴德金創造了理想的概念。[來源請求]
二次整數環對於解釋歐幾里得整環很有幫助。二次整數是高斯整數的推廣,高斯整數中的虛數單位i被替換成一個複數ω。二次整數的形式是,其中和是整數,有兩種形式,取決於參數。如果不等於四的倍數加一,那麼:
如果等於四的倍數加一,那麼:
如果二次整數環有像上文用來比較高斯整數的那樣的範數函式,那麼它就是規範歐幾里德整環。只有當 −11, −7, −3, −2, −1, 2, 3, 5, 6, 7, 11, 13, 17, 19, 21, 29, 33, 37, 41, 57或73時,二次整數環才是規範歐幾里德整環[25]。 −1和−3時的二次整數分別叫作高斯整數和艾森斯坦整數。
但如果範數函式可以是任何歐幾里得函式,那麼使二次整數環是歐幾里得整環的的可能值到目前為止還不確定。[134]是歐幾里得整環但不是規範歐幾里德整環的第一個例子()發表於1994年[134]。溫伯格於1973年證明,在廣義黎曼猜想成立的前提下,時的二次整數環是歐幾里得整環,若且唯若它是一個主理想環。[135]
輾轉相除法也可以應用至非交換環,如赫爾維茨四元數。[136]令和表示這樣一個環中的兩個元素。他們有右公因數如果, (和是環中的元素)。同樣,他們有左公因數如果, (和是環中的元素)。因為乘法不符合交換律,也就有兩個版本的輾轉相除法,一個計算右公因數,一個計算左公因數。例如對於右公因數,輾轉相除法求最大公因數的第一步可以寫成:
其中是商,是餘數。對於左公因數,第一步過程是:
不管是哪一種,這個過程都會重複到最大左公因數或者最大右公因數計算出,像在歐幾里得整環中一樣,的「大小」一定小於,並且對於只有有限種的可能大小,這樣才能保證演算法能夠結束。
由輾轉相除法得出的大多數結果都適用於非交換環。例如,貝祖等式表明最大右公因數可以表示成α的倍數和β的倍數的和,即,存在和使:
對於最大左公因數,等式如下:
貝祖等式可以用來解非交換環的丟番圖方程式。
輾轉相除法有三個性質保證它不會永遠進行下去。第一,它可以寫成一系列遞迴式:
其中每一個餘數都比前一個餘數小,。第二,餘數的大小有嚴格下限,如。第三,小於的數的數量是有限的。輾轉相除法推廣至其他數學結構,如纏結[138]和超限序數[139]時仍保持這種性質。
輾轉相除法的一個重要推廣是代數幾何中格羅布納基的概念。像前文所述,和的最大公因數是它們的理想的生成元素。也就是說,對任何整數和,存在另一個整數使:
雖然這對一元多項式也成立,但是對多元多項式就不成立了。[140]在多元多項式的情況下,生成元素的有限集合可以定義如下:
其中、和是多元多項式。[141]任何這樣的多元多項式可以表示成生成多項式的和加上惟一的餘數多項式, 通常叫做多項式的一般形式。
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.