动态规化 - 汉诺塔
汉诺塔问题(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