由于需要用到行列式的运算与矩阵间的运算的原因,代码会有点多.
首先需要一个及矩阵的类Matrix,命名为Matrix.
import java.util.Arrays;
/**
* @author yiran
* @creat 2021-11-26-13:58
*/
public class Matrix{
// 矩阵
private double[][] matrix;
private int m;
private int n;
public double[][] getMatrix() {
return matrix;
}
public Matrix() {
}
public Matrix(double[][] matrix) {
this.matrix = matrix;
this.m=matrix.length;
this.n=matrix[0].length;
}
public Matrix(int m, int n) {
this.matrix=new double[m][n];
this.m=m;
this.n=n;
}
public void setMatrix(double[][] matrix) {
this.matrix = matrix;
this.m=matrix.length;
this.n=matrix[0].length;
}
public int getM() {
return m;
}
public void setM(int m) {
this.m = m;
}
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
public void print()
{
System.out.println("------------------结果-------------------");
for (int i=0;i<m;i++)
{
for (int j=0;j<n;j++)
{
System.out.print(matrix[i][j]+" ");
}
System.out.println();
}
System.out.println("----------------------------------------");
}
@Override
public String toString() {
return "Matrix{" +
"matrix=" + Arrays.toString(matrix) +
'}';
}
}
还需要一个方阵的Phalanx类(由于求伴随矩阵和逆矩阵的前提是矩阵的方阵).
命名为Phalanx.
/**
* @author yiran
* @creat 2021-11-26-14:01
*/
public class Phalanx extends Matrix {
// 调用父类的构造函数,构造方阵
public Phalanx(int n) {
super(n, n);
}
public Phalanx() {
}
// 初始化方阵,并进行校验
public Phalanx(double[][] matrix) {
if(matrix.length!=matrix[0].length)
{
// 传入参数不符合方阵的要求
System.out.println("初始化失败:传入参数不符合方阵的要求!");
}
else
{
this.setMatrix(matrix);
}
}
public double[][] getPhalanx() {
return getMatrix();
}
public void setPhalanx(double [][] phalanx) {
if(phalanx.length!=phalanx[0].length)
{
// 传入参数不符合方阵的要求
System.out.println("初始化失败:传入参数不符合方阵的要求!");
}
else
{
super.setMatrix(phalanx);
}
}
}
之后是操作矩阵运算的工具类Matrixs.
/**
* 方阵的辅助类
* @author yiran
* @creat 2021-11-26-14:08
*/
public class Matrixs{
// 矩阵转置
public static Matrix reverse(Matrix m)
{
if(m!=null)
{
Matrix new_m=new Matrix();
double[][] m_data = m.getMatrix();
double[][] new_m_data=new double[m.getN()][m.getM()];
for (int i=0;i<m.getN();i++)
{
for (int j=0;j<m.getM();j++)
{
new_m_data[i][j]=m_data[j][i];
}
}
m.setMatrix(new_m_data);
return m;
}
return null;
}
// 矩阵数乘
public static Matrix numtil(Matrix m,double num)
{
if(m!=null)
{
Matrix new_m=new Matrix();
double[][] m_data = m.getMatrix();
double[][] new_m_data=new double[m.getM()][m.getN()];
for (int i=0;i<m.getM();i++)
{
for (int j=0;j<m.getN();j++)
{
new_m_data[i][j] = num * m_data[i][j];
}
}
new_m.setMatrix(new_m_data);
return new_m;
}
return null;
}
/**
*
* @param origin 矩阵数组
* @param i
* @param j
* @return 矩阵对应 i,j 位置的余子式
*/
public static double[][] getLess(double [][] origin,int i,int j)
{
if (origin!=null)
{
int c_i=i-1;
int c_j = j-1;
int n = origin.length;
// 取出余子式
double[][] newArr = new double[n - 1][n - 1];
int index_i = 0;
// 对数组进行赋值
for (int l = 0; l < n; l++) {
// 如果该行不等于所在行
if (c_i != l) {
int index_j = 0;
for (int o = 0; o < n; o++) {
// 列不等该列
if (c_j != o)
{
newArr[index_i][index_j] = origin[l][o];
index_j++;
}
}
// 到第下一行赋值
index_i++;
}
}
return newArr;
}
return null;
}
// 求方阵的伴随矩阵
public static Phalanx getAccompany(Phalanx p)
{
if (p!=null)
{
// 用于存储伴随矩阵的数据
double[][] pMatrix = p.getMatrix();
int n = p.getN();
double [][] new_p=new double[n][n];
// 调用递归算法将余子式算出
if(n>2)
{
for (int i = 0; i< n; i++)
{
for (int j=0;j<n;j++)
{
// 取出来余子项,并进行传参并代入代数余子式
new_p[i][j] = Math.pow(-1,(1+1+i+j))*RowLineFormula.interf(new Phalanx(getLess(pMatrix,i+1,j+1)));
}
}
}else
{
// 仅对二阶的进行特殊处理,不要进行转置
if (n==2)
{
new_p[0][0] = pMatrix[1][1];
new_p[0][1] = -1*pMatrix[1][0];
new_p[1][0] = -1*pMatrix[0][1];
new_p[1][1] = pMatrix[0][0];
}
}
// 得到了矩阵后还要将其反转才得到伴随矩阵
return (Phalanx) Matrixs.reverse(new Phalanx(new_p));
}
else
{
System.out.println("传入参数为空!");
return null;
}
}
// 求矩阵的逆矩阵 使用伴随矩阵的方法
public static Matrix getAlter(Phalanx p)
{
if (p!=null)
{
// 判断方阵是否可逆 后进行行列式的计算,看结果是否为0
double[][] matrix = p.getPhalanx();
double a = RowLineFormula.interf(p);
if (matrix.length!=0 && matrix.length==matrix[0].length && a != 0.0){
// 方阵可逆,则求其伴随矩阵
Phalanx accompany = getAccompany(new Phalanx(matrix));
// 将伴随矩阵乘以 矩阵的行列式的结果
Matrix numtil = Matrixs.numtil(accompany, Math.pow(a,-1));
return numtil;
}
else
{
// 方阵不可逆
System.out.println("方阵不可逆!");
return null;
}
}
else {
System.out.println("传入参数为空!");
return null;
}
}
}
还有一个是计算行列式的类RowLineFormula.
/**
* @author yiran
* @creat 2021-11-23-13:23
*/
// 实现行列式的计算
public class RowLineFormula {
// 行列式展开方法计算行列式 使用递归
public double core(int rank,double[][]a) {
if (rank>2)
{
// ----------------核心代码--------------------
double result=0;
for (int k=0;k<rank;k++)
{
// 取出余子式
double [][]newArr=new double[rank-1][rank-1];
int index=0;
// 对数组进行赋值
for (int i=0;i<rank;i++)
{
if (k!=i)
{
for (int j=1;j<rank;j++)
{
// 如果该行不等于所在行
newArr[index][j-1]=a[i][j];
}
// 到第下一行赋值
index++;
}
}
// 重点注意 由于此处取的是 a11 所以 (-1)^(1+1) = 1 可以进行处理
result+=Math.pow(-1,(k+1+1))*a[k][0]*core(rank-1,newArr);
}
// --------------------------------------
return result;
}
else
{
// 二级行列式计算
return a[0][0]*a[1][1]-a[0][1]*a[1][0];
}
}
// 让其他类调用的API接口
// 传入矩阵计算结果,看结果是否可逆
/**
* 矩阵的行列式求解结果
* @param m 方阵
* @return |A|
*/
public static double interf(Phalanx m)
{
return new RowLineFormula().core(m.getM(),m.getPhalanx());
}
}
就是上面的代码了,将代码复制到idea或者eclipse,再在各个类中导一下包就可以运行了.
由于代码比较乱,大家可以参照下面的测试类进行调用.
求伴随矩阵和逆矩阵的函数分别是Matrixs类中的getAccompany(),getAlter()方法
import org.junit.Test;
/**
* @author yiran
* @creat 2021-11-26-16:18
*/
public class MatrixsTest {
// 测试伴随矩阵
@Test
public void test06()
{
double [][] m1= {
{1,0,1},
{2, 1,0},
{-3,2,-5}
};
double [][] m2= {
{2, 1},
{5, 3}
};
Phalanx accompany = Matrixs.getAccompany(new Phalanx(m1));
accompany.print();
}
// 测试获取余子式
@Test
public void test07()
{
double [][] arr=
{{1,2,3,8},
{2,3,4,7},
{5,8,9,6},
{4,8,9,2}};
double[][] less = Matrixs.getLess(arr, 4, 2);
new Matrix(less).print();
}
/**
* 测试矩阵的行列式计算
*/
@Test
public void test09()
{
// 首先需要一个方阵
double [][] arr = {
{2,1},
{5,3}
};
System.out.println(RowLineFormula.interf(new Phalanx(arr)));
}
/**
* 测试逆矩阵的计算
*/
@Test
public void test10()
{
double [][] m2= {
{2, 1},
{5, 3}
};
double [][] m1= {
{1,0,1},
{2, 1,0},
{-3,2,-5}
};
double [][] m3= {
{1,-1,-1},
{0,1,-1},
{0,0,1}
};
double [][] m4= {
{2,1},
{7,4}
};
Matrixs.getAlter(new Phalanx(m4)).print();
}
}
同理,导一下包,再导一下单元测试,就可以运行测试类了.
如果只是希望求解伴随矩阵和逆矩阵的话,使用下面的轻松使用的代码即可 类名为AlterMatrixFormula.
import java.util.Arrays;
import java.util.Scanner;
/**
* 轻松使用,计算矩阵的伴随矩阵和逆矩阵
* @author yiran
* @creat 2021-12-03-17:21
*/
public class AlterMatrixFormula {
// 方阵的阶数
private static double [][] arr=null;
// 方阵的阶数
private static int n;
private static Scanner scan = null;
private static Phalanx phalanx = null;
private static boolean flag = false;
// 读取矩阵
private static void read()
{
while(true)
{
System.out.print("请输入矩阵的阶数(n):");
String s = scan.nextLine();
String[] s1 = s.trim().split(" ");
if (s1!=null&&s1.length!=1)
{
System.out.println("输入错误!请重新输入");
continue;
}
n =Integer.parseInt(s1[0]);
arr =new double[n][n];
System.out.println("请输入矩阵的数据:");
// System.out.println("如果遇到要输入多一行的情况,请直接回车");
for (int i=0;i<n;i++)
{
// 一行一行地赋值
System.out.print("第"+(i+1)+"行: ");
String s2 = scan.nextLine();
String[] s3 = s2.trim().split(" ");
if (s3.length!=n)
{
// 再次输入
i--;
System.out.println("输入格式错误,请重新输入!");
continue;
}
for (int j=0;j<n;j++)
{
arr[i][j]=Double.parseDouble(s3[j]);
}
}
phalanx = new Phalanx(arr);
break;
}
}
public static void main(String[] args) {
scan = new Scanner(System.in);
while(true)
{
if (flag)
{
scan.nextLine();
}
read();
// 行列式的伴随矩阵为:
System.out.println("该矩阵的伴随矩阵为:");
Matrixs.getAccompany(phalanx).print();
System.out.println("该矩阵的逆矩阵为");
Matrixs.getAlter(phalanx).print();
System.out.print("输入0可以继续:");
flag =true;
int sign = scan.nextInt();
if (sign == 0)
{
continue;
}
else
{
System.out.println("Bye!");
break;
}
}
}
}
class Matrix{
// 矩阵
private double[][] matrix;
private int m;
private int n;
public double[][] getMatrix() {
return matrix;
}
public Matrix() {
}
public Matrix(double[][] matrix) {
this.matrix = matrix;
this.m=matrix.length;
this.n=matrix[0].length;
}
public Matrix(int m, int n) {
this.matrix=new double[m][n];
this.m=m;
this.n=n;
}
public void setMatrix(double[][] matrix) {
this.matrix = matrix;
this.m=matrix.length;
this.n=matrix[0].length;
}
public int getM() {
return m;
}
public void setM(int m) {
this.m = m;
}
public int getN() {
return n;
}
public void setN(int n) {
this.n = n;
}
public void print()
{
System.out.println("------------------结果-------------------");
for (int i=0;i<m;i++)
{
for (int j=0;j<n;j++)
{
System.out.print(matrix[i][j]+" ");
}
System.out.println();
}
System.out.println("----------------------------------------");
}
@Override
public String toString() {
return "Matrix{" +
"matrix=" + Arrays.toString(matrix) +
'}';
}
}
class Phalanx extends Matrix {
// 调用父类的构造函数,构造方阵
public Phalanx(int n) {
super(n, n);
}
public Phalanx() {
}
// 初始化方阵,并进行校验
public Phalanx(double[][] matrix) {
if(matrix.length!=matrix[0].length)
{
// 传入参数不符合方阵的要求
System.out.println("初始化失败:传入参数不符合方阵的要求!");
}
else
{
this.setMatrix(matrix);
}
}
public double[][] getPhalanx() {
return getMatrix();
}
public void setPhalanx(double [][] phalanx) {
if(phalanx.length!=phalanx[0].length)
{
// 传入参数不符合方阵的要求
System.out.println("初始化失败:传入参数不符合方阵的要求!");
}
else
{
super.setMatrix(phalanx);
}
}
}
/**
* 方阵的辅助类
* @author yiran
* @creat 2021-11-26-14:08
*/
class Matrixs{
// 矩阵转置
public static Matrix reverse(Matrix m)
{
if(m!=null)
{
Matrix new_m=new Matrix();
double[][] m_data = m.getMatrix();
double[][] new_m_data=new double[m.getN()][m.getM()];
for (int i=0;i<m.getN();i++)
{
for (int j=0;j<m.getM();j++)
{
new_m_data[i][j]=m_data[j][i];
}
}
m.setMatrix(new_m_data);
return m;
}
return null;
}
// 矩阵数乘
public static Matrix numtil(Matrix m,double num)
{
if(m!=null)
{
Matrix new_m=new Matrix();
double[][] m_data = m.getMatrix();
double[][] new_m_data=new double[m.getM()][m.getN()];
for (int i=0;i<m.getM();i++)
{
for (int j=0;j<m.getN();j++)
{
new_m_data[i][j] = num * m_data[i][j];
}
}
new_m.setMatrix(new_m_data);
return new_m;
}
return null;
}
/**
*
* @param origin 矩阵数组
* @param i
* @param j
* @return 矩阵对应 i,j 位置的余子式
*/
public static double[][] getLess(double [][] origin,int i,int j)
{
if (origin!=null)
{
int c_i=i-1;
int c_j = j-1;
int n = origin.length;
// 取出余子式
double[][] newArr = new double[n - 1][n - 1];
int index_i = 0;
// 对数组进行赋值
for (int l = 0; l < n; l++) {
// 如果该行不等于所在行
if (c_i != l) {
int index_j = 0;
for (int o = 0; o < n; o++) {
// 列不等该列
if (c_j != o)
{
newArr[index_i][index_j] = origin[l][o];
index_j++;
}
}
// 到第下一行赋值
index_i++;
}
}
return newArr;
}
return null;
}
// 求方阵的伴随矩阵
public static Phalanx getAccompany(Phalanx p)
{
if (p!=null)
{
// 用于存储伴随矩阵的数据
double[][] pMatrix = p.getMatrix();
int n = p.getN();
double [][] new_p=new double[n][n];
// 调用递归算法将余子式算出
if(n>2)
{
for (int i = 0; i< n; i++)
{
for (int j=0;j<n;j++)
{
// 取出来余子项,并进行传参并代入代数余子式
new_p[i][j] = Math.pow(-1,(1+1+i+j))*RowLineFormula.interf(new Phalanx(getLess(pMatrix,i+1,j+1)));
}
}
}else
{
// 仅对二阶的进行特殊处理,不要进行转置
if (n==2)
{
new_p[0][0] = pMatrix[1][1];
new_p[0][1] = -1*pMatrix[1][0];
new_p[1][0] = -1*pMatrix[0][1];
new_p[1][1] = pMatrix[0][0];
}
}
// 得到了矩阵后还要将其反转才得到伴随矩阵
return (Phalanx) Matrixs.reverse(new Phalanx(new_p));
}
else
{
System.out.println("传入参数为空!");
return null;
}
}
// 求矩阵的逆矩阵 使用伴随矩阵的方法
public static Matrix getAlter(Phalanx p)
{
if (p!=null)
{
// 判断方阵是否可逆 后进行行列式的计算,看结果是否为0
double[][] matrix = p.getPhalanx();
double a = RowLineFormula.interf(p);
if (matrix.length!=0 && matrix.length==matrix[0].length && a != 0.0){
// 方阵可逆,则求其伴随矩阵
Phalanx accompany = getAccompany(new Phalanx(matrix));
// 将伴随矩阵乘以 矩阵的行列式的结果
Matrix numtil = Matrixs.numtil(accompany, Math.pow(a,-1));
return numtil;
}
else
{
// 方阵不可逆
System.out.println("方阵不可逆!");
return null;
}
}
else {
System.out.println("传入参数为空!");
return null;
}
}
}
class RowLineFormula {
// 行列式展开方法计算行列式 使用递归
public double core(int rank,double[][]a) {
if (rank>2)
{
// ----------------核心代码--------------------
double result=0;
for (int k=0;k<rank;k++)
{
// 取出余子式
double [][]newArr=new double[rank-1][rank-1];
int index=0;
// 对数组进行赋值
for (int i=0;i<rank;i++)
{
if (k!=i)
{
for (int j=1;j<rank;j++)
{
// 如果该行不等于所在行
newArr[index][j-1]=a[i][j];
}
// 到第下一行赋值
index++;
}
}
// 重点注意 由于此处取的是 a11 所以 (-1)^(1+1) = 1 可以进行处理
result+=Math.pow(-1,(k+1+1))*a[k][0]*core(rank-1,newArr);
}
// --------------------------------------
return result;
}
else
{
// 二级行列式计算
return a[0][0]*a[1][1]-a[0][1]*a[1][0];
}
}
// 让其他类调用的API接口
// 传入矩阵计算结果,看结果是否可逆
/**
* 矩阵的行列式求解结果
* @param m 方阵
* @return |A|
*/
public static double interf(Phalanx m)
{
return new RowLineFormula().core(m.getM(),m.getPhalanx());
}
}
编译
javac -encoding utf-8 AlterMatrixFormula.java
编译后产生5个class文件,运行其中的AlterMatrixFormula的class文件即可
运行
java AlterMatrixFormula
测试:
如果对行列式的计算感兴趣的,还可以看我的另一篇文章:Java实现行列式的计算.
如果对矩阵的运算感兴趣的,还可以看我的另一篇文章: Java实现矩阵的运算.