龙空技术网

智力题:汉诺塔移动过程模拟

gway 120

前言:

此时姐妹们对“汉诺塔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

2个盘汉诺塔解法

(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

n个盘汉诺塔问题(递归求解法)

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