迭代算法
2016年公布的管理科学技术名词
迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。
相关概念
函数
在数学中,迭代函数是在分形动力系统中深入研究的对象。迭代函数是重复的与自身复合的函数,这个过程叫做迭代。
模型
迭代模型RUP(Rational Unified Process,统一软件开发过程统一软件过程)推荐的周期模型。
算法
迭代算法是用计算机解决问题的一种基本方法。它利用计算机运算速度快、适合做重复性操作的特点,让计算机对一组指令(或一定步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值。
RUP模型
理解
如果认为这个解释难以理解,可以这样想:
我们开发一个产品,如果不太复杂,会采用瀑布模型,简单的说就是先定义需求,然后构建框架,然后写代码,然后测试,最后发布一个产品。
这样,几个月过去了,直到最后一天发布时,大家才能见到一个产品。
这样的方式有明显的缺点,假如我们对用户的需求判断的不是很准确时——这是很常见的问题,一点也不少见——你工作了几个月甚至是几年,当你把产品拿给客户看时,客户往往会大吃一惊,这就是我要的东西吗?
方法
迭代的方式就有所不同,假如这个产品要求6个月交货,我在第一个月就会拿出一个产品来,当然,这个产品会很不完善,会有很多功能还没有添加进去,bug很多,还不稳定,但客户看了以后,会提出更详细的修改意见,这样,你就知道自己距离客户的需求有多远,我回家以后,再花一个月,在上个月所作的需求分析、框架设计、代码、测试等等的基础上,进一步改进,又拿出一个更完善的产品来,给客户看,让他们提意见。
就这样,我的产品在功能上、质量上都能够逐渐逼近客户的要求,不会出现我花了大量心血后,直到最后发布之时才发现根本不是客户要的东西的情况。
优势
这样的方法很不错,但他也有自己的缺陷,那就是周期长、成本很高。在应付大项目、高风险项目——就比如是航天飞机的控制系统时,迭代的成本比项目失败的风险成本低得多,用这种方式明显有优势。
如果你是给自己的单位开发一个小MIS,自己也比较清楚需求,工期上也不过花上个把月的时间,用迭代就有点杀鸡用了牛刀,那还是瀑布模型更管用,即使是做得不对,顶多再花一个月重来,没什么了不起。
基本算法
有些国外的教材,如《C++ Primer》第四版的中文版,会把iterative翻译成迭代。
在java中Iterative 仅用于遍历集合,本身并不提供盛装对象的能力。如果需要创建Iterative对象,则必须有一个被迭代的集合。没有集合的Iterative仿佛无本之木,没有存在的价值。
iterative是反复的意思,所以,有时候,迭代也会指循环执行,反复执行的意思。
利用迭代算法解决问题,需要做好以下三个方面的工作:
确定变量
在可以用迭代算法解决的问题中,至少存在一个直接或间接地不断由旧值递推出新值的变量,这个变量就是迭代变量。
建立关系式
所谓迭代关系式,指如何从变量的前一个值推出其下一个值的公式(或关系)。迭代关系式的建立是解决迭代问题的关键,通常可以使用递推或倒推的方法来完成。
过程控制
在什么时候结束迭代过程?这是编写迭代程序必须考虑的问题。不能让迭代过程无休止地重复执行下去。迭代过程的控制通常可分为两种情况:一种是所需的迭代次数是个确定的值,可以计算出来;另一种是所需的迭代次数无法确定。对于前一种情况,可以构建一个固定次数的循环来实现对迭代过程的控制;对于后一种情况,需要进一步分析出用来结束迭代过程的条件。
例1 : Fibonacci Sequence(斐波那契数列)
即这样一个数列:0、1、1、2、3、5、8、13......,在数学上该数列定义为:
F(0)=0,F(1)=1; F(n) = F(n-1)+F(n-2) (n≥2,n∈N*)。
一般该数列可以递归实现,下面是用C语言 迭代 实现:
int fab(int n)
{ if (n<3)
{return 1;}
else
{int first = 1,second = 1,temp = 0;
for (int i =0;i
{temp = first + second;
first = second;
second = temp;}
return temp;
}
}
例 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*2
x=y
让计算机对这个迭代关系重复执行 11 次,就可以算出第 12 个月时的兔子数。参考程序如下:
以下是引用片段:
cls
x=1
for i=2 to 12
y=x*2
x=y
next i
print y
end
例 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 次分裂之前的阿米巴个数。因为所需的迭代次数是个确定的值,我们可以使用一个固定次数的循环来实现对迭代过程的控制。参考程序如下:
以下是引用片段:
cls
x=2^20
for i=1 to 15
x=x/2
next i
print x
end
例 3 :验证角谷猜想。日本数学家角谷静夫在研究自然数时发现了一个奇怪现象:对于任意一个自然数 n ,若 n 为偶数,则将其除以 2 ;若 n 为奇数,则将其乘以 3 ,然后再加 1。如此经过有限次运算后,总可以得到自然数1。人们把角谷静夫的这一发现叫做“角谷猜想”。
要求:编写一个程序,由键盘输入一个自然数n ,把 n 经过有限次运算后,最终变成自然数 1 的全过程打印出来。
分析:定义迭代变量为 n ,按照角谷猜想的内容,可以得到两种情况下的迭代关系式:当 n 为偶数时, n=n/2 ;当 n 为奇数时, n=n*3+1。用 QBASIC 语言把它描述出来就是:
以下是引用片段:
if n 为偶数 then
n=n/2
else
n=n*3+1
end if
这就是需要计算机重复执行的迭代过程。这个迭代过程需要重复执行多少次,才能使迭代变量n 最终变成自然数1 ,这是我们无法计算出来的。因此,还需进一步确定用来结束迭代过程的条件。仔细分析题目要求,不难看出,对任意给定的一个自然数n ,只要经过有限次运算后,能够得到自然数 1 ,就已经完成了验证工作。因此,用来结束迭代过程的条件可以定义为:n=1。参考程序如下:
以下是引用片段:
cls
do until n=1
if n mod 2=0 then
rem 如果 n 为偶数,则调用迭代公式 n=n/2
n=n/2
else
n=n*3+1
end if
loop
end
应用实例
迭代法是用于求方程或方程组近似根的一种常用的算法设计方法。设方程为f(x)=0,用某种数学方法导出等价的形式x=g(x),然后按以下步骤执行:
⑴ 选一个方程的近似根,赋给变量x0;
⑵ 将x0的值保存于变量x1,然后计算g(x1),并将结果存于变量x0;
⑶ 当x0与x1的差的绝对值还大于指定的精度要求时,重复步骤⑵的计算。
若方程有根,并且用上述方法计算出来的近似根序列收敛,则按上述方法求得的x0就认为是方程的根。上述算法用C程序的形式表示为:
【算法】迭代法求方程的根
以下是引用片段:
{ x0=初始近似根;
do {
x1=x0;
x0=g(x1); /*按特定的方程计算新的近似根*/
} while (fabs(x0-x1)>Epsilon);
printf(“方程的近似根是%f ”,x0);
}
迭代算法也常用于求方程组的根,令
X=(x0,x1,…,xn-1)
设方程组为:
xi=gi(X) (I=0,1,…,n-1)
则求方程组根的迭代算法可描述如下:
【算法】迭代法求方程组的根
以下是引用片段:
{ for (i=0;i
x=初始近似根;
do {
for (i=0;i
y=x;
for (i=0;i
x=gi(X);
for (delta=0.0,i=0;i
if (fabs(y-x)>delta) delta=fabs(y-x);
} while (delta>Epsilon);
for (i=0;i
printf(“变量x[%d]的近似根是 %f”,I,x);
printf(“ ”);
}
具体使用迭代法求根时应注意以下两种可能发生的情况:
⑴ 如果方程无解,算法求出的近似根序列就不会收敛,迭代过程会变成死循环,因此在使用迭代算法前应先考察方程是否有解,并在程序中对迭代的次数给予限制;
⑵ 方程虽然有解,但迭代公式选择不当,或迭代的初始近似根选择不合理,也会导致迭代失败。
① N 为兔子的个数, M为月份 (N+N*1)^M-1=2N^M-1 (注解)
参考资料
最新修订时间:2024-02-16 04:23
目录
概述
相关概念
RUP模型
参考资料