关于矩阵乘法的Strassen算法,这里不再叙述,推荐简书博客:
https://www.jianshu.com/p/6e21f8e872fd
本篇博客便是参考该简书的算法思想,采用C++进行代码实现,可作为上述简书的补充。

关于使用参数传递二维数组,可参考:
https://www.cnblogs.com/huipengly/p/8892110.html

#include<iostream>
using namespace std;
/*
可以传递二维数组作为参数,有两种方法,
1.change(int **a)直接传递一个指针进去
2.change(int a[][10])数组的第二维维度一定要显式指定
*/
//打印矩阵
void PrintMatrix(int **MatrixA, int N){for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){cout << MatrixA[i][j] << " ";}cout << endl;}
}
//矩阵加法
void Matrix_Sum(int N, int** MatrixA, int** MatrixB, int** Sum_Matrix){for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){Sum_Matrix[i][j] = MatrixA[i][j] + MatrixB[i][j];}}
}
//矩阵减法
void Matrix_Sub(int N, int** MatrixA, int** MatrixB, int** Sub_Matrix){for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){Sub_Matrix[i][j] = MatrixA[i][j] -MatrixB[i][j];}}
}
//矩阵乘法
void Matrix_Mul(int N, int** MatrixA, int** MatrixB, int** Mul_Matrix){for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){Mul_Matrix[i][j] = 0;for (int k = 0; k < N; k++){Mul_Matrix[i][j] = Mul_Matrix[i][j] + MatrixA[i][k] * MatrixB[k][j];}}}
}
//基于Strassen的矩阵乘法,输入矩阵A,B,C
void Strassen(int N, int** MatrixA, int** MatrixB, int** MatrixC){//新建矩阵int** MatrixA11;int** MatrixA12;int** MatrixA21;int** MatrixA22;int** MatrixB11;int** MatrixB12;int** MatrixB21;int** MatrixB22;int** MatrixC11;int** MatrixC12;int** MatrixC21;int** MatrixC22;//初始化每个小矩阵的大小MatrixA11 = new int*[N/2];//数组的第二维一定要显示指定MatrixA12 = new int*[N/2];MatrixA21 = new int*[N/2];MatrixA22 = new int*[N/2];MatrixB11 = new int*[N/2];MatrixB12 = new int*[N/2];MatrixB21 = new int*[N/2];MatrixB22 = new int*[N/2];MatrixC11 = new int*[N/2];MatrixC12 = new int*[N/2];MatrixC21 = new int*[N/2];MatrixC22 = new int*[N/2];for (int i = 0; i < N/2; i++)//分配连续内存{MatrixA11[i] = new int[N/2];MatrixA12[i] = new int[N / 2];MatrixA21[i] = new int[N / 2];MatrixA22[i] = new int[N / 2];MatrixB11[i] = new int[N / 2];MatrixB12[i] = new int[N / 2];MatrixB21[i] = new int[N / 2];MatrixB22[i] = new int[N / 2];MatrixC11[i] = new int[N / 2];MatrixC12[i] = new int[N / 2];MatrixC21[i] = new int[N / 2];MatrixC22[i] = new int[N / 2];}//为每个小矩阵赋值,将大矩阵分割为4个小矩阵for (int i = 0; i < N / 2; i++){for (int j = 0; j < N / 2; j++){MatrixA11[i][j] = MatrixA[i][j];MatrixA12[i][j] = MatrixA[i][j + N / 2];MatrixA21[i][j] = MatrixA[i + N / 2][j];MatrixA22[i][j] = MatrixA[i + N / 2][j + N / 2];MatrixB11[i][j] = MatrixB[i][j];MatrixB12[i][j] = MatrixB[i][j + N / 2];MatrixB21[i][j] = MatrixB[i + N / 2][j];MatrixB22[i][j] = MatrixB[i + N / 2][j + N / 2];}}//做10个辅助矩阵S,计算加法int** MatrixS1=new int*[N/2];int** MatrixS2 = new int*[N/2];int** MatrixS3 = new int*[N/2];int** MatrixS4 = new int*[N / 2];int** MatrixS5 = new int*[N / 2];int** MatrixS6 = new int*[N / 2];int** MatrixS7 = new int*[N / 2];int** MatrixS8 = new int*[N / 2];int** MatrixS9 = new int*[N / 2];int** MatrixS10 = new int*[N / 2];for (int i = 0; i < N / 2; i++)//分配连续内存{MatrixS1[i] = new int[N / 2];MatrixS2[i] = new int[N / 2];MatrixS3[i] = new int[N / 2];MatrixS4[i] = new int[N / 2];MatrixS5[i] = new int[N / 2];MatrixS6[i] = new int[N / 2];MatrixS7[i] = new int[N / 2];MatrixS8[i] = new int[N / 2];MatrixS9[i] = new int[N / 2];MatrixS10[i] = new int[N / 2];}Matrix_Sub(N/2, MatrixB12, MatrixB22, MatrixS1);//S1 = B12 - B22Matrix_Sum(N / 2, MatrixA11, MatrixA12, MatrixS2);//S2 = A11 + A12Matrix_Sum(N / 2, MatrixA21, MatrixA22, MatrixS3);//S3 = A21 + A22Matrix_Sub(N / 2, MatrixB21, MatrixB11, MatrixS4);//S4 = B21 - B11Matrix_Sum(N / 2, MatrixA11, MatrixA22, MatrixS5);//S5 = A11 + A22Matrix_Sum(N / 2, MatrixB11, MatrixB22, MatrixS6);//S6 = B11 + B22Matrix_Sub(N / 2, MatrixA12, MatrixA22, MatrixS7);//S7 = A12 - A22Matrix_Sum(N / 2, MatrixB21, MatrixB22, MatrixS8);//S8 = B21 + B22Matrix_Sub(N / 2, MatrixA11, MatrixA21, MatrixS9);//S9 = A11 - A21Matrix_Sum(N / 2, MatrixB11, MatrixB12, MatrixS10);//S10 = B11 + B12//做7个辅助矩阵P,计算乘法int** MatrixP1 = new int*[N / 2];int** MatrixP2 = new int*[N / 2];int** MatrixP3 = new int*[N / 2];int** MatrixP4 = new int*[N / 2];int** MatrixP5 = new int*[N / 2];int** MatrixP6 = new int*[N / 2];int** MatrixP7 = new int*[N / 2];for (int i = 0; i < N / 2; i++)//分配连续内存{MatrixP1[i] = new int[N / 2];MatrixP2[i] = new int[N / 2];MatrixP3[i] = new int[N / 2];MatrixP4[i] = new int[N / 2];MatrixP5[i] = new int[N / 2];MatrixP6[i] = new int[N / 2];MatrixP7[i] = new int[N / 2];}Matrix_Mul(N / 2, MatrixA11, MatrixS1, MatrixP1);//P1 = A11 • S1Matrix_Mul(N / 2, MatrixS2, MatrixB22, MatrixP2);//P2 = S2 • B22Matrix_Mul(N / 2, MatrixS3, MatrixB11, MatrixP3);//P3 = S3 • B11Matrix_Mul(N / 2, MatrixA22, MatrixS4, MatrixP4);//P4 = A22 • S4Matrix_Mul(N / 2, MatrixS5, MatrixS6, MatrixP5);//P5 = S5 • S6Matrix_Mul(N / 2, MatrixS7, MatrixS8, MatrixP6);//P6 = S7 • S8Matrix_Mul(N / 2, MatrixS9, MatrixS10, MatrixP7);//P7 = S9 • S10//根据以上7个结果计算C矩阵Matrix_Sum(N / 2, MatrixP5, MatrixP4, MatrixC11); //C11 = P5 + P4 - P2 + P6Matrix_Sub(N / 2, MatrixC11, MatrixP2, MatrixC11);Matrix_Sum(N / 2, MatrixC11, MatrixP6, MatrixC11);Matrix_Sum(N / 2, MatrixP1, MatrixP2, MatrixC12);//C12 = P1 + P2Matrix_Sum(N / 2, MatrixP3, MatrixP4, MatrixC21); //C21 = P3 + P4Matrix_Sum(N / 2, MatrixP5, MatrixP1, MatrixC22);  //C22 = P5 + P1 - P3 - P7Matrix_Sub(N / 2, MatrixC22, MatrixP3, MatrixC22);Matrix_Sub(N / 2, MatrixC22, MatrixP7, MatrixC22);//将C11,C12,C21,C21合并为C矩阵for (int i = 0; i < N / 2; i++){for (int j = 0; j < N / 2; j++){MatrixC[i][j] = MatrixC11[i][j];MatrixC[i][j+N/2] = MatrixC12[i][j];MatrixC[i+N/2][j] = MatrixC21[i][j];MatrixC[i+N/2][j+N/2] = MatrixC22[i][j];}}
}
//朴素矩阵相乘算法
void NormalMul_Matrix(int N, int **MatrixA, int **MatrixB, int **MatrixC){for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){MatrixC[i][j] = 0;for (int k = 0; k < N; k++){MatrixC[i][j] = MatrixC[i][j]+MatrixA[i][k] * MatrixB[k][j];}}}
}//初始化矩阵A,B
void Init_Matrix(int N,int** MatrixA, int** MatrixB){for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){MatrixA[i][j] = rand() % 10 + 1;//产生1~10MatrixB[i][j] = rand() % 10 + 1;}}/*C++中rand() 函数的用法1、rand()不需要参数,它会返回一个从0到最大随机数的任意整数,最大随机数的大小通常是固定的一个大整数。2、如果你要产生0~99这100个整数中的一个随机整数,可以表达为:int num = rand() % 100;这样,num的值就是一个0~99中的一个随机数了。3、如果要产生1~100,则是这样:int num = rand() % 100 + 1;4、总结来说,可以表示为:int num = rand() % n +a;其中的a是起始值,n-1+a是终止值,n是整数的范围。*/
}
//矩阵A,B测试用例
void Test_Matrix(int N, int** MatrixA, int** MatrixB){for (int i = 0; i < N; i++){for (int j = 0; j < N; j++){MatrixA[i][j] = 1;MatrixB[i][j] = 2;}}}void main(){int N;cout << "请输入矩阵大小(必须是2的幂指数值(例如:32,64,512,..): ";cin >> N; int** MatrixA = new int *[N];int**  MatrixB = new int *[N];int** MatrixC = new int *[N];//测试Strassen矩阵int** MatrixC1 = new int*[N];//测试朴素相乘矩阵for (int i = 0; i < N; i++)//分配连续内存{MatrixA[i] = new int[N];MatrixB[i] = new int[N];MatrixC[i] = new int[N];MatrixC1[i] = new int[N];}Init_Matrix(N, MatrixA, MatrixB);//Test_Matrix(N, MatrixA, MatrixB);cout << "A矩阵为:" << endl;PrintMatrix(MatrixA, N);cout << "B矩阵为:" << endl;PrintMatrix(MatrixB, N); cout << "朴素矩矩阵为:" << endl;NormalMul_Matrix(N, MatrixA, MatrixB, MatrixC1);PrintMatrix(MatrixC1, N);cout << "Strassen矩阵为:" << endl;Strassen(N, MatrixA, MatrixB, MatrixC);PrintMatrix(MatrixC, N);system("pause");               //等待按任意键退出}

运行结果如下:

关于Strassen算法的性能分析,可参考博客:
https://www.cnblogs.com/zhoutaotao/p/3963048.html
参考博客:
https://blog.csdn.net/zhuangxiaobin/article/details/36476769

[C++]矩阵乘法Strassen算法-----代码实现相关推荐

  1. strassen矩阵乘法 java_矩阵乘法Strassen算法

    矩阵乘法是种极其耗时的运算.以 为例,其中 和 都是 矩阵.根据矩阵乘法的定义, 中的每个元素需要按照如下方式计算 式(4.8)包含一个 次的循环,因此计算 的时间复杂度为 .而 共有 个元素,因此总 ...

  2. 矩阵乘法Strassen算法

    这里主要是给出实现方法,至于算法的介绍,可以参考@ 金戈大王的介绍. 下面算法是有bug的,虽然已经对一些非n*n的矩阵做出了处理,但是没有完善,当计算非n*n的矩阵是会出现数据越界的异常的.所以两个 ...

  3. 快速矩阵乘法的算法实现

    快速矩阵乘法的算法实现 矩阵乘法 一般矩阵乘法 分块算法 Strassen 算法 Coppersmith-Winograd算法 矩阵乘法 对于两个矩阵的相乘,只有在第一个矩阵的列数和第二个矩阵的行数相 ...

  4. strassen矩阵乘法c语言代码,计算机算法:Strassen矩阵乘法

    简介 Strassen矩阵乘法是典型的分而治之算法.我们已经见过诸如归并排序,Karatsuba大数乘法的分而治之的算法.让我们再次领略一下分而治之的含义. 与动态编程的"分散"得 ...

  5. python矩阵乘法分治算法_矩阵乘法的Strassen算法详解 --(算法导论分治法求矩阵)...

    1 题目描述 2 思路分析 3 解法 4 小结 1 题目描述 请编程实现矩阵乘法,并考虑当矩阵规模较大时的优化方法. 2 思路分析 根据wikipedia上的介绍:两个矩阵的乘法仅当第一个矩阵B的列数 ...

  6. 矩阵乘法的算法实现 [转载]

    一般矩阵乘法算法: 原理:矩阵相乘最重要的方法是一般矩阵乘积.它只有在第一个矩阵的栏数(column)和第二个矩阵的列数(row)相同时才有定义.一般单指矩阵乘积时,指的便是一般矩阵乘积.若A为m×n ...

  7. MPI编程——分块矩阵乘法(cannon算法)

    要求: 分析 本题难点在于不同process之间的通信,算法主要利用了cannon算法,cannon算法描述如下: 以上算法主要分为两个过程:分配初始位置.进行乘-加运算.循环单步移位.为了方便,下面 ...

  8. 矩阵连乘算法代码JAVA_矩阵连乘问题的动态规划算法(java)

    /** * 下面是矩阵连乘问题的动态规划算法 * 假设有6个矩阵: * A1 A2A3 A4 A5A6 * 30*35 35*15 15*5 5*10 10*20 20*25 则matrixChain ...

  9. 解题报告——蓝桥 试题 基础练习 矩阵乘法——27行代码AC

    储备知识: 矩阵: 矩阵的乘法: 也就是说,结果矩阵第m行与第n列交叉位置的那个值,等于第一个矩阵第m行与第二个矩阵第n列,对应位置的每个值的乘积之和. 矩阵的n次幂同理.不过是自己乘自己. 本题注意 ...

最新文章

  1. 网上收集下boost::asio发送与传输相关的几个函数,老是忘记
  2. autofac文档:服务类型,名称和键
  3. cJSON源码及解析流程详解
  4. 项目部署到tomcat6.0启动成功后访问页面报500_.net core IIS部署教程
  5. Linux磁盘的划分
  6. [剑指offer]面试题第[58-2]题[JAVA][左旋转字符串][拼接]
  7. python桌面应用html_是否将Python后端与HTML / CSS / JS用户界面集成到桌面应用程序? - javascript...
  8. Spring Boot 面试题整理
  9. Xcode 12 to build a single binary with both 32-bit and 64-bit support
  10. java替换的程序_Java文本文件批量替换小程序的方法
  11. 红红火火的丹麦造陆运动,和它恍恍惚惚的“硅谷梦”
  12. ESP32内部ADC最大采样率真的能达到2MSPS吗?答案是不能。
  13. BLAM源码解析(二)—— 从激光回调入手
  14. 双位置继电器ST2-2L/AC220V
  15. 小学带计算机2000的检讨书,小学生的检讨书(精选10篇)
  16. Verilog初级教程(4)Verilog中的标量与向量
  17. 教你破解隔壁妹子wifi密码,成功率高达90%
  18. 浅谈征信大数据与撸贷
  19. goose house 光るなら 若能绽放光芒 平仮名 平假名 假名 标注 注音 歌词
  20. Linux(Linux系统简介)

热门文章

  1. python综合应用题如何评分_使用pytest测试和评分学生的cod
  2. 个人作业-Week2 案例分析
  3. MySQL学习笔记(基础部分)
  4. IO流批量改文件名字,把文件夹中类似于文件名,“我java_爱好者_最帅“改成“爱好者_最轻特工组合“
  5. 友讯(D-Link)、趋势网络路由器曝远程代码执行漏洞
  6. 2021年12月27日|28日|29日|30日|31日|
  7. 开源建站系统——phpnuke8安装步骤
  8. 程序员秒懂,但会不会误导小朋友
  9. 微信支付宝刷脸支付积极助力行业效率提升
  10. 在Delphi中如何使用TTask并行程序进行多线程下载