测试样例
10
1 3 4 0 2 0 4 -5 9 3
6 7 8 5 2 7 8 4 6 2
8 7 6 9 8 7 6 8 45 2
4 3 2 5 4 3 2 8 6 4
1 2 0 4 1 2 3 9 87 6
5 6 7 8 5 6 8 6 8 1
9 8 7 6 9 8 7 -9 2 3
5 6 3 5 4 1 8 7 9 2
-9 8 6 2 4 56 6 3 8 9
5 3 6 8 6 6 1 8 2 3
答案:7583304
按行(列)展开法
#include <iostream>
#include <fstream>
using namespace std;
//构造第一行第line个元素的余子式
void StructMinor(double* matrix, int dimension, int line, double* minor){
int ptr=0;
for(int cnt1=1; cnt1<dimension; cnt1++) for(int cnt2=0; cnt2<dimension; cnt2++)
if(line!=cnt2) minor[ptr++] = matrix[cnt1*dimension+cnt2];
return;
}
double Determinant(double* matrix, int dimension){
//递归基,当矩阵中只有一个元素的时候,行列式的值即为实数值
if(dimension <= 1) return *matrix;
double minor[(dimension-1)*(dimension-1)];
double determinant = 0;
int sign = 1;
for(int cnt=0; cnt<dimension; cnt++){
//构造matrix[0][cnt]的余子式
StructMinor(matrix, dimension, cnt, minor);
//determinant=ΣELEMENT0j*A0j
determinant += sign*matrix[cnt]*Determinant(minor, dimension-1);
sign *= -1;
}
return determinant;
}
int main(){
int dimension;
int scale;
double matrix[100];
ifstream input("matrix.txt");
input >> dimension;
scale = dimension*dimension;
for(int cnt=0; cnt<scale; cnt++) input >> matrix[cnt];
cout << Determinant(matrix, dimension);
return 0;
}
计算结果
高斯消元转化为上三角阵
#include <iostream>
#include <fstream>
using namespace std;
//通过高斯消元法化矩阵为upper triangle matrix
void GaussElimination2UTM(double* matrix, int dimension){
//注意cnt3一定要从矩阵最右侧运算至左侧,否则主元列对应元素归零,运算就无法正常进行
for(int cnt1=0; cnt1<dimension; cnt1++) for(int cnt2=cnt1+1; cnt2<dimension; cnt2++) for(int cnt3=dimension-1; cnt3>=cnt1; cnt3--)
matrix[cnt2*dimension+cnt3] += -1*matrix[cnt1*dimension+cnt3]*matrix[cnt2*dimension+cnt1]/matrix[cnt1*dimension+cnt1];
return;
}
double Determinant(double* matrix, int dimension){
double determinant=1;
GaussElimination2UTM(matrix, dimension);
//上三角阵对角线乘积即为行列式
for(int cnt=0; cnt<dimension; cnt++) determinant *= matrix[cnt*dimension+cnt];
return determinant;
}
int main(){
int dimension;
int scale;
double matrix[100];
ifstream input("matrix.txt");
input >> dimension;
scale = dimension*dimension;
for(int cnt=0; cnt<scale; cnt++) input >> matrix[cnt];
cout << Determinant(matrix, dimension) << '\n';
return 0;
}
计算结果
计算结果出现明显错误,原因是这个矩阵在进行行变换的时候出现了第四行第四列,极小的主元,所以根本原因在于double的精度对于这种算法依然不够
对于测试样例
7
1 3 4 0 2 33 4
6 7 8 5 62 7 8
98 7 6 9 8 7 6
54 3 2 5 4 3 2
1 2 0 4 1 2 34
5 6 7 8 5 6 78
9 8 7 6 9 8 72
可以得出正确结果
尽管这种算法对精度要求很高,但是计算速度很快
定义法
使用行列式的定义式进行计算
代码
#include <iostream>
#include <fstream>
using namespace std;
int dimension;
char permutation[10];
double matrix[100];
double Determinant(int depth, double sign){
double result;
//递归基,在递归树的叶子返回定义的求和式的其中一项
if(depth>=dimension){
result = sign;
for(int cnt=0; cnt<dimension; cnt++) result *= matrix[cnt*dimension+permutation[cnt]];
}
else{
int temp;
//不交换的情况,对逆序数无贡献
result = Determinant(depth+1, sign);
//将后续几个元素分别于第一个元素进行交换,逆序数加一
for(int cnt=depth+1; cnt<dimension; cnt++){
//交换
temp = permutation[depth];
permutation[depth] = permutation[cnt];
permutation[cnt] = temp;
//计算此情况下所有值之和
result += Determinant(depth+1, -1*sign);
//换回
temp = permutation[depth];
permutation[depth] = permutation[cnt];
permutation[cnt] = temp;
}
}
return result;
}
int main(){
int scale;
ifstream input("matrix.txt");
input >> dimension;
for(int cnt=0; cnt<dimension; cnt++) permutation[cnt] = cnt;
scale = dimension*dimension;
for(int cnt=0; cnt<scale; cnt++) input >> matrix[cnt];
cout << Determinant(0,1) << '\n';
return 0;
}