一兜材、知識(shí)預(yù)備
? 利用 展開定理可以將行列式
按任意行任意列展開. 這里我們采用按第一列展開,得
二酥宴、基本思路
由于3階以下的行列式計(jì)算可以直接使用對角線法則纲辽,因此對于高階行列式颜武,考慮從降階的角度入手. 降階的具體方法是將行列式按第一列展開,并將代數(shù)余子式再按其第一列展開拖吼,依此類推鳞上,直至行列式被降階至3階及3階以下;
? 是可以定義一個(gè)用來執(zhí)行展開定理的函數(shù)用于專門按第一列展開行列式吊档,然后使用遞歸的方法對行列式逐層降階篙议,本文中,我們統(tǒng)一降階到1階來計(jì)算.
三怠硼、實(shí)現(xiàn)方法
- 定義主函數(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;
}
- 接著來編寫 determinant 函數(shù). 如果行列式為1階赖草,行列式的值便是 a_{11}的值,即 matrix[0][0]; 如果行列式的階高于1剪个,我們采用另定義的展開函數(shù) laplace_expansion 來降階秧骑,并在函數(shù)中直接展開后余子式的值. 將展開函數(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)一即可
其中分別執(zhí)行展開時(shí)選定元素在行列式中的行數(shù)和列數(shù),統(tǒng)一選定 忌堂,即選取第一列元素.
展開的結(jié)果是一個(gè)余子式 盒至,用表示,由于公式中是代數(shù)余子式士修,因此定義用來記錄該行該列代數(shù)余子式的符號(hào)枷遂,每換一行乘上 ,于是展開式每一項(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;
}
- 編寫 laplace_expansion 函數(shù)計(jì)算余子式的值:
在函數(shù)中棋嘲,我們向 laplace_expansion 函數(shù)傳遞了選定的行 r 和列 c 酒唉;在余子式的定義中,元素 a_{rc} 的余子式是劃掉行列式第 r 行第 c 列沸移,并把留下原來的元素按原來的相對位置關(guān)系排列得到的行列式. 可以這樣構(gòu)思來取余子式:選定了元素 a_{rc} 后痪伦,對于行數(shù) i 小于 r ,列數(shù) j 小于 c 的位置雹锣,余子式网沾;對于行數(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階, 函數(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))