Jacobi法、Gauss-Seidel法、超松弛法求解线性代数方程组

问题引入

利用计算机求解线性方程组,精度要求为 ε = 0.001 \varepsilon=0.001
{ 10 x 1 x 2 2 x 3 = 7.2 x 1 + 10 x 2 2 x 3 = 8.3 x 1 x 2 + 5 x 3 = 4.2 \left\{\begin{array}{l}10x_1-x_2-2x_3=7.2\\-x_1+10x_2-2x_3=8.3\\-x_1-x_2+5x_3=4.2\end{array}\right.
精确解为:
{ x 1 = 1.1 x 2 = 1.2 x 3 = 1.3 \left\{\begin{array}{l}x_1^\ast=1.1\\x_2^\ast=1.2\\x_3^\ast=1.3\end{array}\right.

雅可比(Jacobi)迭代公式

考察一般线性方程组:
j = 1 n a i j x j = b i , i N ( 1 ) {\textstyle\sum_{j=1}^n}a_{ij}x_j=b_i,i\in N^\ast(1)
将式 ( 1 ) (1) 改写为:
x i = b i j = 1 n a i j x j a i i , i N , ( j i ) . ( 2 ) x_i=\frac{b_i-\sum_{j=1}^na_{ij}x_j}{a_{ii}},i\in N^\ast,(j≠i).(2)
根据上述两式,建立雅可比(Jacobi)迭代公式:
x i ( k + 1 ) = b i j = 1 n a i j x j ( k ) a i i , i N , ( j i ) . x_i^{(k+1)}=\frac{b_i-\sum_{j=1}^na_{ij}x_j^{(k)}}{a_{ii}},i\in N^\ast,(j≠i).

算法描述

在这里插入图片描述

程序运行结果截图

在这里插入图片描述

Source Codes(github)

/**
 * @Classname Jacobi
 * @Description TODO
 * @Date 2020/4/24 19:04
 * @Created by Jason
 */
public class Jacobi {
    private static double[][] datas = {
            {10.0,-1.0,-2.0,7.2},
            {-1.0,10.0,-2.0,8.3},
            {-1.0,-1.0,5.0,4.2}
    };
    private static double[] x = {0.0,0.0,0.0};

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入最大允许区间长度e:");
        double e = scanner.nextDouble();
        System.out.print("请输入最大迭代次数N:");
        int N = scanner.nextInt();
        scanner.close();
        double[] result = getEstimates(datas,e,N,x);
        System.out.println("x1=" + result[0] + "\tx2=" + result[1] + "\tx3=" + result[2]);
    }
    
    private static double[] getEstimates(double[][] datas, double e,int N,double[] x) {
        int length = datas[0].length;
        double [] y = new double[x.length];
        for (int k = 1 ; true; k++ ) {
            for (int i = 0; i < x.length ; i++ ) {
                y[i] = (datas[i][length-1] - F(i,x,datas))/datas[i][i];
            }
            if(isConditionsEstablished(x,y,e)){
                System.out.println("迭代" + k + "次得到结果");
                return y;
            }
            if( k == N ){
                throw new RuntimeException("达到最大迭代次数,仍未得到预期结果...");
            }
            for (int i = 0; i < x.length; i++ ) {
                x[i] = y[i];
            }
        }
    }

    private static double F(int i, double[] x, double[][] datas) {
        double sum = 0;
        for (int j = 0; j < datas[0].length - 1 ; j++ ) {
            if(j != i){
                sum += datas[i][j]*x[j];
            }
        }
        return sum;
    }

    //    max|xi - yi| < e : true
    private static boolean isConditionsEstablished(double[] x,double[] y,double e) {
        boolean flag = true;
        for (int i = 0 ; i < x.length ; i ++ ) {
            if(Math.abs(x[i] - y[i]) >= e){
                flag = false;
            }
        }
        return flag;
    }
}

Gauss-Seidel法

高斯-塞德尔(Gauss-Seidel)迭代公式

x i ( k + 1 ) = b i j = 1 i 1 a i j x j ( k + 1 ) j = i + 1 n a i j x j ( k ) a i i , i N , ( j i ) . x_i^{(k+1)}=\frac{b_i-\sum_{j=1}^{i-1}a_{ij}x_j^{(k+1)}-\sum_{j=i+1}^na_{ij}x_j^{(k)}}{a_{ii}},i\in N^\ast,(j≠i).

算法描述

在这里插入图片描述

程序运行结果截图

在这里插入图片描述

Source Codes(github)

由于代码实现更改较小,这里不提供代码,可到github查看详细代码。

超松弛法

计算公式

x i ( k + 1 ) = ( 1 ω ) x i ( k ) + ω ( b i j = 1 i 1 a i j x j ( k + 1 ) j = i + 1 n a i j x j ( k ) ) a i i , i N ω ω ( 0 , 2 ) , . x_i^{(k+1)}=(1-\omega)x_i^{(k)}+\frac{\omega(b_i-\sum_{j=1}^{i-1}a_{ij}x_j^{(k+1)}-\sum_{j=i+1}^na_{ij}x_j^{(k)})}{a_{ii}},i\in N^\ast\\\omega\mathrm{为松弛因子},且\omega\in(0,2),\mathrm{以保证收敛}.

算法描述

在这里插入图片描述

Source Codes(github)

由于代码实现更改较小,这里不提供代码,可到github查看详细代码。

猜你喜欢

转载自blog.csdn.net/qq_45744501/article/details/105753189
今日推荐