方陣求行列式

一兜材、知識(shí)預(yù)備

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

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

三怠硼、實(shí)現(xiàn)方法

  1. 定義主函數(shù)鬼贱,分別來實(shí)現(xiàn):輸入行列式的階(order),判斷階是否合法香璃;如果階合法这难,再輸入一個(gè)order階行列式本身,這里采用二維數(shù)組來儲(chǔ)存矩陣(matrix)葡秒;利用另定義的行列式計(jì)算函數(shù)(determinant)姻乓,將矩陣和階傳入 determinant 函數(shù)嵌溢,計(jì)算行列式的值;最后輸出結(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("請輸入一個(gè)%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ù)里面的方陣禁偎,而是未來將要被降階的一個(gè)容器腿堤。當(dāng)然也可以改名為其他阀坏,保持名字統(tǒng)一即可

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

展開的結(jié)果是一個(gè)余子式\boldsymbol{M} 盒至,用cofactor表示,由于公式中是代數(shù)余子式\boldsymbol{A} = (-1)^{i + j}\boldsymbol{M}士修,因此定義sign = 1用來記錄該行該列代數(shù)余子式的符號(hào)枷遂,每換一行乘上 -1,于是展開式每一項(xiàng)的值便是

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ù)計(jì)算余子式的值:

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 對應(yīng)到余子式上蕊爵;對于行數(shù) i 小于 r 而列數(shù) j 大于 c 的位置辉哥,將原行列式的列數(shù)減去 1 對應(yīng)到余子式上;而對于行數(shù) i 大于 r 且列數(shù) j 大于 c 的位置攒射,則需要將原行列式的行數(shù)和列數(shù)均減去 1 對應(yīng)到余子式上. 根據(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中儲(chǔ)存了余子式對應(yīng)的矩陣,這時(shí)候把cofactor和降階后的階數(shù)order - 1 傳回 determinant 函數(shù)会放,利用

determinant(cofactor,order - 1);

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

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

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

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

當(dāng)然,由于python的numpy更為強(qiáng)大

import numpy as np

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

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

print("給定3x3矩陣的行列式為:", int(det))
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末脓诡,一起剝皮案震驚了整個(gè)濱河市无午,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌祝谚,老刑警劉巖宪迟,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異交惯,居然都是意外死亡次泽,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門席爽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來意荤,“玉大人,你說我怎么就攤上這事只锻【料瘢” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵齐饮,是天一觀的道長捐寥。 經(jīng)常有香客問我,道長沈矿,這世上最難降的妖魔是什么上真? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮羹膳,結(jié)果婚禮上睡互,老公的妹妹穿的比我還像新娘。我一直安慰自己陵像,他們只是感情好就珠,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著醒颖,像睡著了一般妻怎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上泞歉,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天逼侦,我揣著相機(jī)與錄音匿辩,去河邊找鬼。 笑死榛丢,一個(gè)胖子當(dāng)著我的面吹牛铲球,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播晰赞,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼稼病,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了掖鱼?” 一聲冷哼從身側(cè)響起然走,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎戏挡,沒想到半個(gè)月后芍瑞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡增拥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年啄巧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寻歧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掌栅。...
    茶點(diǎn)故事閱讀 38,646評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖码泛,靈堂內(nèi)的尸體忽然破棺而出猾封,到底是詐尸還是另有隱情,我是刑警寧澤噪珊,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布晌缘,位于F島的核電站,受9級(jí)特大地震影響痢站,放射性物質(zhì)發(fā)生泄漏磷箕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一阵难、第九天 我趴在偏房一處隱蔽的房頂上張望岳枷。 院中可真熱鬧,春花似錦呜叫、人聲如沸空繁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盛泡。三九已至,卻和暖如春娱颊,著一層夾襖步出監(jiān)牢的瞬間傲诵,已是汗流浹背凯砍。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拴竹,地道東北人果覆。 一個(gè)月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像殖熟,于是被迫代替她去往敵國和親局待。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容