迭代算法是用计算机解决问题的一种基本方法。它利用计算机运算速度快、适合做重复性操作的特点让计算机对一组指令(或一定步骤)进行重复执行在每次执行这组指令(或这些步骤)时都从变量的原值推出它的一个新值。
利用迭代算法解决问题需要做好以下三个方面的工作
一、确定迭代变量。在可以用迭代算法解决的问题中至少存在一个直接或间接地不断由旧值递推出新值的变量这个变量就是迭代变量。
二、建立迭代关系式。所谓迭代关系式指如何从变量的前一个值推出其下一个值的公式(或关系) 。迭代关系式的建立是解决迭代问题的关键通常可以使用递推或倒推的方法来完成。
三、对迭代过程进行控制。在什么时候结束迭代过程?这是编写迭代程序必须考虑的问题。不能让迭代过程无休止地重复执行下去。迭代过程的控制通常可分为两种情况一种是所需的迭代次数是个确定的值可以计算出来;另一种是所需的迭代次数无法确定。对于前一种情况可以构建一个固定次数的循环来实现对迭代过程的控制;对于后一种情况需要进一步分析出用来结束迭代过程的条件。
例1 一个饲养场引进一只刚出生的新品种兔子这种兔子从出生的下一个月开始每月新生一只兔子新生的兔子也如此繁殖。如果所有的兔子都不死去问到第12个月时该饲养场共有兔子多少只?
分析 这是一个典型的递推问题。我们不妨假设第1个月时兔子的只数为u 1 第2个月时兔子的只数为u 2 第3个月时兔子的只数为u 3 „„根据题意 “这种兔子从出生的下一个月开始每月新生一只兔子” 则有
以下是引用片段u 1 = 1 u 2 = u 1 + u 1 × 1 = 2 u 3 = u 2 + u 2 × 1 = 4 „„
根据这个规律可以归纳出下面的递推公式
以下是引用片段u n = u n - 1 × 2 (n≥2)
对应u n和u n - 1 定义两个迭代变量y和x 可将上面的递推公式转换成如下迭代关系
以下是引用片段y=x*2x=y
让计算机对这个迭代关系重复执行11次就可以算出第12个月时的兔子数。参考程序如下
以下是引用片段clsx=1for i=2 to 12y=x*2x=ynext iprint yend
例2 阿米巴用简单分裂的方式繁殖它每分裂一次要用3分钟。将若干个阿米巴放在一个盛满营养参液的容器内 45分钟后容器内充满了阿米巴。已知容器最多可以装阿米巴2 20个。试问开始的时候往容器内放了多少个阿米巴?请编程序算出。
分析 根据题意阿米巴每3分钟分裂一次那么从开始的时候将阿米巴放入容器里面到45分钟后充满容器需要分裂45/3=15次。而“容器最多可以装阿米巴2 20个”即阿米巴分裂15次以后得到的个数是2 20 。题目要求我们计算分裂之前的阿米巴数不妨使用倒推的方法从第15次分裂之后的2 20个倒推出第15次分裂之前(即第14次分裂之后)的个数再进一步倒推出第13次分裂之后、第12次分裂之后、„„第1次分裂之前的个数。
设第1次分裂之前的个数为x 0 、第1次分裂之后的个数为x 1 、第2次分裂之后的个数为x 2 、„„第15次分裂之后的个数为x 15 则有
以下是引用片段x 14 =x 15 /2 、 x 13 =x 14 /2 、„„x n-1 =x n /2 (n≥1)
因为第15次分裂之后的个数x 15是已知的如果定义迭代变量为x 则可以将上面的倒推公式转换成如下的迭代公式x=x/2 ( x的初值为第15次分裂之后的个数2 20 )
让这个迭代公式重复执行15次就可以倒推出第1次分裂之前的阿米巴个数。因为所需的迭代次数是个确定的值我们可以使用一个固定次数的循环来实现对迭代过程的控制。参考程序如下
以下是引用片段clsx=2^20for i=1 to 15x=x/2next iprint xend
例3 验证谷角猜想。 日本数学家谷角静夫在研究自然数时发现了一个奇怪现象对于任意一个自然数n 若n为偶数则将其除以2 ;若n为奇数则将其乘以3 然后再加
1 。如此经过有限次运算后总可以得到自然数1 。人们把谷角静夫的这一发现叫做“谷角猜想” 。
要求编写一个程序 由键盘输入一个自然数n 把n经过有限次运算后最终变成自然数1的全过程打印出来。
分析 定义迭代变量为n 按照谷角猜想的内容可以得到两种情况下的迭代关系式当n为偶数时 n=n/2 ;当n为奇数时 n=n*3+1 。用QBASIC语言把它描述出来就是
以下是引用片段if n为偶数thenn=n/2elsen=n*3+1end if
这就是需要计算机重复执行的迭代过程。这个迭代过程需要重复执行多少次才能使迭代变量n最终变成自然数1 这是我们无法计算出来的。因此还需进一步确定用来结束迭代过程的条件。仔细分析题目要求不难看出对任意给定的一个自然数n 只要经过有限次运算后能够得到自然数1 就已经完成了验证工作。因此用来结束迭代过程的条件可以定义为 n=1 。参考程序如下
以下是引用片段clsinput "Please input n=";ndo until n=1if n mod 2=0 thenrem如果n为偶数则调用迭代公式n=n/2n=n/2
print "—";n;elsen=n*3+1print "—";n;end ifloopend
迭代法
迭代法是用于求方程或方程组近似根的一种常用的算法设计方法。设方程为f(x)=0用某种数学方法导出等价的形式x=g(x) 然后按以下步骤执行
(1)选一个方程的近似根赋给变量x0;
(2)将x0的值保存于变量x1然后计算g(x1) 并将结果存于变量x0;
(3) 当x0与x1的差的绝对值还小于指定的精度要求时重复步骤(2)的计算。
若方程有根并且用上述方法计算出来的近似根序列收敛则按上述方法求得的x0就认为是方程的根。上述算法用C程序的形式表示为
【算法】迭代法求方程的根
以下是引用片段
{ x0=初始近似根;do {x1=x0;x0=g(x1) ; /*按特定的方程计算新的近似根*/
} while ( fabs(x0-x1)>Epsilon) ;printf( “方程的近似根是%f\n” x0) ;
}
迭代算法也常用于求方程组的根令
X=(x0 x1 „ xn-1)
设方程组为xi=gi (X) (I=0 1 „ n-1)
则求方程组根的迭代算法可描述如下
【算法】迭代法求方程组的根
具体使用迭代法求根时应注意以下两种可能发生的情况
(1)如果方程无解算法求出的近似根序列就不会收敛迭代过程会变成死循环因此在使用迭代算法前应先考察方程是否有解并在程序中对迭代的次数给予限制;
(2)方程虽然有解但迭代公式选择不当或迭代的初始近似根选择不合理也会导致迭代失败。
递归
递归是设计和描述算法的一种有力的工具由于它在复杂算法的描述中被经常采用为此在进一步介绍其他算法设计方法之前先讨论它。
能采用递归描述的算法通常有这样的特征为求解规模为N的问题设法将它分解成规模较小的问题然后从这些小问题的解方便地构造出大问题的解并且这些规模较小的问题也能采用同样的分解和综合方法分解成规模更小的问题并从这些更小问题的解构造出规模较大问题的解。特别地 当规模N=1时能直接得解。
【问题】 编写计算斐波那契(Fibonacci)数列的第n项函数fib(n) 。
斐波那契数列为 0、 1、 1、 2、 3、„„ 即
以下是引用片段fib(0)=0;fib(1)=1 ;fib(n)=fib(n-1)+fib(n-2) (当n>1时) 。
写成递归函数有
以下是引用片段int fib(int n)
{ if (n==0) return 0;if (n==1) return 1 ;if (n>1) return fib(n-1)+fib(n-2) ;
}
递归算法的执行过程分递推和回归两个阶段。在递推阶段把较复杂的问题(规模为n)的求解推到比原问题简单一些的问题(规模小于n)的求解。例如上例中求解fib(n) 把它推到求解fib(n-1)和fib(n-2) 。也就是说为计算fib(n) 必须先计算fib(n-1)和fib(n- 2) 而计算fib(n-1)和fib(n-2) 又必须先计算fib(n-3)和fib(n-4) 。依次类推直至计算fib(1)和fib(0) 分别能立即得到结果1和0。在递推阶段必须要有终止递归的情况。例如在函数fib中 当n为1和0的情况。
在回归阶段当获得最简单情况的解后逐级返回依次得到稍复杂问题的解例如得到fib(1)和fib(0)后返回得到fib(2)的结果 „„在得到了fib(n-1)和fib(n-2)的结果后返回得到fib(n)的结果。
在编写递归函数时要注意函数中的局部变量和参数知识局限于当前调用层当递推进入“简单问题”层时原来层次上的参数和局部变量便被隐蔽起来。在一系列“简单问题”层它们各有自己的参数和局部变量。
由于递归引起一系列的函数调用并且可能会有一系列的重复计算递归算法的执行效率相对较低。当某个递归算法能较方便地转换成递推算法时通常按递推算法编写程序。例如上例计算斐波那契数列的第n项的函数fib(n)应采用递推算法即从斐波那契数列的前两项出发逐次由前两项计算出下一项直至计算出要求的第n项。
【问题】 组合问题
问题描述找出从自然数1、 2、„„、 n中任取r个数的所有组合。例如n=5 r=3的所有组合为 (1)5、 4、 3 (2)5、 4、 2 (3)5、 4、 1
(4)5、 3、 2 (5)5、 3、 1 (6)5、 2、 1
(7)4、 3、 2 (8)4、 3、 1 (9)4、 2、 1
(10)3、 2、 1
分析所列的10个组合可以采用这样的递归思想来考虑求组合函数的算法。设函数为void comb(int m, int k)为找出从自然数1、 2、„„、 m中任取k个数的所有组合。当组合的第一个数字选定时其后的数字是从余下的m-1个数中取k-1数的组合。这就将求m个数中取k个数的组合问题转化成求m-1个数中取k-1个数的组合问题。设函数引入工作数组a[ ]
存放求出的组合的数字约定函数将确定的k个数字组合的第一个数字放在a[k]中 当一个组合求出后才将a[ ]中的一个组合输出。第一个数可以是m、 m-1、„„、 k函数将确定组合的第一个数字放入数组后有两种可能的选择因还未去顶组合的其余元素继续递归去确定;或因已确定了组合的全部元素输出这个组合。细节见以下程序中的函数comb。
【程序】
【问题】 背包问题
问题描述有不同价值、不同重量的物品n件求从这n件物品中选取一部分物品的选择方案使选中物品的总重量不超过指定的限制重量但选中物品的价值之和最大。
设n件物品的重量分别为w0、 w1、„、 wn-1物品的价值分别为v0、 v1、„、 vn-1。采用递归寻找物品的选择方案。设前面已有了多种选择的方案并保留了其中总价值最大的方案于数组option[ ] 该方案的总价值存于变量maxv。当前正在考察新方案其物品选择情况保存于数组cop[ ] 。假定当前方案已考虑了前i-1件物品现在要考虑第i件物品;当前方案已包含的物品的重量之和为tw;至此若其余物品都选择是可能的话本方案能达到的总价值的期望值为tv。算法引入tv是当一旦当前方案的总价值的期望值也小于前面方案的总价值maxv时继续考察当前方案变成无意义的工作应终止当前方案立即去考察下一个方案。因为当方案的总价值不比maxv大时该方案不会被再考察这同时保证函数后找到的方案一定会比前面的方案更好。
对于第i件物品的选择考虑有两种可能
(1)考虑物品i被选择这种可能性仅当包含它不会超过方案总重量限制时才是可行的。选中后继续递归去考虑其余物品的选择。
(2)考虑物品i不被选择这种可能性仅当不包含物品i也有可能会找到价值更大的方案的情况。
按以上思想写出递归算法如下
为了理解上述算法特举以下实例。设有4件物品它们的重量和价值见表
物品0 1 2 3
重量5 3 2 1
价值4 4 3 1
并设限制重量为7。则按以上算法下图表示找解过程。 由图知一旦找到一个解算法就进一步找更好的佳。如能判定某个查找分支不会找到更好的解算法不会在该分支继续查找而是立即终止该分支并去考察下一个分支。
按上述算法编写函数和程序如下【程序】
炭云怎么样?炭云(之前的碳云),国人商家,正规公司(哈尔滨桓林信息技术有限公司),主机之家测评介绍过多次。现在上海CN2共享IP的VPS有一款特价,上海cn2 vps,2核/384MB内存/8GB空间/800GB流量/77Mbps端口/共享IP/Hyper-v,188元/年,特别适合电信网络。有需要的可以关注一下。点击进入:炭云官方网站地址炭云vps套餐:套餐cpu内存硬盘流量/带宽ip价格购买上...
ThomasHost域名注册自2012年,部落最早分享始于2016年,还算成立了有几年了,商家提供基于KVM架构的VPS,数据中心包括美国、法国、英国、加拿大和爱尔兰等6个地区机房,VPS主机套餐最低2GB内存起步,支持Windows或者Linux操作系统,1Gbps端口不限制流量。最近商家提供了一个5折优惠码,优惠后最低套餐月付5美元起。下面列出部分套餐配置信息。CPU:1core内存:2GB硬...
tmhhost放出了2021年的端午佳节+618年中大促的优惠活动:日本软银、洛杉矶200G高防cn2 gia、洛杉矶三网cn2 gia、香港200M直连BGP、韩国cn2,全都是高端优化线路,所有这些VPS直接8折,部分已经做了季付8折然后再在此基础上继续8折(也就是6.4折)。 官方网站:https://www.tmhhost.com 香港BGP线路VPS ,200M带宽 200M带...