package chap04_Divide_And_Conquer;

import static org.junit.Assert.*;

import java.util.Arrays;

import org.junit.Test;

/**
* 矩阵相乘的算法
*
* @author xiaojintao
*
*/
public class MatrixOperation {
/**
* 普通的矩阵相乘算法,c=a*b。其中,a、b都是n*n的方阵
*
* @param a
* @param b
* @return c
*/
static int[][] matrixMultiplicationByCommonMethod(int[][] a, int[][] b) {
int n = a.length;
int[][] c = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = 0;
for (int k = 0; k < n; k++) {
c[i][j] += a[i][k] * b[k][j];
}
}
}
return c;
} /**
* strassen 算法求矩阵乘法 n为2的幂
*
* @param a
* @param b
* @return
*/
static int[][] matrixMultiplicationByStrassen(int[][] a, int[][] b) {
int n = a.length;
if (n == 1) {
int[][] c = new int[1][1];
c[0][0] = a[0][0] * b[0][0];
return c;
}
int m = n / 2;
int[][] a11, a12, a21, a22, b11, b12, b21, b22;
int[][] c = new int[n][n];
a11 = new int[m][m];
a12 = new int[m][m];
a21 = new int[m][m];
a22 = new int[m][m];
b11 = new int[m][m];
b12 = new int[m][m];
b21 = new int[m][m];
b22 = new int[m][m]; for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
a11[i][j] = a[i][j];
}
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
b11[i][j] = b[i][j];
}
}
for (int i = 0; i < m; i++) {
for (int j = m; j < n; j++) {
a12[i][j - m] = a[i][j];
}
}
for (int i = 0; i < m; i++) {
for (int j = m; j < n; j++) {
b12[i][j - m] = b[i][j];
}
}
for (int i = m; i < n; i++) {
for (int j = 0; j < m; j++) {
a21[i - m][j] = a[i][j];
}
}
for (int i = m; i < n; i++) {
for (int j = 0; j < m; j++) {
b21[i - m][j] = b[i][j];
}
}
for (int i = m; i < n; i++) {
for (int j = m; j < n; j++) {
a22[i - m][j - m] = a[i][j];
}
}
for (int i = m; i < n; i++) {
for (int j = m; j < n; j++) {
b22[i - m][j - m] = b[i][j];
}
}
int[][] s1 = matrixMinus(b12, b22);
int[][] s2 = matrixAdd(a11, a12);
int[][] s3 = matrixAdd(a21, a22);
int[][] s4 = matrixMinus(b21, b11);
int[][] s5 = matrixAdd(a11, a22);
int[][] s6 = matrixAdd(b11, b22);
int[][] s7 = matrixMinus(a12, a22);
int[][] s8 = matrixAdd(b21, b22);
int[][] s9 = matrixMinus(a11, a21);
int[][] s10 = matrixAdd(b11, b12); int[][] p1 = matrixMultiplicationByStrassen(a11, s1);
int[][] p2 = matrixMultiplicationByStrassen(s2, b22);
int[][] p3 = matrixMultiplicationByStrassen(s3, b11);
int[][] p4 = matrixMultiplicationByStrassen(a22, s4);
int[][] p5 = matrixMultiplicationByStrassen(s5, s6);
int[][] p6 = matrixMultiplicationByStrassen(s7, s8);
int[][] p7 = matrixMultiplicationByStrassen(s9, s10); int[][] t1, t2, t3;
t1 = matrixAdd(p5, p4);
t2 = matrixMinus(t1, p2);
int[][] c11 = matrixAdd(t2, p6);
int[][] c12 = matrixAdd(p1, p2);
int[][] c21 = matrixAdd(p3, p4);
t1 = matrixAdd(p5, p1);
t2 = matrixMinus(t1, p3);
int[][] c22 = matrixMinus(t2, p7);
c = matrixConbine(c11, c12, c21, c22);
return c;
} /**
* 矩阵加法 c=a+b
*
* @param a
* @param b
* @return
*/
static int[][] matrixAdd(int[][] a, int[][] b) {
int n = a.length;
int[][] c = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = a[i][j] + b[i][j];
}
}
return c;
} /**
* 矩阵减法 c=a-b
*
* @param a
* @param b
* @return
*/
static int[][] matrixMinus(int[][] a, int[][] b) {
int n = a.length;
int[][] c = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = a[i][j] - b[i][j];
}
}
return c;
} /**
* 将矩阵的四个部分组合
*
* @param t11
* @param t12
* @param t21
* @param t22
* @return
*/
protected static int[][] matrixConbine(int[][] t11, int[][] t12,
int[][] t21, int[][] t22) {
int n = t11.length;
int m = 2 * n;
int[][] c = new int[m][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j] = t11[i][j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i][j + n] = t12[i][j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i + n][j] = t21[i][j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
c[i + n][j + n] = t22[i][j];
}
}
return c;
} @Test
public void testName() throws Exception {
// int[][] a = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
// int[][] b = { { 1, 3, 5 }, { 2, 4, 6 }, { 9, 8, 7 } };
// int[][] c = commonMatrixMultiplication(a, b);
// int[][] c = matrixAdd(a, b); int[][] m = { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 },
{ 13, 14, 15, 16 } };
int[][] n = { { 1, 3, 5, 7 }, { 2, 4, 6, 8 }, { 4, 3, 2, 1 },
{ 9, 8, 7, 6 } }; int[][] c = matrixMultiplicationByStrassen(m, n);
System.out.println(Arrays.deepToString(c));
int[][] d = matrixMultiplicationByCommonMethod(m, n);
System.out.println(Arrays.deepToString(d));
}
}

