迭代-递归

迭代

1.1 定义

  1. 迭代算法是用计算机解决问题的一种基本方法。
  2. 它利用计算机运算速度快、适合做重复性操作的特点,让计算机对一组指令(或一定步骤)进行重复执行,
  3. 在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值。

1.2 处理迭代问题的条件()

  1. 确定迭代变量(三个变量,a1,a2,a3)---------------------------具有的原始变量(a1=1,a2=1),用原始变量可以推出新值(a3=2),通过重复操作把原始变量重新赋值(a1=a2,a2=a3),持续推出新值a3
  2. 建立迭代关系式------------------------关键用上一个变量推断出下一个变量的公式(a3=a2+a1),通常使用递推或倒推来完成
  3. 对迭代过程进行控制。
    3.1 知道迭代次数:求出迭代次数,利用循环控制
    3.2 不知道迭代次数:需要进一步分析出用来结束迭代过程的条件

1.3 斐波那契迭代图解

在这里插入图片描述

1.4 具体案例分析

1.4.1 一个豢养场引进一只刚出生的新品种兔子,这种兔子从出生的下一个月开始,每月重生一只兔子,重生的兔子也如此繁殖。如果所有的兔子都不死去,问到第 12 个月时,该豢养场共有兔子多少只?

解题分析:
条件①:从这种兔子从出生的下一个月开始,每月重生一只兔子得知,(n+1)月兔子数量=n月兔子数量 × 2
假设: 1 月 有 m 1 只 , 2 月 有 m 2 只 , 3 月 有 m 3 只 , 4 月 有 m 4 只 , … … , n 月 有 m n 只 1月有m_1只,2月有m_2只,3月有m_3只,4月有m_4只,……,n月有m_n只 1m12m23m34m4nmn
条件② m 2 = m 1 + m 1 ∗ 1 , m 3 = m 2 + m 2 ∗ 1 , … … m n = m n − 1 + m n − 1 ∗ 1 m_2=m_1+m_1*1,m_3=m_2+m_2*1,……m_n=m_{n-1}+m_{n-1}*1 m2=m1+m11,m3=m2+m21,mn=mn1+mn11
根据条件①② 得到: 公式① m n = 2 m n − 1 m_n=2m_{n-1} mn=2mn1
根据公式①里的变量对应设置迭代变量:x,y
根据公式①和迭代变量确定迭代关系: y = 2 x ( x > = 2 ) ; x = y ; y=2x(x>=2);x=y; y=2x(x>=2)x=y
根据问到第 12 个月时得到迭代控制条件:[1,12) 循环11次

迭代变量:x=1,y   迭代关系式 y=2x(x>=2);x=y; 迭代次数:[1,12] 循环11# 代码实现
		def ra():
			x = 1                      # 第1个月
			for echo in range(1,12):   # 后边11个月
				y = 2 * x
				x = y
			print('12个月兔子繁殖总数是%d' % y)
	# 调用函数
		ra()
		输出: 12个月兔子繁殖总数是2048
1.4.2 阿米巴用简单分裂的方式繁殖,它每分裂一次要用 3 分钟。将若干个阿米巴放在一个盛满营养液的容器内, 45 分钟后容器内充满了阿米巴。已知容器最多能够装 2 20 2^{20} 220 阿米巴个。试问,开始的时候往容器内放了多少个阿米巴?

解题分析:
条件①:从阿米巴用简单分裂的方式繁殖得知,(n-1)月阿米巴数量=n月阿米巴数量 / 2
假设: 1 月 有 m 1 只 , 2 月 有 m 2 只 , 3 月 有 m 3 只 , 4 月 有 m 4 只 , … … , n 月 有 m n 只 1月有m_1只,2月有m_2只,3月有m_3只,4月有m_4只,……,n月有m_n只 1m12m23m34m4nmn
条件② m 1 = m 2 / 2 , m 2 = m 3 / 2 , … … m n − 1 = m n / 2 m_1=m_2/2,m_2=m_3/2,……m_{n-1}=m_n/2 m1=m2/2,m2=m3/2,mn1=mn/2
根据条件①② 得到: 公式① m n − 1 = m n / 2 m_{n-1}=m_{n}/2 mn1=mn/2
根据公式①里的变量对应设置迭代变量:y= m n m_{n} mn,x = m n − 1 m_{n-1} mn1
根据公式①和迭代变量确定迭代关系: x = y / 2 ; y = x ; x=y/2;y=x; x=y/2y=x
根据45 分钟后容器内充满了阿米巴,它每分裂一次要用 3 分钟得到45/3=15迭代控制条件:[1,16) 循环15次

迭代变量:x,y=2^20   迭代关系式 x=y/2;y=x; 迭代次数:[1,16] 循环15# 代码实现
		def ra():
			y=2**20    
			for echo in range(1,16):
				x = y / 2
				y = x
			print(x,y)

	# 调用函数
		ra()
		输出: 初始阿米巴数量为32
