漢諾塔雜談(三)——非遞歸演算法
來自專欄 Liu言雜記
下面介紹 個盤子的漢諾塔的非遞歸演算法:
1. 將三根柱子按順序排成品字型,若 為偶數,按順時針方向依次擺放A、B、C;若 為奇數,按順時針方向依次擺放A、C、B。
2. 把圓盤1從現在的柱子移動到順時針方向的下一根柱。
3. 接著,把另外兩根柱上可以移動的圓盤移動到新的柱上(事實上只有唯一的選擇)。
4. 如果沒有達到目標要求,則返回步驟2。
例如下圖是 的情況:
由二進位也可以得到 個盤子的漢諾塔的非遞歸演算法:
對於有 個盤子的漢諾塔問題,按序寫出所有 位普通二進位碼 ,自左而右標記為第 位、第 位、…第2位、第1位。則 表示第 步移動 號盤子。
- 對於最小的盤子而言,總是有兩種移動的可能性。若 為偶數,最小的盤子的移動次序是A→B→C→A→…;若 為奇數,最小的盤子的移動次序是A→C→B→A→…。
- 對於其他盤子,總是有唯一的移動可能性。
的情況見下表。
在Mathematica中有一個函數「IntegerExponent」,官方的幫助給出的說明是:
IntegerExponent[n, b] gives the highest power of b that divides n.
就是返回能整除 的(大於1的整數) 的最高次冪。例如:
說明 而 。
於是在Mathematica中,輸入「IntegerExponent [Range[2^n - 1], 2] + 1」 可以得到 個盤子的漢諾塔問題依次移動的盤子的號碼。
例如:
具體移動方法同前。
由格雷碼也可以得到一個非遞歸演算法,這部分內容我將放在下一篇中介紹。
此外,假設 的二進位表示為 ,則可以由 得到移動 步後 個盤子在3個柱的分布情況,這一部分也將在下一篇中介紹。
(注意到格雷碼與普通二進位碼的轉換關係,則可以將 的二進位表示轉換為 對應的格雷碼)。
推薦閱讀:
※遞歸函數(八):偏序結構
※頓時錯亂(Instant Insanity)玩具
※麻花辮(Braid)
※不能證明也無法否定的「連續統假說」——集合的勢(三)
TAG:趣味數學 | 離散數學 | 組合數學Combinatorics |