按照算法导论写的

还没有测试复杂度到底怎么样

不过这个真的很卡内存,挖个坑,以后写空间优化

还有Matthew Anderson, Siddharth Barman写了一个关于矩阵乘法的论文

《The Coppersmith-Winograd Matrix Multiplication Algorithm》

提出了矩阵乘法的O(n^2.37)算法,有时间再膜吧orz

#include <iostream>
#include <cstring>
#include <cstdio>
#include <iomanip>
using namespace std;
const int maxn = ;
struct Matrix
{
double v[maxn][maxn];
int n, m;
Matrix() { memset(v, , sizeof(v));}
Matrix operator +(const Matrix& B)
{
Matrix C; C.n = n; C.m = m;
for(int i = ; i < n; i++)
for(int j = ; j < n; j++)
C.v[i][j] = v[i][j] + B.v[i][j];
return C;
}
Matrix operator -(const Matrix& B)
{
Matrix C; C.n = n; C.m = m;
for(int i = ; i < n; i++)
for(int j = ; j < n; j++)
C.v[i][j] = v[i][j] - B.v[i][j];
return C;
}
Matrix operator *(const Matrix &B)
{
Matrix C; C.n = n; C.m = B.m;
for(int i = ; i < n; i++)
for(int j = ; j < m; j++)
{
if(v[i][j] == ) continue; //矩阵常数优化
for(int k = ; k < m; k++)
C.v[i][k] += v[i][j]*B.v[j][k];
}
return C;
}
void prepare() //将矩阵转换成2^k的形式,便于分治
{
int _n = ;
while(_n < n) _n <<= ;
while(_n < m) _n <<= ;
for(int i = ; i < n; i++)
for(int j = m; j < _n; j++)
v[i][j] = ;
for(int i = n; i < _n; i++)
for(int j = ; j < _n; j++)
v[i][j] = ;
n = m = _n;
}
void read()
{
cin>>n>>m;
for(int i = ; i < n; i++)
for(int j = ; j < m; j++)
cin>>v[i][j];
}
Matrix get(int i1, int j1, int i2, int j2)
{
Matrix C; C.n = i2-i1+; C.m = j2-j1+;
for(int i = i1-; i < i2; i++)
for(int j = j1-; j < j2; j++)
C.v[i-i1+][j-j1+] = v[i][j];
return C;
}
void give(Matrix &B, int i1, int j1, int i2, int j2)
{
for(int i = i1-; i < i2; i++)
for(int j = j1-; j < j2; j++)
v[i][j] = B.v[i-i1+][j-j1+];
}
void print()
{
for(int i = ; i < n; i++)
{
for(int j = ; j < m; j++)
cout<<setw()<<v[i][j];
cout<<endl;
} }
}A, B; Matrix Strassen(Matrix &X, Matrix &Y) //分治+利用多次矩阵相加代替矩阵相乘优化,复杂度O(n^2.81)
{
if(X.n == ) return X*Y;
int n = X.n;
Matrix A[][], B[][], S[], P[];
A[][] = X.get(, , n/, n/); A[][] = X.get(, n/+, n/, n);
A[][] = X.get(n/+, , n, n/); A[][] = X.get(n/+, n/+, n, n);
B[][] = Y.get(, , n/, n/); B[][] = Y.get(, n/+, n/, n);
B[][] = Y.get(n/+, , n, n/); B[][] = Y.get(n/+, n/+, n, n);
//for(int i = 0; i < 2; i++) { for(int j = 0; j < 2; j++) A[i][j].print(); cout<<endl; }
//for(int i = 0; i < 2; i++) { for(int j = 0; j < 2; j++) B[i][j].print(); cout<<endl; }
S[] = B[][] - B[][]; S[] = A[][] + A[][];
S[] = A[][] + A[][]; S[] = B[][] - B[][]; S[] = A[][] + A[][];
S[] = B[][] + B[][]; S[] = A[][] - A[][];
S[] = B[][] + B[][]; S[] = A[][] - A[][]; S[] = B[][] + B[][];
P[] = Strassen(A[][], S[]); P[] = Strassen(S[], B[][]);
P[] = Strassen(S[], B[][]); P[] = Strassen(A[][], S[]);
P[] = Strassen(S[], S[]); P[] = Strassen(S[], S[]); P[] = Strassen(S[], S[]);
//for(int i = 0; i < 7; i++) P[i].print(); cout<<endl;
B[][] = P[] + P[] - P[] + P[]; B[][] = P[] + P[];
B[][] = P[] + P[]; B[][] = P[] + P[] - P[] - P[];
//for(int i = 0; i < 2; i++) { for(int j = 0; j < 2; j++) B[i][j].print(); }
X.give(B[][], , , n/, n/); X.give(B[][], , n/+, n/, n);
X.give(B[][], n/+, , n, n/); X.give(B[][], n/+, n/+, n, n);
return X;
} int main()
{
Matrix C;
A.read(); B.read();
int n = A.n, m = B.m;
A.prepare(); B.prepare();
C = Strassen(A, B); C.n = n; C.m = m; C.print();
}

