方阵求行列式

一、知识预备

利用{\rm Laplace} 展开定理可以将行列式
\ D=\left|\begin{array}{cccc} a_{11}&a_{12}&a_{13}&…&a_{1n}\\ a_{21}&a_{22}&a_{13}&…&a_{2n}\\ a_{31}&a_{32}&a_{33}&…&a_{3n}\\ \vdots&\vdots&\vdots&\ddots& \vdots \\ a_{n1}&a_{n2}&a_{n3}&…&a_{nn}\\ \end{array}\right|\
按任意行任意列展开. 这里我们采用按第一列展开,得

\ D=\left|\begin{array}{c}a_{11}&a_{12}&a_{13}&…&a_{1n}\\ a_{21}&a_{22}&a_{13}&…&a_{2n}\\ a_{31}&a_{32}&a_{33}&…&a_{3n}\\ \vdots &\vdots &\vdots & \ddots& \vdots \\ a_{n1}&a_{n2}&a_{n3}&…&a_{nn}\\ \end{array}\right|=a_{11}A_{11}+a_{21}A_{21}+a_{31}A_{31}+ \cdots +a_{n1}A_{n1} \

二、基本思路

由于3阶以下的行列式计算可以直接使用对角线法则,因此对于高阶行列式,考虑从降阶的角度入手. 降阶的具体方法是将行列式按第一列展开,并将代数余子式再按其第一列展开,依此类推,直至行列式被降阶至3阶及3阶以下;

是可以定义一个用来执行{\rm Laplace}展开定理的函数用于专门按第一列展开行列式,然后使用递归的方法对行列式逐层降阶,本文中,我们统一降阶到1阶来计算.

三、实现方法

  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;
}
  1. 接着来编写 determinant 函数. 如果行列式为1阶,行列式的值便是 a_{11}的值,即 matrix[0][0]; 如果行列式的阶高于1,我们采用另定义的{\rm Laplace}展开函数 laplace_expansion 来降阶,并在函数中直接展开后余子式的值. 将{\rm Laplace}展开函数定义为
int laplace_expansion(int matrix[20][20],int r,int c,int order);

注意,这里的martix[20][20]已经不是main函数里面的方阵,而是未来将要被降阶的一个容器。当然也可以改名为其他,保持名字统一即可

其中r ,c分别执行展开时选定元素在行列式中的行数和列数,统一选定c=0 ,即选取第一列元素.

展开的结果是一个余子式\boldsymbol{M} ,用cofactor表示,由于公式中是代数余子式\boldsymbol{A} = (-1)^{i + j}\boldsymbol{M},因此定义sign = 1用来记录该行该列代数余子式的符号,每换一行乘上 -1,于是展开式每一项的值便是

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;
}
  1. 编写 laplace_expansion 函数计算余子式的值:

determinant函数中,我们向 laplace_expansion 函数传递了选定的行 r 和列 c ;在余子式的定义中,元素 a_{rc} 的余子式是划掉行列式第 r 行第 c 列,并把留下原来的元素按原来的相对位置关系排列得到的行列式. 可以这样构思来取余子式:选定了元素 a_{rc} 后,对于行数 i 小于 r ,列数 j 小于 c 的位置,余子式cofactor[i][j] = matrix[i][j];对于行数 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阶,determinant 函数又回让余子式重新执行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))
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容