Strassen优化矩阵乘法(复杂度O(n^lg7))
按照算法导论写的
还没有测试复杂度到底怎么样
不过这个真的很卡内存,挖个坑,以后写空间优化
还有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))的更多相关文章
- OpenACC 优化矩阵乘法
▶ 按书上的步骤使用不同的导语优化矩阵乘法 ● 所有的代码 #include <iostream> #include <cstdlib> #include <chrono ...
- poj3613:Cow Relays(倍增优化+矩阵乘法floyd+快速幂)
Cow Relays Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7825 Accepted: 3068 Descri ...
- 利用Cayley-Hamilton theorem 优化矩阵线性递推
平时有关线性递推的题,很多都可以利用矩阵乘法来解决. 时间复杂度一般是O(K3logn)因此对矩阵的规模限制比较大. 下面介绍一种利用利用Cayley-Hamilton theorem加速矩阵乘法的方 ...
- 4-2.矩阵乘法的Strassen算法详解
题目描述 请编程实现矩阵乘法,并考虑当矩阵规模较大时的优化方法. 思路分析 根据wikipedia上的介绍:两个矩阵的乘法仅当第一个矩阵B的列数和另一个矩阵A的行数相等时才能定义.如A是m×n矩阵和B ...
- 第四章 分治策略 4.2 矩阵乘法的Strassen算法
package chap04_Divide_And_Conquer; import static org.junit.Assert.*; import java.util.Arrays; import ...
- cuda(2) 矩阵乘法优化过程
Created on 2013-8-5URL : http://blog.sina.com.cn/s/blog_a502f1a30101mjch.html@author: zhxfl转载请说明出处 # ...
- [学习笔记]矩阵乘法及其优化dp
1.定义: $c[i][j]=\sum a[i][k]\times b[k][j]$ 所以矩阵乘法有条件,(n*m)*(m*p)=n*p 即第一个矩阵的列数等于第二个矩阵的行数,否则没有意义. 2.结 ...
- 形态形成场(矩阵乘法优化dp)
形态形成场(矩阵乘法优化dp) 短信中将会涉及前\(k\)种大写字母,每个大写字母都有一个对应的替换式\(Si\),替换式中只会出现大写字母和数字,比如\(A→BB,B→CC0,C→123\),代表 ...
- POJ 3213 矩阵乘法(优化)
思路: 1.暴力出奇迹 n=1000 n^3矩阵乘法竟然能卡过...(Tips:不要乱写读入优化,这玩意儿加了超时,不加AC--) 2. 注意题目中的"最多只能有一个地方不一样,," ...
随机推荐
- 知识总结和记录——HTML
文档结构 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="U ...
- yum 仓库配置
[base]name=aliyum basebaseurl=https://mirrors.aliyun.com/centos/6/os/x86_64/ ...
- ethereum(以太坊)(十三)--异常处理/元祖
pragma solidity ^0.4.4; contract Students{ uint[] data= new uint[](4); address _owner = msg.sender; ...
- 【jQuery】输入框自带清除按钮
最近一个项目,需要在输入框时右边出现“X”标志,点击X即可清空,主要使用了click和blur事件,难点在于点击‘X’时,input框获得焦点时出现“X”标志,而点击"x"标志时i ...
- PHP CodeIgniter框架实现读写分离
一.目标 当前服务器只做了主从,未配置读写分离,读写分离的功能就只有交给程序来实现,本文主要谈谈Codeigniter怎么实现读写分离,并且需要满足以下两点: 1.读写分离对开发应该透明. 网上有方案 ...
- OC中block作方法参数时的用法
方式一.在传参时直接声明block回调方法. 1. 定义方法: - (int)doTest:(NSString *)name para1:(int)temp1 para2:(int)temp2 suc ...
- Pandas 数据结构Series:基本概念及创建
Series:"一维数组" 1. 和一维数组的区别 # Series 数据结构 # Series 是带有标签的一维数组,可以保存任何数据类型(整数,字符串,浮点数,Python对象 ...
- 007---Django的视图层
视图函数 一个视图函数,简称视图,是一个简单的python函数.它接收web请求并且返回web响应. 1.一张网页的HTML内容 2.一个重定向 3.一个404错误 4.一个xml文档 5.一个字符串 ...
- [Bzoj3894]文理分科(最小割)
Description 文理分科是一件很纠结的事情!(虽然看到这个题目的人肯定都没有纠结过) 小P所在的班级要进行文理分科.他的班级可以用一个n*m的矩阵进行描述,每个格子代表一个同学的座位.每位 ...
- 2,Flask 中的 Render Redirect HttpResponse
一,Flask中的HTTPResponse 在Flask 中的HttpResponse 在我们看来其实就是直接返回字符串 二,.Flask中的Redirect 每当访问"/redi" ...