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. 注意题目中的"最多只能有一个地方不一样,," ...
随机推荐
- SpringBoot学习10:springboot整合mybatis
需求:通过使用 SpringBoot+SpringMVC+MyBatis 整合实现一个对数据库中的 t_user 表的 CRUD 的操作 1.创建maven项目,添加项目所需依赖 <!--spr ...
- Webpack4 学习笔记四 暴露全局变量、externals
前言 此内容是个人学习笔记,以便日后翻阅.非教程,如有错误还请指出 webpack 暴露全局变量 通过 expose-loader 内联配置 在 webpack中配置 每个模块通过注入的方式 通过CD ...
- [转] vim配置python自动补全
vim python自动补全插件:pydiction 可以实现下面python代码的自动补全: 1.简单python关键词补全 2.python 函数补全带括号 3.python 模块补全 4.pyt ...
- python json.dumps raise TypeError(repr(o) + " is not JSON serializable") TypeError: 0 is not JSON serializable
出错如题. 这个问题有可能是因为python的json.dumps没法识别dump内容里的某些数据类型导致的.我的问题是因为dict中含有numpy.int64,numpy.float等类型导致的,需 ...
- PL/sql中如何声明变量,常量,控制语句及for,loop,while和顺序控制的使用
pl/sql 什么是PL/SQL PL/SQL是结合oracle过程语言和机构化查询运行(SQL) 的一种扩展语言.使用PL/SQL可以编写具有很多高级功能的程序,有以下优点 PL/SOL可以采用过程 ...
- 微信小程序CheckBox选中事件
1.微信小程CheckBox选中问题 <checkbox-group bindchange="checkboxChange" data-index="{{index ...
- C5509A启动使用定时器
#include <stdio.h> #include <csl.h> #include <csl_pll.h> #include <csl_chip.h&g ...
- 数据结构学习-BST二叉查找树 : 插入、删除、中序遍历、前序遍历、后序遍历、广度遍历、绘图
二叉查找树(Binary Search Tree) 是一种树形的存储数据的结构 如图所示,它具有的特点是: 1.具有一个根节点 2.每个节点可能有0.1.2个分支 3.对于某个节点,他的左分支小于自身 ...
- C语言数组篇(五)多级指针和二维数组指针的区别
多级指针 以二级指针为例 二级指针的由来是 指针数组 的指针形式. int *p[10] 读取的顺序是 p[] --> 10个空间的数组 * p[] --> 这10个空间的数组里面存放 ...
- linux-shell——02
Linux命令的通用命令格式 :命令字 [选项] [参数] 选项: 作用:用于调节命令的具体功能 "-"引导短格式选项(单个字符) EX:“-l” "--"引导 ...