1. 程式人生 > >用遞歸方法解決漢諾塔問題(Recursion Hanoi Tower Python)

用遞歸方法解決漢諾塔問題(Recursion Hanoi Tower Python)

else tro 如果 strong noi ron 最小 傳說 大小

漢諾塔問題源於印度的一個古老傳說:梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。梵天命令婆羅門把圓盤按大小順序重新擺放在另一根柱子上,並且規定小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤當所有的黃金圓盤都重新擺放在另一根柱子上時,世界就將在霹靂聲中毀滅,梵塔、廟宇和眾生都將同歸於盡。

假設A是起始柱,B是中間柱,C是目標柱。

從最簡單的例子開始看:

  • 如果A柱上只剩一個圓盤,那麽將圓盤從A柱移到C柱即可。 (A --> C)
  • 如果A柱上剩兩個圓盤,那麽先將小圓盤從A柱移到B柱,再將大圓盤從A柱移到C柱,最後將B柱上的小圓盤移到C柱。(A --> B, A --> C, B --> C)
  • 如果A柱上剩三個圓盤,那麽先將最小的圓盤從A柱移到C柱,再將中間大小的圓盤從A柱移到B柱,然後將C柱上的最小的圓盤移到B柱,然後將A柱上的最大的圓盤移到C柱,然後將B柱上的最小的圓盤移到A柱,繼續將B柱上的中間大小的圓盤移到C柱,最後將A柱上的最小的圓盤移到C柱。 (A -->C, A -->B, C --> B, A --> C, B --> A, B --> C, A --> C) --- 前三步(A -->C, A -->B, C --> B)可以看成是A --> B的過程,中間是A --> C的過程,最後三步(B --> A, B --> C, A --> C)可以看成是B --> C的過程

綜上所述,如果需要移動n個圓盤,那麽整個過程可以抽象成以下三個步驟:

1. 將除底盤以外的圓盤(n-1個圓盤)從A柱移動到B柱

2. 將底盤從A柱移動到C柱

3. 將B柱上的圓盤(n-1個圓盤)移動到C柱

從最復雜的例子開始看:

  • 如果A柱上有64個圓盤,最簡單的做法是把A柱上的64個圓盤想象成一共是2個圓盤(底盤是一個圓盤,底盤上面的63個圓盤是一個圓盤),這樣的話,只需先將A柱上的63個圓盤移動到B柱,再將底盤從A柱移到C柱,最後將B柱上的63個圓盤移到C柱。
  • 如果A柱上有63個圓盤,則把A柱上的63個圓盤想象成一共是2個圓盤(底盤是一個圓盤,底盤上面的62個圓盤是一個圓盤),這樣的話,只需先將A柱上的62個圓盤移動到B柱,再將底盤從A柱移到C柱,最後將B柱上的62個圓盤移到C柱。
  • 以此類推,直到A柱上只剩一個圓盤,然後將該圓盤從A柱移到C柱即可。

綜上可以看出,通過不斷重復嵌套,這個問題可以用遞歸方法解決。

代碼如下:
def hanoi(n,a,b,c):   # n表示需要移動幾個圓盤,a代表起始柱,b代表中間柱,c代表目標柱
    if n==1:              # 如果只剩1個圓盤,那麽將圓盤從a柱移動c柱即可
        print(a,"->",c)
    else:             # 當n > 1時,用抽象出的3步來移動
        hanoi(n-1,a,c,b)        # 將n-1個圓盤從a移動到b
        print(a,"->",c)        # 將底盤從a移動到c
        hanoi(n-1,b,a,c)        # 將b上的n-1個圓盤移動到c

試一下移動3個圓盤的步驟是否和前文一致:

hanoi(3,"A","B","C")

運行結果如下:

A -> C
A -> B
C -> B
A -> C
B -> A
B -> C
A -> C

可以看出,移動3個圓盤需要7步。根據推算,移動n個圓盤需要2n-1步。假設每次移動一個圓盤都是1秒鐘的時間,婆羅門不停地在移動圓盤,那麽總共需要(264-1)秒的時間,世界就會毀滅。按一年365天計,需要584,942,417,355.072年世界才會毀滅。

用遞歸方法解決漢諾塔問題(Recursion Hanoi Tower Python)