strassen算法——矩阵乘法

strassen算法可以看做是分治递归法求解矩阵乘法的改进。

利用分治递归法求解矩阵乘法的过程大致:

矩阵C = A * B(A、B、C都是n x n矩阵)

可以发现(A11 * B11)、(A12 * B21)……等子矩阵的乘法运算需要继续递归。上面有8个乘法,所以需要递归8次。

时间复杂度关系公式 T(n) = 8T(n/2) + O(n^2),这里8T(n/2)8次递归,O(n^2)是求C11,C12,C21,C22所做的加法,因为(A11*B11)、(A12*B21)……都有n^2 / 4个元素。

通过推导公式T(n) = 8T(n/2) + O(n^2),我们会得到T(n) = O(n^3),等等……这不是跟普通的3次循环做矩阵乘法的方法时间复杂度一样吗。

不要着急,算法还有改善的空间。

请看上面红框所选的部分,是不是可以想办法减少一下乘法的数量,8次乘法就代表8次递归。8次乘法中有很多乘法因子都是相同的……

这确实是个不小的挑战,很考验数学功底。笔者写满了一张演草纸也没有找到好方法。看了下strassen算法的实现,也只省去了一个乘法,还剩7个。多少有些失望……

Strassen算法的简化思路是——尽量用加减来代替乘法

推导结果:

C11 = P5 + P4 - P2 + P6

C12 = P1 + P2

C21 = P3 + P4

C22 = P5 + P1 - P3 - P7

P1 = A11 * S1

P2 = S2 * B22

P3 = S3 * B11

P4 = A22 * S4

P5 = S5 * S6

P6 = S7 * S8

P7 = S9 * S10

S1 = B12 - B22

S2 = A11 + A12

S3 = A21 + A22

S4 = B21 - B11

S5 = A11 + A22

S6 = B11 + B22

S7 = A12 - A22

S8 = B21 + B22

S9 = A11 - A21

S10 = B11 + B12

上面的计算过程有7个乘法,分别是计算P1、P2……

你可能会向笔者一样思考,这种方法是怎么想出来的呢?他是经过怎样的反复试验和推敲才找到了这种思路呢?我想,这只有他自己最清楚了。就像数学公式一样,我们只要知道结论就可以了,这并不妨碍我们以后的应用。

经过这一折腾,算法的时间复杂度公式变为T(n) = 7T(n/2) + O(n^2),经过推导得出T(n) = O(n^lg7)lg7约为2.81,所以最终T(n) = O(n^2.81)

时间: 2024-10-29 08:01:07

strassen算法——矩阵乘法的相关文章

Strassen优化矩阵乘法(复杂度O(n^lg7))

按照算法导论写的 还没有测试复杂度到底怎么样 不过这个真的很卡内存,挖个坑,以后写空间优化 还有Matthew Anderson, Siddharth Barman写了一个关于矩阵乘法的论文 <The Coppersmith-Winograd Matrix Multiplication Algorithm> 提出了矩阵乘法的O(n^2.37)算法,有时间再膜吧orz #include <iostream> #include <cstring> #include <

BZOJ 1009 HNOI2008 GT考试 KMP算法+矩阵乘法

题目大意:给定长度为m的数字串s,求不包含子串s的长度为n的数字串的数量 n<=10^9 光看这个O(n)就是挂 我们不考虑这个 令f[i][j]为长度为i的数字串中最后j位与s中的前j位匹配的方案数 比如当s为12312时 f[i][3]表示长度为i,以123结尾且不包含子串"12312"的方案数 a[x][y]为f[i-1][x]转移至f[i][y]的方案数 换句话说(可能描述不清楚) a[x][y]为s的长度为x的前缀加上一个数字后 后缀可以与最长长度为y的前缀匹配 这个数

矩阵乘法的Strassen算法详解

题目描述 请编程实现矩阵乘法,并考虑当矩阵规模较大时的优化方法. 思路分析 根据wikipedia上的介绍:两个矩阵的乘法仅当第一个矩阵B的列数和另一个矩阵A的行数相等时才能定义.如A是m×n矩阵和B是n×p矩阵,它们的乘积AB是一个m×p矩阵,它的一个元素其中 1 ≤ i ≤ m, 1 ≤ j ≤ p. 值得一提的是,矩阵乘法满足结合律和分配率,但并不满足交换律,如下图所示的这个例子,两个矩阵交换相乘后,结果变了: 下面咱们来具体解决这个矩阵相乘的问题. 解法一.暴力解法 其实,通过前面的分析

第四章 分治策略 4.2 矩阵乘法的Strassen算法

package chap04_Divide_And_Conquer; import static org.junit.Assert.*; import java.util.Arrays; import org.junit.Test; /** * 矩阵相乘的算法 * * @author xiaojintao * */ public class MatrixOperation { /** * 普通的矩阵相乘算法,c=a*b.其中,a.b都是n*n的方阵 * * @param a * @param b

算法导论-矩阵乘法-strassen算法

目录 1.矩阵相乘的朴素算法 2.矩阵相乘的strassen算法 3.完整测试代码c++ 4.性能分析 5.参考资料 内容 1.矩阵相乘的朴素算法 T(n) = Θ(n3) 朴素矩阵相乘算法,思想明了,编程实现简单.时间复杂度是Θ(n^3).伪码如下 1 for i ← 1 to n 2 do for j ← 1 to n 3 do c[i][j] ← 0 4 for k ← 1 to n 5 do c[i][j] ← c[i][j] + a[i][k]⋅ b[k][j] 2.矩阵相乘的stra

算法重拾之路——strassen矩阵乘法

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 第一章:分治与递归 STRASSEN矩阵乘法 算法描述: 矩阵乘法是线性代数中最常见的问题之一,它在数值计算中有广泛的应用.设A 和 B 是两个n × n矩阵,它们的乘积AB同样是一个n×n矩阵.A和B的乘积矩阵C 中的元素cij定义为: 按照这个定义来看,计算

矩阵乘法的Strassen算法及时间复杂度

[问题]普通方法计算矩阵相乘,时间复杂度为O(n^3),请设计优化算法. [Strassen算法] [时间复杂度]

Strassen矩阵乘法

Strassen矩阵乘法是通过递归实现的,它将一般情况下二阶矩阵乘法(可扩展到n阶,但Strassen矩阵乘法要求n是2的幂)所需的8次乘法降低为7次,将计算时间从O(nE3)降低为O(nE2.81). 矩阵C = A*B,可写为C11 = A11B11 + A12B21C12 = A11B12 + A12B22C21 = A21B11 + A22B21C22 = A21B12 + A22B22如果A.B.C都是二阶矩阵,则共需要8次乘法和4次加法.如果阶大于2,可以将矩阵分块进行计算.耗费的时

【算法导论】矩阵乘法

离过年都不到十天了,还要等到这周五才能回家,想想也一年没回家了.从寒假开始到现在,已经有二十来天,这期间把2014年总结中的寒假计划也大多数完成了:The Element Of Style的阅读,三门数学课<随机过程>.<工程优化>.<数值分析>的算法实现.回家过年期间肯定不会写博客了,今天一看,这个月只写了三篇,于是乎今天必须再写一篇来完成这个月的基本工作量.言归正传,这篇文章写写选修课<算法设计>作业题中的矩阵乘法的三种方法. 矩阵乘法 传统方法 理论公