【分治算法】Strassen矩阵乘法Python实现

news2024/11/26 20:51:09

文章目录

    • @[toc]
      • 问题描述
      • 基础算法
        • 时间复杂性
      • `Strassen`算法
        • 时间复杂性
      • 问题时间复杂性
      • `Python`实现

因上努力

个人主页:丷从心.

系列专栏:Python基础

学习指南:Python学习指南

果上随缘


问题描述

  • A A A B B B是两个 n × n n \times n n×n矩阵, A A A B B B的乘积矩阵 C C C中元素 c i j = ∑ k = 1 n a i k b k j c_{ij} = \displaystyle\sum\limits_{k = 1}^{n}{a_{ik} b_{kj}} cij=k=1naikbkj
  • 每计算 C C C的一个元素 c i j c_{ij} cij,需要做 n n n次乘法和 n − 1 n - 1 n1次加法,求出矩阵 C C C n 2 n^{2} n2个元素所需的时间为 O ( n 3 ) O(n^{3}) O(n3)

基础算法

  • 假设 n n n 2 2 2的幂,将矩阵 A A A B B B C C C中每个矩阵都分块成 4 4 4个大小相等的子矩阵,每个子矩阵都是 n / 2 × n / 2 n / 2 \times n / 2 n/2×n/2的方阵

∣ C 11 C 12 C 21 C 22 ∣ = ∣ A 11 A 12 A 21 A 22 ∣ ∣ B 11 B 12 B 21 B 22 ∣ \begin{vmatrix} C_{11} & C_{12} \\ C_{21} & C_{22} \end{vmatrix} = \begin{vmatrix} A_{11} & A_{12} \\ A_{21} & A_{22} \end{vmatrix} \begin{vmatrix} B_{11} & B_{12} \\ B_{21} & B_{22} \end{vmatrix} C11C21C12C22 = A11A21A12A22 B11B21B12B22

C 11 = A 11 B 11 + A 12 B 21 C 12 = A 11 B 12 + A 12 B 22 C 21 = A 21 B 11 + A 22 B 21 C 22 = A 21 B 12 + A 22 B 22 C_{11} = A_{11} B_{11} + A_{12} B_{21} \\ C_{12} = A_{11} B_{12} + A_{12} B_{22} \\ C_{21} = A_{21} B_{11} + A_{22} B_{21} \\ C_{22} = A_{21} B_{12} + A_{22} B_{22} C11=A11B11+A12B21C12=A11B12+A12B22C21=A21B11+A22B21C22=A21B12+A22B22

时间复杂性
  • 计算 2 2 2 n n n阶方阵的乘积转化为计算 8 8 8 n / 2 n / 2 n/2阶方阵的乘积和 4 4 4 n / 2 n / 2 n/2阶方阵的加法, 2 2 2 n / 2 × n / 2 n / 2 \times n / 2 n/2×n/2矩阵的加法显然可以在 O ( n 2 ) O(n^{2}) O(n2)时间内完成

