分治法解决矩阵乘法问题

传统for循环:

#include<iostream>
#include<cstdio>
#include <vector>
#include<algorithm>
using namespace std;
int n, m, p;
int main()
{printf("第一个n×m矩阵?\n");cin >> n >> m;vector<vector<int>> A(n, vector<int>(m));printf("依次输入A矩阵元素:\n");//读入矩阵Afor (int i = 0; i < n; i++)for (int j = 0; j < m; j++)cin >> A[i][j];printf("A矩阵如下:\n");for (int i = 0; i < n; i++){for (int j = 0; j < m; j++)cout << A[i][j] << " ";cout << endl;}cout << endl;//读入矩阵Bprintf("B矩阵有几列:\n");cin >> p;vector<vector<int>> B(m, vector<int>(p));printf("依次输入B矩阵元素:\n");for (int i = 0; i < n; i++)for (int j = 0; j < p; j++)cin >> B[i][j];printf("A矩阵如下:\n");for (int i = 0; i < n; i++){for (int j = 0; j < p; j++)cout << B[i][j] << " ";cout << endl;}cout << endl;printf("矩阵相乘得到:\n");//三重循环运算输出结果for (int i = 0; i < n; i++){for (int j = 0; j < p; j++){int res = 0;for (int k = 0; k < m; k++){res += A[i][k] * B[k][j];}cout << res << " ";}cout << endl;}return 0;
}

分治法:

咱就是说,暴力循环解法确实好理解,但是考虑到当两个矩阵的维度变得很大的时候时间复杂度也是个需要解决的问题。

所以咱考虑使用一种更优的解法。

通常我们在进行数据处理的时候,会将比较大的数据分割成一个个小数据。那么给到两个很大的矩阵,也可以考虑分治的方法逐步解决处理一个个小矩阵。我们发现,两个矩阵相乘时,有8次的乘法运算,4次的加法运算。

矩阵乘法的复杂度主要体现在相乘上,而加法的次数增加几次在复杂度上是几乎不会上升多少。所以我们可以通过减少乘法的运算次数,从而进一步降低算法的复杂度。

#include <iostream>
#include <cstring>
#include <cstdio>using namespace std;
const int N = 4;
int A[N][N], B[N][N], C[N][N];产生n个随机数组从1~10中选
void random(int a[][N]) {for (int i = 0; i < N; i++) {for (int j = 0; j < N; j++) {a[i][j] = rand() % 10 + 1;}}
}//矩阵输出函数
void output(int a[][N]) {int count = 0;for (int i = 0; i < N; i++) {for (int j = 0; j < N; j++) {cout << a[i][j] << "\t";}cout << endl;}
}// 二阶矩阵用通常的算法来做,做为递归终止的条件
void end(int A[][N], int B[][N], int C[][N])
{for (int i = 0; i < 2; i++)for (int j = 0; j < 2; j++){C[i][j] = 0; // 恢复现场for (int k = 0; k < 2; k++)C[i][j] = C[i][j] + A[i][k] * B[k][j];}
}// 矩阵相加
void add(int n, int A[][N], int B[][N], int C[][N])
{for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)C[i][j] = A[i][j] + B[i][j];
}//矩阵乘法算法
void strassen(int n, int A[][N], int B[][N], int C[][N])
{int A11[N][N], A12[N][N], A21[N][N], A22[N][N];int B11[N][N], B12[N][N], B21[N][N], B22[N][N];int C11[N][N], C12[N][N], C21[N][N], C22[N][N];int M1[N][N], M2[N][N], M3[N][N], M4[N][N], M5[N][N], M6[N][N], M7[N][N], M8[N][N];//设置边界条件:当矩阵阶数为2时 递归终止if (n == 2){end(A, B, C); // 二阶}else{// 将矩阵拆为4块for (int i = 0; i < n / 2; i++)for (int j = 0; j < n / 2; j++){A11[i][j] = A[i][j];A12[i][j] = A[i][j + n / 2];A21[i][j] = A[i + n / 2][j];A22[i][j] = A[i + n / 2][j + n / 2];B11[i][j] = B[i][j];B12[i][j] = B[i][j + n / 2];B21[i][j] = B[i + n / 2][j];B22[i][j] = B[i + n / 2][j + n / 2];}strassen(n / 2, A11, B11, M1);strassen(n / 2, A12, B21, M2);strassen(n / 2, A11, B12, M3);strassen(n / 2, A12, B22, M4);strassen(n / 2, A21, B11, M5);strassen(n / 2, A22, B21, M6);strassen(n / 2, A21, B12, M7);strassen(n / 2, A22, B22, M8);//递归结束并将数值返回数组Cadd(N / 2, M1, M2, C11);add(N / 2, M3, M4, C12);add(N / 2, M5, M6, C21);add(N / 2, M7, M8, C22);//求得矩阵Cfor (int i = 0; i < n / 2; i++)for (int j = 0; j < n / 2; j++){C[i][j] = C11[i][j];C[i][j + n / 2] = C12[i][j];C[i + n / 2][j] = C21[i][j];C[i + n / 2][j + n / 2] = C22[i][j];}}
}int main()
{clock_t start, finish;   //定义一个计数器double timee;  //用于存储时间单位//初始化矩阵A和矩阵Brandom(B);cout << "随机生成矩阵A" << endl;random(A);output(A);cout << "随机生成矩阵B" << endl;random(B);output(B);start = clock();//开始计时cout << "矩阵A和B的乘积为:" << endl;strassen(N, A, B, C);output(C);finish = clock();timee = finish;cout << "此算法运行时间单位:" << timee << endl;return 0;
}

