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]));
}
}
}
高斯列选主元消去法 Java 代码
最新推荐文章于 2022-09-06 21:18:34 发布