暴力求解复杂度为O(n3),Strassen算法为O(n log7)

第四章 分治策略 4.2 矩阵乘法的Strassen算法的更多相关文章

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

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

  2. 《算法导论》——矩阵乘法的Strassen算法

    前言: 很多朋友看到我写的<算法导论>系列,可能会觉得云里雾里,不知所云.这里我再次说明,本系列博文时配合<算法导论>一书,给出该书涉及的算法的c++实现.请结合<算法导 ...

  3. 【技术文档】《算法设计与分析导论》R.C.T.Lee等·第4章 分治策略

    分治策略有一种“大事化小,小事化了”的境界,它的思想是将原问题分解成两个子问题,两个子问题的性质和原问题相同,因此这两个子问题可以再用分治策略求解,最终将两个子问题的解合并成原问题的解.有时,我们会有 ...

  4. 分治与递归-Starssen矩阵乘法

    代码实现: /** * 矩阵乘法求解 * @author Administrator * */ public class Strassen { public static final int NUMB ...

  5. 整数快速乘法/快速幂+矩阵快速幂+Strassen算法

    快速幂算法可以说是ACM一类竞赛中必不可少,并且也是非常基础的一类算法,鉴于我一直学的比较零散,所以今天用这个帖子总结一下 快速乘法通常有两类应用:一.整数的运算,计算(a*b) mod c  二.矩 ...

  6. 第4章 分治策略 monge阵列

    /* fi表示第i行的最左最小元素的列小标,则有f0<f1<f2<...<fn-1 取数组的偶数行,组成新的子数组,递归求解最左最小元素的列下表,利用偶数项限定奇数项的范围,再 ...

  7. 数学(矩阵乘法,随机化算法):POJ 3318 Matrix Multiplication

    Matrix Multiplication Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17783   Accepted: ...

  8. 算法导论 第三章 and 第四章

    第三章 渐进的基本O().... 常用函数 % 和  // 转换 斯特林近似公式 斐波那契数 第四章 分治策略:分解(递归)--解决(递归触底)--合并 求解递归式的3种方法: 1:代入法(替代法): ...

  9. 算法导论-矩阵乘法-strassen算法

    目录 1.矩阵相乘的朴素算法 2.矩阵相乘的strassen算法 3.完整测试代码c++ 4.性能分析 5.参考资料 内容 1.矩阵相乘的朴素算法 T(n) = Θ(n3) 朴素矩阵相乘算法,思想明了 ...

随机推荐

  1. 静态代码审查工具FxCop插件开发(c#)

    FxCop是一款微软官方提供的.net平台代码审查工具,目的是检查我们编写的程序集的代码是否符合规范.FxCop默认提供的是微软默认的审查规则,而且该规则符合<Framework DesignG ...

  2. Horseman - 让你更轻松的使用 PhantomJS

    Horseman 是一个 Node.js 模块,让你可以更轻松的使用 PhantomJS 进行功能测试,页面自动机,网络监控,屏幕捕获等.它提供了直接,链式的 API,易于理解的控制流,避免回调陷阱. ...

  3. 【HTML5】浅析HTML5应用程序缓存(ApplicationCache)

    一.为什么需要Web应用程序缓存 在移动互联网时代,设备终端位置不再固定,依赖无线信号,网络的可靠性变得降低,比如坐在火车上,过了一个隧道(15分钟),便无法访问网站,这对于web的伤害是很大的    ...

  4. 30分钟手把手教你学webpack实战

    30分钟手把手教你学webpack实战 阅读目录 一:什么是webpack? 他有什么优点? 二:如何安装和配置 三:理解webpack加载器 四:理解less-loader加载器的使用 五:理解ba ...

  5. 几个有用的JSON工具

    好久没写博客了,这里都要长草了:) 这几天研究PLM360 REST API和Infraworks REST API,一天到晚和JSON打交道,发现这几个小工具非常好用,推荐给大家. 第0个,大名鼎鼎 ...

  6. Android之滑屏动画和自定义控件

    滑屏动画 在Android系统中,通过手势识别切换界面时,通常会在界面切换时加入动画,以提高用户的体验效果,这种动画一般都采用平移动画,下一个界面进入时,上一个界面移除屏幕. 图中标识的均为左上角坐标 ...

  7. Java Collection Framework概述

    文章出自:听云博客 Collection概述 Java collection是java提供的工具包,包含了常用的数据结构:集合.链表.队列.栈.数组.映射等. Java集合主要可以划分为4个部分:Li ...

  8. view渐变色,透明度渐变

    1 功能描述 开发中经常遇到这样的需求:view2显示在view1上面,透过view2可以渐渐的看到view1.效果如图1所示:view1是一个imageView,view2是一个普通view.vie ...

  9. C语言中的复合类型

    复合类型 一.掌握的类型 1. 指针数组 int * arr[10]; //arr是一个数组,有10个元素,每个元素都是一个指针,即arr是一个指针数组 int a,b,c,d; arr[0] = & ...

  10. HTML5 初步了解

    这是HTM5L的第一篇博客. 那么就让我们简单的了解HTML5的语法吧. (HTML5运行环境要求极低,非关键地方就不做截图了) <!--根标签--> <html> <! ...