矩陣

blind5883發表於2024-04-28

矩陣
顧名思義就是一個小破方陣
類似這樣

0 0 1 1
0 1 0 1
0 1 1 1
0 0 0 0

這就是一個四行四列的矩陣,
矩陣包含三個資訊, 長度, 寬度, 數值
數值就是矩陣裡每一位上的數值, 通常用一個數值來存

為了方便使用我們常寫成結構體形式

定義
struct Mat
{
	int l, r;  // 長, 寬
	int a[N][N]; // 矩陣陣列
};

那麼矩陣有什麼作用呢?
在定義中, 矩陣滿足加, 減, 乘三種運算

矩陣加減

兩個矩陣A, B可以加減的前提是他們的長寬對應相等
如下
A

1 2 3
4 5 6 
7 8 9 
3 4 2

B

5 3 3
4 5 8
9 9 9 
7 7 7 

這兩個矩陣長寬相等於是可以加減
而矩陣加減非常簡單, 就是對應位置加減, 就和普通運算一樣, 具有交換律和結合律

如B - A

4 1 0
0 0 2
2 1 0
4 3 5

可得到如上矩陣
這就是矩陣加減, 因為很簡單, 所以基本不考

程式碼
核心程式碼
struct Mat
{
    int l, r;
    int a[N][N];
}A, B, C;

Mat Mat_add(Mat &A, Mat &B) // 矩陣減同理
{
    Mat temp;
    temp = {A.l, A.r};
    for (int i = 1; i <= A.l; i ++ )
        for (int j = 1; j <= A.r; j ++ )
            temp.a[i][j] = A.a[i][j] + B.a[i][j];
    return temp;
}
具體程式碼
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 100;

int n, m;

struct Mat
{
    int l, r;
    int a[N][N];
}A, B, C;

Mat Mat_add(Mat &A, Mat &B)
{
    Mat temp;
    temp = {A.l, A.r};
    for (int i = 1; i <= A.l; i ++ )
        for (int j = 1; j <= A.r; j ++ )
            temp.a[i][j] = A.a[i][j] + B.a[i][j];
    return temp;
}

void print(Mat &A)
{
    for (int i = 1; i <= A.l; i ++ )
    {
        for (int j = 1; j <= A.r; j ++ )
            printf("%-2d ", A.a[i][j]);
        puts("");
    }
    puts("");
}

int main()
{
    
    cin >> n >> m;
    A = {n, m};
    B = {n, m};
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= m; j ++ )
            cin >> A.a[i][j];
            
    for (int i = 1; i <= n; i ++ )
        for (int j = 1; j <= m; j ++ )  
            cin >> B.a[i][j];
            
    C = Mat_add(A, B);
    
    print(C);
    return 0;
}

矩陣乘法

相對於矩陣加減, 矩陣乘法就要重要很多
它的前提是兩個矩陣A * B, A的寬度要等於, B的長度 (長度為上面定義中的l,寬度為r)

怎麼乘呢?
設A

1 2 3
4 5 6

B

3 1
4 2
5 8

用A第i行的第k個數去乘, B第j列的第k個數, 得到的這k個結果相加就是新矩陣C的第i行第j列的數值

設i = 1, j = 2
那麼就是
1 2 3

1
2
8

ans = 1 * 1 + 2 * 2 +3 * 8
那麼C.a[i][j] = 1 * 1 + 2 * 2 +3 * 8 = 29

總結一下就是, A矩陣的第i行和B矩陣的第j列對應項相乘之就是, 結果矩陣C的第i行第j列的結果
同時結果矩陣C的長度為A的長度, 寬度為B的寬度

那麼A * B的結果矩陣C就是
26 29
48 62

剛開始學矩陣會很陌生, 但是不要緊, 多算算就熟練了

性質

因為其這個i行j列相乘的性質, 所以矩陣乘法是沒有交換律
你現在可以試試求求B * A 看看是否滿足 B * A == A * B

雖然沒有交換律, 但是它具有結合律, 也就是(A * B) * C == A * (B * C)
自己也可以試試, 這裡不證明了

程式碼

看看程式碼吧

Mat Mat_mul(Mat &A, Mat &B, int p) // A * B 每一項取模 p, 返回結果矩陣
{
	Mat temp = {A.l, B.r}; // 我們一般開一個矩陣存結果, 並在最後返回它
	// 下面就是正常的計算, 請自行理解, 這裡沒法言傳
	for (int i = 1; i <= A.l; i ++ ) 
		for (int j = 1; j <= B.r; j ++ )
			for (int k = 1; k <= A.r; k ++ ) // A.r == B.l
				temp.a[i][j] = (temp.a[i][j] + 1ll * A.a[i][k] * B.a[k][j]) % p;
				// 記得防爆int
	return temp;
}

這就是最基本的矩陣了

對於矩陣更重要的作用是[[矩陣快速冪]]

相關文章