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

文章目录

    • @[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 npdef strassen_matrix_multiply(a, b):n = a.shape[0]# 如果输入矩阵的维度小于等于阈值, 使用传统的矩阵乘法if n <= 128:return np.dot(a, b)# 将输入矩阵划分为四个子矩阵mid = n // 2a11 = 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 + m6c12 = m1 + m2c21 = m3 + m4c22 = m5 + m1 - m3 - m7# 组合四个子矩阵形成结果矩阵c = np.zeros((n, n))c[:mid, :mid] = c11c[:mid, mid:] = c12c[mid:, :mid] = c21c[mid:, mid:] = c22return ca = 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.hqwc.cn/news/600956.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Studio导入第三方so库和jar包——Android Studio

导入so库 方式一&#xff08;libs文件夹&#xff09; 将项目以【Project】的结构显示&#xff0c;将目标架构对应的so文件夹&#xff08;如下图中 的arm64-v8a&#xff09;复制粘贴到app文件下的lib文件夹中&#xff08;如下图的步骤1 2 3&#xff09; 在build.gradle&…

应用方案 | D431L可调精密基准源

概述 D431L是一种低压三端可调稳压器&#xff0c;保证在适用温度范围内的热稳定性。输出电压可以设置为VREF(约1.24V)~16V&#xff08;接两个外部电阻&#xff09;。该装置具有典型的动态输出0.2Ω的阻抗。在很多应用中&#xff0c;可替代齐纳二极管。 D431L有TO-92和SOT23封装…

JVM高级篇之GC

文章目录 版权声明垃圾回收器的技术演进ShenandoahShenandoah GC体验Shenandoah GC循环过程 ZGCZGC简介ZGC的版本更迭ZGC体验&使用ZGC的参数设置ZGC的调优 版权声明 本博客的内容基于我个人学习黑马程序员课程的学习笔记整理而成。我特此声明&#xff0c;所有版权属于黑马…

[Windows] Wireshark v3.6.1 【网络抓包工具】

Wireshark是世界上最流行的网络分析工具。 这个强大的工具可以捕捉网络中的数据&#xff0c;并为用户提供关于网络和上层协议的各种信息。与很多其他网络工具一样&#xff0c;Wireshark也使用pcap network library来进行封包捕捉。 Wireshark的优势&#xff1a;- 绿色版免安…

Excel 文件底部sheet 如何恢复

偶然打开一个excel文件&#xff0c;惊奇地发现&#xff1a;原来excel文件底部的若干个sheet居然全都看不到了。好神奇啊。 用其它的电脑打开同样的excel文件&#xff0c;发现&#xff1a;其实能看到的。说明这个excel文件并没有被损坏。只要将修改相关设置。就可以再次看…

h5 笔记3 多媒体素材运用

关于电影编码 我们经常用扩展名来判断文件的类型&#xff0c;但是对于影音文件未必适用&#xff0c;影音文件的文件格式(container)和编码(codec)之间并非绝对相关。决定影音文件播放的关键在于浏览器是否含有适合的影音编解码技术。 笔记来源&#xff1a; ©《HTML5CSS3J…

SpringFramework实战指南(八)

SpringFramework实战指南&#xff08;八&#xff09; 5.1 场景设定和问题复现5.2 解决技术代理模式 5.1 场景设定和问题复现 准备AOP项目 项目名&#xff1a;spring-aop-annotation pom.xml <dependencies><!--spring context依赖--><!--当你引入Spring Conte…

图像识别网络与训练策略——基于经典网络架构训练图像分类模型

基于经典网络架构训练图像分类模型 总体框架 数据预处理部分&#xff1a;- 数据增强&#xff1a;torchvision中transforms模块自带功能&#xff0c;比较实用 - 数据预处理&#xff1a;torchvision中transforms也帮我们实现好了&#xff0c;直接调用即可 - DataLoader模块直接…

小小算式(1 + 2) * (3 + 4)背后的大道理

目录 前缀表示法&#xff08;波兰表达式&#xff09; 中缀表达法 后缀表达法&#xff08;逆波兰表达式&#xff09; 三种表达法的相互转换 练习&#xff1a;逆波兰表达式求值 前缀表示法&#xff08;波兰表达式&#xff09; 波兰表示法&#xff08;英语&#xff1a;Polis…

【二分查找】Leetcode 寻找旋转排序数组中的最小值

题目解析 153. 寻找旋转排序数组中的最小值 我们可以发现旋转后的数组是有这样一个顺序特征&#xff1a; 1.要么是旋转长度次&#xff0c;刚好还是原来的数组 2.要么一定存在一段一段的升序区间&#xff0c;再其中一段的升序区间中就存在最小值 算法讲解 但是我们这一次使用…

代码随想录阅读笔记-二叉树【修剪二叉搜索树】

题目 给定一个二叉搜索树&#xff0c;同时给定最小边界L 和最大边界 R。通过修剪二叉搜索树&#xff0c;使得所有节点的值在[L, R]中 (R>L) 。你可能需要改变树的根节点&#xff0c;所以结果应当返回修剪好的二叉搜索树的新的根节点。 思路 相信看到这道题目大家都感觉是…

健身房如何通过软文获客?媒介盒子告诉你

如今全民健康意识上升&#xff0c;大家越来越重视运动带给人的获得感以及成就感&#xff0c;对于健身房来说&#xff0c;适当进行推广&#xff0c;不仅可以提高品牌知名度&#xff0c;还能吸引更多的潜在客户。今天媒介盒子就从专业角度和大家聊聊&#xff1a;健身房如何通过软…