公告

👇 微信 👇

图片

欢迎私信交流

Skip to content

7-高斯消元 ​

算法思想 ​

算法模板 ​

java
import java.util.*;
public class Main {
    static int N = 110;
    static double[][] a = new double[N][N];
    static final double eps = 1e-8;
    static int n;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        n = in.nextInt();

        for(int i = 0; i < n; i ++ )
            for(int j = 0; j < n + 1; j ++ )
                a[i][j] = in.nextDouble();

        int t = gauss();
        if(t == 2) System.out.println("No solution");
        else if(t == 1) System.out.println("Infinite group solutions");
        else
        {
            for(int i = 0; i < n; i ++ )
                System.out.printf("%.2f\n", a[i][n]);
        }
    }

    public static int gauss()
    {
        // r 代表当前所在的行号,c 代表当前所在的列号
        int r, c;
        for(r = 0, c = 0; c < n; c ++ )
        {
            // (从第 r ~ n - 1 行中)找出第 c 列中绝对值最大的元素所在的行号
            int t = r;
            for(int i = r; i < n; i ++ )
                if(Math.abs(a[i][c]) > Math.abs(a[t][c]))
                    t = i;

            if(Math.abs(a[t][c]) < eps) continue;

            // 交换第 r 行与第 t 行的元素
            for(int j = c; j <= n; j ++ )
            {
                double temp = a[t][j];
                a[t][j] = a[r][j];
                a[r][j] = temp;
            }

            // 第 r 行元素同除 a[r][c],
            // 使得第 c 列第 r 行的元素变为1
            for(int j = n; j >= c; j -- ) a[r][j] /= a[r][c];
            // 用第 r 行将第 r + 1 ~ n - 1 行第 c 列的元素,
            // 变为0
            for(int i = r + 1; i < n; i ++ )
            {
                if(Math.abs(a[i][c]) > eps)
                {
                    for(int j = n; j >= c; j -- )
                        a[i][j] -= a[r][j] * a[i][c];
                }
            }

            r ++ ;
        }

        if(r < n)
        {
            // r(A) < r(A | b)
            for(int i = r; i < n; i ++ )
                if(Math.abs(a[i][n]) > eps)
                    return 2; // 无解

            // r(A) = r(A | b) < n
            // 有无穷多个解
            return 1;
        }

        // 求解化简后的 Ax = b
        for(int i = n - 1; i >= 0; i -- )
        {
            for(int j = i + 1; j < n; j ++ )
            {
                a[i][n] -= a[i][j] * a[j][n];
            }
        }
        // 有唯一解
        return 0;
    }
}

参考资料 ​