算法-汉诺塔原理介绍-python3实现-可输出圆盘编号

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节的程序相比,将输出函数单写,具体功能可根据需要定义。

猜你喜欢

转载自blog.csdn.net/qq_17753903/article/details/82788543
今日推荐