矩阵的行列式求法
行列式求法很多,下面是比较常见的几种。矩阵A的行列式记成 d e t ( A ) det(A) det(A).
拉普拉斯展开
根据行列式的代数余子式定义,矩阵按某行或某列展开:
det
(
A
)
=
∑
j
=
1
n
(
−
1
)
i
+
j
a
i
j
det
(
A
i
j
)
=
∑
i
=
1
n
(
−
1
)
i
+
j
a
i
j
det
(
A
i
j
)
\operatorname{det}(A)=\sum_{j=1}^{n}(-1)^{i+j} a_{i j} \operatorname{det}\left(A_{i j}\right)=\sum_{i=1}^{n}(-1)^{i+j} a_{i j} \operatorname{det}\left(A_{i j}\right)
det(A)=j=1∑n(−1)i+jaijdet(Aij)=i=1∑n(−1)i+jaijdet(Aij)
这个直接递归就能搞定,时间复杂度:
T
(
n
)
=
T
(
n
−
1
)
n
+
n
T(n)=T(n-1)n+n
T(n)=T(n−1)n+n
这个复杂度迭代计算得到:
T
(
n
)
=
∑
i
=
0
n
−
1
n
!
i
!
=
O
(
n
∗
n
!
)
T(n)=\sum_{i=0}^{n-1}\frac{n!}{i!}=O(n*n!)
T(n)=i=0∑n−1i!n!=O(n∗n!)
复杂度过于骇人听闻,所以实际没人敢用。只适用于一些线性代数考试题。
核心代码:
int det_matrix(Matrix& mat, int row)
{
if(row == 2)
{
double* arr = mat.get_mat();
return arr[0 * row + 0] * arr[1 * row + 1] - arr[0 * row + 1] * arr[1 * row + 0];
}
else
{
double res = 0;
double *vec = mat.get_mat();
for(int i = 0; i < row; i++)
{
int k = 1;
if(i % 2 == 1)
{
k = -1;
}
Matrix new_mat = remove_row_col(mat,1, i + 1);
res += vec[i] * k * det(new_mat,row - 1);
}
return res;
}
}
交错和
这种方法是生成一个1-n的排列p,然后按这个排列选数累乘,按排列的逆序对数决定符号。显然一共n!项,每项连乘O(n),复杂度还是O(n*n!)。连线性代数考试都不屑于用。
想办法变成上三角矩阵
上三角矩阵的行列式是主对角线元素的连乘,可以按第一列做拉普拉斯展开,数学归纳法证明。
经典高斯消元法
用第三类初等行变换把矩阵变成上三角阵,这样行列式是不变的。第三类初等行变换是把某行的k倍加到别的行上去。这个实际上是高斯消元。
LU分解
这个本质上还是高斯消元。因为把初等变换施加到单位矩阵E上,可以记录下变换操作。将原矩阵左乘这个记录矩阵就相当于对原矩阵做了初等行变换。这里大概描述LU分解的原理:
一个可逆矩阵A一定可以分解成
A
=
L
∗
U
A=L*U
A=L∗U
U是和A等价的上三角矩阵。
L是一个下三角矩阵,对主角线一定都是1,L与A向U变换的操作步骤有关。
很明显L和U的求法可以高斯消元,也可以直接求。具体另一篇博客会解释。

本文详细介绍了矩阵行列式的多种求解方法,包括拉普拉斯展开、交错和、上三角矩阵转换、高斯消元法及LU分解。通过对比不同方法的时间复杂度,帮助读者理解并选择合适的求解策略。
1965

被折叠的 条评论
为什么被折叠?



