Jacobi和Gauss-Seidel迭代法求解方程组

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_27508477/article/details/83152993

迭代法简介

迭代法也称辗转法,是一种不断用变量的旧值递推新值的过程,跟迭代法相对应的是直接法(或者称为一次解法),即一次性解决问题。迭代算法是用计算机解决问题的一种基本方法,它利用计算机运算速度快、适合做重复性操作的特点,让计算机对一组指令(或一定步骤)进行重复执行,在每次执行这组指令(或这些步骤)时,都从变量的原值推出它的一个新值,迭代法又分为精确迭代和近似迭代。比较典型的迭代法如“二分法”和"牛顿迭代法”属于近似迭代法。

Jacobi迭代

以如下方程组为例:
10 x 1 2 x 2 x 3 = 3 10x{_1}-2x{_2}-x{_3}=3
2 x 1 + 10 x 2 x 3 = 15 -2x{_1}+10x{_2}-x{_3}=15
1 x 1 2 x 2 5 x 3 = 10 -1x{_1}-2x{_2}-5x{_3}=10

高斯消元法(高中用的那种)可以算出结果分别为1,2,3

Jacobi的计算过程:
先对每行分别进行变换,左边分别只留下 x 1 x 2 x 3 x{_1}、x{_2}、x{_3}
x 1 = 0.2 x 2 + 0.1 x 3 + 0.3 x{_1}=0.2x{_2}+0.1x{_3}+0.3
x 2 = 0.2 x 1 + 0.1 x 3 + 1.5 x{_2}=0.2x{_1}+0.1x{_3}+1.5
x 3 = 0.2 x 1 + 0.4 x 2 + 2 x{_3}=0.2x{_1}+0.4x{_2}+2
相信大家到这一步都会,那么我们就开始分别计算 x 1 x 2 x 3 x{_1}、x{_2}、x{_3} 的值吧。

先设 x 1 x 2 x 3 x{_1}、x{_2}、x{_3} 都为0,第一次迭代,他们的结果分别为: 0.3 1.5 2 0.3、1.5、2

然后把 0.3 1.5 2 0.3、1.5、2 分别带入 x 1 x 2 x 3 x{_1}、x{_2}、x{_3} 计算,则:
x 1 = 0.2 x 2 + 0.1 x 3 + 0.3 = 0.2 1.5 + 0.1 2 + 0.3 = 0.8 x{_1}=0.2x{_2}+0.1x{_3}+0.3=0.2*1.5+0.1*2+0.3=0.8
x 2 = 0.2 x 1 + 0.1 x 3 + 1.5 = 0.2 0.3 + 0.1 0.2 + 1.5 = 1.76 x{_2}=0.2x{_1}+0.1x{_3}+1.5=0.2*0.3+0.1*0.2+1.5=1.76
x 3 = 0.2 x 1 + 0.4 x 2 + 2 = 0.2 0.3 + 0.4 1.5 + 2 = 2.66 x{_3}=0.2x{_1}+0.4x{_2}+2=0.2*0.3+0.4*1.5+2=2.66

迭代10次可得结果如下:

次数 x 1 x{_1} x 2 x{_2} x 3 x{_3}
1 0.3 1.5 2.0
2 0.8 1.76 2.66
3 0.918 1.926 2.864
4 0.972 1.97 2.954
5 0.989 1.99 2.982
6 0.996 1.996 2.994
7 0.999 1.999 2.998
8 1.0 2.0 2.999
9 1.0 2.0 3.0
10 1.0 2.0 3.0

其python代码如下:

x1=0
x2=0
x3=0
print('Jacobi')
for i in range(10):
    x11=round(0.2*x2+0.1*x3+0.3,3)
    x22=round(0.2*x1+0.1*x3+1.5,3)
    x33=round(0.2*x1+0.4*x2+2,3)
    print('|',i+1,'|',x11,'|',x22,'|',x33,'|')
    x1=x11
    x2=x22
    x3=x33

其中round是将结果保留3位小数。

上面这个过程叫Jacobi迭代。

Gauss-Seidel迭代

高斯迭代唯一的区别在于,在每次迭代的过程中,都使用最新的值,直接上代码大家应该也可以看明白:

x1=0
x2=0
x3=0
print('Gauss-Seidel')
for i in range(10):
    x1=round(0.2*x2+0.1*x3+0.3,3)
    x2=round(0.2*x1+0.1*x3+1.5,3)
    x3=round(0.2*x1+0.4*x2+2,3)
    print('|',i+1,'|',x1,'|',x2,'|',x3,'|')

其10次迭代的结果如下:

次数 x 1 x{_1} x 2 x{_2} x 3 x{_3}
1 0.3 1.56 2.684
2 0.88 1.944 2.954
3 0.984 1.992 2.994
4 0.998 1.999 2.999
5 1.0 2.0 3.0
6 1.0 2.0 3.0
7 1.0 2.0 3.0
8 1.0 2.0 3.0
9 1.0 2.0 3.0
10 1.0 2.0 3.0

可以看到,只用5次就得到了正确的结果。
所以这里可以发现,高斯迭代法使用的空间小,并且计算速度快。

