分治与递归-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 ...
随机推荐
- Flask 使用pycharm 创建项目,一个简单的web 搭建
1:新建项目后 2:Flask web 项目重要的就是app 所有每个都需要app app=Flask(__name__) 3:Flask 的路径是有app.route('path')装饰决定, ...
- 第一个爬虫经历----豆瓣电影top250(经典案例)
因为要学习数据分析,需要从网上爬取数据,所以开始学习爬虫,使用python进行爬虫,有好几种模拟发送请求的方法,最基础的是使用urllib.request模块(python自带,无需再下载),第二是r ...
- 雅奇880、990、小土豆调用EPX Studio 编译的DLL的编程方法~
在雅奇990中,使用“外部文件-调用链接库文件”命令实现与EP的通信,例如: 1.调用链接库文件(取项目文件信息() + '资源文件\Project1.dll', 'Unit1.rpas:Result ...
- NLP(二十七)开放领域的三元组抽取的一次尝试
当我写下这篇文章的时候,我的内心是激动的,这是因为,自从去年6月份写了文章利用关系抽取构建知识图谱的一次尝试 后,我就一直在试图寻找一种在开放领域能够进行三元组抽取的办法,也有很多读者问过我这方面 ...
- 对tf.nn.softmax的理解
对tf.nn.softmax的理解 转载自律者自由 最后发布于2018-10-31 16:39:40 阅读数 25096 收藏 展开 Softmax的含义:Softmax简单的说就是把一个N*1的向 ...
- Cisco 综合配置(二)
要求: 1. PC1 属于VLAN10,PC2属于VLAN20,网关:Master Router2. VLAN10.20 的网段为:192.168.10.0/24 . 192.168.20.0/24 ...
- 树莓派4B踩坑指南 - (13)用samba建立家庭局域网共享中心
树莓派在家中至少三个作用:家庭资源共享中心.无线打印服务器.下载服务器. 家庭资源共享中心用samba实现家庭局域网共享,树莓派4B的话可以接2个3.0的移动硬盘. 实测速度不快,Win读2Mb/s写 ...
- 洛谷2212Watering the Fields S 最小生成树
题目链接:https://www.luogu.com.cn/problem/P2212 几乎是Kruskal裸题,但是建n*(n-1)条边给我T了俩点,后来我发现只要C(n,2)条边就可以,因为假设( ...
- 洛谷P1957口算练习题题解
前言: 题目传送门:https://www.luogu.com.cn/problem/P1957 其实这很简单 纯模拟撒~~~~ 正文开始: _话说 ,就当本蒟蒻正高高兴兴的刷水题时,居然 碰到了这个 ...
- P5021 赛道修建 题解
原题链接 简要题意: 在一棵树上求 \(m\) 条不相交的路径的最小值的最大值. 本题部分分很多,而且本人也交了 \(27\) 次,所以一定要仔细讲部分分! 算法一 对于 \(b_i = a_i + ...