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. 【转】PHP计划任务:如何使用Linux的Crontab执行PHP脚本

    转:https://www.centos.bz/2011/03/auto-run-task-crontab/ 我们的PHP程序有时候需要定时执行,我们可以使用ignore_user_abort函数或是 ...

  2. JavaScript for循环 闭包 【转】

    个网友问了个问题,如下的html,为什么每次输出都是5,而不是点击每个p,就alert出对应的1,2,3,4,5. <html > <head> <meta http-e ...

  3. Apple Watch PSD 源文件【免费素材下载】

    Apple Watch 是苹果公司于2014年9月发布的一款智能手表.分为运动款.普通款和定制款三种,采用蓝宝石屏幕,有银色,金色,红色,绿色和白色等多种颜色可以选择.这里分享的是 Apple Wat ...

  4. Debug - 支持浏览器和 Node 平台的全端调试工具

    Debug 是一个跟踪调试消息的 JavaScript 库.因为它只是对 console.log 的包装,所以支持 Node 和浏览器.它允许你过滤日志输出而不需要改变你的源代码,也输出时间差异,可以 ...

  5. emberjs学习一(环境和第一个例子)

    code { margin: 0; padding: 0; white-space: pre; border: none; background: transparent; } code, pre t ...

  6. web时代变迁及html5与4的区别

    HTML5的新结构标签 在之前的HTML页面中,大家基本上都是用了Div+CSS的布局方式.而搜索引擎去抓取页面的内容的时候,它只能猜测 你的某个Div内的内容是文章内容容器,或者是导航模块的容器,或 ...

  7. C/C++构建系统 GNU autotool

    我们在网上经常可以看到c/c++开源的项目,其中很多都是使用GNU的构建系统进行配置和编译的,如果按照规范构造这些的步骤,有一定的门槛和复杂度,下文把关于auotools系列的工具和概要的流程简要汇总 ...

  8. Laravel 5 性能优化技巧

    说明 性能一直是 Laravel 框架为人诟病的一个点,所以调优 Laravel 程序算是一个必学的技能. 接下来分享一些开发的最佳实践,还有调优技巧,大家有别的建议也欢迎留言讨论. 这里是简单的列表 ...

  9. CAShaperLayer的应用

    关于CAShapeLayer的一些实用案例和技巧 实现遮罩 音量大小动态改变的控件 圆形进度条 iOS 利用CAShapeLayer的FillRule属性生成一个空心遮罩的layer fillrule ...

  10. SQLite Design and Concepts

    API 分为两大类 core API. 基本的SQL操作 extension API. 创建自定义的SQL操作. 基本数据结构 需要了解的组成部分有连接.statments.B树.pager. 为了写 ...