java实现求可逆矩阵使用代数余子式的形式

import java.text.DecimalFormat;

/**
 * 求可逆矩阵使用代数余子式的形式
 * @author imlilu
 *
 */
public class InverseMatrix {

	/***
	 * 求行列式的算法
	 * @param value 需要算的行列式
	 * @return 计算的结果
	 */
	public static double mathDeterminantCalculation(double[][] value) throws Exception{
		if (value.length == 1) {
			//当行列式为1阶的时候就直接返回本身
			return value[0][0];
		}else if (value.length == 2) {
			//如果行列式为二阶的时候直接进行计算
			return value[0][0]*value[1][1]-value[0][1]*value[1][0];
		}
		//当行列式的阶数大于2时
		double result = 1;
		for (int i = 0; i < value.length; i++) {       
			//检查数组对角线位置的数值是否是0,如果是零则对该数组进行调换,查找到一行不为0的进行调换
			if (value[i][i] == 0) {
				value = changeDeterminantNoZero(value,i,i);
				result*=-1;
			}
			for (int j = 0; j <i; j++) {
				//让开始处理的行的首位为0处理为三角形式
				//如果要处理的列为0则和自己调换一下位置,这样就省去了计算
				if (value[i][j] == 0) {
					continue;
				}
				//如果要是要处理的行是0则和上面的一行进行调换
				if (value[j][j]==0) {
					double[] temp = value[i];
					value[i] = value[i-1];
					value[i-1] = temp;
					result*=-1;
					continue;
				}
				double  ratio = -(value[i][j]/value[j][j]);
				value[i] = addValue(value[i],value[j],ratio);
			}
		}
		DecimalFormat df = new DecimalFormat(".##");
		return Double.parseDouble(df.format(mathValue(value,result)));
	}
	
	/**
	 * 计算行列式的结果
	 * @param value
	 * @return
	 */
	public static double mathValue(double[][] value,double result) throws Exception{
		for (int i = 0; i < value.length; i++) {
			//如果对角线上有一个值为0则全部为0,直接返回结果
			if (value[i][i]==0) {
				return 0;
			}
			result *= value[i][i];
		}
		return result;
	}
	
	/***
	 * 将i行之前的每一行乘以一个系数,使得从i行的第i列之前的数字置换为0
	 * @param currentRow 当前要处理的行
	 * @param frontRow i行之前的遍历的行
	 * @param ratio 要乘以的系数
	 * @return 将i行i列之前数字置换为0后的新的行
	 */
	public static double[] addValue(double[] currentRow,double[] frontRow, double ratio)throws Exception{
		for (int i = 0; i < currentRow.length; i++) {
			currentRow[i] += frontRow[i]*ratio;
		}
		return currentRow;
	}
	
	/**
	 * 指定列的位置是否为0,查找第一个不为0的位置的行进行位置调换,如果没有则返回原来的值
	 * @param determinant 需要处理的行列式
	 * @param line 要调换的行
	 * @param row 要判断的列
	 */
	public static double[][] changeDeterminantNoZero(double[][] determinant,int line,int row)throws Exception{
		for (int j = line; j < determinant.length; j++) {
			//进行行调换
			if (determinant[j][row] != 0) {
				double[] temp = determinant[line];
				determinant[line] = determinant[j];
				determinant[j] = temp;
				return determinant;
			}
		}
		return determinant;
	}
	
	/**
	 * 求传入的矩阵的逆矩阵
	 * @param value 需要转换的矩阵
	 * @return 逆矩阵
	 * @throws Exception 
	 */
	public static double[][] getInverseMatrix(double[][] value,double result) throws Exception{
		double[][] transferMatrix = new double[value.length][value[0].length];
		//计算代数余子式,并赋值给|A|
		for (int i = 0; i < value.length; i++) {
			for (int j = 0; j < value[i].length; j++) {
				transferMatrix[j][i] =  mathDeterminantCalculation(getNewMatrix(i, j, value));
				if ((i+j)%2!=0) {
					transferMatrix[j][i] = -transferMatrix[j][i];
				}
				transferMatrix[j][i] /= result; 
				DecimalFormat df = new DecimalFormat(".##");
				transferMatrix[j][i] = Double.parseDouble(df.format(transferMatrix[j][i]));
			}
		}
		return transferMatrix;
	}
	
