数值计算方法 用逐次松弛法求方程组的解
中北大学理学院
课 程 设 计
题目:用逐次松弛法求方程组的解 课程:数值计算方法 成员: 1107014124 董强
1107014126 李迎 1107014128 冯梦文
已知方程组:
=1⎧2u 1-u 2
⎪-u +2u -u =0⎪123
⎨
-u +2u -u =1234⎪⎪-u 3+2u 4=0⎩
1T
取初值x (0)=(1,1,1,1),要求x (k )-x (k -1)≤⨯10-5。
2
一、问题分析
求解这个方程组,从题目中我们可以看出,有三种方法,雅可比迭代法、高赛德尔迭代法、逐次超松弛法。但是迭代发收敛速度太慢,就会增加计算量,而失去使用价值。逐次超松弛(Successive Over Relaxation)迭代法,简称SOR 迭代法,它是在GS 法基础上为提高收敛速度,采用加权平均而得到的新算法。它是大型解稀疏矩阵方程组的有效方法之一,具有计算公式简单,程序设计容易,占用计算机内存少等优点,但需要选择加速因子。 超松弛迭代法的理论基础
逐次超松弛(Successive Over Relaxation) 迭代法,简称SOR 迭代法,它是在GS 法基础上为提高收敛速度,采用加权平均而得到的新算法,设解方程(7.1.3)的GS 法记为
x
(k +1)
i -1n 1(k +1)
=(b i -∑a ij x j -∑a ij x (j k ) ), i =1, 2,... n (1)
j =1j =i +1a ii
再由与加权平均得
x i (k +1) =(1-w ) x i (k ) +w i (k +1) =x i (k ) +w (i (k +1) -x i (k ) ), i =1, 2,.... n 这里ω>0称为松弛参数,将(1)代入则得
x i
(k +1)
=(1-w ) x i
(k )
i -1n
w (k +1) (k ) +(b i -∑a ij x j -∑a ij x j ) a ii j =1j =i +1 (2)
该法称为SOR 迭代法,[WTBX]ω>0称为松弛因子,当ω=1时(2)式即为高斯-赛德尔迭代法,简记GS 法,将(2)写成矩阵形式,则得 Dx (k +1) =(1-w ) Dx (k ) +w (b +Lx (k +1) +Ux (k ) )
即 (D -wL ) x (k +1) =[(1-w ) D +wU ]x (k ) +wb 从而
x (k +1) =-(D +wL ) -1[(w -1) D +wU ]x (k ) +w (D +wL ) -1b k=0、1、2、、、、、 于是得SOR 迭代的矩阵表示
M SO R =-(D +wL ) -1[(w -1) D +wU ]
加速因子w 的选择
对于SOR 法,松弛因子的选择对于收敛速度影响较大,关于最优松弛因子W 的研究较为复杂,对此我们选用不同的松弛因子比较其收敛速度。
由SOR 法收敛,则0
二、问题求解
结果说明及分析:
不同松弛因子的收敛速度比较
注:w=1时,是高斯赛德尔迭代法。
最后对于不同的w 取值,我们进行计算并列表比较,可以发现不同w 取值迭代收敛速度不同,当w=1.3时,迭代收敛速度最快。
最终方程组的解为x =(1. 19999838, 1. 39999928, 1. 59999984, 0. 79999980) T 与精确
解x =(1, 20000000, 1. 40000000, 1. 60000000, 0. 80000000) T 接近,且满足题目所要求的精度
附录:计算程序
#include #include #include using namespace std;
#define kk 50 //定义最大方程元数 int n,i,c,j,ll,hh,gg,mm,f=1;
double A[kk][kk],x[kk][kk],b[kk],y[kk],a[kk],z[kk],m,nn,d,e=1,w,fff ;
void main() {
cout
**********************************************************************"
cout
cout
**********************************************************************">n;
cout>A[i][j];
cout>b[i];
cout>fff;
cout>mm;
for(i=0;i
b[i]=b[i]/A[i][i];
for(j=0;j
if(i==j)
{
x[i][i]=0; } else {
x[i][j]=-A[i][j]/A[i][i]; } } }
//*****************************赋迭代初值*********************************** cout>y[i];
//***********************************逐次超松弛法********************************
dd: cout>w; if(w>=2) {
cout>w; }
if(w
cout>w; }
cout
cout
cout
cout
coutfff) {
for(i=0;i
{
z[i]=y[i];
nn=0;
for(j=0;j
{
nn=nn+x[i][j]*y[j];
y[i]=(1-w)*z[i]+w*(nn+b[i]);
}
e=fabs(z[0]-y[0]);
if(fabs(z[i]-y[i])>e)
e=fabs(z[i]-y[i]);
if(i==0)
{
cout
cout
cout
cout
}
cout
cout
if(f>mm)
{
cout
cout
exit(1);
}
}
cout
cout
cout
cout
for(i=0;i
{
cout
cout
}
exit(1);
}
10