分治与递归-Starssen矩阵乘法
代码实现:
/**
* 矩阵乘法求解
* @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矩阵乘法的更多相关文章
- 第四章 分治策略 4.2 矩阵乘法的Strassen算法
package chap04_Divide_And_Conquer; import static org.junit.Assert.*; import java.util.Arrays; import ...
- bzoj 3231 [ Sdoi 2008 ] 递归数列 —— 矩阵乘法
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3231 裸矩阵乘法. 代码如下: #include<iostream> #incl ...
- bzoj 3231 [Sdoi2008]递归数列——矩阵乘法
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3231 矩阵乘法裸题. 1018是10^18.别忘了开long long. #include& ...
- [bzoj3231][SDOI2008]递归数列——矩阵乘法
题目大意: 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai-k 其中bj和 cj ...
- 【bzoj3231】[Sdoi2008]递归数列 矩阵乘法+快速幂
题目描述 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai-k 其中bj和 cj ...
- [luogu2461 SDOI2008] 递归数列 (矩阵乘法)
传送门 Description 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai- ...
- P2461 [SDOI2008]递归数列 矩阵乘法+构造
还好$QwQ$ 思路:矩阵快速幂 提交:1次 题解: 如图: 注意$n,m$如果小于$k$就不要快速幂了,直接算就行... #include<cstdio> #include<ios ...
- BZOJ_3231_[Sdoi2008]递归数列_矩阵乘法
BZOJ_3231_[Sdoi2008]递归数列_矩阵乘法 Description 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1a ...
- bzoj 3231: [Sdoi2008]递归数列【矩阵乘法】
今天真是莫名石乐志 一眼矩阵乘法,但是这个矩阵的建立还是挺有意思的,就是把sum再开一列,建成大概这样 然后记!得!开!long!long!! #include<iostream> #in ...
随机推荐
- 什么是FHS,Linux的文件系统目录标准是怎样的
Filesystem Hierarchy Standard(文件系统目录标准)的缩写,多数Linux版本采用这种文件组织形式,类似于Windows操作系统中c盘的文件目录,FHS采用树形结构组织文件. ...
- postman设置测试环境
有时需要我们在不同的环境下跑相同的测试,就可以通过postman设置环境 展开环境切换下拉列表,点击[Manage Environments]
- 把 GitHub 放入口袋,“开箱”官方客户端
GitHub 2019 开发者大会说要出的客户端,今天(2020.3.18)终于放出了下载.之前如果登记过的小伙伴应该也和我一样收到了下面样子的邮件: 好了,那么接下来我们就来"开箱&quo ...
- react 新创建项目
1,先创建一个文件夹用于存放项目 2,运行cmd,路径选择到你创建的文件夹内 3, npm install -g create-react-app create-react-app ...
- 为什么 String 是 immutable 类
二哥,你能给我说说为什么 String 是 immutable 类(不可变对象)吗?我想研究它,想知道为什么它就不可变了,这种强烈的愿望就像想研究浩瀚的星空一样.但无奈自身功力有限,始终觉得雾里看花终 ...
- Flask 偏函数、g对象、flask-session、数据库连接池、信号、自制命令、flask-admin
目录 一.偏函数 二.g对象 g对象和session的区别 三.flask-session 四.数据库连接池 pymsql链接数据库 数据库连接池版 utils/sql.py 五.信号 六.命令fla ...
- java-3个例子(新手)
//创建的一个包名. package ri0318; //创建的一个类. public class Li3 { //公共静态的主方法. public static void main(String[] ...
- HTML每日学习笔记(0)
2019.7.14 1.属性为 HTML 元素提供附加信息,总是在 HTML 元素的开始标签中规定. 例子:<h1 align="center"> 对齐方式 <b ...
- linux入门系列18--Web服务之Apache服务1
前面系列文章讲解了Linux下通过文件传输.文件共享.邮件系统来分享和获取资源,本文讲解网络资源获取和共享的另外一种形式,通过Apache服务程序来提供Web服务. 本文先讲解目前主流的Web服务程序 ...
- I2C的基本概念和协议
概念 I2C总线是由Philips公司开发的一种简单.双向二线制同步串行总线.它只需要两根线即可在连接于总线上的器件之间传送信息. 主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任 ...