一、知识预备
• 利用 展开定理可以将行列式
按任意行任意列展开. 这里我们采用按第一列展开,得
二、基本思路
由于3阶以下的行列式计算可以直接使用对角线法则,因此对于高阶行列式,考虑从降阶的角度入手. 降阶的具体方法是将行列式按第一列展开,并将代数余子式再按其第一列展开,依此类推,直至行列式被降阶至3阶及3阶以下;
• 是可以定义一个用来执行展开定理的函数用于专门按第一列展开行列式,然后使用递归的方法对行列式逐层降阶,本文中,我们统一降阶到1阶来计算.
三、实现方法
- 定义主函数,分别来实现:输入行列式的阶(order),判断阶是否合法;如果阶合法,再输入一个order阶行列式本身,这里采用二维数组来储存矩阵(matrix);利用另定义的行列式计算函数(determinant),将矩阵和阶传入 determinant 函数,计算行列式的值;最后输出结果.
int main()
{
int order,matrix[20][20],result = 0,i,j;
printf("请输入阶数:");
scanf("%d",&order);
if(order <= 0)
printf("请输入大于0的整数!");
else
{
printf("请输入一个%d阶行列式:\n",order);
for(i = 0;i < order;i ++)
for(j = 0;j < order;j ++)
scanf("%d",&matrix[i][j]);
result = determinant(matrix,order);
printf("行列式的值为: %d",result);
}
return 0;
}
- 接着来编写 determinant 函数. 如果行列式为1阶,行列式的值便是 a_{11}的值,即 matrix[0][0]; 如果行列式的阶高于1,我们采用另定义的
展开函数 laplace_expansion 来降阶,并在函数中直接展开后余子式的值. 将
展开函数定义为
int laplace_expansion(int matrix[20][20],int r,int c,int order);
注意,这里的martix[20][20]已经不是main函数里面的方阵,而是未来将要被降阶的一个容器。当然也可以改名为其他,保持名字统一即可
其中分别执行展开时选定元素在行列式中的行数和列数,统一选定
,即选取第一列元素.
展开的结果是一个余子式 ,用
表示,由于公式中是代数余子式
,因此定义
用来记录该行该列代数余子式的符号,每换一行乘上
,于是展开式每一项的值便是
sign * matrix[i][0] * cofactor
于是有:
int determinant(int matrix[20][20],int order)
{
int result = 0,sign = 1,cofactor,i;
if(order == 1)
result = matrix[0][0];
else
for(i = 0;i < order;i ++)
{
cofactor = laplace_expansion(matrix,i,0,order);
result += sign * matrix[i][0] * cofactor;
sign *= -1;
}
return result;
}
- 编写 laplace_expansion 函数计算余子式的值:
在函数中,我们向 laplace_expansion 函数传递了选定的行 r 和列 c ;在余子式的定义中,元素 a_{rc} 的余子式是划掉行列式第 r 行第 c 列,并把留下原来的元素按原来的相对位置关系排列得到的行列式. 可以这样构思来取余子式:选定了元素 a_{rc} 后,对于行数 i 小于 r ,列数 j 小于 c 的位置,余子式
;对于行数 i 大于 r 而列数 j 小于 c 的位置,将原行列式的行数减去 1 对应到余子式上;对于行数 i 小于 r 而列数 j 大于 c 的位置,将原行列式的列数减去 1 对应到余子式上;而对于行数 i 大于 r 且列数 j 大于 c 的位置,则需要将原行列式的行数和列数均减去 1 对应到余子式上. 根据上述思路写出以下代码:
for(i = 0;i < order;i ++)
for(j = 0;j < order;j ++)
{
original_i = i;
original_j = j;
if(i == r || j == c);
else
{
if(i > r)
i --;
if(j > c)
j --;
cofactor[i][j] = matrix[original_i][original_j];
i = original_i;
j = original_j;
}
}
这样一来,二维数组cofactor中储存了余子式对应的矩阵,这时候把cofactor和降阶后的阶数order - 1 传回 determinant 函数,利用
determinant(cofactor,order - 1);
计算余子式的值,而如果余子式依然高于1阶, 函数又回让余子式重新执行laplace_expansion 函数继续降阶,直至被降至1阶. 如此操作,便在两个函数之间实现了递归,行列式被一层层“剥开”并被逐步计算出来. 整个过程的代码为:
int laplace_expansion(int matrix[20][20],int r,int c,int order)
{
int result = 0,cofactor[20][20],original_i,original_j,i,j;
for(i = 0;i < order;i ++)
for(j = 0;j < order;j ++)
{
original_i = i;
original_j = j;
if(i == r || j == c);
else
{
if(i > r)
i --;
if(j > c)
j --;
cofactor[i][j] = matrix[original_i][original_j];
i = original_i;
j = original_j;
}
}
if(order >= 2)
result = determinant(cofactor,order - 1);
return result;
}
这时候,整个程序已经能实现行列式计算了,最后加上一些基本的说明以便用户操作即可. 以下是本程序的全部代码:
#include <stdio.h>
#include <windows.h>
int determinant(int matrix[20][20],int order);
int laplace_expansion(int matrix[20][20],int r,int c,int order);
int main()
{
int order,matrix[20][20],result = 0,i,j;
printf("行列式计算器可以计算20阶以下的行列式。你可以先输入阶数,然后形如\n");
Sleep(800);
printf("1 2 3\n4 5 6\n7 8 9\n");
Sleep(800);
printf("这样来输入你需要计算的行列式。\n\n");
Sleep(600);
printf("请输入阶数:");
scanf("%d",&order);
if(order <= 0)
printf("请输入大于0的整数!");
else
{
printf("请输入一个%d阶行列式:\n",order);
for(i = 0;i < order;i ++)
for(j = 0;j < order;j ++)
scanf("%d",&matrix[i][j]);
result = determinant(matrix,order);
printf("行列式的值为: %d",result);
}
return 0;
}
int determinant(int matrix[20][20],int order)
{
int result = 0,sign = 1,cofactor,i;
if(order == 1)
result = matrix[0][0];
else
for(i = 0;i < order;i ++)
{
cofactor = laplace_expansion(matrix,i,0,order);
result += sign * matrix[i][0] * cofactor;
sign *= -1;
}
return result;
}
int laplace_expansion(int matrix[20][20],int r,int c,int order)
{
int result = 0,cofactor[20][20],original_i,original_j,i,j;
for(i = 0;i < order;i ++)
for(j = 0;j < order;j ++)
{
original_i = i;
original_j = j;
if(i == r || j == c);
else
{
if(i > r)
i --;
if(j > c)
j --;
cofactor[i][j] = matrix[original_i][original_j];
i = original_i;
j = original_j;
}
}
if(order >= 2)
result = determinant(cofactor,order - 1);
return result;
}
当然,由于python的numpy更为强大
import numpy as np
# 创建一个3x3的Numpy矩阵
matrix = np.array([[55, 25, 15], [30, 44, 2], [11, 45, 77]])
# 计算矩阵的行列式
det = np.linalg.det(matrix)
print("给定3x3矩阵的行列式为:", int(det))