	/**
	 * 转换为代数余子式
	 * @param row 行
	 * @param line 列
	 * @param matrix 要转换的矩阵
	 * @return 转换的代数余子式
	 */
	public static double[][] getNewMatrix(int row,int line,double[][] matrix){
		double[][] newMatrix = new double[matrix.length-1][matrix[0].length-1];
		int rowNum = 0,lineNum = 0;
		for (int i = 0; i < matrix.length; i++) {
			if (i == row){
				continue;
			}
			for (int j = 0; j < matrix[i].length; j++) {
				if (j == line) {
					continue;
				}
				newMatrix[rowNum][lineNum++%(matrix[0].length-1)] = matrix[i][j];
			}
			rowNum++;
		}
		return newMatrix;
	}
	
	public static void main(String[] args) {
//		double[][] test = {{2,1,1},{3,1,2},{1,-1,0}};
//		double[][] test = {{3,-2,0,0},{5,-3,0,0},{0,0,3,4},{0,0,1,1}};
		double[][] test = {{0,0,0,1,2},{0,0,0,2,3},{1,1,0,0,0},{0,1,1,0,0},{0,0,1,0,0}};
		double result;
		try {
			double[][] temp = new double[test.length][test[0].length];
			for (int i = 0; i < test.length; i++) {
				for (int j = 0; j < test[i].length; j++) {
					temp[i][j] = test[i][j];
				}
			}
			//先计算矩阵的行列式的值是否等于0,如果不等于0则该矩阵是可逆的
			result = mathDeterminantCalculation(temp);
			if (result == 0) {
				System.out.println("矩阵不可逆");
			}else {
				System.out.println("矩阵可逆");
				//求出逆矩阵
				double[][] result11 = getInverseMatrix(test,result);
				//打印逆矩阵
				for (int i = 0; i < result11.length; i++) {
					for (int j = 0; j < result11[i].length; j++) {
						System.out.print(result11[i][j]+"	");						
					}
					System.out.println();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("不是正确的行列式!!");
		}
	}
	
	
}

代数余子式是矩阵的一个重要概念。在C语言中,我们可以通过二维数组来表示矩阵,并且可以通过递归的方式解矩阵的代数余子式代数余子式的定义是:对于n阶方阵A中的元素a[i][j],其代数余子式记为A[i][j],其值为(-1)^(i+j)乘以A[i][j]的代数余子式,即去掉第i行和第j列得到的n-1阶子阵的行列式。 以下是C语言实现矩阵的代数余子式的代码示例: ```c #include <stdio.h> #define N 3 // 矩阵的阶数 int det(int a[][N], int n) { int i, j, k, sign = 1, res = 0; int b[N - 1][N - 1]; if(n == 1) { return a[0][0]; } for(i = 0; i < n; i++) { for(j = 0; j < n - 1; j++) { for(k = 0; k < n - 1; k++) { b[j][k] = a[j + 1][(k >= i) ? k + 1 : k]; } } res += sign * a[0][i] * det(b, n - 1); sign = -sign; } return res; } int cofactor(int a[][N], int n, int i, int j) { int b[N - 1][N - 1]; int sign = ((i + j) % 2 == 0) ? 1 : -1; int det_b; int k, l; for(k = 0; k < n - 1; k++) { for(l = 0; l < n - 1; l++) { b[k][l] = a[(k < i) ? k : k + 1][(l < j) ? l : l + 1]; } } det_b = det(b, n - 1); return sign * det_b; } int main() { int a[N][N] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}; int i, j; printf("matrix:\n"); for(i = 0; i < N; i++) { for(j = 0; j < N; j++) { printf("%d ", a[i][j]); } printf("\n"); } printf("\ncofactor matrix:\n"); for(i = 0; i < N; i++) { for(j = 0; j < N; j++) { printf("%d ", cofactor(a, N, i, j)); } printf("\n"); } return 0; } ``` 代码中使用了两个函数,det和cofactor。其中,det函数用于计算矩阵的行列式,cofactor函数用于计算矩阵的代数余子式。 在主函数中,我们定义了一个3阶矩阵,并将其输出到屏幕上。然后,我们使用cofactor函数计算矩阵的每个元素的代数余子式,并将结果输出到屏幕上。 注意,这里的矩阵大小是预定义的,如果要处理不同大小的矩阵,需要修改代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值