矩阵乘法 之 strassen 算法
一般情况下矩阵乘法需要三个for循环,时间复杂度为O(n^3),现在我们将矩阵分块如图:( 来自MIT算法导论 )一般算法需要八次乘法r = a * e + b * g ;s = a * f + b * h ;t = c * e + d * g;u = c * f + d * h;strassen将其变成7次乘法,因为大家都知道乘法比加减法消耗更多,所有时间复杂更高!strassen的处理是:令:p1 = a * ( f - h )p2 = ( a + b ) * hp3 = ( c +d ) * ep4 = d * ( g - e )p5 = ( a + d ) * ( e + h )p6 = ( b - d ) * ( g + h )p7 = ( a - c ) * ( e + f )那么我们可以知道:r = p5 + p4 + p6 - p2s = p1 + p2t = p3 + p4u = p5 + p1 - p3 - p7我们可以看到上面只有7次乘法和多次加减法,最终达到降低复杂度为O( n^lg7 ) ~= O( n^2.81 );代码实现如下:[cpp]// strassen 算法:将矩阵相乘的复杂度降到O(n^lg7) ~= O(n^2.81)// 原理是将8次乘法减少到7次的处理// 现在理论上的最好的算法是O(n^2,367),仅仅是理论上的而已////// 下面的代码仅仅是简单的实例而已,不必较真哦,呵呵~// 下面的空间可以优化的,此处就不麻烦了~#include <stdio.h>#define N 10//matrix + matrixvoid plus( int t[N/2][N/2], int r[N/2][N/2], int s[N/2][N/2] ){int i, j;for( i = 0; i < N / 2; i++ ){for( j = 0; j < N / 2; j++ ){t[i][j] = r[i][j] + s[i][j];}}}//matrix - matrixvoid minus( int t[N/2][N/2], int r[N/2][N/2], int s[N/2][N/2] ){int i, j;for( i = 0; i < N / 2; i++ ){for( j = 0; j < N / 2; j++ ){t[i][j] = r[i][j] - s[i][j];}}}//matrix * matrixvoid mul( int t[N/2][N/2], int r[N/2][N/2], int s[N/2][N/2] ){int i, j, k;for( i = 0; i < N / 2; i++ ){for( j = 0; j < N / 2; j++ ){t[i][j] = 0;for( k = 0; k < N / 2; k++ ){t[i][j] += r[i][k] * s[k][j];}}}}int main(){int i, j, k;int mat[N][N];int m1[N][N];int m2[N][N];int a[N/2][N/2],b[N/2][N/2],c[N/2][N/2],d[N/2][N/2];int e[N/2][N/2],f[N/2][N/2],g[N/2][N/2],h[N/2][N/2];int p1[N/2][N/2],p2[N/2][N/2],p3[N/2][N/2],p4[N/2][N/2];int p5[N/2][N/2],p6[N/2][N/2],p7[N/2][N/2];int r[N/2][N/2], s[N/2][N/2], t[N/2][N/2], u[N/2][N/2], t1[N/2][N/2], t2[N/2][N/2];printf("\nInput the first matrix...:\n");for( i = 0; i < N; i++ ){for( j = 0; j < N; j++ ){scanf("%d", &m1[i][j]);}}printf("\nInput the second matrix...:\n");for( i = 0; i < N; i++ ){for( j = 0; j < N; j++ ){scanf("%d", &m2[i][j]);}}// a b c d e f g hfor( i = 0; i < N / 2; i++ ){for( j = 0; j < N / 2; j++ ){a[i][j] = m1[i][j];b[i][j] = m1[i][j + N / 2];c[i][j] = m1[i + N / 2][j];d[i][j] = m1[i + N / 2][j + N / 2];e[i][j] = m2[i][j];f[i][j] = m2[i][j + N / 2];g[i][j] = m2[i + N / 2][j];h[i][j] = m2[i + N / 2][j + N / 2];}}//p1minus( r, f, h );mul( p1, a, r );//p2plus( r, a, b );mul( p2, r, h );//p3plus( r, c, d );mul( p3, r, e );//p4minus( r, g, e );mul( p4, d, r );//p5plus( r, a, d );plus( s, e, f );mul( p5, r, s );//p6minus( r, b, d );plus( s, g, h );mul( p6, r, s );//p7minus( r, a, c );plus( s, e, f );mul( p7, r, s );//r = p5 + p4 - p2 + p6plus( t1, p5, p4 );  补充:软件开发 , C++ ,
上一个:4_1三角形类
下一个:hdu 2059 简单动态规划
- 更多C/C++疑问解答:
- 关于c++的cout输出的问题。
- 在学校里学过C和C++,不过学的很一般,现在自学C#,会不会很难?
- 全国计算机二级C语言笔试题
- 已知某树有2个2度结点,3个3度结点,4个4度结点,问有几个叶子结点?
- c++数据结构内部排序问题,整数排序
- 2012九月计算机二级C语言全国题库,,急求急求
- 如果assert只有一个字符串作为参数,是什么意思呢?
- C语言中,哪些运算符具有左结合性,哪些具有右结合性,帮忙总结下,谢谢了!
- 为什么用结构体编写的程序输入是,0输不出来啊~~~
- 将IEEE—754的十六进制转化为十进制浮点类型,用C或C++都行,多谢各位大侠啊,非常感谢!
- 为什么这个程序求不出公式?
- 这个链表倒置的算法请大家分析下
- c语言函数库调用
- C语言unsigned int纠错
- C语言快排求解啊