高斯消元(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
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
高斯消元法是一种线性方程组求解的方法,可以用JAVA中的List实现。具体实现步骤如下: 1. 定义一个二维List作为系数矩阵,同时定义一个一维List作为常数向量。 2. 实现高斯消元的主要代码,包括将系数矩阵化为上三角矩阵、回带求解等。 3. 在主函数中输入系数矩阵和常数向量,并调用高斯消元方法求解线性方程组。 以下是JAVA代码实现: ``` import java.util.*; public class GaussElimination { public static void main(String[] args) { // 输入系数矩阵和常数向量 Scanner input = new Scanner(System.in); System.out.println("请输入系数矩阵的行数和列数:"); int m = input.nextInt(); int n = input.nextInt(); List<List<Double>> A = new ArrayList<List<Double>>(); System.out.println("请输入系数矩阵:"); for (int i = 0; i < m; i++) { List<Double> row = new ArrayList<Double>(); for (int j = 0; j < n; j++) { row.add(input.nextDouble()); } A.add(row); } System.out.println("请输入常数向量:"); List<Double> B = new ArrayList<Double>(); for (int i = 0; i < m; i++) { B.add(input.nextDouble()); } // 高斯消元求解线性方程组 List<Double> X = gaussElimination(A, B); // 输出解向量 System.out.println("解向量为:"); for (int i = 0; i < X.size(); i++) { System.out.print(X.get(i) + " "); } System.out.println(); } // 高斯消元求解线性方程组 public static List<Double> gaussElimination(List<List<Double>> A, List<Double> B) { int n = A.size(); for (int k = 0; k < n; k++) { // 找到主元素所在行 int maxRow = k; double maxVal = Math.abs(A.get(k).get(k)); for (int i = k + 1; i < n; i++) { double val = Math.abs(A.get(i).get(k)); if (val > maxVal) { maxRow = i; maxVal = val; } } // 交换行 if (maxRow != k) { List<Double> tmp = A.get(k); A.set(k, A.get(maxRow)); A.set(maxRow, tmp); double tmpB = B.get(k); B.set(k, B.get(maxRow)); B.set(maxRow, tmpB); } // 消元 for (int i = k + 1; i < n; i++) { double factor = A.get(i).get(k) / A.get(k).get(k); for (int j = k + 1; j < n; j++) { A.get(i).set(j, A.get(i).get(j) - factor * A.get(k).get(j)); } B.set(i, B.get(i) - factor * B.get(k)); } } // 回带求解 List<Double> X = new ArrayList<Double>(); for (int i = n - 1; i >= 0; i--) { double sum = 0.0; for (int j = i + 1; j < n; j++) { sum += A.get(i).get(j) * X.get(n - j - 1); } X.add((B.get(i) - sum) / A.get(i).get(i)); } // 翻转解向量 Collections.reverse(X); return X; } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值