分治法解决矩阵乘法问题相关推荐

  1. python矩阵乘法分治_分治法实现矩阵乘法

    #include #include #include #include using namespace std; int *InitMatrix(int row,int col);//初始化 void ...

  2. 分治法解决最大子数组问题

    分治法解决最大子数组问题 参考文章: (1)分治法解决最大子数组问题 (2)https://www.cnblogs.com/Christal-R/p/Christal_R.html (3)https: ...

  3. 分治法解决组合总和问题(leetcode216)

    nums数组中元素是正整数 大问题转换为小问题 思路和分治法解决组合相同,代码也相似 分治法解决组合问题(递归)_m0_52043808的博客-CSDN博客 只不过递归出口时需要判断组合总和是否为n ...

  4. 分治法解决循环赛日程表

    分治法解决循环赛日程表 问题描述 设有n=2^k个运动员要进行羽毛球循环赛,现要设计一个满足以下要求的比赛日程表: (1)每个选手必须与其他n-1个选手各赛一次. (2)每个选手一天只能比赛一次. ( ...

  5. 分治法解决棋盘覆盖问题

    分治法解决棋盘覆盖问题 问题描述: 在一个2k×2k(k≥0)个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格.显然,特殊方格在棋盘中出现的位置有4k中情形,因而有4k中不同的棋盘. ...

  6. 分治法解决最小套圈问题

    /*     Copyright    by ZhongMing-Bian     Jan,6,2010   */ /*             分治法解决最小套圈问题                 ...

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

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

  8. 分治法解决最近点对问题

    问题 给定平面上n个点,找其中的一对点,使得在n个点的所有点对中,该点对的距离最小.严格地说,最接近点对可能多于1对.为了简单起见,这里只限于找其中的一对. 原理(这段为抄袭https://blog. ...

  9. 分治法解决计算凸包问题

    清华大学的邓俊辉老师的<计算几何>公开课中,在计算凸包问题时会遇到极点法和极边法: 极点法是假设所有的点都是凸包上的点,然后根据In-triangle测试,把去除不是极点的点,时间复杂度是 ...

最新文章

  1. 2021年大数据Kafka(六):❤️安装Kafka-Eagle❤️
  2. ant 获取当前url的参数
  3. mysql远程连接设置_MySQL远程连接设置
  4. CSS Sprite “精灵图“
  5. 走心!北京语言大学教授毕业致辞:在人生的道路上,一定要把自己当回事儿...
  6. php monolith,单体架构(Monolith)与微服务架构(MicroService)
  7. SCRF的简介及防护手段
  8. tipask二次开发总结_二次开发自我总结
  9. stretchblt 模糊_微软开源持续开发模糊测试工具OneFuzz
  10. mysql数据库解锁
  11. python求斜边上的高_直角三角形斜边上的高如何求?
  12. 云巡店php源码,云巡店™〡连锁版正式上线开放注册〡《系统使用手册 1.0》
  13. html模拟点击某个键盘按钮,如何使用JavaScript模拟按键或单击?
  14. trim函数去掉字符串首尾空格
  15. Spring扩展点总结
  16. 乐高 计算机泡泡龙教案,科学小实验----有趣的泡泡龙
  17. 电磁场知识回顾——重要方程,定理
  18. c语言基础循环练习题,C语言练习题:循环部分
  19. 项目经理如何提升核心竞争力,给自己增值
  20. matlab 使用小波变换和方差性质处理带状噪声

热门文章

  1. [oeasy]python0122_日韩字符_日文假名_JIS_Shift_韩国谚文
  2. 【MySQL--创建表语句】优秀的人都有段难熬的经历--MySQL创建表新手入门基础语句
  3. vi编辑器的常见命令
  4. 用java Swing做的小游戏quot;像素鸟quot;
  5. 【蓝桥杯真题】 Python题解
  6. 读书百客:《白雪歌送武判官归京》赏析二
  7. 项目管理中解决瓶颈问题指南
  8. 基于AT89C52单片机的多功能万年历设计
  9. Java面向对象系列[v1.0.0][SQL语法之DDL]
  10. 中值滤波算法的Verilog实现