zoukankan      html  css  js  c++  java
  • 迭代算法经典问题之汉诺塔

    汉诺塔的传说

    相传在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。

    算法分析

    该问题实际上是一个非常典型的迭代问题,所谓迭代问题就是原问题拆分的子问题实质上仍然是原问题,此外,每个迭代问题都应该有一个base case,即在此情况下停止迭代。

    用迭代的角度来看汉诺塔问题:

    • 把n个金片从第一个银针上全部转移到第三个银针上的操作定义为函数Transfer(n,start=1,end=3)。
    • 把n-1个金片从第一个银针上全部转移到第三个银针上为函数Transfer(n-1,start=1,end=3)。
    • Transfer(n-1,start=1,end=3)与Transfer(n,start=1,end=3)属于一类问题。
    • Transfer(n,start=1,end=2)与Transfer(n-1,start=1,end=3)有联系,即在n-1个金片全部从第一根到第三根后,只需将第n个金片从第一根转移到第二根,然后再把其他的n-1个金片放到它上面,即发生了Transfer(n-1,start=3,end=2),最后得到Transfer(n,start=1,end=2)。
    • Base case就是n=1时,直接将n=1的金片从1移到3.

    Python代码实现

    def Transfer(n,start=1,end=3):
        if n:
            Transfer(n-1,start,6-start-end) # 将n-1个金片从start转移到6-start-end
            print('Move disk %d from rod %d to rod %d  '%(n, start,end))
            Transfer(n-1,6-start-end,end)# 将n-1个金片从6-start-end转移到end
    

    output:

    Transfer(3)
    Move disk 1 from rod 1 to rod 3  
    Move disk 2 from rod 1 to rod 2  
    Move disk 1 from rod 3 to rod 3  
    Move disk 3 from rod 1 to rod 3  
    Move disk 1 from rod 2 to rod 1  
    Move disk 2 from rod 2 to rod 3  
    Move disk 1 from rod 1 to rod 3 
    
    Transfer(4)
    Move disk 1 from rod 1 to rod 2  
    Move disk 2 from rod 1 to rod 3  
    Move disk 1 from rod 2 to rod 3  
    Move disk 3 from rod 1 to rod 2  
    Move disk 1 from rod 3 to rod 0  
    Move disk 2 from rod 3 to rod 3  
    Move disk 1 from rod 0 to rod 3  
    Move disk 4 from rod 1 to rod 3  
    Move disk 1 from rod 2 to rod 3  
    Move disk 2 from rod 2 to rod 1  
    Move disk 1 from rod 3 to rod 3  
    Move disk 3 from rod 2 to rod 3  
    Move disk 1 from rod 1 to rod 2  
    Move disk 2 from rod 1 to rod 3  
    Move disk 1 from rod 2 to rod 3 
    

    需要注意几点:

    • 将n-1个金片从start转移到6-start-end,这里start不能用1代替,因为在迭代中start是动态变动的,而end=6-start-end则是动态的表示是除了start和end外的宝石针,6=1+2+3。
    • 在将n-1个金片全部转移到6-start-end后,将第n个金片转移到end,因此可以用print输出此时是将哪个金片从哪里移动到哪里,也可以理解为此时将第n个金片移动到了end。
    • print输出后(将第n个金片移动到了end后),将n-1个金片从6-start-end转移到既定的end。
    ##### 愿你一寸一寸地攻城略地,一点一点地焕然一新 #####
  • 相关阅读:
    Docker 常用命令及操作
    Docker 启动 tomcat 成功,但是访问为 404
    Linux 使用 yum install 安装程序时,提示另外一个程序锁定了 yum 等待它退出...
    Centos 6.8 安装 Docker 及 Docker 入门介绍
    iptables常见的模块拓展-m iprange 、-m multiport、
    iptables -m state模块 注意与-m conntrack的区别
    ros single network adapter的nat
    trap 信号捕捉
    ifconfig命令
    使用pipework给docker配置物理机器网卡上的地址
  • 原文地址:https://www.cnblogs.com/johnyang/p/13629306.html
Copyright © 2011-2022 走看看