代码实现:

 /**
* 矩阵乘法求解
* @author Administrator
*
*/
public class Strassen {
public static final int NUMBER = 4;
private static int[][] A;
private static int[][] B; public Strassen() {
A = new int[NUMBER][NUMBER];
B = new int[NUMBER][NUMBER];
} public int[][] starssen(int[][] A, int[][] B) {
int divide_length = A.length / 2;
// 定义一些中间变量
int[][] result = new int[A.length][A.length]; int[][] M1 = new int[divide_length][divide_length];
int[][] M2 = new int[divide_length][divide_length];
int[][] M3 = new int[divide_length][divide_length];
int[][] M4 = new int[divide_length][divide_length];
int[][] M5 = new int[divide_length][divide_length];
int[][] M6 = new int[divide_length][divide_length];
int[][] M7 = new int[divide_length][divide_length]; int[][] C11 = new int[divide_length][divide_length];
int[][] C12 = new int[divide_length][divide_length];
int[][] C21 = new int[divide_length][divide_length];
int[][] C22 = new int[divide_length][divide_length]; int[][] A11 = new int[divide_length][divide_length];
int[][] A12 = new int[divide_length][divide_length];
int[][] A21 = new int[divide_length][divide_length];
int[][] A22 = new int[divide_length][divide_length]; int[][] B11 = new int[divide_length][divide_length];
int[][] B12 = new int[divide_length][divide_length];
int[][] B21 = new int[divide_length][divide_length];
int[][] B22 = new int[divide_length][divide_length]; if (A.length == 2) {
result = multi(A, B, A.length);
} else {
// 首先将矩阵A,B分为4块
for (int i = 0; i < divide_length; ++i) {
for (int j = 0; j < divide_length; ++j) {
A11[i][j] = A[i][j];
A12[i][j] = A[i][j + divide_length];
A21[i][j] = A[i + divide_length][j];
A22[i][j] = A[i + divide_length][j + divide_length]; B11[i][j] = B[i][j];
B12[i][j] = B[i][j + divide_length];
B21[i][j] = B[i + divide_length][j];
B22[i][j] = B[i + divide_length][j + divide_length];
}
} // 计算M1
M1 = starssen(A11, sub(B12, B22, divide_length));
// 计算M2
M2 = starssen(add(A11, A12, divide_length), B22);
// 计算M3
M3 = starssen(add(A21, A22, divide_length), B11);
// 计算M4
M4 = starssen(A22, sub(B21, B11, divide_length));
// 计算M5
M5 = starssen(add(A11, A22, divide_length), add(B11, B22, divide_length));
// 计算M6
M6 = starssen(sub(A12, A22, divide_length), add(B21, B22, divide_length));
// 计算M7
M7 = starssen(sub(A11, A21, divide_length), add(B11, B12, divide_length)); // 计算C11,C12,C21,C22
C11 = add(sub(add(M5, M4, divide_length), M2, divide_length), M6, divide_length);
C12 = add(M1, M2, divide_length);
C21 = add(M3, M4, divide_length);
C22 = sub(sub(add(M5, M1, divide_length), M3, divide_length), M7, divide_length); // 合并C11,C12,C21,C22到C
for (int i = 0; i < divide_length; ++i) {
for (int j = 0; j < divide_length; ++j) {
result[i][j] = C11[i][j];
result[i][j + divide_length] = C12[i][j];
result[i + divide_length][j] = C21[i][j];
result[i + divide_length][j + divide_length] = C22[i][j];
}
}
}
return result;
} public static int[][] initial() {
int [][] result = new int[NUMBER][NUMBER];
for (int i = 0; i < NUMBER; ++i) {
for (int j = 0; j < NUMBER; ++j) {
// 采用Math生成1~10之间的随机数
result[i][j] = (int)(Math.random()*10);
}
}
return result;
} public void output(int[][] result) {
for (int b[] :result) {
for (int temp : b) {
System.out.print(temp + " ");
}
System.out.println();
}
} /**
* 蛮力求解矩阵乘法
* @param a:矩阵a n*n
* @param b:矩阵b n*n
* @param n: 矩阵大小
*/
public int[][] multi(int a[][], int b[][], int n) {
int result[][] = new int[n][n];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
result[i][j] = 0;
for (int k = 0; k < n; ++k) {
result[i][j] += a[i][k] * b[k][j];
}
}
}
return result;
} /**
* 矩阵加法
* @param a
* @param b
* @param n
* @return
*/
public int[][] add(int a[][], int b[][], int n) {
int result[][] = new int[n][n];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
result[i][j] = a[i][j] + b[i][j];
}
}
return result;
} /**
* 矩阵减法
* @param a
* @param b
* @param n
* @return
*/
public int[][] sub(int a[][], int b[][], int n) {
int result[][] = new int[n][n];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
result[i][j] = a[i][j] - b[i][j];
}
}
return result;
} public static void main(String[] args) {
Strassen s = new Strassen();
A = initial();
B = initial();
s.output(A);
System.out.println("----------------------");
s.output(B);
System.out.println("----------------------"); s.output(s.multi(A, B, NUMBER));
System.out.println("----------------------"); int K[][] = new int[2][2];
K = s.starssen(A, B);
s.output(K);
}
}