例2

为了计算复用,可以将函数封装一下:

#1.(1)
data=[
[10,-2,-1,3],
[-2,10,-1,15],
[-1,-2,5,10]
]

x=zeros(3)
xx=zeros(3)
print('Jacobi')
for i in range(10):
    xx[0]=round((-data[0][1]*x[1]-data[0][2]*x[2]+data[0][3])/data[0][0],3)
    xx[1]=round((-data[1][0]*x[0]-data[1][2]*x[2]+data[1][3])/data[1][1],3)
    xx[2]=round((-data[2][0]*x[0]-data[2][1]*x[1]+data[2][3])/data[2][2],3)
    x[0]=xx[0];x[1]=xx[1];x[2]=xx[2]
    print('|',i+1,'|',x[0],'|',x[1],'|',x[2],'|')
    #print(i+1,x[0],x[1],x[2])

x=zeros(3)
print('Gauss-Seidel')
for i in range(10):
    x[0]=round((-data[0][1]*x[1]-data[0][2]*x[2]+data[0][3])/data[0][0],3)
    x[1]=round((-data[1][0]*x[0]-data[1][2]*x[2]+data[1][3])/data[1][1],3)
    x[2]=round((-data[2][0]*x[0]-data[2][1]*x[1]+data[2][3])/data[2][2],3)
    print('|',i+1,'|',x[0],'|',x[1],'|',x[2],'|')
    #print(i+1,x[0],x[1],x[2])

得到的结果和上面一致:
Jacobi:

次数 x 1 x{_1} x 2 x{_2} x 3 x{_3}
1 0.3 1.5 2.0
2 0.8 1.76 2.66
3 0.918 1.926 2.864
4 0.972 1.97 2.954
5 0.989 1.99 2.982
6 0.996 1.996 2.994
7 0.999 1.999 2.998
8 1.0 2.0 2.999
9 1.0 2.0 3.0
10 1.0 2.0 3.0

Gauss-Seidel:

次数 x 1 x{_1} x 2 x{_2} x 3 x{_3}
1 0.3 1.56 2.684
2 0.88 1.944 2.954
3 0.984 1.992 2.994
4 0.998 1.999 2.999
5 1.0 2.0 3.0
6 1.0 2.0 3.0
7 1.0 2.0 3.0
8 1.0 2.0 3.0
9 1.0 2.0 3.0
10 1.0 2.0 3.0

上面这个例子是《数值计算方法》第二版 北京理工大学出版社 习题三的1(1),下面计算1(1)。
只需要修改数据:

#1.(2)
data=[
[8,-3,2,20],
[4,11,-1,33],
[2,1,4,12]
]

运行结果如下:
Jacobi:

次数 x 1 x{_1} x 2 x{_2} x 3 x{_3}
1 2.5 3.0 3.0
2 2.875 2.364 1.0
3 3.136 2.045 0.971
4 3.024 1.948 0.921
5 3.0 1.984 1.001
6 2.994 2.0 1.004
7 2.999 2.003 1.003
8 3.0 2.001 1.0
9 3.0 2.0 1.0
10 3.0 2.0 1.0

Gauss-Seidel:

次数 x 1 x{_1} x 2 x{_2} x 3 x{_3}
1 2.5 2.091 1.227
2 2.977 2.029 1.004
3 3.01 1.997 0.996
4 3.0 2.0 1.0
5 3.0 2.0 1.0
6 3.0 2.0 1.0
7 3.0 2.0 1.0
8 3.0 2.0 1.0
9 3.0 2.0 1.0
10 3.0 2.0 1.0

可以看出高斯法只需要4次就有结果了。

例3

以习题三的3题为例:

data=[
[1,2,-2,1],
[1,1,1,1],
[2,2,1,1]
]

其结果如下:
Jacobi:

次数 x 1 x{_1} x 2 x{_2} x 3 x{_3}
1 1.0 1.0 1.0
2 1.0 -1.0 -3.0
3 -3.0 3.0 1.0
4 -3.0 3.0 1.0
5 -3.0 3.0 1.0
6 -3.0 3.0 1.0
7 -3.0 3.0 1.0
8 -3.0 3.0 1.0
9 -3.0 3.0 1.0
10 -3.0 3.0 1.0

Gauss-Seidel:

次数 x 1 x{_1} x 2 x{_2} x 3 x{_3}
1 1.0 0.0 -1.0
2 -1.0 3.0 -3.0
3 -11.0 15.0 -7.0
4 -43.0 51.0 -15.0
5 -131.0 147.0 -31.0
6 -355.0 387.0 -63.0
7 -899.0 963.0 -127.0
8 -2179.0 2307.0 -255.0
9 -5123.0 5379.0 -511.0
10 -11779.0 12291.0 -1023.0

可以看出Jacobi迭代法迭代3次就能计算出答案,而Gauss-Seidel法得到的结果却发散了,可见Gauss-Seidel在使用时还有一定的要求。

上述内容是本人课程学习随笔,如有错误欢迎指出,共同学习。

猜你喜欢

转载自blog.csdn.net/qq_27508477/article/details/83152993
今日推荐