C# 矩阵判定
假设存在给定的二维数组C# 矩阵判定,c#,java,algorithm,C#,Java,Algorithm,假设存在给定的二维数组 int a[][]=new int[4][4]; 我试图找到矩阵的行列式,请帮助我知道如何找到它的数学,但我试图找到它的编程 我使用的是语言java和C语言,但在这种情况下,我认为C++也会帮助< /p> 如果你知道如何在数学上做,然后应用这些知识,编写与你手工计算行列式(在纸上)一样的代码。正如伊格纳西奥在评论中告诉你的那样,请告诉我们你尝试了什么,也许到时候你会得到更好的答案。我将很乐意编辑我的答案并帮助您 编辑: 因为这里的问题似乎不是公式本身,而是理解如何使用数
int a[][]=new int[4][4];
我试图找到矩阵的行列式,请帮助我知道如何找到它的数学,但我试图找到它的编程
我使用的是语言java和C语言,但在这种情况下,我认为C++也会帮助< /p> 如果你知道如何在数学上做,然后应用这些知识,编写与你手工计算行列式(在纸上)一样的代码。正如伊格纳西奥在评论中告诉你的那样,请告诉我们你尝试了什么,也许到时候你会得到更好的答案。我将很乐意编辑我的答案并帮助您 编辑: 因为这里的问题似乎不是公式本身,而是理解如何使用数组,所以我建议使用类似于本教程的内容(我假设您使用C#):
如果固定为4x4,最简单的解决方案就是对公式进行硬编码
public double determinant(int[][] m) {
return
m[0][3] * m[1][2] * m[2][1] * m[3][0] - m[0][2] * m[1][3] * m[2][1] * m[3][0] -
m[0][3] * m[1][1] * m[2][2] * m[3][0] + m[0][1] * m[1][3] * m[2][2] * m[3][0] +
m[0][2] * m[1][1] * m[2][3] * m[3][0] - m[0][1] * m[1][2] * m[2][3] * m[3][0] -
m[0][3] * m[1][2] * m[2][0] * m[3][1] + m[0][2] * m[1][3] * m[2][0] * m[3][1] +
m[0][3] * m[1][0] * m[2][2] * m[3][1] - m[0][0] * m[1][3] * m[2][2] * m[3][1] -
m[0][2] * m[1][0] * m[2][3] * m[3][1] + m[0][0] * m[1][2] * m[2][3] * m[3][1] +
m[0][3] * m[1][1] * m[2][0] * m[3][2] - m[0][1] * m[1][3] * m[2][0] * m[3][2] -
m[0][3] * m[1][0] * m[2][1] * m[3][2] + m[0][0] * m[1][3] * m[2][1] * m[3][2] +
m[0][1] * m[1][0] * m[2][3] * m[3][2] - m[0][0] * m[1][1] * m[2][3] * m[3][2] -
m[0][2] * m[1][1] * m[2][0] * m[3][3] + m[0][1] * m[1][2] * m[2][0] * m[3][3] +
m[0][2] * m[1][0] * m[2][1] * m[3][3] - m[0][0] * m[1][2] * m[2][1] * m[3][3] -
m[0][1] * m[1][0] * m[2][2] * m[3][3] + m[0][0] * m[1][1] * m[2][2] * m[3][3];
}
对于一般的NxN,问题要困难得多,各种算法的顺序是O(N!)
,O(N^3)
,等等
工具书类
静态双行列式高斯极限(双[,]矩阵)
static double DeterminantGaussElimination(double[,] matrix)
{
int n = int.Parse(System.Math.Sqrt(matrix.Length).ToString());
int nm1 = n - 1;
int kp1;
double p;
double det=1;
for (int k = 0; k < nm1; k++)
{
kp1 = k + 1;
for(int i=kp1;i<n;i++)
{
p = matrix[i, k] / matrix[k, k];
for (int j = kp1; j < n; j++)
matrix[i, j] = matrix[i, j] - p * matrix[k, j];
}
}
for (int i = 0; i < n; i++)
det = det * matrix[i, i];
return det;
}
{
int n=int.Parse(System.Math.Sqrt(matrix.Length.ToString());
int nm1=n-1;
int-kp1;
双p;
双det=1;
对于(int k=0;k 对于(int i=kp1;i对于在搜索矩阵计算行列式算法时可能遇到此问题的任何人,请注意,上面发布的解决方案由以下代码组成:
static double DeterminantGaussElimination(double[,] matrix)
{
int n = int.Parse(System.Math.Sqrt(matrix.Length).ToString());
int nm1 = n - 1;
int kp1;
double p;
double det=1;
for (int k = 0; k < nm1; k++)
{
kp1 = k + 1;
for(int i=kp1;i<n;i++)
{
p = matrix[i, k] / matrix[k, k];
for (int j = kp1; j < n; j++)
matrix[i, j] = matrix[i, j] - p * matrix[k, j];
}
}
for (int i = 0; i < n; i++)
det = det * matrix[i, i];
return det;
}
静态双行列式高斯线性化(双[,]矩阵)
{
int n=int.Parse(System.Math.Sqrt(matrix.Length.ToString());
int nm1=n-1;
int-kp1;
双p;
双det=1;
对于(int k=0;k 对于(int i=kp1;i我可以确认以前的解决方案适用于3x3和4x4,但不适用于5x5等。
遵循适用于任何尺寸(也可为5x5或更多)的解决方案(非常简单)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MatrixTest
{
public class Matrix
{
private int dimension; //number of rows & colums for matrix
private double[][] matrix; //holds values of matrix itself
/// <summary>
/// Create dim*dim matrix and fill it with data passed to this constructor.
/// </summary>
/// <param name="double_array"></param>
/// <param name="dim"></param>
public Matrix(double[][] double_array)
{
matrix = double_array;
dimension = matrix.Length;
// check square matrix:
for (int i = 0; i < dimension; i++)
if (matrix[i].Length != dimension)
throw new Exception("Matrix is not square");
}
/// <summary>
/// Get determinant of current matrix
/// </summary>
/// <returns></returns>
public double Determinant()
{
if (dimension == 1)
return matrix[0][0];
// else ricorsive call:
double det = 0;
for (int j = 0; j < dimension; j++)
{
if (j % 2 == 0)
det += matrix[0][j] * GetSubmatrix(this, 0, j).Determinant();
else
det -= matrix[0][j] * GetSubmatrix(this, 0, j).Determinant();
}
return det;
}
/// <summary>
/// Return a new Matrix with:
/// dimension = passed matrix dimension - 1
/// elements = all element of the original matrix, except row and column specified
/// </summary>
/// <param name="m"></param>
/// <param name="rowToExclude"></param>
/// <param name="colToExclude"></param>
/// <returns></returns>
public Matrix GetSubmatrix(Matrix m, int rowToExclude, int colToExclude)
{
double[][] values = new double[m.dimension - 1][];
for (int i = 0; i < m.dimension; i++)
{
// create row array:
if (i < m.dimension - 1)
values[i] = new double[m.dimension - 1];
// copy values:
for (int j = 0; j < m.dimension; j++)
if (i != rowToExclude && j != colToExclude)
values[i < rowToExclude ? i : i - 1][j < colToExclude ? j : j - 1] = m.matrix[i][j];
}
return new Matrix(values);
}
internal class Program
{
private static void Main(string[] args)
{
Matrix mat02 = new Matrix(
new double[][] {
new double[] { 1.0, 2.0},
new double[] { -2.0, -5.0} });
Matrix mat03 = new Matrix(
new double[][] {
new double[] { 1.0, 2.0, -1.0 },
new double[] { -2.0, -5.0, -1.0},
new double[] { 1.0, -1.0, -2.0 } });
Matrix mat04 = new Matrix(
new double[][] {
new double[] {1.0, 2.0, 1.0, 3.0},
new double[] { -2.0, -5.0, -2.0, 1.0 },
new double[] { 1.0, -1.0, -3.0, 2.0 },
new double[] {4.0, -1.0, -3.0, 1.0} });
Matrix mat05 = new Matrix(
new double[][] {
new double[] {1.0, 2.0, 1.0, 2.0, 3.0},
new double[] {2.0, 1.0, 2.0, 2.0, 1.0},
new double[] {3.0, 1.0, 3.0, 1.0, 2.0},
new double[] {1.0, 2.0, 4.0, 3.0, 2.0},
new double[] {2.0, 2.0, 1.0, 2.0, 1.0} });
double determinant = mat02.Determinant();
Console.WriteLine("determinant is: {0}", determinant);
determinant = mat03.Determinant();
Console.WriteLine("determinant is: {0}", determinant);
determinant = mat04.Determinant();
Console.WriteLine("determinant is: {0}", determinant);
determinant = mat05.Determinant();
Console.WriteLine("determinant is: {0}", determinant);
Console.ReadLine();
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
名称空间矩阵
{
公共类矩阵
{
private int dimension;//矩阵的行数和列数
私有双精度[]矩阵;//保存矩阵本身的值
///
///创建dim*dim矩阵并用传递给此构造函数的数据填充它。
///
///
///
公共矩阵(双[]双[]双_阵列)
{
矩阵=双_数组;
尺寸=矩阵长度;
//方阵检查:
对于(int i=0;iusing System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MatrixTest
{
public class Matrix
{
private int dimension; //number of rows & colums for matrix
private double[][] matrix; //holds values of matrix itself
/// <summary>
/// Create dim*dim matrix and fill it with data passed to this constructor.
/// </summary>
/// <param name="double_array"></param>
/// <param name="dim"></param>
public Matrix(double[][] double_array)
{
matrix = double_array;
dimension = matrix.Length;
// check square matrix:
for (int i = 0; i < dimension; i++)
if (matrix[i].Length != dimension)
throw new Exception("Matrix is not square");
}
/// <summary>
/// Get determinant of current matrix
/// </summary>
/// <returns></returns>
public double Determinant()
{
if (dimension == 1)
return matrix[0][0];
// else ricorsive call:
double det = 0;
for (int j = 0; j < dimension; j++)
{
if (j % 2 == 0)
det += matrix[0][j] * GetSubmatrix(this, 0, j).Determinant();
else
det -= matrix[0][j] * GetSubmatrix(this, 0, j).Determinant();
}
return det;
}
/// <summary>
/// Return a new Matrix with:
/// dimension = passed matrix dimension - 1
/// elements = all element of the original matrix, except row and column specified
/// </summary>
/// <param name="m"></param>
/// <param name="rowToExclude"></param>
/// <param name="colToExclude"></param>
/// <returns></returns>
public Matrix GetSubmatrix(Matrix m, int rowToExclude, int colToExclude)
{
double[][] values = new double[m.dimension - 1][];
for (int i = 0; i < m.dimension; i++)
{
// create row array:
if (i < m.dimension - 1)
values[i] = new double[m.dimension - 1];
// copy values:
for (int j = 0; j < m.dimension; j++)
if (i != rowToExclude && j != colToExclude)
values[i < rowToExclude ? i : i - 1][j < colToExclude ? j : j - 1] = m.matrix[i][j];
}
return new Matrix(values);
}
internal class Program
{
private static void Main(string[] args)
{
Matrix mat02 = new Matrix(
new double[][] {
new double[] { 1.0, 2.0},
new double[] { -2.0, -5.0} });
Matrix mat03 = new Matrix(
new double[][] {
new double[] { 1.0, 2.0, -1.0 },
new double[] { -2.0, -5.0, -1.0},
new double[] { 1.0, -1.0, -2.0 } });
Matrix mat04 = new Matrix(
new double[][] {
new double[] {1.0, 2.0, 1.0, 3.0},
new double[] { -2.0, -5.0, -2.0, 1.0 },
new double[] { 1.0, -1.0, -3.0, 2.0 },
new double[] {4.0, -1.0, -3.0, 1.0} });
Matrix mat05 = new Matrix(
new double[][] {
new double[] {1.0, 2.0, 1.0, 2.0, 3.0},
new double[] {2.0, 1.0, 2.0, 2.0, 1.0},
new double[] {3.0, 1.0, 3.0, 1.0, 2.0},
new double[] {1.0, 2.0, 4.0, 3.0, 2.0},
new double[] {2.0, 2.0, 1.0, 2.0, 1.0} });
double determinant = mat02.Determinant();
Console.WriteLine("determinant is: {0}", determinant);
determinant = mat03.Determinant();
Console.WriteLine("determinant is: {0}", determinant);
determinant = mat04.Determinant();
Console.WriteLine("determinant is: {0}", determinant);
determinant = mat05.Determinant();
Console.WriteLine("determinant is: {0}", determinant);
Console.ReadLine();
}
}
}
import java.math.BigDecimal;
public class DeterminantCalc {
private double[][] matrix;
private int sign = 1;
DeterminantCalc(double[][] matrix) {
this.matrix = matrix;
}
public int getSign() {
return sign;
}
public BigDecimal determinant() {
BigDecimal deter;
if (isUpperTriangular() || isLowerTriangular())
deter = multiplyDiameter().multiply(BigDecimal.valueOf(sign));
else {
makeTriangular();
deter = multiplyDiameter().multiply(BigDecimal.valueOf(sign));
}
return deter;
}
/* receives a matrix and makes it triangular using allowed operations
on columns and rows
*/
public void makeTriangular() {
for (int j = 0; j < matrix.length; j++) {
sortCol(j);
for (int i = matrix.length - 1; i > j; i--) {
if (matrix[i][j] == 0)
continue;
double x = matrix[i][j];
double y = matrix[i - 1][j];
multiplyRow(i, (-y / x));
addRow(i, i - 1);
multiplyRow(i, (-x / y));
}
}
}
public boolean isUpperTriangular() {
if (matrix.length < 2)
return false;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < i; j++) {
if (matrix[i][j] != 0)
return false;
}
}
return true;
}
public boolean isLowerTriangular() {
if (matrix.length < 2)
return false;
for (int j = 0; j < matrix.length; j++) {
for (int i = 0; j > i; i++) {
if (matrix[i][j] != 0)
return false;
}
}
return true;
}
public BigDecimal multiplyDiameter() {
BigDecimal result = BigDecimal.ONE;
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix.length; j++) {
if (i == j)
result = result.multiply(BigDecimal.valueOf(matrix[i][j]));
}
}
return result;
}
// when matrix[i][j] = 0 it makes it's value non-zero
public void makeNonZero(int rowPos, int colPos) {
int len = matrix.length;
outer:
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
if (matrix[i][j] != 0) {
if (i == rowPos) { // found "!= 0" in it's own row, so cols must be added
addCol(colPos, j);
break outer;
}
if (j == colPos) { // found "!= 0" in it's own col, so rows must be added
addRow(rowPos, i);
break outer;
}
}
}
}
}
//add row1 to row2 and store in row1
public void addRow(int row1, int row2) {
for (int j = 0; j < matrix.length; j++)
matrix[row1][j] += matrix[row2][j];
}
//add col1 to col2 and store in col1
public void addCol(int col1, int col2) {
for (int i = 0; i < matrix.length; i++)
matrix[i][col1] += matrix[i][col2];
}
//multiply the whole row by num
public void multiplyRow(int row, double num) {
if (num < 0)
sign *= -1;
for (int j = 0; j < matrix.length; j++) {
matrix[row][j] *= num;
}
}
//multiply the whole column by num
public void multiplyCol(int col, double num) {
if (num < 0)
sign *= -1;
for (int i = 0; i < matrix.length; i++)
matrix[i][col] *= num;
}
// sort the cols from the biggest to the lowest value
public void sortCol(int col) {
for (int i = matrix.length - 1; i >= col; i--) {
for (int k = matrix.length - 1; k >= col; k--) {
double tmp1 = matrix[i][col];
double tmp2 = matrix[k][col];
if (Math.abs(tmp1) < Math.abs(tmp2))
replaceRow(i, k);
}
}
}
//replace row1 with row2
public void replaceRow(int row1, int row2) {
if (row1 != row2)
sign *= -1;
double[] tempRow = new double[matrix.length];
for (int j = 0; j < matrix.length; j++) {
tempRow[j] = matrix[row1][j];
matrix[row1][j] = matrix[row2][j];
matrix[row2][j] = tempRow[j];
}
}
//replace col1 with col2
public void replaceCol(int col1, int col2) {
if (col1 != col2)
sign *= -1;
System.out.printf("replace col%d with col%d, sign = %d%n", col1, col2, sign);
double[][] tempCol = new double[matrix.length][1];
for (int i = 0; i < matrix.length; i++) {
tempCol[i][0] = matrix[i][col1];
matrix[i][col1] = matrix[i][col2];
matrix[i][col2] = tempCol[i][0];
}
}
import java.math.BigDecimal;
import java.security.SecureRandom;
import java.text.NumberFormat;
import java.util.Scanner;
public class DeterminantTest {
public static void main(String[] args) {
String determinant;
//generating random numbers
int len = 500;
SecureRandom random = new SecureRandom();
double[][] matrix = new double[len][len];
for (int i = 0; i < len; i++) {
for (int j = 0; j < len; j++) {
matrix[i][j] = random.nextInt(500);
System.out.printf("%15.2f", matrix[i][j]);
}
}
System.out.println();
/*double[][] matrix = {
{1, 5, 2, -2, 3, 2, 5, 1, 0, 5},
{4, 6, 0, -2, -2, 0, 1, 1, -2, 1},
{0, 5, 1, 0, 1, -5, -9, 0, 4, 1},
{2, 3, 5, -1, 2, 2, 0, 4, 5, -1},
{1, 0, 3, -1, 5, 1, 0, 2, 0, 2},
{1, 1, 0, -2, 5, 1, 2, 1, 1, 6},
{1, 0, 1, -1, 1, 1, 0, 1, 1, 1},
{1, 5, 5, 0, 3, 5, 5, 0, 0, 6},
{1, -5, 2, -2, 3, 2, 5, 1, 1, 5},
{1, 5, -2, -2, 3, 1, 5, 0, 0, 1}
};
double[][] matrix = menu();*/
DeterminantCalc deter = new DeterminantCalc(matrix);
BigDecimal det = deter.determinant();
determinant = NumberFormat.getInstance().format(det);
for (int i = 0; i < matrix.length; i++) {
for (int j = 0; j < matrix.length; j++) {
System.out.printf("%15.2f", matrix[i][j]);
}
System.out.println();
}
System.out.println();
System.out.printf("%s%s%n", "Determinant: ", determinant);
System.out.printf("%s%d", "sign: ", deter.getSign());
}
public static double[][] menu() {
Scanner scanner = new Scanner(System.in);
System.out.print("Matrix Dimension: ");
int dim = scanner.nextInt();
double[][] inputMatrix = new double[dim][dim];
System.out.println("Set the Matrix: ");
for (int i = 0; i < dim; i++) {
System.out.printf("%5s%d%n", "row", i + 1);
for (int j = 0; j < dim; j++) {
System.out.printf("M[%d][%d] = ", i + 1, j + 1);
inputMatrix[i][j] = scanner.nextDouble();
}
System.out.println();
}
scanner.close();
return inputMatrix;
}