代码实现:

 /**
* 矩阵乘法求解
* @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. vue项目 github 上传项目并链接地址

    git init git init: 通过命令git init把这个文件夹变成Git可管理的仓库git status git status:查看当前仓库状态 git add . 这里提示你虽然把项目粘 ...

  2. 用纯Python实现循环神经网络RNN向前传播过程(吴恩达DeepLearning.ai作业)

    Google TensorFlow程序员点赞的文章!   前言 目录: - 向量表示以及它的维度 - rnn cell - rnn 向前传播 重点关注: - 如何把数据向量化的,它们的维度是怎么来的 ...

  3. python如何通过正则表达式一次性提取到一串字符中所有的汉字

    1.python如何通过正则表达式一次性提取到一串字符中所有的汉字 https://blog.csdn.net/py0312/article/details/93999895 说明:字符串前的 “ r ...

  4. VS2019 C++动态链接库的创建使用(2) - 客户调用接口

    因为动态链接库里的内容是自己定义的,所以在外部程序调用时我们自己知道库里包含哪些变量和函数,如果我们提供库给其他人使用,则最好增加一个头文件,告知库里包含的函数: ①将动态链接库源文件内容增加红色框内 ...

  5. [IROS 2018]Semantic Mapping with Simultaneous Object Detection and Localization

      论文地址:https://arxiv.org/abs/1810.11525   论文视频:https://www.youtube.com/watch?v=W-6ViSlrrZg​www.youtu ...

  6. Servlet(三)----Servlet体系与HTTP

    ## Servlet的体系结构 Servlet  ---  接口 | | GenericServlet  ---  抽象类 | | HttpServlet  --  抽象类 GenericServle ...

  7. CF1324F Maximum White Subtree 题解

    原题链接 简要题意: 给定一棵树,每个点有黑白两种颜色:对每个节点,求出包含当前节点的连通图,使得白点数与黑点数差最小.输出这些值. F题也这么简单,咳咳,要是我也熬夜打上那么一场...可惜没时间打啊 ...

  8. 题解 P1002 【过河卒】

    正文 简单描述一下题意: 士兵想要过河,他每一次可以往下走一格,也可以往右走一格,但马一步走到的地方是不能走的,问走到\(n\)行,\(m\)列有多少种走法 我们显然应该先根据马的位置将不能走的格子做 ...

  9. 关于LSTM实现长短期记忆功能问题

    2019-09-07 22:01:45 问题描述:LSTM是如何实现长短期记忆功能的? 问题求解: 与传统的循环神经网络相比,LSTM仍然是基于当前输入和之前的隐状态来计算当前的隐状态,只不过对内部的 ...

  10. Java进阶之心态

    不管什么时候学习都是一个积累的过程,量变才能引起质变.一口吃一个胖子是不存在的,成长的路上没有捷径,只有学到的知识才是我们走向远方道路的基石!