網測/精密光學 VIAVI 第四次提出收購 EXFO ,EXFO 創始人第四次迴應堅決不賣
漢諾塔問題
漢諾塔問題,是心理學實驗研究常用的任務之一。該問題的主要材料包括三根高度相同的柱子和一些大小及顏色不同的圓盤,三根柱子分別為起始柱A、輔助柱B及目標柱C。遊戲的目標:把A杆上的金盤全部移到C杆上,並仍保持原有順序疊好。操作規則:每次只能移動一個盤子,並且在移動過程中三根杆上都始終保持大盤在下,小盤在上,操作過程中盤子可以置於A、B、C任一杆上。
T0 | T1 | T2 | T3 | T4 | T5 | T6 | T7 | T8 | T9 |
0 | 1 | 3 | 7 | 15 | 31 | 63 | 127 | 255 | ? |
觀察表格發現,
Tn=2Tn-1+ 1 |
如果上式子正確,可以證明下式:
Tn= 2n- 1 |
證明方法可以使用數學歸納法,這裡就不介紹了。我們看漢諾塔的遞迴與非遞迴演算法。
為了搬動最底部且最大的盤子,必須先將上面的盤子全部搬到中間的柱子B。一定要這樣嗎?應該沒有其他可能,如果上面的任意一隻盤子散落於左邊的柱子,那麼最底部且最大的盤子不能被搬動;若上面的任意一隻盤子散落於右邊的柱子,那麼最底部且最大的盤子將無處可放。
遞迴的虛擬碼描述:
void Hanoi(n,A,C,B) //搬動n只盤子從柱子A到柱子C,可藉助柱子B
{
if (n >= 1) then
{
Hanoi(n-1,A,B,C); //從柱子A搬動n-1只盤子到中間柱子B
write("從柱子" ,A ,"搬到一隻盤子到柱子",C);
Hanoi(n-1,B,C,A);//從柱子B搬n-1只盤子到中間柱子C
}
}
如果不用遞迴演算法,我們可以解決嗎?
先看幾張表格(n=4):
步驟 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
移動的盤子 | 1 | 2 | 1 | 3 | 1 | 2 | 1 | 4 | 1 | 2 | 1 | 3 | 1 | 2 | 1 |
C | |||||||||||||||
B | |||||||||||||||
A |
第一個盤子整個搬動過程的搬動方向:
偶數號盤子在整個搬動過程中搬動方向:
我們可以根據現象觀察得到下述規律:
1、k號盤子每隔2k次搬動一次;
2、當漢諾塔問題的盤子是奇數時,奇數號盤子往下移動到底後,就跳上去;而偶數號盤子往上移動到頂後,就掉下來。
因而:
輸入 | 漢諾塔的盤子數n,盤子編號為{1,2,...,n}。三根柱子編號為0、1、2 |
輸出 | 全部 2n- 1 次移動過程 |
步驟 |
一個迴圈控制整數 i 從 1 到2n- 1 執行下列步驟完成每一隻盤子的移動: Step1: 計算最大的k,使得i=2k* y(故本次將搬動第k+1號盤子) Step2: 當n為偶數且k+1為奇數時,移動第k+1號盤子從當前的s柱子搬到第(s+1)MOD 3 柱子 當n為偶數且k+1為偶數時,移動第k+1號盤子從當前的s柱子搬到第(s-1)MOD 3 柱子 當n為奇數且k+1為奇數時,移動第k+1號盤子從第s柱子搬到第(s-1)MOD 3 柱子 當n為奇數且k+1為偶數時,移動第k+1號盤子從第s柱子搬到第(s+1)MOD 3 柱子 |
--摘自《圖解演算法》俞徵武著 第一章 “一切從觀察開始”