方陣求行列式

一、知識預備

? 利用{\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階以下的行列式計算可以直接使用對角線法則,因此對于高階行列式,考慮從降階的角度入手. 降階的具體方法是將行列式按第一列展開,并將代數(shù)余子式再按其第一列展開,依此類推,直至行列式被降階至3階及3階以下;

? 是可以定義一個用來執(zhí)行{\rm Laplace}展開定理的函數(shù)用于專門按第一列展開行列式,然后使用遞歸的方法對行列式逐層降階,本文中,我們統(tǒng)一降階到1階來計算.

三、實現(xiàn)方法

  1. 定義主函數(shù),分別來實現(xiàn):輸入行列式的階(order),判斷階是否合法;如果階合法,再輸入一個order階行列式本身,這里采用二維數(shù)組來儲存矩陣(matrix);利用另定義的行列式計算函數(shù)(determinant),將矩陣和階傳入 determinant 函數(shù),計算行列式的值;最后輸出結(jié)果.
int main()
{
    int order,matrix[20][20],result = 0,i,j;
    
    printf("請輸入階數(shù):");
    scanf("%d",&order);
    if(order <= 0)
        printf("請輸入大于0的整數(shù)!");
    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 函數(shù). 如果行列式為1階,行列式的值便是 a_{11}的值,即 matrix[0][0]; 如果行列式的階高于1,我們采用另定義的{\rm Laplace}展開函數(shù) laplace_expansion 來降階,并在函數(shù)中直接展開后余子式的值. 將{\rm Laplace}展開函數(shù)定義為
int laplace_expansion(int matrix[20][20],int r,int c,int order);

注意,這里的martix[20][20]已經(jīng)不是main函數(shù)里面的方陣,而是未來將要被降階的一個容器。當然也可以改名為其他,保持名字統(tǒng)一即可

其中r ,c分別執(zhí)行展開時選定元素在行列式中的行數(shù)和列數(shù),統(tǒng)一選定c=0 ,即選取第一列元素.

展開的結(jié)果是一個余子式\boldsymbol{M} ,用cofactor表示,由于公式中是代數(shù)余子式\boldsymbol{A} = (-1)^{i + j}\boldsymbol{M},因此定義sign = 1用來記錄該行該列代數(shù)余子式的符號,每換一行乘上 -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 函數(shù)計算余子式的值:

determinant函數(shù)中,我們向 laplace_expansion 函數(shù)傳遞了選定的行 r 和列 c ;在余子式的定義中,元素 a_{rc} 的余子式是劃掉行列式第 r 行第 c 列,并把留下原來的元素按原來的相對位置關(guān)系排列得到的行列式. 可以這樣構(gòu)思來取余子式:選定了元素 a_{rc} 后,對于行數(shù) i 小于 r ,列數(shù) j 小于 c 的位置,余子式cofactor[i][j] = matrix[i][j];對于行數(shù) i 大于 r 而列數(shù) j 小于 c 的位置,將原行列式的行數(shù)減去 1 對應到余子式上;對于行數(shù) i 小于 r 而列數(shù) j 大于 c 的位置,將原行列式的列數(shù)減去 1 對應到余子式上;而對于行數(shù) i 大于 r 且列數(shù) j 大于 c 的位置,則需要將原行列式的行數(shù)和列數(shù)均減去 1 對應到余子式上. 根據(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;
        }
    }

這樣一來,二維數(shù)組cofactor中儲存了余子式對應的矩陣,這時候把cofactor和降階后的階數(shù)order - 1 傳回 determinant 函數(shù),利用

determinant(cofactor,order - 1);

計算余子式的值,而如果余子式依然高于1階,determinant 函數(shù)又回讓余子式重新執(zhí)行l(wèi)aplace_expansion 函數(shù)繼續(xù)降階,直至被降至1階. 如此操作,便在兩個函數(shù)之間實現(xiàn)了遞歸,行列式被一層層“剝開”并被逐步計算出來. 整個過程的代碼為:

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;
}

這時候,整個程序已經(jīng)能實現(xiàn)行列式計算了,最后加上一些基本的說明以便用戶操作即可. 以下是本程序的全部代碼:

#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階以下的行列式。你可以先輸入階數(shù),然后形如\n");
    Sleep(800);
    printf("1 2 3\n4 5 6\n7 8 9\n");
    Sleep(800);
    printf("這樣來輸入你需要計算的行列式。\n\n");
    Sleep(600);
    printf("請輸入階數(shù):");
    scanf("%d",&order);
    if(order <= 0)
        printf("請輸入大于0的整數(shù)!");
    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

# 創(chuàng)建一個3x3的Numpy矩陣
matrix = np.array([[55, 25, 15], [30, 44, 2], [11, 45, 77]])

# 計算矩陣的行列式
det = np.linalg.det(matrix)

print("給定3x3矩陣的行列式為:", int(det))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容