0.摘要
本文使用python3实现汉诺塔问题。
1.问题阐述与分析
有三个柱子A,B,C,每个柱子上都可以放置圆盘。最初,所有圆盘都在A柱子上,需要把所有圆盘都移动到C柱子上。
要求:
1.每次只移动一个圆盘
2.只能移动柱子最上面的圆盘
3.保证每根柱子上,上面的圆盘一定比下面的圆盘小
经过分析,我们发现,这样的问题可以分解为下面三个子步骤
step1:如果想把A柱子上的圆盘都移动到C柱子上,那么必须先想办法把A柱子上n-1个圆盘移动到B柱子上。
不难看出,“把A柱子上圆盘移动到B柱子上”和“把A柱子上的圆盘都移动到C柱子上”,这是同一类问题。区别只不过圆盘数量变为了n-1,source是A柱子,target是B柱子。
step2:这时候可以把最大的圆盘移动到C柱子上。并且由于这个圆盘是最大的,所以其他任意圆盘都可以放在C柱子上。这时候的C柱子,和空柱子具有相同的作用。
step3:这时候,我们发现,问题转换成了如何把B柱子上n-1个圆盘移动到C柱子上?
不难看出,“把B柱子上圆盘移动到C柱子上”和“把A柱子上的圆盘都移动到C柱子上”,又是同一类问题。区别只不过圆盘数量变为了n-1,source是B柱子,target是C柱子。
2.代码实现
通过上面的分析,我们发现:
当需要移动的圆盘数量n=1时,直接移动圆盘即可;
当需要移动的圆盘数量n>1时,这个问题都可以转化成n-1个圆盘的问题。
#coding=utf-8
def hanoi(n,a,b,c):
if n == 1:
print(a , ' --> ',c)
else:
hanoi(n-1,a,c,b)
hanoi(1,a,b,c)
hanoi(n-1,b,a,c)
if __name__ == '__main__':
hanoi(3,'A','B','C')
3.自定义输出方式
有些问题中,我们除了输出圆盘移动路径之外,还需要输出其他的信息,比如每次移动的是哪个圆盘。
在这里,本文给出一个示例,输出圆盘编号,仅供参考:
#coding=utf-8
import numpy as np
def print_message(a,c):
if not a :
print('Something wrong in data!')
return -1
disk = a['disks'].pop()
c['disks'].append(disk)
print(disk,end='#')
print(a['name'], ' --> ', c['name'])
return 0
def hanoi(n,a,b,c):
if n == 1:
print_message(a,c)
else:
hanoi(n-1,a,c,b)
hanoi(1,a,b,c)
hanoi(n-1,b,a,c)
if __name__ == '__main__':
disks_num = 3
disks = np.arange(disks_num,0,-1).tolist()
A = {'name':'A','disks':disks}
B = {'name':'B','disks':[]}
C = {'name':'C','disks':[]}
# print(A,B,C)
hanoi(disks_num,A,B,C)
这里通过字典的方式,存储了每个柱子的名称和堆放的圆盘信息。
与第2节的程序相比,将输出函数单写,具体功能可根据需要定义。
来源:CSDN
作者:shangyj17
链接:https://blog.csdn.net/qq_17753903/article/details/82788543