什么是牛顿迭代法 迭代算法原理


迭代法计算步骤迭代法计算步骤
迭代法
迭代法(Iteration)是一种不断用变量的旧值递推出新值的解决问题的方法 。迭代算法是用计算机解决问题的一种基本方法,一般用于数值计算 。累加、累乘都是迭代算法的基础应用 。典型案例:牛顿迭代法
步骤:
确定迭代模型:分析得出前一个(或几个)值与其下一个值的迭代关系数学模型;
建立迭代关系式
对迭代过程进行控制
经典案例:
示例: 斐波那契数列:1、1、2、3、5、8、13、21、34
对于斐波那契数列,当n趋于无穷时,数列最后的两项的商 (xn-1/xn) 趋于黄金分割数0.618
迭代算法是什么啊?迭代算法就是实现数值分析中通过从一个初始估计出发寻找一系列近似解来解决问题(一般是解方程或者方程组)的过程的方法 。
最常见的迭代法是牛顿法 。其他还包括最速下降法、共轭迭代法、变尺度迭代法、最小二乘法、线性规划、非线性规划、单纯型法、惩罚函数法、斜率投影法、遗传算法、模拟退火等等 。
迭代法的应用:
迭代法的主要研究课题是对所论问题构造收敛的迭代格式,分析它们的收敛速度及收敛范围 。迭代法的收敛性定理可分成下列三类:
1、局部收敛性定理:假设问题解存在,断定当初始近似与解充分接近时迭代法收敛 。
2、半局部收敛性定理:在不假定解存在的情况下,根据迭代法在初始近似处满足的条件,断定迭代法收敛于问题的解 。
3、大范围收敛性定理:在不假定初始近似与解充分接近的条件下,断定迭代法收敛于问题的解 。
迭代法在线性和非线性方程组求解,最优化计算及特征值计算等问题中被广泛应用 。
请问迭代是什么意思???望得到准确回答,谢谢 。。。是迭代法吧?
迭代法迭代法也称辗转法,是一种不断用变量的旧值递推新值的过程,跟迭代法相对应的是直接法(或者称为一次解法),即一次性解决问题 。迭代法又分为精确迭代和近似迭代 。“二分法”和“牛顿迭代法”属于近似迭代法 。
迭代算法是用计算机解决问题的一种基本方法 。它利用计算机运算速度快、适合做重复性操作的特点,让计算机对一组指令(或一定步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值 。
利用迭代算法解决问题,需要做好以下三个方面的工作:
一、确定迭代变量 。在可以用迭代算法解决的问题中,至少存在一个直接或间接地不断由旧值递推出新值的变量,这个变量就是迭代变量 。
二、建立迭代关系式 。所谓迭代关系式,指如何从变量的前一个值推出其下一个值的公式(或关系) 。迭代关系式的建立是解决迭代问题的关键,通常可以使用递推或倒推的方法来完成 。
三、对迭代过程进行控制 。在什么时候结束迭代过程?这是编写迭代程序必须考虑的问题 。不能让迭代过程无休止地重复执行下去 。迭代过程的控制通常可分为两种情况:一种是所需的迭代次数是个确定的值,可以计算出来;另一种是所需的迭代次数无法确定 。对于前一种情况,可以构建一个固定次数的循环来实现对迭代过程的控制;对于后一种情况,需要进一步分析出用来结束迭代过程的条件
迭代法的算法迭代是数值分析中通过从一个初始估计出发寻找一系列近似解来解决问题(一般是解方程或者方程组)的过程,为实现这一过程所使用的方法统称为迭代法(Iterative Method) 。
一般可以做如下定义:对于给定的线性方程组(这里的x、B、f同为矩阵,任意线性方程组都可以变换成此形式),用公式 (代表迭代k次得到的x,初始时k=0)逐步带入求近似解的方法称为迭代法(或称一阶定常迭代法) 。如果存在,记为x*,称此迭代法收敛 。显然x*就是此方程组的解,否则称为迭代法发散 。
跟迭代法相对应的是直接法(或者称为一次解法),即一次性的快速解决问题,例如通过开方解决方程x +3= 4 。一般如果可能,直接解法总是优先考虑的 。但当遇到复杂问题时,特别是在未知量很多,方程为非线性时,我们无法找到直接解法(例如五次以及更高次的代数方程没有解析解,参见阿贝耳定理),这时候或许可以通过迭代法寻求方程(组)的近似解 。
最常见的迭代法是牛顿法 。其他还包括最速下降法、共轭迭代法、变尺度迭代法、最小二乘法、线性规划、非线性规划、单纯型法、惩罚函数法、斜率投影法、遗传算法、模拟退火等等 。
利用迭代算法解决问题,需要做好以下三个方面的工作: 例 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 分钟后容器内充满了阿米巴 。已知容器最多可以装阿米巴 220,220个 。试问,开始的时候往容器内放了多少个阿米巴?请编程序算出 。
分析:根据题意,阿米巴每 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
ps:java中幂的算法是Math.pow(2,20);返回double,稍微注意一下
例 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
input Please input n=;n
do until n=1
if n mod 2=0 then
rem 如果 n 为偶数,则调用迭代公式 n=n/2
n=n/2
print —;n;
else
n=n*3+1
print —;n;
end if
loop
end
迭代法开平方:
#include<stdio.h>
#include<math.h>
void main()
{
double a,x0,x1;
printf(Input a:
);
scanf(%lf,&a);//因为a是double型数据,所以要用%lf,而不是%f
if(a<0)
printf(Error!
);
else
{
x0=a/2;
x1=(x0+a/x0)/2;
do
{
x0=x1;
x1=(x0+a/x0)/2;
}while(fabs(x0-x1)>=1e-6);
}
printf(Result:
);
printf(sqrt(%g)=%g
,a,x1);
}
求平方根的迭代公式:x1=1/2*(x0+a/x0) 。
算法:1.先自定一个初值x0,作为a的平方根值,在我们的程序中取a/2作为a的初值;利用迭代公式求出一个x1 。此值与真正的a的平方根值相比,误差很大 。
⒉把新求得的x1代入x0中,准备用此新的x0再去求出一个新的x1.
⒊利用迭代公式再求出一个新的x1的值,也就是用新的x0又求出一个新的平方根值x1,此值将更趋近于真正的平方根值 。
⒋比较前后两次求得的平方根值x0和x1,如果它们的差值小于我们指定的值,即达到我们要求的精度,则认为x1就是a的平方根值,去执行步骤5;否则执行步骤2,即循环进行迭代 。
迭代法是用于求方程或方程组近似根的一种常用的算法设计方法 。设方程为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的问题,设法将它分解成规模较小的问题,然后从这些小问题的解方便地构造出大问题的解,并且这些规模较小的问题也能采用同样的分解和综合方法,分解成规模更小的问题,并从这些更小问题的解构造出规模较大问题的解 。特别地,当规模N=1时,能直接得解 。
【问题】 编写计算斐波那契(Fibonacci)数列的第n项函数fib(n) 。
斐波那契数列为:0、1、1、2、3、……,即:
fib(0)=0;
fib⑴=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⑴和fib(0),分别能立即得到结果1和0 。在递推阶段,必须要有终止递归的情况 。例如在函数fib中,当n为1和0的情况 。
在回归阶段,当获得最简单情况的解后,逐级返回,依次得到稍复杂问题的解,例如得到fib⑴和fib(0)后,返回得到fib⑵的结果,……,在得到了fib(n-1)和fib(n-2)的结果后,返回得到fib(n)的结果 。
在编写递归函数时要注意,函数中的局部变量和参数知识局限于当前调用层,当递推进入“简单问题”层时,原来层次上的参数和局部变量便被隐蔽起来 。在一系列“简单问题”层,它们各有自己的参数和局部变量 。
由于递归引起一系列的函数调用,并且可能会有一系列的重复计算,递归算法的执行效率相对较低 。当某个递归算法能较方便地转换成递推算法时,通常按递推算法编写程序 。例如上例计算斐波那契数列的第n项的函数fib(n)应采用递推算法,即从斐波那契数列的前两项出发,逐次由前两项计算出下一项,直至计算出要求的第n项 。
【问题】 组合问题
问题描述:找出从自然数1、2、……、n中任取r个数的所有组合 。例如n=5,r=3的所有组合为:⑴5、4、3 ⑵5、4、2 ⑶5、4、1
⑷5、3、2 ⑸5、3、1 ⑹5、2、1
⑺4、3、2 ⑻4、3、1 ⑼4、2、1
⑽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 。
【程序】
# include
# define MAXN 100
int a[MAXN];
void comb(int m,int k)
{ int i,j;
for (i=m;i>=k;i--)
{ a[k]=i;
if (k>1)
comb(i-1,k-1);
else
{ for (j=a[0];j>0;j--)
printf(“%4d”,a[j]);
printf(“
”);
}
}
}
void main()
{ a[0]=3;
comb(5,3);
}
【问题】 背包问题
问题描述:有不同价值、不同重量的物品n件,求从这n件物品中选取一部分物品的选择方案,使选中物品的总重量不超过指定的限制重量,但选中物品的价值之和最大 。
设n 件物品的重量分别为w0、w1、…、wn-1,物品的价值分别为v0、v1、…、vn-1 。采用递归寻找物品的选择方案 。设前面已有了多种选择的方案,并保留了其中总价值最大的方案于数组option[ ],该方案的总价值存于变量maxv 。当前正在考察新方案,其物品选择情况保存于数组cop[ ] 。假定当前方案已考虑了前i-1件物品,现在要考虑第i件物品;当前方案已包含的物品的重量之和为tw;至此,若其余物品都选择是可能的话,本方案能达到的总价值的期望值为tv 。算法引入tv是当一旦当前方案的总价值的期望值也小于前面方案的总价值maxv时,继续考察当前方案变成无意义的工作,应终止当前方案,立即去考察下一个方案 。因为当方案的总价值不比maxv大时,该方案不会被再考察,这同时保证函数后找到的方案一定会比前面的方案更好 。
对于第i件物品的选择考虑有两种可能:
⑴ 考虑物品i被选择,这种可能性仅当包含它不会超过方案总重量限制时才是可行的 。选中后,继续递归去考虑其余物品的选择 。
⑵ 考虑物品i不被选择,这种可能性仅当不包含物品i也有可能会找到价值更大的方案的情况 。
按以上思想写出递归算法如下:
try(物品i,当前选择已达到的重量和,本方案可能达到的总价值tv)
{ /*考虑物品i包含在当前方案中的可能性*/
if(包含物品i是可以接受的)
{ 将物品i包含在当前方案中;
if (i
try(i+1,tw+物品i的重量,tv);
else
/*又一个完整方案,因为它比前面的方案好,以它作为最佳方案*/
以当前方案作为临时最佳方案保存;
恢复物品i不包含状态;
}
/*考虑物品i不包含在当前方案中的可能性*/
if (不包含物品i仅是可男考虑的)
if (i
try(i+1,tw,tv-物品i的价值);
else
/*又一个完整方案,因它比前面的方案好,以它作为最佳方案*/
以当前方案作为临时最佳方案保存;
}
为了理解上述算法,特举以下实例 。设有4件物品,它们的重量和价值见表:
物品 0 1 2 3
重量 5 3 2 1
价值 4 4 3 1
并设限制重量为7 。则按以上算法,下图表示找解过程 。由图知,一旦找到一个解,算法就进一步找更好的佳 。如能判定某个查找分支不会找到更好的解,算法不会在该分支继续查找,而是立即终止该分支,并去考察下一个分支 。
按上述算法编写函数和程序如下:
【程序】
# include
# define N 100
double limitW,totV,maxV;
int option[N],cop[N];
struct { double weight;
double value;
}a[N];
int n;
void find(int i,double tw,double tv)
{ int k;
/*考虑物品i包含在当前方案中的可能性*/
if (tw+a.weight<=limitW)
{ cop=1;
if (i
else
{ for (k=0;k
option[k]=cop[k];
maxv=tv;
}
cop=0;
}
/*考虑物品i不包含在当前方案中的可能性*/
if (tv-a.value>maxV)
if (i
else
{ for (k=0;k
option[k]=cop[k];
maxv=tv-a.value;
}
}
void main()
{ int k;
double w,v;
printf(“输入物品种数
”);
scanf((“%d”,&n);
printf(“输入各物品的重量和价值
”);
for (totv=0.0,k=0;k
{ scanf(“%1f%1f”,&w,&v);
a[k].weight=w;
a[k].value=https://pipe99.com/new/v;
totV+=V;
}
printf(“输入限制重量
”);
scanf(“%1f”,&limitV);
maxv=0.0;
for (k=0;k find(0,0.0,totV);
for (k=0;k
if (option[k]) printf(“%4d”,k+1);
printf(“
总价值为%.2f
”,maxv);
}
作为对比,下面以同样的解题思想,考虑非递归的程序解 。为了提高找解速度,程序不是简单地逐一生成所有候选解,而是从每个物品对候选解的影响来形成值得进一步考虑的候选解,一个候选解是通过依次考察每个物品形成的 。对物品i的考察有这样几种情况:当该物品被包含在候选解中依旧满足解的总重量的限制,该物品被包含在候选解中是应该继续考虑的;反之,该物品不应该包括在当前正在形成的候选解中 。同样地,仅当物品不被包括在候选解中,还是有可能找到比目前临时最佳解更好的候选解时,才去考虑该物品不被包括在候选解中;反之,该物品不包括在当前候选解中的方案也不应继续考虑 。对于任一值得继续考虑的方案,程序就去进一步考虑下一个物品 。
【程序】
# include
# define N 100
double limitW;
int cop[N];
struct ele { double weight;
double value;
} a[N];
int k,n;
struct { int ;
double tw;
double tv;
}twv[N];
void next(int i,double tw,double tv)
{ twv.=1;
twv tw=tw;
twv tv=tv;
}
double find(struct ele *a,int n)
{ int i,k,f;
double maxv,tw,tv,totv;
maxv=0;
for (totv=0.0,k=0;k
totv+=a[k].value;
next(0,0.0,totv);
i=0;
While (i>=0)
{ f=twv.;
tw=twv tw;
tv=twv tv;
switch(f)
{ case 1: twv.++;
if (tw+a.weight<=limitW)
if (i
{ next(i+1,tw+a.weight,tv);
i++;
}
else
{ maxv=tv;
for (k=0;k
cop[k]=twv[k].!=0;
}
break;
case 0: i--;
break;
default: twv.=0;
if (tv-a.value>maxv)
if (i
{ next(i+1,tw,tv-a.value);
i++;
}
else
{ maxv=tv-a.value;
for (k=0;k
cop[k]=twv[k].!=0;
}
break;
}
}
return maxv;
}
void main()
{ double maxv;
printf(“输入物品种数
”);
scanf((“%d”,&n);
printf(“输入限制重量
”);
scanf(“%1f”,&limitW);
printf(“输入各物品的重量和价值
”);
for (k=0;k
scanf(“%1f%1f”,&a[k].weight,&a[k].value);
maxv=find(a,n);
printf(“
选中的物品为
”);
for (k=0;k
if (option[k]) printf(“%4d”,k+1);
printf(“
总价值为%.2f
”,maxv);
}

什么是迭代算法?迭代算法是用计算机解决问题的一种基本方法 。它利用计算机运算速度快、适合做重复性操作的特点,让计算机对一组指令(或一定步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值 。
利用迭代算法解决问题,需要做好以下三个方面的工作:
一、确定迭代变量 。在可以用迭代算法解决的问题中,至少存在一个直接或间接地不断由旧值递推出新值的变量,这个变量就是迭代变量 。
二、建立迭代关系式 。所谓迭代关系式,指如何从变量的前一个值推出其下一个值的公式(或关系) 。迭代关系式的建立是解决迭代问题的关键,通常可以使用递推或倒推的方法来完成 。
三、对迭代过程进行控制 。在什么时候结束迭代过程?这是编写迭代程序必须考虑的问题 。不能让迭代过程无休止地重复执行下去 。迭代过程的控制通常可分为两种情况:一种是所需的迭代次数是个确定的值,可以计算出来;另一种是所需的迭代次数无法确定 。对于前一种情况,可以构建一个固定次数的循环来实现对迭代过程的控制;对于后一种情况,需要进一步分析出用来结束迭代过程的条件 。
例 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
什么是牛顿迭代法?产生背景
牛顿迭代法(Newton's method)又称为牛顿-拉夫逊方法(Newton-Raphson method),它是牛顿在17世纪提出的一种在实数域和复数域上近似求解方程的方法 。多数方程不存在求根公式,因此求精确根非常困难,甚至不可能,从而寻找方程的近似根就显得特别重要 。方法使用函数f(x)的泰勒级数的前面几项来寻找方程f(x) = 0的根 。牛顿迭代法是求方程根的重要方法之一,其最大优点是在方程f(x) = 0的单根附近具有平方收敛,而且该法还可以用来求方程的重根、复根,此时线性收敛,但是可通过一些方法变成超线性收敛 。另外该方法广泛用于计算机编程中 。
编辑本段牛顿迭代公式
设r是f(x) = 0的根,选取x0作为r初始近似值,过点(x0,f(x0))做曲线y = f(x)的切线L,L的方程为y = f(x0)+f'(x0)(x-x0),求出L与x轴交点的横坐标 x1 = x0-f(x0)/f'(x0),称x1为r的一次近似值 。过点(x1,f(x1))做曲线y = f(x)的切线,并求该切线与x轴交点的横坐标 x2 = x1-f(x1)/f'(x1),称x2为r的二次近似值 。重复以上过程,得r的近似值序列,其中x(n+1)=x(n)-f(x(n))/f'(x(n)),称为r的n+1次近似值,上式称为牛顿迭代公式 。解非线性方程f(x)=0的牛顿法是把非线性方程线性化的一种近似方法 。把f(x)在x0点附近展开成泰勒级数 f(x) = f(x0)+(x-x0)f'(x0)+(x-x0)^2*f''(x0)/2! +… 取其线性部分,作为非线性方程f(x) = 0的近似方程,即泰勒展开的前两项,则有f(x0)+f'(x0)(x-x0)=0 设f'(x0)≠0则其解为x1=x0-f(x0)/f'(x0) 这样,得到牛顿法的一个迭代序列:x(n+1)=x(n)-f(x(n))/f'(x(n)) 。牛顿迭代法示意图
军人在进攻时常采用交替掩护进攻的方式,若在数轴上的点表示A,B两人的位置,规定在前面的数大于后面的数,则是A>B,B>A交替出现 。但现在假设军中有一个胆小鬼,同时大家又都很照顾他,每次冲锋都是让他跟在后面,每当前面的人占据一个新的位置,就把位置交给他,然后其他人再往前占领新的位置 。也就是A始终在B的前面,A向前迈进,B跟上,A把自己的位置交给B(即执行B = A操作),然后A 再前进占领新的位置,B再跟上……直到占领所有的阵地,前进结束 。像这种两个数一前一后逐步向某个位置逼近的方法称之为迭代法 。迭代法也称辗转法,是一种不断用变量的旧值递推新值的过程,跟迭代法相对应的是直接法(或者称为一次解法),即一次性解决问题 。迭代算法是用计算机解决问题的一种基本方法 。它利用计算机运算速度快、适合做重复性操作的特点,让计算机对一组指令(或一定步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值 。利用迭代算法解决问题,需要做好以下三个方面的工作: 一、确定迭代变量 。在可以用迭代算法解决的问题中,至少存在一个直接或间接地不断由旧值递推出新值的变量,这个变量就是迭代变量 。二、建立迭代关系式 。所谓迭代关系式,指如何从变量的前一个值推出其下一个值的公式(或关系) 。迭代关系式的建立是解决迭代问题的关键,通常可以使用递推或倒推的方法来完成 。三、对迭代过程进行控制 。在什么时候结束迭代过程?这是编写迭代程序必须考虑的问题 。不能让迭代过程无休止地重复执行下去 。迭代过程的控制通常可分为两种情况:一种是所需的迭代次数是个确定的值,可以计算出来;另一种是所需的迭代次数无法确定 。对于前一种情况,可以构建一个固定次数的循环来实现对迭代过程的控制;对于后一种情况,需要进一步分析出用来结束迭代过程的条件 。最经典的迭代算法是欧几里德算法,用于计算两个整数a,b的最大公约数 。其计算原理依赖于下面的定理: 定理:gcd(a, b) = gcd(b, a mod b) 证明:a可以表示成a = kb + r,则r = a mod b。假设d是a,b的一个公约数,则有 a%d==0, b%d==0,而r = a - kb,因此r%d==0,因此d是(b, a mod b)的公约数 同理,假设d 是(b, a mod b)的公约数,则 b%d==0 , r%d==0,但是a = kb +r,因此d也是(a,b)的公约数。因此(a,b)和(b,a mod b)的公约数是一样的,其最大公约数也必然相等,得证 。欧几里德算法就是根据这个原理来做的,欧几里德算法又叫辗转相除法,它是一个反复迭代执行,直到余数等于0停止的步骤,这实际上是一个循环结构 。其算法用C语言描述为: int Gcd_2(int a, int b)// 欧几里德算法求a, b的最大公约数 { if (a<=0 || b<=0) //预防错误 return 0; int temp; while (b > 0) //b总是表示较小的那个数,若不是则交换a,b的值 { temp = a % b; //迭代关系式 a = b%a; //是那个胆小鬼,始终跟在b的后面 b = temp%b; //向前冲锋占领新的位置 } return a; } 从上面的程序我们可以看到a,b是迭代变量,迭代关系是temp = a % b; 根据迭代关系我们可以由旧值推出新值,然后循环执a = b; b = temp;直到迭代过程结束(余数为0) 。在这里a好比那个胆小鬼,总是从b手中接过位置,而b则是那个努力向前冲的先锋 。还有一个很典型的例子是斐波那契(Fibonacci)数列 。斐波那契数列为:0、1、1、2、3、5、8、13、21、…,即 fib(1)=0; fib(2)=1; fib(n)=fib(n-1)+fib(n-2) (当n>2时) 。在n>2时,fib(n)总可以由fib(n-1)和fib(n-2)得到,由旧值递推出新值,这是一个典型的迭代关系,所以我们可以考虑迭代算法 。int Fib(int n) //斐波那契(Fibonacci)数列 { if (n < 1)//预防错误 return 0; if (n == 1 || n == 2)//特殊值,无需迭代 return 1; int f1 = 1, f2 = 1, fn;//迭代变量 int i; for(i=3; i<=n; ++i)//用i的值来限制迭代的次数 { fn = f1 + f2; //迭代关系式 f1 = f2; //f1和f2迭代前进,其中f2在f1的前面 f2 = fn; } return fn; }
编辑本段C语言代码
double func(double x) //函数 { return x*x*x*x-3*x*x*x+1.5*x*x-4.0; } double func1(double x) //导函数 { return 4*x*x*x-9*x*x+3*x; } int Newton(double *x,double precision,int maxcyc) //迭代次数 { double x1,x0; int k; x0=*x; for(k=0;k<maxcyc;k++) { if(func1(x0)==0.0)//若通过初值,函数返回值为0 { printf("迭代过程中导数为0!
"); return 0; } x1=x0-func(x0)/func1(x0);//进行牛顿迭代计算 if(fabs(x1-x0)<precision || fabs(func(x1))<precision) //达到结束条件 { *x=x1; //返回结果 return 1; } else //未达到结束条件 x0=x1; //准备下一次迭代 } printf("迭代次数超过预期!
"); //迭代次数达到,仍没有达到精度 return 0; } int main() { double x,precision; int maxcyc; printf("输入初始迭代值x0:"); scanf("%lf",&x); printf("输入最大迭代次数:"); scanf("%d",&maxcyc); printf("迭代要求的精度:"); scanf("%lf",&precision); if(Newton(&x,precision,maxcyc)==1) //若函数返回值为1 printf("该值附近的根为:%lf
",x); else //若函数返回值为0 printf("迭代失败!
"); getch(); return 0; }
编辑本段C++代码
//此函数是用来求3元一次方程ax^3+bx^2+cx+d=0的解 //比如 x^3-27=0,我们就可以输入1 0 0 -27,这样我们就可以得到一个解 #include<iostream> #include<cmath> using namespace std; int main() { double diedai(double a,double b,double c,double d,double x); double a,b,c,d; double x=10000.0; cout<<"请依次输入方程四个系数:"; cin>>a>>b>>c>>d; x=diedai(a,b,c,d,x); cout<<x<<endl; return 0; } double diedai(double a,double b,double c,double d,double x) { while(abs(a*x*x*x+b*x*x+c*x+d)>0.000001) { x=x-(a*x*x*x+b*x*x+c*x+d)/(3*a*x*x+2*b*x+c); } return x; }
编辑本段matlab代码
1.定义函数
function y=f(x) y=f(x);%函数f(x)的表达式 function y=z(x) y=z(x);%函数z(x)的表达式
2.主程序
x=X;%迭代初值 i=0;%迭代次数计算 while i<= I;%迭代次数 y=x-y(x)/z(x);%牛顿迭代格式 if abs(y-x)>ε;%收敛判断 x=y; else break end i=i+1; end fprintf('
%s%.4f\t%s%d','x=',x,'i=',i) %输出结果
编辑本段Python代码
Python代码以实例展示求解f(x) = (x-3)**3,f(x) = 0 的根 。
[1]def f(x): return (x-3)**3 ’''定义f(x) = (x-3)**3''' def fd(x): return 3*((x-3)**2) ’''定义f'(x) = 3*((x-3)**2) def newtonMethod(n,assum): time = n x = assum Next = 0 A = f(x) B = fd(x) print('A = ' + str(A) + ',B = ' + str(B) + ',time = ' + str(time)) if f(x) == 0.0: return time,x else: Next = x - A/B print('Next x = '+ str(Next)) if A == f(Next): print('Meet f(x) = 0 , x = ' + str(Next)) ’''设置迭代跳出条件,同时输出满足f(x) = 0的x值''' else: return newtonMethod(n+1,Next) newtonMethod(0,4.0) ’''设置从0开始计数,x0 = 4.0'''
关于迭代算法和迭代算法原理的内容就分享到这儿!更多实用知识经验,尽在 www.hubeilong.com