C++ 程序 矩阵行列式
矩阵行列式是什么?
矩阵行列式是一个特殊的数字,仅针对方阵(行和列一样多的矩阵)定义。行列式在微积分和其他涉及代数的矩阵中使用,实际上它以一个实数代表矩阵,可用于解线性方程组并找到矩阵的逆。
如何计算行列式?
矩阵行列式的值可以通过以下过程计算:
对于第一行或第一列的每个元素,取那些元素的余子式,然后将该元素乘以相应余子式的行列式,并用交替符号将它们相加。作为基本情况,1*1矩阵的行列式值为单个值本身。
一个元素的余子式 是一个矩阵,我们可以通过从该矩阵中删除该元素的行和列来获得。
2 x 2矩阵的行列式:
3 x 3矩阵的行列式:
// C++程序,用于查找矩阵的行列式
#include <iostream>
using namespace std;
// 输入矩阵的维度
#define N 4
// 函数用于在temp[][]中获取mat[p][q]的代数余子式。n是mat[][]当前的维度
void getCofactor(int mat[N][N],
int temp[N][N], int p,
int q, int n)
{
int i = 0, j = 0;
// 循环遍历矩阵中的每个元素
for (int row = 0; row < n; row++)
{
for (int col = 0; col < n; col++)
{
// 只复制不在给定行和列的元素到临时矩阵中
if (row != p && col != q)
{
temp[i][j++] = mat[row][col];
// 行已满,因此增加行索引并重新设置列索引
if (j == n - 1)
{
j = 0;
i++;
}
}
}
}
}
/* 递归函数,用于查找矩阵的行列式。
n是mat[][]的当前维度。*/
int determinantOfMatrix(int mat[N][N], int n)
{
// 初始化结果
int D = 0;
// 基本情况:如果矩阵只包含一个元素
if (n == 1)
return mat[0][0];
// 存储代数余子式
int temp[N][N];
// 存储符号乘数
int sign = 1;
// 循环遍历第一行的每个元素
for (int f = 0; f < n; f++)
{
// 获取mat[0][f]的代数余子式
getCofactor(mat, temp, 0, f, n);
D += sign * mat[0][f] *
determinantOfMatrix(temp, n - 1);
// 这些项需要交替带符号相加
sign = -sign;
}
return D;
}
// 函数用于显示矩阵
void display(int mat[N][N],
int row, int col)
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
cout << " " << mat[i][j];
cout << "n";
}
}
// 主函数
int main()
{
int mat[N][N] = {{1, 0, 2, -1},
{3, 0, 0, 5},
{2, 1, 4, -3},
{1, 0, 5, 0}};
// 调用函数
cout << "矩阵的行列式为:" <<
determinantOfMatrix(mat, N);
return 0;
}
// 由shivanisinghss2110贡献```
输出
矩阵的行列式为:30
时间复杂度: O(n!)。
说明: getCofactor()函数的时间复杂度为O(N ^ 2),因为它需要循环遍历N x N矩阵的所有元素。determinantOfMatrix()函数的时间复杂度可以使用以下递归关系计算:
T(N)= N * T(N-1)+ O(N ^ 3)
第一个项N * T(N-1)表示计算(N-1)x(N-1)子矩阵行列式所需的时间,第二个项O(N ^ 3)表示计算原始矩阵第一行中每个元素的代数余子式所需的时间。使用析因展开,我们可以将一个NxN矩阵的行列式计算为每个(N-1)x(N-1)矩阵的行列式之和,每个矩阵计算代数余子式需要O(N ^ 2)的时间。因此,determinantOfMatrix()函数的时间复杂度为O(N!),这是最坏情况下的情况,其中矩阵是置换矩阵。
display()函数的时间复杂度为O(N ^ 2),因为它循环遍历矩阵的所有元素以打印它们。程序的整体时间复杂度由determinantOfMatrix()函数主导,因此程序的时间复杂度为O(N!)。
空间复杂度: O(n * n),因为创建了temp矩阵。
矩阵的伴随和逆
行列式具有各种有用的特性,可以用于解决与矩阵相关的问题,
本文由Utkarsh Trivedi撰写。如果您发现任何错误或想分享更多有关上述主题的信息,请在评论中写下。
上述方法中讨论了递归方法。 当矩阵的大小较大时,它消耗更多的堆栈大小。
在这种方法中,我们使用行列式的特性。在这种方法中,我们将给定的矩阵转换为上三角矩阵,使用行列式的特性。上三角矩阵的行列式是对角线上所有元素的乘积。有关行列式的特性,请参阅此网站:https://cran.r-project.org/web/packages/matlib/vignettes/det-ex1.html
在这种方法中,我们迭代每个对角线元素,并使用行列式的特性将对角线以下的所有元素都变为零。
如果对角线元素为零,则在同一列中搜索下一个非零元素。
有两种情况
情况1:
如果没有非零元素。在这种情况下,矩阵的行列式为零。
情况2:
如果存在非零元素,则存在两种情况
情况a:
如果索引是相对于对角线行元素的。使用行列式的特性,将所有列元素都变为零。
情况b:
在这种情况下,我们需要交换具有相对于对角线元素列的行,并继续情况‘a’操作。
下面是上述方法的实现:
// C ++程序以找到矩阵的行列式
//计算机领域的英文文章
#include <bits/stdc++.h>
using namespace std;
// 输入方阵的维度
#define N 4
// 获取矩阵行列式的函数
int determinantOfMatrix(int mat[N][N], int n)
{
// 初始化结果
int num1, num2, det = 1, index,
total = 1;
// 用于存储行的临时数组
int temp[n + 1];
// 遍历对角线元素的循环
for (int i = 0; i < n; i++)
{
// 初始化索引
index = i;
// 找到具有非零值的索引
while (index < n && mat[index][i] == 0)
{
index++;
}
// 如果有非零元素
if (index == n)
{
// 矩阵的行列式为零
continue;
}
if (index!= i)
{
// 交换对角线元素行和索引行的循环
for (int j = 0; j < n; j++)
{
swap(mat[index][j], mat[i][j]);
}
// 当我们移动行穿过行列式时,行列式符号会更改
// 属性
det = det * pow(-1, index - i);
}
// 存储对角线行元素的值
for (int j = 0; j < n; j++)
{
temp[j] = mat[i][j];
}
// 遍历对角线元素以下的每一行
for (int j = i + 1; j < n; j++)
{
// 对角线元素的值
num1 = temp[i];
// 下一个行元素的值
num2 = mat[j][i];
// 遍历行的每一列并将其乘以每一行
for (int k = 0; k < n; k++)
{
//乘以使对角线元素和下一行元素相等
mat[j][k]
=(num1 * mat[j][k]) -(num2 * temp[k]);
}
总数=总数* num1; // Det(kA)=kDet(A);
}
}
//将对角线元素相乘以获得行列式
for (int i = 0; i < n; i++)
{
det = det * mat[i][i];
}
// Det(kA)/ k=Det(A);
返回(det / total);
}
// 主函数
int main()
{
int mat [N] [N] = {{1, 0, 2, -1},
{3, 0, 0, 5},
{2, 1, 4, -3},
{1, 0, 5, 0}};
// 函数调用
printf("矩阵行列式为:%d",
determinantOfMatrix(mat,N));
回归0;
}
输出
矩阵行列式为:30
时间复杂度: O(n 3 )
辅助空间: O(n)
方法:高斯-约旦消元法
步骤:
- 从所给矩阵开始,并将行列式初始化为1。
- 应用初等行操作,将矩阵转换为其行梯形形式,同时跟踪行列式。
- 如果执行了任何行交换操作,请将行列式乘以-1。
- 如果任何一行具有0的主导系数,则行列式为0,我们可以停止。
- 行列式是行梯形式中对角线条目的乘积。
- 返回行列式值。
#include<iostream>
using namespace std;
const int MAXN = 105;
double a[MAXN][MAXN];
double cofactor[MAXN][MAXN];
int sign = 1;
double determinant(int n) {
if (n == 1) {
return a[0][0];
}
double det = 0.0;
for (int k = 0; k < n; k++) {
int sub_i = 0;
int sub_j = 0;
for (int i = 1; i < n; i++) {
for (int j = 0; j < n; j++) {
if (j == k) {
continue;
}
cofactor[sub_i][sub_j] = a[i][j];
sub_j++;
if (sub_j == n - 1) {
sub_i++;
sub_j = 0;
}
}
}
det += sign * a[0][k] * determinant(n - 1);
sign = -sign;
}
return det;
}
int main() {
int n = 4;
double matrix[4][4] = {{1, 0, 2, -1},
{3, 0, 0, 5},
{2, 1, 4, -3},
{1, 0, 5, 0}};
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
a[i][j] = matrix[i][j];
}
}
double det = determinant(n);
cout << "Determinant = " << det << endl;
return 0;
}
输出
Determinant = 30
时间复杂度: O(n!)
空间复杂度: O(n^2)