Strassen优化矩阵乘法(复杂度O(n^lg7))的更多相关文章

  1. OpenACC 优化矩阵乘法

    ▶ 按书上的步骤使用不同的导语优化矩阵乘法 ● 所有的代码 #include <iostream> #include <cstdlib> #include <chrono ...

  2. poj3613:Cow Relays(倍增优化+矩阵乘法floyd+快速幂)

    Cow Relays Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7825   Accepted: 3068 Descri ...

  3. 利用Cayley-Hamilton theorem 优化矩阵线性递推

    平时有关线性递推的题,很多都可以利用矩阵乘法来解决. 时间复杂度一般是O(K3logn)因此对矩阵的规模限制比较大. 下面介绍一种利用利用Cayley-Hamilton theorem加速矩阵乘法的方 ...

  4. 4-2.矩阵乘法的Strassen算法详解

    题目描述 请编程实现矩阵乘法,并考虑当矩阵规模较大时的优化方法. 思路分析 根据wikipedia上的介绍:两个矩阵的乘法仅当第一个矩阵B的列数和另一个矩阵A的行数相等时才能定义.如A是m×n矩阵和B ...

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

    package chap04_Divide_And_Conquer; import static org.junit.Assert.*; import java.util.Arrays; import ...

  6. cuda(2) 矩阵乘法优化过程

    Created on 2013-8-5URL : http://blog.sina.com.cn/s/blog_a502f1a30101mjch.html@author: zhxfl转载请说明出处 # ...

  7. [学习笔记]矩阵乘法及其优化dp

    1.定义: $c[i][j]=\sum a[i][k]\times b[k][j]$ 所以矩阵乘法有条件,(n*m)*(m*p)=n*p 即第一个矩阵的列数等于第二个矩阵的行数,否则没有意义. 2.结 ...

  8. 形态形成场(矩阵乘法优化dp)

    形态形成场(矩阵乘法优化dp) 短信中将会涉及前\(k\)种大写字母,每个大写字母都有一个对应的替换式\(Si\),替换式中只会出现大写字母和数字,比如\(A→BB,B→CC0,C→123\),代表 ...

  9. POJ 3213 矩阵乘法(优化)

    思路: 1.暴力出奇迹 n=1000 n^3矩阵乘法竟然能卡过...(Tips:不要乱写读入优化,这玩意儿加了超时,不加AC--) 2. 注意题目中的"最多只能有一个地方不一样,," ...

随机推荐

  1. 判断一个Object是否为数组Array的方法

    1.constructor constructor 属性是每个有原型对象的原型成员 arr.constructor == Array  //true说明arr是数组 2.isArray arr.isA ...

  2. 使用PHP生成分享图片

    小程序导航 wq.xmaht.top 假设代码中用到的资源文件夹在当前code_png目录下: /** * 分享图片生成 * @param $gData 商品数据,array * @param $co ...

  3. 史上最强大的wordpress后台框架redux-framework安装及使用

    redux-framework的相关链接 Redux的官方网站:https://reduxframework.com/ Redux文档查询:https://docs.reduxframework.co ...

  4. tp5简单构造

    application 应用目录 网站核心index前台目录 controller 控制器admin 后台目录 model 数据模型view 视图extend 静态类库目录public 静态资源和入口 ...

  5. Python 中关于文件操作的注意事项

    文件操作 #打开文件 f = open('要打开的文件路径',mode = 'r/w/a', encoding = '文件原来写入时的编码') #操作 data = f.read() #读取 f.wr ...

  6. strak组件(8):基本增删改查实现及应用和排序

    效果图: 新增函数: def reverse_common_url(self, name, *args, **kwargs) 反向生成url,需要传增删改的url作为参数,携带原参数 def reve ...

  7. C#简单的文件阅读器

    写一个简单的文件阅读器  1.可以读取大文件(2G)2.实现首页.下一页.前一页.末页的跳转3.实现到指定页面的跳转,比如跳转到第**页4.限制每页显示字符数 1029-4069byte,且用户可自定 ...

  8. 3. 与服务器对话:理解 HTTP 协议

    0.服务器与本地交换机制 2.详解HTtp服务 (1)与服务器对话的流程 (2)Reque 请求 (3)Response 响应 200 成功 404 没有网页 (4)Get/Post区别 get查询数 ...

  9. 3611: [Heoi2014]大工程

    3611: [Heoi2014]大工程 链接 分析: 树形dp+虚树. 首先建立虚树,在虚树上dp. dp:sum[i]为i的子树中所有询问点之间的和.siz[i]为i的子树中有多少询问点,mn[i] ...

  10. Docker容器 - 容器时间跟宿主机时间同步

    在Docker容器创建好之后,可能会发现容器时间跟宿主机时间不一致,这就需要同步它们的时间,让容器时间跟宿主机时间保持一致. 转载自:https://www.cnblogs.com/kevingrac ...