T ( n ) = { O ( 1 ) n = 2 8 T ( n / 2 ) + O ( n 2 ) n > 2 T(n) = \begin{cases} O(1) & n = 2 \\ 8 T(n / 2) + O(n^{2}) & n > 2 \end{cases} T(n)={O(1)8T(n/2)+O(n2)n=2n>2

T ( n ) = O ( n 3 ) T(n) = O(n^{3}) T(n)=O(n3)


Strassen算法

  • Strassen算法只用了 7 7 7次乘法运算,但增加了加减法的运算次数

M 1 = A 11 ( B 12 − B 22 ) M 2 = ( A 11 + A 12 ) B 22 M 3 = ( A 21 + A 22 ) B 11 M 4 = A 22 ( B 21 − B 11 ) M 5 = ( A 11 + A 22 ) ( B 11 + B 22 ) M 6 = ( A 12 − A 22 ) ( B 21 + B 22 ) M 7 = ( A 11 − A 21 ) ( B 11 + B 12 ) M_{1} = A_{11} (B_{12} - B_{22}) \\ M_{2} = (A_{11} + A_{12}) B_{22} \\ M_{3} = (A_{21} + A_{22}) B_{11} \\ M_{4} = A_{22} (B_{21} - B_{11}) \\ M_{5} = (A_{11} + A_{22})(B_{11} + B_{22}) \\ M_{6} = (A_{12} - A_{22})(B_{21} + B_{22}) \\ M_{7} = (A_{11} - A_{21})(B_{11} + B_{12}) M1=A11(B12B22)M2=(A11+A12)B22M3=(A21+A22)B11M4=A22(B21B11)M5=(A11+A22)(B11+B22)M6=(A12A22)(B21+B22)M7=(A11A21)(B11+B12)

C 11 = M 5 + M 4 − M 2 + M 6 C 12 = M 1 + M 2 C 21 = M 3 + M 4 C 22 = M 5 + M 1 − M 3 − M 7 C_{11} = M_{5} + M_{4} - M_{2} + M_{6} \\ C_{12} = M_{1} + M_{2} \\ C_{21} = M_{3} + M_{4} \\ C_{22} = M_{5} + M_{1} - M_{3} - M_{7} C11=M5+M4M2+M6C12=M1+M2C21=M3+M4C22=M5+M1M3M7

时间复杂性
  • Strassen算法用了 7 7 7次对于 n / 2 n / 2 n/2阶矩阵乘积的递归调用和 18 18 18 n / 2 n / 2 n/2阶矩阵的加减运算

T ( n ) = { O ( 1 ) n = 2 7 T ( n / 2 ) + O ( n 2 ) n > 2 T(n) = \begin{cases} O(1) & n = 2 \\ 7 T(n / 2) + O(n^{2}) & n > 2 \end{cases} T(n)={O(1)7T(n/2)+O(n2)n=2n>2

T ( n ) = O ( n log ⁡ 7 ) ≈ O ( n 2.81 ) T(n) = O(n^{\log{7}}) \approx O(n^{2.81}) T(n)=O(nlog7)O(n2.81)


问题时间复杂性

  • H o p c r o f t Hopcroft Hopcroft K e r r Kerr Kerr已经证明计算 2 2 2 2 × 2 2 \times 2 2×2矩阵的乘积, 7 7 7次乘法是必要的
  • 目前最好的计算时间上界是 O ( n 2.376 ) O(n^{2.376}) O(n2.376),所知的矩阵乘法的最好下界仍是它的平凡下界 Ω ( n 2 ) \Omega(n^{2}) Ω(n2)

Python实现

import numpy as np


def strassen_matrix_multiply(a, b):
    n = a.shape[0]

    # 如果输入矩阵的维度小于等于阈值, 使用传统的矩阵乘法
    if n <= 128:
        return np.dot(a, b)

    # 将输入矩阵划分为四个子矩阵
    mid = n // 2

    a11 = a[:mid, :mid]
    a12 = a[:mid, mid:]
    a21 = a[mid:, :mid]
    a22 = a[mid:, mid:]

    b11 = b[:mid, :mid]
    b12 = b[:mid, mid:]
    b21 = b[mid:, :mid]
    b22 = b[mid:, mid:]

    # 递归地计算七个矩阵乘法
    m1 = strassen_matrix_multiply(a11, b12 - b22)
    m2 = strassen_matrix_multiply(a11 + a12, b22)
    m3 = strassen_matrix_multiply(a21 + a22, b11)
    m4 = strassen_matrix_multiply(a22, b21 - b11)
    m5 = strassen_matrix_multiply(a11 + a22, b11 + b22)
    m6 = strassen_matrix_multiply(a12 - a22, b21 + b22)
    m7 = strassen_matrix_multiply(a11 - a21, b11 + b12)

    # 计算结果矩阵的四个子矩阵
    c11 = m5 + m4 - m2 + m6
    c12 = m1 + m2
    c21 = m3 + m4
    c22 = m5 + m1 - m3 - m7

    # 组合四个子矩阵形成结果矩阵
    c = np.zeros((n, n))

    c[:mid, :mid] = c11
    c[:mid, mid:] = c12
    c[mid:, :mid] = c21
    c[mid:, mid:] = c22

    return c


a = np.random.randint(0, 10, (256, 256))
b = np.random.randint(0, 10, (256, 256))

res = strassen_matrix_multiply(a, b)

print('矩阵 a:')
print(a)

print('\n矩阵 b:')
print(b)

print('\n乘积矩阵 c:')
print(res)
矩阵 a:
[[2 6 1 ... 9 7 7]
 [7 1 8 ... 1 0 9]
 [5 0 8 ... 6 2 5]
 ...
 [6 7 2 ... 6 0 1]
 [1 4 7 ... 0 5 2]
 [3 3 3 ... 9 6 8]]

矩阵 b:
[[3 5 1 ... 9 8 9]
 [9 6 0 ... 8 1 5]
 [3 9 6 ... 9 0 5]
 ...
 [5 7 7 ... 3 8 8]
 [9 5 3 ... 1 8 1]
 [3 3 9 ... 4 7 0]]

乘积矩阵 c:
[[5090. 5517. 4863. ... 4977. 4769. 4939.]
 [5148. 5909. 5747. ... 5603. 5070. 5260.]
 [4376. 5175. 4717. ... 4968. 4668. 4526.]
 ...
 [4708. 5294. 4991. ... 4945. 4681. 5202.]
 [4641. 5307. 4955. ... 5087. 5157. 4795.]
 [4722. 5173. 5144. ... 5050. 4845. 4829.]]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1577561.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

东方博宜 1426. 年龄与疾病

东方博宜 1426. 年龄与疾病 思路&#xff1a;1 读取数组 2 遍历数组并进行比较 遇到的坑是百分号且保留两位的输出方式&#xff0c;以及两个整数求商的时候要记得转换成小数形式 #include<iostream> #include<cstdio> using namespace std; int main() {int n ;cin…

第十四届蓝桥杯岛屿个数

题目描述&#xff1a; 小蓝得到了一副大小为 MN 的格子地图&#xff0c;可以将其视作一个只包含字符 0&#xff08;代表海水&#xff09;和 1&#xff08;代表陆地&#xff09;的二维数组&#xff0c;地图之外可以视作全部是海水&#xff0c;每个岛屿由在上/下/左/右四个方向上…

晶核养号攻略:如何轻松搬砖?两大要点!

晶核游戏中&#xff0c;想通过搬砖来养号并不是一件难事。本攻略将为你介绍两种主要的金币获取方式&#xff0c;让你轻松提升游戏财富&#xff0c;实现更多游戏目标。 一、刷深渊&#xff1a;稳定金币收入 深渊地图在晶核游戏中是一个稳定的金币来源。这张地图从55级开始可刷&…

【Segment Anything Model】十三:Meta的最新工作EfficientSAM,微调到自己的数据集,代码。

&#x1f349; 博主微信 cvxiayixiao 还有其他专栏点击头像查询 &#x1f353; 【Segment Anything Model】计算机视觉检测分割任务专栏。 &#x1f351; 【公开数据集预处理】特别是医疗公开数据集的接受和预处理&#xff0c;提供代码讲解。 &#x1f348; 【opencv图像处理】…

N4433A安捷伦N4433A电子校准件

181/2461/8938产品概述&#xff1a; 300 kHz至20 GHz频率范围标准3.5毫米接口通过单一连接实现快速完整的3或4端口校准NIST可追溯的精确校准减少连接器磨损用于直接控制PNA和ENA系列网络分析仪的USB接口可靠的固态开关提供混合3.5毫米公/母连接器选项 安捷伦N4433A微波电子校准…

代码随想录|Day34|动态规划03|343.整数拆分、96.不同的二叉搜索树

343.整数拆分 动规五步&#xff1a; 确定 dp[i] 含义&#xff1a;拆分数字 i&#xff0c;可以获得的最大乘积为 dp[i]。递推公式&#xff1a;dp[i] max(j * (i - j), j * dp[i - j])。i 可以被拆解为两个数&#xff08;j 和 i - j&#xff09;或者多个数&#xff08;j 和 dp[i…

app上架-您的应用存在最近任务列表隐藏风险活动的行为,不符合华为应用市场审核标准。

上架提示 您的应用存在最近任务列表隐藏风险活动的行为&#xff0c;不符合华为应用市场审核标准。 修改建议&#xff1a;请参考测试结果进行修改。 请参考《审核指南》第2.19相关审核要求&#xff1a;https://developer.huawei.com/consumer/cn/doc/app/50104-02 造成原因 …

数字电路基础(Digital Circuit Basis )

目录 一、什么是数字电路&#xff1f; &#xff08;Digital Circuit &#xff09; 1.概念 2.分类 3.优点 4.数电与模电的区别 二、数制 (十进制&#xff1a;Decimal) 1.概述 2.进位制 3.基数 4.位权 5.二进制的算术运算 三、编码 (二进制&#xff1a;Binary ) 1.什…

2024/4/1—力扣—按摩师

代码实现&#xff1a; 思路&#xff1a;打家劫舍题 int massage(int *nums, int numsSize) {if (nums NULL || numsSize 0) {return 0;}if (numsSize 1) {return nums[0];}int dp[numsSize];memset(dp, 0, sizeof(dp));dp[0] nums[0];dp[1] (nums[0] < nums[1] ? nums…

【大功率汽车大灯升压方案】LED恒流驱动芯片FP7208升压车灯调光应用,PWM内部转模拟,调光深度1%,无频闪顾虑,低亮无抖动

宝马X5前中排座椅宽大舒适&#xff0c;车厢内储物空间丰富。操控性能极佳&#xff0c;底盘稳扎精良。原车为氙气灯&#xff0c;其实宝马的氙气大灯配的比其他车型要好&#xff0c;照明效果是没得说的。但是不管什么灯久了都会出现光衰的情况。下面这辆宝马X5车灯已老化严重。 宝…

【Linux】安装+基本指令

&#x1f308;个人主页&#xff1a;秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343&#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/qinjh_/category_12625432.html 目录 Linux系统的安装 登录 XShell 下的复制粘贴 指令 pwd指令 ls指令 cd 指令 …

哪个好人,2024年还在做push攻略科普啊!

当拥有适当工具的时候&#xff0c;增加用户留存率的艰巨任务也能轻松解决。推送通知&#xff08;Push&#xff09;就是这样的宝藏工具&#xff0c;不用客户主动浏览&#xff0c;就可以触达客户。说起推送的优点&#xff08;Push&#xff09;&#xff0c;用户不需要主动触发&…

图像版PDF文件OCR识别转换为文本的3款免费工具软件

图像版PDF文件里面都是图片&#xff0c;要先通过OCR技术识别出文本&#xff0c;然后才能进行进一步处理编辑。下面是3个免费的PDF文件OCR识别软件工具&#xff1a; ●简可信PDF批量识别工具 简可信PDF批量识别工具是一款专门用于将PDF文件进行批量OCR&#xff08;光学字符识别…

React 集成三方登录按钮样式的插件库

按钮不提供任何社交逻辑。 效果如下&#xff1a; 原地址&#xff1a;https://www.npmjs.com/package/react-social-login-buttons 时小记&#xff0c;终有成。

conda修改默认安装python版本为指定版本

1.查看conda中当前的python版本号: 打开Anaconda Powershell Prompt 输入python -V 回车会输出版本号 2.查看conda所支持的python版本,并选择指定版本安装 选择一个3.9.13版本的进行安装 安装命令: conda install python3.9.13 如果一直卡在这个画面,请使用管理员权限运行…

循序表实战——基于循序表的通讯录

前言&#xff1a;本篇文章主要是利用顺序表作为底层&#xff0c; 实现一个通讯录。偏向于应用&#xff0c; 对于已经学习过c的友友们可能没有难度了已经。没有学习过c的友友&#xff0c; 如果顺序表不会写&#xff0c; 或者说没有自己实现过&#xff0c; 请移步学习顺序表相关内…

PMP证书究竟值不值得考?含金量如何?

PMP证书在项目管理领域还是很受关注&#xff0c;但其含金量和是否必须考取一直存在争议。在这里&#xff0c;我们来深入分析&#xff0c;看看PMP证书到底值不值得考&#xff0c;以及背后的原因。 首先&#xff0c;我们要关注的是PMP考试的通过率。根据网络和培训机构的数据&am…

基于Springboot框架四川成都某大学教室自习室预约系统设计与实现 研究背景和意义、国内外现状

二、国内外现状 在国内外&#xff0c;教室和自习室预约系统作为高校信息化建设的重要组成部分&#xff0c;已经得到了广泛的关注和应用。不同国家和地区的高校在预约系统的建设和应用方面呈现出不同的特点和趋势。 在国内方面&#xff0c;随着高校信息化建设的不断深入&#…

【CKA模拟题】边车容器Shared-Volume的具体用法

Useful Resources: Persistent Volumes Claim , Pod to Use a PV 题干 For this question, please set this context (In exam, diff cluster name) kubectl config use-context kubernetes-adminkubernetes An existing nginx pod, my-pod-cka and Persistent Volume Claim…

移动机器人运动规划 | 基于图搜索的Dijkstra 和 A*算法详解

Dijkstra 算法 Dijkstra 算法与BFS算法的区别就是 : 从容器中弹出接下来要访问的节点的规则不同 BFS 弹出: 层级最浅的原则&#xff0c;队列里最下方的元素 Dijkstra 弹出: 代价最小的节点g(n) g(n) :表示的是从开始节点到当前n节点的代价累加 Dijkstra在扩展的时候&#x…