数据结构与算法之分治法求解矩阵乘法(Strassen算法)

目录

前言

for循环求解

分析 

代码

分治法求解 

分析

结束语


前言

今天是坚持写博客的第十天,坚持的天数上两位数了,路漫漫其修远兮,继续坚持,今天也要继续加油!

矩阵乘法是线性代数当中非常让大家头疼的一环,所以我们今天也斗胆来看看数据结构与算法中的矩阵乘法问题。


矩阵乘法在数据结构与算法中主要分为两种方法,分别是传统for循环求解法和Strassen算法,即分治法求解矩阵乘法。接下来请听我娓娓道来,为您献上两种方法的使用手册。

for循环求解

分析 

在求解矩阵乘法时,最常见的方法必然是我们使用三层循环进行求解,逐步将A矩阵的行与B矩阵的列相乘后相加,最终得到结果并存入矩阵C中,最后打印。但是我们一定要注意矩阵乘法的核心问题:矩阵A的列数必须等于矩阵B的行数,否则矩阵乘法将无法进行。

代码

由于for循环的方法属于暴力解法,属于常规思路之一,非常好理解,因此我也不做过多解释,具体的示例代码如下:

void matrixMultiplication(int rowsA, int colsA, int A[rowsA][colsA],
                          int rowsB, int colsB, int B[rowsB][colsB],
                          int rowsC, int colsC, int C[rowsC][colsC]) {
    // 确保A的列数等于B的行数,否则无法进行乘法
    if(colsA != rowsB) {
        printf("矩阵A的列数必须等于矩阵B的行数。\n");
        return;
    }
    
    // 初始化结果矩阵C为0
    for(int i = 0; i < rowsC; i++)
        for(int j = 0; j < colsC; j++)
            C[i][j] = 0;

    // 矩阵乘法的核心计算
    for(int i = 0; i < rowsA; i++) {
        for(int j = 0; j < colsB; j++) {
            for(int k = 0; k < colsA; k++) { // 注意这里是colsA,因为是A的列数
                C[i][j] += A[i][k] * B[k][j]; // 对应位置相乘累加
            }
        }
    }
}
// 打印矩阵的函数
void printMatrix(int rows, int cols, int matrix[rows][cols]) {
    for(int i = 0; i < rows; i++) {
        for(int j = 0; j < cols; j++)
            printf("%d\t", matrix[i][j]);
        printf("\n");
    }
}

没想到吧,这里没有寄术主播的灵魂画图手法

但是需要注意的是,for循环的求解方法由于存在三层循环,时间复杂度会很高,为O(n^3),因此一旦数据量增大,则时间会增长很快。


分治法求解 

分析

书接上文,因为三层for循环的时间复杂度很高,因此基于分治法思想的Strassen算法出现了,这个算法可以快速求解矩阵乘法,提升效率。

Strassen算法给予分治思想,通过将大矩阵分解为较小的子矩阵,然后对这些子矩阵进行较少数量的乘法运算,再合并结果,从而减少了整体的计算量。

Strassen算法的主要步骤如下:

1、将矩阵A、B及结果矩阵C分别划分为四个子矩阵A11, A12, A21, A22和B11, B12, B21, B22以及C11, C12, C21, C22。如下图:

2、通过7次乘法计算7个中间矩阵M1至M7:

  • M1 = (A11 + A22) x (B11 + B22)
  • M2 = (A21 + A22) x B11
  • M3 = A11 x (B12 - B22)
  • M4 = A22 x (B21 - B11)
  • M5 = (A11 + A12) x B22
  • M6 = (A21 - A11) x (B11 + B12)
  • M7 = (A12 - A22) x (B21 + B22)

3、将M1-M7进行合并,得到矩阵C:

  • C11 = M1 + M4 - M5 + M7
  • C12 = M3 + M5
  • C21 = M2 + M4
  • C22 = M1 - M2 + M3 + M6

4、进行递归合并,在n>2时,不断递归重复上述步骤,否则得出结果。

Strassen算法的时间复杂度为O(n^log2(7)),约等于O(n^2.807),相较于传统算法的O(n^3),时间复杂度有一定优化,效率提升,尤其是在处理大矩阵时。 


结束语

分治法求解矩阵乘法在数据结构中的地位虽然没有DFS等高,但是仍然是大家值得掌握的算法。如果本文对您有帮助,希望您可以为我点赞或关注,这对我很重要,谢谢! 

  • 16
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值