分治与递归-Starssen矩阵乘法的更多相关文章

  1. 第四章 分治策略 4.2 矩阵乘法的Strassen算法

    package chap04_Divide_And_Conquer; import static org.junit.Assert.*; import java.util.Arrays; import ...

  2. bzoj 3231 [ Sdoi 2008 ] 递归数列 —— 矩阵乘法

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3231 裸矩阵乘法. 代码如下: #include<iostream> #incl ...

  3. bzoj 3231 [Sdoi2008]递归数列——矩阵乘法

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3231 矩阵乘法裸题. 1018是10^18.别忘了开long long. #include& ...

  4. [bzoj3231][SDOI2008]递归数列——矩阵乘法

    题目大意: 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai-k 其中bj和 cj ...

  5. 【bzoj3231】[Sdoi2008]递归数列 矩阵乘法+快速幂

    题目描述 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai-k 其中bj和 cj  ...

  6. [luogu2461 SDOI2008] 递归数列 (矩阵乘法)

    传送门 Description 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai- ...

  7. P2461 [SDOI2008]递归数列 矩阵乘法+构造

    还好$QwQ$ 思路:矩阵快速幂 提交:1次 题解: 如图: 注意$n,m$如果小于$k$就不要快速幂了,直接算就行... #include<cstdio> #include<ios ...

  8. BZOJ_3231_[Sdoi2008]递归数列_矩阵乘法

    BZOJ_3231_[Sdoi2008]递归数列_矩阵乘法 Description 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1a ...

  9. bzoj 3231: [Sdoi2008]递归数列【矩阵乘法】

    今天真是莫名石乐志 一眼矩阵乘法,但是这个矩阵的建立还是挺有意思的,就是把sum再开一列,建成大概这样 然后记!得!开!long!long!! #include<iostream> #in ...

随机推荐

  1. Lucene查询语法汇总

    目录 一.单词查询 二.通配符查询 三.模糊查询 四.近似查询 五.范围查询 六.优先级查询 七.逻辑操作 八.括号分组 九.转义特殊字符 Lucene是目前最为流行的开源全文搜索引擎工具包,提供了完 ...

  2. 问题描述:判断一个整数 n 是否为 2 的幂次方

    一.2的幂次方的基本定义 什么样的数为2的幂次方?例如2^0=1,2^1=2,2^2=4……,符合公式2^n(n>=0)的数称为2的幂次方. 如何判断一个数是否为2的幂次方呢?基本思路:把一个数 ...

  3. props watch 接口抖动

    readType (val) { this.innerReadType = '-' this.$nextTick(() => { this.innerReadType = val }) },

  4. Spring 多数据源配置(转)

    转载自:https://www.cnblogs.com/digdeep/p/4512368.html 同一个项目有时会涉及到多个数据库,也就是多数据源.多数据源又可以分为两种情况: 1)两个或多个数据 ...

  5. linux 执行计划任务crontab

    crontab 一些常用的命令 service crond start //启动服务 service crond stop //关闭服务 service crond restart //重启服务 se ...

  6. 常用的 Git 命令与场景

    Git 分布式版本控制系统 它拥有完整的版本控制功能,能够解决多人协作的问题 将自己的代码同步到 Github 上能够提升开发效率 git 会记录你每一次的版本修改操作 常用的 Git 操作 # 指定 ...

  7. 深度学习归一化:BN、GN与FRN

    在深度学习中,使用归一化层成为了很多网络的标配.最近,研究了不同的归一化层,如BN,GN和FRN.接下来,介绍一下这三种归一化算法. BN层 BN层是由谷歌提出的,其相关论文为<Batch No ...

  8. 关于浏览器Number.toFixed的错误修复

    问题描述如下: var n = 1.255; var fixed = n.toFixed(2); console.log(fixed);//结果:1.25 /* 以上代码运行预期的结果是1.26,但是 ...

  9. 详解聚类算法Kmeans的两大优化——mini-batch和Kmeans++

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是机器学习专题的第13篇文章,我们来看下Kmeans算法的优化. 在上一篇文章当中我们一起学习了Kmeans这个聚类算法,在算法的最后我 ...

  10. Flutter 使用阿里巴巴icon库

    在Flutter默认创建的项目中可以使用系统Material图标,在pubspec.yaml文件中使用图标设置如下: flutter: uses-material-design: true 系统图标如 ...