動態規化 - 漢諾塔
漢諾塔問題(tower of Hanoi)是心理學實驗研究常用的任務之一。該問題的主要材料包括三根高度相同的柱子和一些大小及顏色不同的圓盤,三根柱子分別爲起始柱A、輔助柱B及目標柱C。在A杆自下而上、由大到小按順序放置64個金盤。遊戲的目標:把A杆上的金盤全部移到C杆上,並仍保持原有順序疊好。操作規則:每次只能移動一個盤子,並且在移動過程中三根杆上都始終保持大盤在下,小盤在上,操作過程中盤子可以置於A、B、C任一杆上。
動態規化子問題分解:設移動盤子數爲n,爲了將這n個盤子從A杆移動到C杆,可以做以下三步:
- 以C盤爲中介,從A杆將1至n-1號盤移至B杆;
- 將A杆中剩下的第n號盤移至C杆;
- 以A杆爲中介;從B杆將1至n-1號盤移至C杆。
# -*- coding: utf-8 -*-
def hanoi(n, path={"start": "A", "transfer": "B", "end": "C"}):
"""
tower of hanoi
stick: A, B, C
pan: 1 < 2 < ... < n
"""
if n == 1:
print("%d: %s -> %s" % (n, path["start"], path["end"]))
return
# step1, {1, ..., n - 1}: A -> C -> B
path_ = {}
path_["start"] = path["start"]
path_["transfer"] = path["end"]
path_["end"] = path["transfer"]
hanoi(n - 1, path=path_)
# step2, n: A -> C
print("%d: %s -> %s" % (n, path["start"], path["end"]))
# step3, {1, ..., n - 1}: B -> A -> C
path_["start"] = path["transfer"]
path_["transfer"] = path["start"]
path_["end"] = path["end"]
hanoi(n - 1, path=path_)
if __name__ == "__main__":
hanoi(5)
1: A -> C
2: A -> B
1: C -> B
3: A -> C
1: B -> A
2: B -> C
1: A -> C
4: A -> B
1: C -> B
2: C -> A
1: B -> A
3: C -> B
1: A -> C
2: A -> B
1: C -> B
5: A -> C
1: B -> A
2: B -> C
1: A -> C
3: B -> A
1: C -> B
2: C -> A
1: B -> A
4: B -> C
1: A -> C
2: A -> B
1: C -> B
3: A -> C
1: B -> A
2: B -> C
1: A -> C