高斯列选主元消去法 Java 代码

该博客介绍了如何使用Java实现高斯消元法来解决非病态实线性方程组。代码已简化,便于理解。首先定义增广矩阵,然后通过交换行序和列选主元策略进行消元,最后进行回代求解,输出解向量。博客附带了一个测试类用于输入矩阵并展示解的结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package numericalanalysis;

import java.util.Scanner;

/**
 * 为增加可读性,代码已简化
 * 求解 n 行 n + 1 列 的非病态实线性方程组(n > 0)
 */
public class GaussianElimination {
    //定义增广矩阵
    private static double[][] augmentedMatrix;

    //通过 set 函数输入矩阵
    public static void setAugmentedMatrix(double[][] augmentedMatrix) {
        GaussianElimination.augmentedMatrix = augmentedMatrix;
    }

    //寻找 j 列绝对值最大元素对应的行下标
    private static int findMaxRowIndex(int j) {
        int index = 0;
        double max = 0;
        for (int i = j; i < augmentedMatrix.length; i++) {
            if (Math.abs(augmentedMatrix[i][j]) > max) {
                max = augmentedMatrix[i][j];
                index = i;
            }
        }
        return index;
    }

    //交换 j 列上 i 行与 k 行的元素
    private static void swap(int i, int j, int k) {
        double temp = augmentedMatrix[i][j];
        augmentedMatrix[i][j] = augmentedMatrix[k][j];
        augmentedMatrix[k][j] = temp;
    }

    //判断方程组是否有解
    private static boolean isSolve(double[] row) {
        int index = -1;
        for (int i = 0; i < row.length - 1; i++) {
            if (Math.abs(row[i]) > 1E-4) {
                index++;
            }
        }
        return index > -1;
    }

    //高斯列选主元
    public static double[] gaussElimination() {
        if (augmentedMatrix == null || augmentedMatrix.length == 0 ||
                augmentedMatrix.length + 1 != augmentedMatrix[0].length) {
            System.out.println("不能求解");
            System.exit(0);
        }
        //增广矩阵行数
        int row = augmentedMatrix.length;
        //用数组 res 表示解向量
        double[] res = new double[row];
        int i = 0, j, k;
        while (i < row - 1) {
            //列选主元,交换行序
            k = findMaxRowIndex(i);
            if (k > i) {
                for (j = i; j < row + 1; j++) {
                    swap(i, j, k);
                }
            }
            //每一行除以主元,使主元为 1
            for (j = i + 1; j < row + 1; j++) {
                augmentedMatrix[i][j] /= augmentedMatrix[i][i];
            }
            augmentedMatrix[i][i] = 1.0;
            //初等行变换
            for (int l = i + 1; l < row; l++) {
                double factor = -augmentedMatrix[l][i];
                for (int c = 0; c < augmentedMatrix[0].length; c++) {
                    augmentedMatrix[l][c] += augmentedMatrix[i][c] * factor;
                }
            }
            i++;
        }
        //回代,进行求解
        for (int s = row - 1; s >= 0; s--) {
            if (s == row - 1) {
                if (!isSolve(augmentedMatrix[s])) {
                    System.out.println("不能求解");
                    System.exit(0);
                }
                res[s] = augmentedMatrix[s][augmentedMatrix[s].length - 1] /
                        augmentedMatrix[s][augmentedMatrix[s].length - 2];
            } else {
                res[s] = augmentedMatrix[s][augmentedMatrix[s].length - 1];
                int t = augmentedMatrix[s].length - 2;
                for (; t > s; t--) {
                    res[s] -= res[t] * augmentedMatrix[s][t];
                }
                res[s] /= augmentedMatrix[s][t];
            }
        }
        return res;
    }
}

/**
 * 定义测试类
 */
class GaussianEliminationTest {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入矩阵行数:");
        int row = scanner.nextInt();
        System.out.println("请输入矩阵列数:");
        int col = scanner.nextInt();
        double[][] matrix = new double[row][col];
        System.out.println("请输入矩阵:");
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                matrix[i][j] = scanner.nextDouble();
            }
        }
        GaussianElimination.setAugmentedMatrix(matrix);
        for (int i = 0; i < GaussianElimination.gaussElimination().length; i++) {
            //保留四位小数输出
            System.out.println("x" + (i + 1) + " = " + String.format("%.4f", GaussianElimination.gaussElimination()[i]));
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

旺仔爱吃夹心面包

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值