前言:
此时姐妹们对“汉诺塔python”大概比较看重,各位老铁们都需要分析一些“汉诺塔python”的相关资讯。那么小编在网摘上汇集了一些关于“汉诺塔python””的相关文章,希望咱们能喜欢,咱们快快来学习一下吧!汉诺塔问题是程序设计中的经典递归问题。
汉诺塔游戏:有n个盘,A为起始柱,B为借力柱,C为目标柱,n个盘从小到大编号为1、2、3、...、n-1,n,求需要移动的步数最优解F(N).
汉诺塔游戏的规则如下:
1、每次只能移动一个圆盘。
2、圆盘只能放在空柱子上或者比自己大的圆盘上。
3、不能将圆盘放在比自己小的圆盘上。
1、解题思路:
(1)、当n=0,则没有盘,无需移动,故F(n=0)=0
(2)、当n=1,则直接从A柱移动到C柱即可,故F(n=1)=1
(3)、当n=2时,则需要需要的步数F(n=2)=3:
2个盘汉诺塔解法如下图所示:
第1步:将盘1从A柱移动到B柱,需要移动次数为1
第2步:将盘2从A柱移动到C柱,需要移动次数为1
第3步:将盘1从B柱移动到C柱,需要移动次数为1
综上,F(n=2)=1+1+1
(4)、当有n个盘时,将盘1至盘n-1当作一个整体盘,则问题就转化为整体盘、盘n的两个盘汉诺塔问题了,故需要移动的次数为:F(n)=F(n-1)+1+F(n-1)
n个盘汉诺塔需要移动次数记为F(n),则n个盘汉诺塔解法如下图所示:
第1步:将整体盘(盘1至盘n-1)从A柱移动到B柱,则需要移动次数为F(n-1)
第2步:将单个盘n从A柱移动到C柱,则需要移动次数为1次
第3步:将整体盘(盘1至盘n-1)从B柱移动到C柱,则需要移动次数为F(n-1)
综上:F(n)=F(n-1)+1+F(n-1)=2*F(n-1)+1
2、递归求解F(n)
由上面的解题思路,可得n个汉诺塔需移动的步数的递归公式为:F(n)=2F(n-1)+1,其中n>=1,F(0)=0,F(1)=1,经举例发现F(n)=2^n-1(n>=2)。
(1)当n=0时,F(n=0)=0
(2)当n=1时,F(n=1)=1=2^0
(3)当n=2时,F(n=2)=2F(n-1)+1=2F(1)+1=2*1+1=2+1=2^1+2^0=2^2-1=3
(4)当n=3时,F(n=3)=2F(n-1)+1=2F(2)+1=2*(2^1+2^0)+2^0=2^2+2^1+2^0=2^3-1=7
(5)当n=4时,F(n=4)=2F(n-1)+1=2F(3)+1=2*(2^2+2^1+2^0)+2^0=2^3+2^2+2^1+2^0=2^4-1=15
观察上式可得,F(n)=2F(n-1)+1=2^n-1,下面用数学归纳法证明F(n)=2^n-1成立即可。
3、数学归纳法证明F(n)=2^n-1,证明过程如下:
(1)当n=0时,F(n=0)=0=2^0-1
(1)当n=1时,F(n=1)=2F0)+1=2*0+1=1=2^1-1
(2)当n=2时,F(n=2)=2F(n-1)+1=2F(1)+1=2*1+1=3=2^2-1
(3)当n=3时,F(n=3)=2F(n-1)+1=2F(2)+1=2*3+1=7=2^3-1
(4)当n=4时,F(n=4)=2F(n-1)+1=2F(3)+1=2*7+1=15=2^4-1
(5)假设当n=k时,F(n=k)=2F(k-1)+1=2^k-1成立,则只需证明当n=k+1时,等式也成立即可
(6)当n=k+1时,F(n=k+1)=2F(k)+1=2*( 2^k-1 )+1=2*2^k-2+1=2^(k+1)-1,即当n=k+1时,F(n=k+1)=2^(k+1)-1,等式成立,故F(n)=2^n-1(n>=2)等式成立。
综上:n个盘的汉诺塔需要移动的步数最优解:F(N)=2^n-1.
4、python模拟实现汉诺塔移动过程:
count=0 # 移动次数# n个盘汉诺塔从A柱移动C柱,B柱为借力柱移动过程模拟,list_start为起始柱的盘子def hannuota_list(list_start,A_start,B_min,C_end): global count n=len(list_start) if n==0: print(f'无需移动,已移动次数{count}') elif n==1: count=count+1 print(f'第{count}次移动: 盘{list_start[n-1]}:{A_start} --> {C_end}') # 整体盘从起始柱 A_start 移动到目标柱 C_end else: list_aa=[list_start[x] for x in range(n-1)] # 盘切分成两部分 #list_bb=list_start[n-1] # 最后一个盘 hannuota_list(list_aa,A_start,C_end,B_min) # 整体盘从起始柱 A_start 移动到 借力柱 B_min,目标柱 C_end 为过渡 count=count+1 print(f'第{count}次移动: 盘{list_start[n-1]}:{A_start} --> {C_end}') # 整体盘从起始柱 A_start 移动到目标柱 C_end hannuota_list(list_aa,B_min,A_start,C_end) # 整体盘从借力柱 B_min 移动到 目标柱 C_end,起始柱 A_start 为过渡 # 主程序:if __name__ == '__main__': n=4 list_a=[x+1 for x in range(n)] # 生成盘号分别为1,2,3,...,n-1,n的盘 print(f'{n}个汉诺塔从上往底部的盘号依次为:{list_a}') print() print(f'{n}个盘汉诺塔移动模拟过程如下: ') count=0 hannuota_list(list_a,A_start='A柱',B_min='B柱',C_end='C柱') # 移动4个盘,起始柱为A柱,目标柱为C柱,借力柱为B柱
运行结果如下:
标签: #汉诺塔python