Java 实现线性方程组求解:LU 分解与部分主元法
在数值计算中,求解线性方程组 $Ax=b$ 是基础且高频的任务。虽然可以直接调用库函数,但理解底层的 LU 分解(LUP)有助于处理更复杂的数值问题。这里分享一个基于 Java 的完整实现,重点展示了如何通过部分主元法(Partial Pivoting)来避免除零错误并提高精度。
核心思路
我们将系数矩阵 $A$ 分解为一个下三角矩阵 $L$ 和一个上三角矩阵 $U$,同时引入置换向量 $p$ 记录行交换情况。这样原方程转化为 $PAx = Pb$,即 $LUx = Pb$。求解分为两步:先向前代入求中间变量 $Y$,再向后回代求最终解 $X$。
代码实现
package com.data.struct;
public class LinearEquation {
// 系数矩阵 A
private double[][] A = new double[][]{
{1, 2, 0},
{3, 4, 4},
{5, 6, 3}
};
// 常数向量 B
private double[] B = new double[]{3, 7, 8};
// 存储分解后的 L 和 U 矩阵
private double[][] L = new double[3][3];
private double[][] U = new double[3][3];
// 行交换记录
private int[] p = new int[3];
[] X = [];
Exception {
lupDecomposition();
[] Y = [];
( ; i < ; i++) {
Y[i] = B[p[i]];
;
( ; j <= i - ; j++) {
sub += L[i][j] * Y[j];
}
Y[i] = Y[i] - sub;
}
( ; i >= ; i--) {
;
( i + ; j < ; j++) {
sub += U[i][j] * X[j];
}
X[i] = (Y[i] - sub) / U[i][i];
}
}
Exception {
( ; i < ; i++) {
p[i] = i;
}
( ; k < ; k++) {
;
k;
( k; i < ; i++) {
(Math.abs(A[i][k]) > s) {
s = Math.abs(A[i][k]);
k2 = i;
}
}
(s == ) {
();
}
p[k];
p[k] = p[k2];
p[k2] = tmp;
( ; i < ; i++) {
A[k][i];
A[k][i] = A[k2][i];
A[k2][i] = tmp2;
}
( k + ; i < ; i++) {
A[i][k] = A[i][k] / A[k][k];
( k + ; j < ; j++) {
A[i][j] = A[i][j] - A[i][k] * A[k][j];
}
}
}
( ; i < ; i++) {
( ; j <= i; j++) {
(i == j) {
L[i][j] = ;
} {
L[i][j] = A[i][j];
}
}
( i; j < ; j++) {
U[i][j] = A[i][j];
}
}
}
{
( ; i < ; i++) {
( ; j < ; j++) {
System.out.print(L[i][j] + );
}
System.out.println();
}
}
{
( ; i < ; i++) {
( ; j < ; j++) {
System.out.print(U[i][j] + );
}
System.out.println();
}
}
{
System.out.println();
( ; i < ; i++) {
System.out.println( + i + + X[i]);
}
}
{
{
();
solver.solve();
System.out.println();
solver.printL();
System.out.println();
solver.printU();
solver.print();
} (Exception e) {
e.printStackTrace();
}
}
}