1.4.3 验证谷角猜想。日本数学家谷角静夫在研究天然数时发觉了一个奇怪现象:对于任意一个天然数 n ,若 n 为偶数,则将其除以 2 ;若 n 为奇数,则将其乘以 3 ,然后再加 1 。如此经过有限次运算后,分能够得到天然数 1 。人们把谷角静夫的这一发觉叫做“谷角猜想”。
# 构造函数
	def ra(y):
		while(y!=1):
			n = 0         #计数器
			if y % 2 == 0:
				y = y / 2
				n=n+1
			else :
				y = y * 3 + 1
				n=n+1
		print('得到自然数%d,总循环次数%d' % (y,n))

# 调用函数
	ra(34)
	# 输出:得到自然数1,总循环次数1

递归

1.1 定义

递归是设想和描述算法的一种有力的工具,由于它在复杂算法的描述中被经常采用,为此在进一步引见其他算法设想方法之前先讨论它。

1.2 使用递归描述算法的特征

  • 为求解规模为N的问题,设法将它分解成规模较小的问题,然后从这些小问题的解方便地构造出大问题的解
  • 并且这些规模较小的问题也能采用同样的分解和分析方法,分解成规模更小的问题,并从这些更小问题的解构造出规模较大问题的解
  • 特别地,当规模N=1时,能间接得解

1.3 斐波那契数列递归图解

在这里插入图片描述

1.4 斐波那契(Fibonacci)数列(黄金分割比例(0.618))

斐波那契数列为:0、1、1、2、3、5……,
后一项等于前两项之和,即: a n = a n − 1 + a n − 2 a_n=a_{n-1}+a_{n-2} an=an1+an2

1.5 斐波那契数列-生兔子

经过月数123456789101112
兔子对数1123581321345589144

① 迭代实现算到100000个月未卡死

  • 迭代式: n 3 = n 1 + n 2 ; n 1 = n 2 ; n 2 = n 3 n_3=n_1+n_2;n_1=n_2;n_2=n_3 n3=n1+n2;n1=n2;n2=n3
  • 迭代变量(运算开始): a 1 = 1 , a 2 = 1 a_1=1,a_2=1 a1=1,a2=1
  • 控制条件:while(用户输入)
# 定义函数 
	def fib():
	    n1=1
	    n2=1
	    n3=0
	    n = int(input('请输入查询几个月的兔子总数'))
	    if n < 1 :
	        print('输入数据有误')
	    if n ==1 or n ==2 :
	        return 1
	    if(n > 2):
	        m=n
	        while(m>2):
	            n3=n1+n2
	            n1 = n2
	            n2 = n3
	            m-=1
	        print('%d个月的兔子总数为%d' % (n,n3))
# 调用函数
	fib()
	请输入查询几个月的兔子总数 12
	# 输出 :12个月的兔子总数为144

② 递归实现算到40个月卡死

  • 运算开始:fib(1)=1,fib(2)=1
# 定义函数
	def fib(n):
		if n < 1:
			return '输入数据有误'
		if n == 1 or n == 2:   # fib(1)=1,fib(2)=1  运算起点
			return 1
		if n > 2:
			return fib(n-1)+fib(n-2)
# 调用函数
	fib(12)
	# 输出:144  

1.6 汉诺塔

计算汉诺塔几层需要多少步: 2 层 数 − 1 2^{层数}-1 21

1.6.1 核心思想:
  • 条件:三个轴(x,y,z)n个木盘
  • 解决:①把(n-1)个木盘从x轴转移到y轴,②把x轴的第n个木盘转移到z轴,③把y轴的(n-1)个木盘转移到z轴
1.6.2 图解

在这里插入图片描述

  • 分析①:把x轴的木盘移动到z轴,需要y轴当中介
  • 分析②:把y轴的木盘转移到z轴,需要x轴当中介
  • 递归思想(n-1)层转移的时候思路还是一样的,一直向下递归,直到n=1时,执行相应的操作,并依次把结果向上递归回去。
1.6.3 代码实现
# 汉诺塔游戏攻略
m = 0                    # 计数器,记录共用了多少步 
def han(n,x,y,z):        # n 盘子数,x,y,z 对应三根针
    if( n == 1 ):
        global m
        m=m+1
        print(x,'----->',z,'------>',m)  
    else:
        han(n-1,x,z,y)                  # 将前n-1个盘子从x移动到y上,z为中转
        m=m+1
        print(x,'----->',z,'------>',m) # 最后一个盘子移动到z上
        han(n-1,y,x,z)                  # 将y上的n-1个盘子移动到z上
n = int(input('汉诺塔层数'))
han(n,'X','Y','Z')
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值