计算方法------解线性方程组的迭代法
在科学研究和工程技术中有许多
问题可归结为求解线性代数方程组。关于线性代数方程组的数值解法一般分为两大类:直接法和迭代法。迭代法是通过构造适当的迭代公式,经过有限次的迭代运算来求得方程组近似解的方法。通过本实验的
学习,应掌握Jacobi迭代法和G-S迭代法的基本思想和原理,了解它们各自的优缺点及适用范围。
分别用Jacobi迭代法和G-S迭代法求解方程组
要求:(1)求解过程中,应输出系数矩阵详细的变化过程;
(2)通过迭代过程,说明这两种方法是否收敛。
1.基本原理:迭代法是一种逐次逼近法。雅克比(Jacobi)迭代法在求解线性方程组时,先定义一个初始向量x(0)=(0,0,0,…),其中初始向量的零的个数与所求的方程组的未知数的个数相等。
再依次代入x=Bx+f,因此可以构造出一个向量序列{x(k)},如果该得到的向量序列{x(k)}是收敛的,则就可得到解。而高斯-塞德尔(G-S)迭代法与雅克比(Jacobi)迭代法相似,只是高斯-塞德尔(G-S)迭代法每迭代一次只需计算一次矩阵与向量的乘法。
2.
程序框图:
3.源程序如下:
①雅克比(Jacobi)迭代法:
#include
#include
intfunction(floaty[3],floatx[3]);/*判断是否收敛,满足精度函数申明*/
floatx[3]={0,0,0},z;/*定义初始向量x*/
inti,j,k,n=3;
main()
{
floata[3][3]={{1,2,-2},{1,1,1},{2,2,1}},b[3]={1,1,1};
floaty[3],sum;
intflag;
for(k=0;k<100;k++)/*迭代的次数*/
{
for(i=0;i {
sum=0;
for(j=0;j {
if(j!=i)
sum=sum+a[i][j]*x[j];
}
y[i]=(b[i]-sum)/a[i][i];/*算出该迭代时的y[i]*/
}
for(i=0;i {
printf("x%d=%-10.6f",i+1,y[i]);
}
printf("\n");
flag=function(y,x);/*调用函数function()*/
if(flag==1)/*结束循环*/
break;
}
}
intfunction(floaty[3],floatx[3])/*判断是否收敛,满足精度函数的定义*/
{
intflag=0;/*标志主函数中的循环是否要结束*/
z=fabs(y[0]-x[0]);
for(i=0;i if(z z=fabs(y[i]-x[i]);
if(z<10e-6)
{
flag=1;
printf("diedaidecishushik=%d\n",k+1);/*输出得到最后结果迭代的次数*/
printf("zuihoudejieguoshi:\n");
for(i=0;i printf("x%d=%-10.6f",i+1,y[i]);/*输出方程组的解*/
printf("\n");
}
else
for(i=0;i x[i]=y[i];
return(flag);
}
②高斯-塞德尔(G-S)迭代法:
#include
#include
main()
{
floata[3][3]={{1,2,-2},{1,1,1},{2,2,1}},b[3]={1,1,1};
floatx[3]={0,0,0},sum1,sum2;
inti,j,k,n;
prinf("pleaseinputn:\n");
scanf("%d",&;n);/*输入未知数的个数*/
for(k=0;k<6;k++)/*迭代的次数*/
{for(i=0;i {sum1=0;sum2=0;
for(j=0;j sum1=sum1+a[i][j]*x[j];
for(j=i+1;j sum2=sum2+a[i][j]*x[j];
x[i]=(b[i]-sum1-sum2)/a[i][i];/*运用公式*/
}
for(i=0;i printf("x%d=%-15f",i+1,x[i]);/*输出迭代的数值*/
printf("\n");
}