按照算法导论写的

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

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

还有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. SpringBoot学习10:springboot整合mybatis

    需求:通过使用 SpringBoot+SpringMVC+MyBatis 整合实现一个对数据库中的 t_user 表的 CRUD 的操作 1.创建maven项目,添加项目所需依赖 <!--spr ...

  2. Webpack4 学习笔记四 暴露全局变量、externals

    前言 此内容是个人学习笔记,以便日后翻阅.非教程,如有错误还请指出 webpack 暴露全局变量 通过 expose-loader 内联配置 在 webpack中配置 每个模块通过注入的方式 通过CD ...

  3. [转] vim配置python自动补全

    vim python自动补全插件:pydiction 可以实现下面python代码的自动补全: 1.简单python关键词补全 2.python 函数补全带括号 3.python 模块补全 4.pyt ...

  4. 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等类型导致的,需 ...

  5. PL/sql中如何声明变量,常量,控制语句及for,loop,while和顺序控制的使用

    pl/sql 什么是PL/SQL PL/SQL是结合oracle过程语言和机构化查询运行(SQL) 的一种扩展语言.使用PL/SQL可以编写具有很多高级功能的程序,有以下优点 PL/SOL可以采用过程 ...

  6. 微信小程序CheckBox选中事件

    1.微信小程CheckBox选中问题 <checkbox-group bindchange="checkboxChange" data-index="{{index ...

  7. C5509A启动使用定时器

    #include <stdio.h> #include <csl.h> #include <csl_pll.h> #include <csl_chip.h&g ...

  8. 数据结构学习-BST二叉查找树 : 插入、删除、中序遍历、前序遍历、后序遍历、广度遍历、绘图

    二叉查找树(Binary Search Tree) 是一种树形的存储数据的结构 如图所示,它具有的特点是: 1.具有一个根节点 2.每个节点可能有0.1.2个分支 3.对于某个节点,他的左分支小于自身 ...

  9. C语言数组篇(五)多级指针和二维数组指针的区别

    多级指针   以二级指针为例 二级指针的由来是 指针数组 的指针形式. int *p[10] 读取的顺序是 p[] --> 10个空间的数组 * p[] --> 这10个空间的数组里面存放 ...

  10. linux-shell——02

    Linux命令的通用命令格式 :命令字 [选项] [参数] 选项: 作用:用于调节命令的具体功能 "-"引导短格式选项(单个字符) EX:“-l” "--"引导 ...