Iterative Method
程度★ 難度★★★
道生一,一生二,二生三,三生萬物。《老子》
Iterative Method
「疊代法」是把求得的數值,不斷重覆代入,再求得新數值的方法。
疊代法會有無窮無盡的情況,例如微積分所學的牛頓法,遇到曲線時,小數位數是越算越多。又例如以試除法建立質數,質數是越建越多。
寫程式時經常以迴圈來實作疊代法。因為迴圈事實上也可以用遞迴來完成,所以讀者也可以利用遞迴來實作,只不過我想大家沒必要這麼累。
範例:秦九韶演算法(Horner's Rule)
給定一個x後,一乘一加不斷更迭,求得多項式的值。完全不需要次方運算。
a * x^n + b * x^(n-1) + c * x^(n-2) + ... = ((((a * x) + b) * x) + c) * x) + ...
UVa 498 10268
範例:3n+1猜想(Collatz Conjecture)
至今尚未有人能證明其正確性。有趣的是,目前也尚未檢查出任何反例。
猜想的內容是這樣的:有一個整數,如果是偶數,就除以2;如果是奇數,就乘以3再加1。一個整數不斷這樣操作下去,最後一定會變成1。這個操作的過程就是一種疊代。
UVa 100 371 694
範例:牛頓法(Newton's Method)
一個經典的疊代法範例,微積分課程一定都有教過。牛頓法用來求連續函數的其中一個根。一開始先隨便設定一點,然後不斷利用斜率,疊代求出下一點。
Xn+1 = Xn - f(Xn) / f'(Xn)
範例:以試除法建立質數
從表面上來看是窮舉法,窮舉正整數一一試驗是否為質數,然後窮舉所有已知質數一一試除正整數,以找出正確的質數。
但是從另一個角度來看,利用已求得的質數,求出更多質數,其實就是疊代法。
延伸閱讀:數學歸納法(Mathematical Induction)
數學歸納法的第二步驟,就是證明可不可以疊代!第二步驟的證明過程中一定會用到疊代!
1. 先證明 n = 1 成立。(有時候不見得要從1開始。) 2. 假設 n = k 成立,證明 n = k+1 也會成立。 當 1. 2. 得證,就表示 n = 1 ... ∞ 全部都成立。
Recursive Method
程度★ 難度★★★
易有太極,是生兩儀。兩儀生四象,四象生八卦。《易傳》
Recursive Method
「遞迴法」是重複用相同手段來縮減問題範圍的方法。
遞迴法會有無窮無盡的情況,例如碎形是越分越細緻。
寫程式時主要以遞迴來實作。因為遞迴也可以用stack和迴圈來完成,所以讀者也可以利用迴圈來實作,只不過我想大家沒必要這麼累。
UVa 10994 10212 10471 10922
範例:碎形(Fractal)
碎形是一個經典的Recursive Method範例。
UVa 177
比較Iterative Method與Recursive Method
疊代法以確定的部分作為起始點,循序漸進推演,最後求得答案。
遞迴法找出一套縮小問題範疇的規律,以此規律不斷縮小問題,直到能釐清細節,找到確定的部份。
疊代法與遞迴法恰好顛倒:疊代法是針對已知,逐步累積,直至周全;遞迴法是針對未知,反覆拆解,直至精細。
範例:秦九韶演算法(Horner's Rule)
若疊代、遞迴是有窮有盡的時候,疊代、遞迴是一體兩面,同時存在。
a * x^2 + b * x^1 + c
Iterative Method:
{a} * x^2 + b * x^1 + c
{a, *x} * x^1 + b * x^1 + c
{a, *x, +b} * x^1 + c
{a, *x, +b, *x} + c
{a, *x, +b, *x, +c}
Recursive Method:
{a * x^2 + b * x^1 + c}
{a * x^2 + b * x^1}, +c
{a * x^1 + b}, *x, +c
{a * x^1}, +b, *x, +c
{a}, *x, +b, *x, +c
疊代法是不斷配x,擴增已知;遞迴法是不斷提x,減少未知。
雖然疊代法與遞迴法的推理方向是相反的,但是疊代法與遞迴法的計算方向是一樣的,兩者都是由小範圍算到大範圍,最後求得正確答案。
Iterative Method: a, *x, +b, *x, +c Recursive Method: a, *x, +b, *x, +c
Book Stacking Problem
程度★ 難度★★
Book Stacking Problem
原理是一本書上面所有書的平均重心,要落在這一本書上。【待補圖片】
Iterative Method
書本是一本一本疊起來的,採取Incremental Method的概念,我們嘗試一本一本依序推理。我們可以從最上面一本書開始推理,也可以從最下面一本書開始推理。
從最上面第一本書開始推理。最上面第一本書的重心,在書本正中央。接下來考慮上面兩本書,【待補文字】
從最下面的書開始推理,可以發現推理不出來。這表示疊代的方向只能從上而下,不能從下而上。
Recursive Method
【待補文字】
Stairs Climbing
程度★ 難度★★★
爬樓梯
這裡介紹一個知名的爬樓梯問題:眼前有五階樓梯,每次可踏上一階或踏上兩階,那麼爬完五階共有幾種踏法?例如(1,1,1,1,1)是其中一種踏法,(1,2,1,1)是另一種不同的踏法。
Iterative Method
我們先試著只爬少少的幾階樓梯,觀察一下踏法。
爬完一階的踏法很明顯的只有一種:(1)。
至於爬完兩階的踏法有兩種:(1,1)和(2)。
至於爬完三階的踏法:因為一次只能往上踏一階或兩階,所以只可能從第一階或從第二階踏上第三階。只要將(爬完一階的踏法,2),再綜合(爬完兩階的踏法,1),就是爬完三階的踏法。
同理,只要將(爬完兩階的踏法,2),再綜合(爬完三階的踏法,1),就是爬完四階的踏法。
疊代下去,就可求出爬完五階的踏法種類。
爬完一階 (1) 爬完兩階 (1,1) (2) 爬完三階,即是(爬完一階,2)與(爬完二階,1) (1,2) (1,1,1) (2,1) 爬完四階,即是(爬完二階,2)與(爬完三階,1) (1,1,2) (2,2) (1,2,1) (1,1,1,1) (2,1,1) 爬完五階,即是(爬完三階,2)與(爬完四階,1) (1,2,2) (1,1,1,2) (2,1,2) (1,1,2,1) (2,2,1) (1,2,1,1) (1,1,1,1,1) (2,1,1,1)
至於踏法種類數目,則是以相加方式求得。
Recursive Method
我們由踏出的最後一步開始分析。
要「爬完五階」,最後一步一定是踏上第五階。要踏上第五階,只可能從第四階和第三階踏過來,也就是(爬完四階的踏法,1),再綜合(爬完三階的踏法,2)。
但是我們不知道如何「爬完四階」和「爬完三階」,所以只好再分別研究「爬完四階」與「爬完三階」,反正它們一定又是由更之前的樓梯踏過來。只要不斷追究下去,問題必會漸漸簡單明朗,總有一天會撥雲見日。
追究到「爬完一階」與「爬完兩階」的時候,已經可以確認答案了。現在「爬完五階」的踏法種類也就清楚了!
爬完五階,即是(爬完四階,1)與(爬完三階,2) 爬完四階,即是(爬完三階,1)與(爬完二階,2) 爬完三階,即是(爬完二階,1)與(爬完一階,2) 爬完兩階:(2) (1,1) 爬完一階:(1)
雙向都可以疊代
前面是採用上樓梯的方式進行疊代,由第一階開始疊代到第五階。其實我們也可以採用下樓梯的方式進行疊代,我們從第五階開始分析,先求出「降到四階」、「降到三階」的踏法,然後就可以疊代出「降到平面」的踏法了。如此也能求出爬完五階的各種踏法。
降到四階 (1) 降到三階 (1,1) (2) 降到二階,即是(2,降到四階)與(1,降到三階) (2,1) (1,1,1) (1,2) 降到一階,即是(2,降到三階)與(1,降到二階) (2,1,1) (2,2) (1,2,1) (1,1,1,1) (1,1,2) 降到平面,即是(2,降到二階)與(1,降到一階) (2,2,1) (2,1,1,1) (2,1,2) (1,2,1,1) (1,2,2) (1,1,2,1) (1,1,1,1,1) (1,1,1,2)
有一些問題是可以雙向疊代的,例如此處的爬樓梯問題。當一個問題可以雙向疊代的時候,通常我們會將數值由小到大的方向稱為「正向」或「順向」(forward),數值由大到小的方向稱為「反向」或「逆向」(backward)。
雙向都可以遞迴
若疊代法、遞迴法是有窮有盡的時候,疊代與遞迴一體兩面、同時存在。既然雙向都可以疊代,當然也代表雙向都可以遞迴,正向疊代對應逆向遞迴,逆向疊代對應正向遞迴。
Gray Code
程度★ 難度★★★
Gray Code
有n個位元的二進位數列,頭尾相接、繞成一圈。在這個數列當中,所有相鄰的數字都只相差一個位元──可能是由1變成0,也可能是由0變成1。在這個數列當中,每一種數字只會出現一次,一樣的數字不會重複出現。
這個數列有沒有辦法窮舉出n個位元的二進位數字呢?
[n = 1] 0 1 [n = 2] 00 01 11 10 [n = 3] 000 001 011 010 110 111 101 100 [n = 4] 0000 0001 0011 0010 0110 0111 0101 0100 1100 1101 1111 1110 1010 1011 1001 1000
Iterative Method
GrayCode(n-1)的每個數字,最高位數加一個0。 GrayCode(n-1)的每個數字,高位數與低位數整個顛倒,然後在最高位數加一個1。 兩者銜接起來就是GrayCode(n)。
也可以用最低位數為主,進行疊代,生成順序不同的Gray Code。Gray Code具有循環的特性,有多種疊代方式,不分正向與逆向。
Recursive Method
GrayCode(n)的每個數字,分成兩類。 第一類最高位數是0,把最高位數拿掉後,即形成GrayCode(n-1)。 第二類最高位數是1,把最高位數拿掉後,即形成GrayCode(n-1)。
也可以用最低位數為主,進行遞迴,生成順序不同的Gray Code。Gray Code具有循環的特性,有多種遞迴方式,不分正向與逆向。
Incremental Method
有一個簡單的方式,可以生成其中一種Gray Code。
[n = 4] 0000 0001 0011 0010 0110 0111 0101 0100 1100 1101 1111 1110 1010 1011 1001 1000 數列的第一個數字,我們當作是第零項,是偶數項。 奇數項數字,是由上一個數字,改變最低位數而得。 偶數項數字,是由上一個數字,改變最低位的位元1而得。
位元操作是電腦的強項,程式碼可以寫的很精鍊,可參考:http://www.matrix67.com/blog/archives/266。
UVa 10455 11535
多維度的Gray Code
Gray Code還可以推廣到高維度,例如在二維的情況下,Gray Code是一個方陣,當然上下左右皆可循環。
延伸閱讀:在正N方體上散步
在N維空間的第一象限,有一個體積為1的正N方體,貼齊座標軸,靠在原點上。
現在任選一個頂點做為起點,沿邊行走,每個點都經過恰好一次,走完一圈回到起點。途中歷經的座標,就是Gray Code的順序!
延伸閱讀:河內塔(Tower of Hanoi)
河內塔的解法就是Gray Code的順序!
延伸閱讀:中國九連環(Chinese Ring Puzzle)
中國九連環的解法就是Gray Code的順序!
http://britton.disted.camosun.bc.ca/chinesering/ninering_sol.html