什麼是歐幾里得算法
歐幾里得算法 (Euclidean algorithm),又稱輾轉相除法,是一種用於高效計算兩個自然數(或整數)最大公因數(Greatest Common Divisor, GCD)的算法。大約在公元前300年,古希臘數學家歐幾里得在其數學著作《幾何原本》(Elements)第7卷中記載了該算法,它也被廣泛認為是「人類最古老的算法」之一。
求最大公因數最樸素的方法是將兩個數分別進行質因數分解,然後將相同的質因數相乘。但是,當數字變得非常龐大時,質因數分解本身的計算量會變得極其巨大,難以在現實時間內得出結果。相反,如果使用 歐幾里得算法 ,即使是長達數千位的巨大數字,也能以極快的速度計算出它們的最大公因數。
基本定理與原理
設兩個自然數 $a$ 和 $b$ ($a \ge b$)的最大公因數為 $\gcd(a, b)$。 歐幾里得算法基於以下簡單的定理:
$$ a = bq + r \implies \gcd(a, b) = \gcd(b, r) $$也就是說,它利用了這樣一個性質:「當 $a$ 除以 $b$ 的商數為 $q$ 、餘數為 $r$ 時, $a$ 和 $b$ 的最大公因數等於 $b$ 和 $r$ 的最大公因數。」
定理的證明
為什麼 $\gcd(a, b) = \gcd(b, r)$ 成立呢?讓我們簡單證明一下。
- 設 $d$ 為 $a$ 和 $b$ 的任意公因數。此時,可以表示為 $a = md, b = nd$ ($m, n$ 為整數)。
- 由 $a = bq + r$ 可得, $r = a - bq$。
- 將前面的式子代入,得到 $r = md - (nd)q = d(m - nq)$。
- 因為 $m - nq$ 是整數,所以 $d$ 也是 $r$ 的因數。因此, $a$ 和 $b$ 的公因數 $d$ 也是 $b$ 和 $r$ 的公因數。
- 反之,設 $e$ 為 $b$ 和 $r$ 的公因數,可以表示為 $b = k e, r = l e$。
- $a = bq + r = (k e)q + l e = e(kq + l)$,因此 $e$ 是 $a$ 的因數。所以, $b$ 和 $r$ 的公因數 $e$ 也是 $a$ 和 $b$ 的公因數。
- 因此, $\{a, b\}$ 的公因數集合與 $\{b, r\}$ 的公因數集合完全一致,它們的最大值(即最大公因數)也相等。 $\blacksquare$
算法流程圖
利用這一性質,歐幾里得算法通過不斷重複除法運算,直到餘數為 $0$ 為止。
flowchart TD
Start["開始: 輸入 a, b"] --> Check{"b == 0 ?"}
Check -- "Yes" --> End["GCD 為 a"]
Check -- "No" --> Calc["r = a % b"]
Calc --> Update["a = b, b = r"]
Update --> Check
具體計算範例
作為範例,讓我們求出 $a = 1071$ 和 $b = 1029$ 的最大公因數。
- $1071 \div 1029 = 1 \cdots 42$ (更新為 $a=1029, b=42$)
- $1029 \div 42 = 24 \cdots 21$ (更新為 $a=42, b=21$)
- $42 \div 21 = 2 \cdots 0$ (餘數為 $0$ ,結束計算)
最後作為除數留下的 $21$ ,就是 $1071$ 和 $1029$ 的最大公因數。
程式實作
Python實作
在Python中,可以使用遞迴函數或者 while 迴圈來實作。由於迴圈方法沒有函數呼叫的額外開銷,因此執行速度更快。
| |
C++實作
在C++17及更高版本中, <numeric> 標頭檔標準實作了 std::gcd ,但如果要自己編寫程式碼,可以參考以下方式:
| |
時間複雜度與拉梅定理
歐幾里得算法到底有多快呢?關於其計算複雜度,法國數學家加布里埃爾·拉梅在1844年證明的 拉梅定理 (Lamé’s theorem)非常著名。
拉梅定理 對兩個自然數 $a, b$ ($a > b$)應用歐幾里得算法時,除法的次數不超過 $b$ 在十進位下位數的 $5$ 倍。
由此可知,該算法的時間複雜度為 $O(\log(\min(a, b)))$。
最壞的情況(即除法次數最多的情況)發生在輸入費氏數列的相鄰兩項時。例如,在求 $F_{n+2}$ 和 $F_{n+1}$ 的最大公因數的過程中,商數始終為 $1$,並不斷向更小的費氏數過渡。
擴展歐幾里得算法
不僅能求出最大公因數,還能求出滿足以下裴蜀定理(Bézout’s identity)的整數 $x, y$ 的算法,被稱為 擴展歐幾里得算法 (Extended Euclidean algorithm)。
$$ ax + by = \gcd(a, b) $$擴展歐幾里得算法的實作
在遞迴呼叫返回的過程中,逆向推導出 $x, y$ 的係數。
| |
在現代社會中的應用(RSA加密等)
擴展歐幾里得算法不僅僅是一個數學難題,它還是支撐現代網際網路社會不可或缺的技術。 一個典型的例子就是 RSA加密 。在RSA加密的金鑰生成過程中,對於某個數 $e$ 和歐拉函數 $\phi(N)$ ,需要求解滿足 $e d \equiv 1 \pmod{\phi(N)}$ 的私鑰 $d$ (模反元素)。 因為它可以轉化為 $ed + k\phi(N) = 1$ 的形式,所以我們可以直接使用擴展歐幾里得算法以極快的速度計算出 $d$。
總結
儘管歐幾里得算法早在公元前就被發現,但由於其精簡的邏輯和極高的計算效率,它至今仍在支撐著現代計算機科學的根基。在學習算法時,這往往是我們最先接觸的主題之一,但其背後卻蘊含著豐富的數學之美與實用性。
