• 高斯消元(Java实现)


    高斯消元或者解决矩阵的秩,Java实现

    求解阶梯矩阵

    遍历列

    1. 对于每一列来说,找到本列最大的行,即主元行,如果主元行的本列为0,直接continue。
    2. 将主元行交换到首行,并且令主元行的首列置为1。(逆序) a[r][c]应该最后操作
    3. 最后使用主元行消除其他行 a[i][j] -= a[r][j] * a[i][c] 。(逆序) a[i][c]应该最后消除
    4. 矩阵的秩 + 1

    判断 + 求解答案

    1. 根据增广矩阵和本矩阵的秩是否相同进行判断。
    2. 如果只有一个解,使用回代求解答案,和闫总不同,这里使用的是平常计算时候常用的顺序。用最后一行向上删除,然后用倒数第二行向上删除…i表示使用哪一行,使用i删除i上面的全部行也就是删除j行。
      a [ j ] [ n ] − = a [ i ] [ n ] ∗ a [ j ] [ i ] 。 i   i n   r a n g e ( n − 1 , 0 ) , j   i n   r a n g e ( 0 , i ) a[j][n] -= a[i][n] * a[j][i]。 i \ in \ range(n - 1, 0), j \ in \ range(0, i) a[j][n]=a[i][n]a[j][i]i in range(n1,0),j in range(0,i)

    闫总的顺序是使用倒数第二行删除倒数第一行,倒数第三行删除倒数第二行和倒数第一行…也就是逆序使用本行删除下面的行。
    a [ i ] [ n ] − = a [ i ] [ j ] ∗ a [ j ] [ n ] 。 i   i n   r a n g e ( n − 2 , 0 ] , j   i n   r a n g e ( i + 1 , n ) a[i][n] -= a[i][j] * a[j][n]。 i \ in \ range(n - 2, 0], j \ in \ range(i + 1, n) a[i][n]=a[i][j]a[j][n]i in range(n2,0],j in range(i+1,n)

    注意点

    1. double判断为0的时候,使用Math.abs(x) <= exp
    2. 输出的时候,有可能出现-0.00需要对0进行特殊判断。
    
    
    import java.util.Scanner;
    
    /**
     * @author: Zekun Fu
     * @date: 2022/11/14 15:12
     * @Description: 高斯消元
     * 对于每一列
     * 1. 找到本列最大值所在的行,主元行
     * 2. 如果,主元为0, 直接continue, 否则将主元行,交换到当前首行
     * 3. 将主元行的主元变成1
     * 4. 使用主元行,将其他行的本列消元成0
     *
     * 5. 进行判断,如果扩展矩阵的秩大于原矩阵的秩无解,否则看r == n : 唯一解:无穷解。
     * 6. 如果有唯一的解,将矩阵化为行最简形。
     */
    public class Main {
    
        /*
        *   return
        * 0 : 唯一的解,1无穷多解,2;无解
        * */
        private static final double exp = 1e-10;
        public static void out(double[][] a) {
            for (double[] aa: a) {
                for (double x : aa) {
                    System.out.print(x + " ");
                }
                System.out.println();
            }
            System.out.println();
        }
        public static int guass(double[][] a) {
            // 0.遍历每一列
            int n = a.length;
            int r = 0;
            for (int c = 0; c < n; c++) {
                // 1. 找到主元行
                int t = r;
                for (int i = r; i < n; i++) {
                    if (Math.abs(a[i][c]) > Math.abs(a[t][c]))
                        t = i;
                }
    //            System.out.println(Math.abs(a[t][c]));
                if (Math.abs(a[t][c]) <= exp) continue;
                // 2. 将主元行交换到最上面
                for (int j = c; j <= n; j++) {
                    double tmp = a[r][j];
                    a[r][j] = a[t][j];
                    a[t][j] = tmp;
                }
                // 3. 主元行本列(c列)置为1
                for (int j = n; j >= c; j--) a[r][j] /= a[r][c];
                // 4. 使用主元行消去其他行, 需要逆序,因为a[i][c]一直在使用
                for (int i = r + 1; i < n; i++) {
                    for (int j = n; j >= c; j--) {
                        a[i][j] -= a[r][j] * a[i][c];
                    }
                }
    //            out(a);
                r++;
            }
            if (n != r) {
                for (int i = r; i < n; i++) {
                    if (Math.abs(a[i][n]) > exp) return 2;
                }
                return 1;
            }
    //        out(a);
            // 回代答案
            for (int i = n - 1; i >= 0; i--) {
                for (int j = i - 1; j >= 0; j--) {
                    a[j][n] -= a[j][i] * a[i][n];
                }
            }
            return 0;
        }
    
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            double[][] a= new double[n][n + 1];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n + 1; j++)
                    a[i][j] = sc.nextDouble();
            }
            int x = guass(a);
            if (x == 0) {                       // 唯一的解
                for (int i = 0; i < n; i++) {
                    System.out.printf("%.2f\n", Math.abs(a[i][n]) <= exp ? 0.00 : a[i][n]);
                }
            }
            else if (x == 1) {                  // 无穷多解
                System.out.println("Infinite group solutions");
            }
            else {                              // 无解
                System.out.println("No solution");
            }
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
  • 相关阅读:
    20套面向对象程序设计选题Java Swing(含教程) (二) 持续更新 建议收藏
    金蝶云星空套打设计
    Go语言学习笔记——错误处理
    搭建Python开发环境
    小程序--分包加载
    【有ISSN、ISBN号!!往届均已完成EI检索】2024年第四届计算机视觉与模式分析国际学术大会(ICCPA 2024)
    全球排名前十的搜索引擎,你猜百度排名在第几位?bing稳居二位!
    ​企业该如何做好源代码防泄密工作
    IP地址欺骗的危害与后果
    Windows 安装 汉化版 burp suite
  • 原文地址:https://blog.csdn.net/fuzekun/article/details/127850241