Strassen算法于1969年由德国数学家Strassen提出,该方法引入七个中间变量,每个中间变量都只需要进行一次乘法运算。而朴素算法却需要进行8次乘法运算。

原理

Strassen算法的原理如下所示,使用sympy验证Strassen算法的正确性

import sympy as s

A = s.Symbol("A")

B = s.Symbol("B")

C = s.Symbol("C")

D = s.Symbol("D")

E = s.Symbol("E")

F = s.Symbol("F")

G = s.Symbol("G")

H = s.Symbol("H")

p1 = A * (F - H)

p2 = (A + B) * H

p3 = (C + D) * E

p4 = D * (G - E)

p5 = (A + D) * (E + H)

p6 = (B - D) * (G + H)

p7 = (A - C) * (E + F)

print(A * E + B * G, (p5 + p4 - p2 + p6).simplify())

print(A * F + B * H, (p1 + p2).simplify())

print(C * E + D * G, (p3 + p4).simplify())

print(C * F + D * H, (p1 + p5 - p3 - p7).simplify())

复杂度分析

$$f(N)=7\times f(\frac{N}{2})=7^2\times f(\frac{N}{4})=...=7^k\times f(\frac{N}{2^k})$$

最终复杂度为$7^{log_2 N}=N^{log_2 7}$

java矩阵乘法(Strassen算法)

代码如下,可以看看数据结构的定义,时间换空间。

public class Matrix {

private final Matrix[] _matrixArray;

private final int n;

private int element;

public Matrix(int n) {

this.n = n;

if (n != 1) {

this._matrixArray = new Matrix[4];

for (int i = 0; i < 4; i++) {

this._matrixArray[i] = new Matrix(n / 2);

}

} else {

this._matrixArray = null;

}

}

private Matrix(int n, boolean needInit) {

this.n = n;

if (n != 1) {

this._matrixArray = new Matrix[4];

} else {

this._matrixArray = null;

}

}

public void set(int i, int j, int a) {

if (n == 1) {

element = a;

} else {

int size = n / 2;

this._matrixArray[(i / size) * 2 + (j / size)].set(i % size, j % size, a);

}

}

public Matrix multi(Matrix m) {

Matrix result = null;

if (n == 1) {

result = new Matrix(1);

result.set(0, 0, (element * m.element));

} else {

result = new Matrix(n, false);

result._matrixArray[0] = P5(m).add(P4(m)).minus(P2(m)).add(P6(m));

result._matrixArray[1] = P1(m).add(P2(m));

result._matrixArray[2] = P3(m).add(P4(m));

result._matrixArray[3] = P5(m).add(P1(m)).minus(P3(m)).minus(P7(m));

}

return result;

}

public Matrix add(Matrix m) {

Matrix result = null;

if (n == 1) {

result = new Matrix(1);

result.set(0, 0, (element + m.element));

} else {

result = new Matrix(n, false);

result._matrixArray[0] = this._matrixArray[0].add(m._matrixArray[0]);

result._matrixArray[1] = this._matrixArray[1].add(m._matrixArray[1]);

result._matrixArray[2] = this._matrixArray[2].add(m._matrixArray[2]);

result._matrixArray[3] = this._matrixArray[3].add(m._matrixArray[3]);;

}

return result;

}

public Matrix minus(Matrix m) {

Matrix result = null;

if (n == 1) {

result = new Matrix(1);

result.set(0, 0, (element - m.element));

} else {

result = new Matrix(n, false);

result._matrixArray[0] = this._matrixArray[0].minus(m._matrixArray[0]);

result._matrixArray[1] = this._matrixArray[1].minus(m._matrixArray[1]);

result._matrixArray[2] = this._matrixArray[2].minus(m._matrixArray[2]);

result._matrixArray[3] = this._matrixArray[3].minus(m._matrixArray[3]);;

}

return result;

}

protected Matrix P1(Matrix m) {

return _matrixArray[0].multi(m._matrixArray[1]).minus(_matrixArray[0].multi(m._matrixArray[3]));

}

protected Matrix P2(Matrix m) {

return _matrixArray[0].multi(m._matrixArray[3]).add(_matrixArray[1].multi(m._matrixArray[3]));

}

protected Matrix P3(Matrix m) {

return _matrixArray[2].multi(m._matrixArray[0]).add(_matrixArray[3].multi(m._matrixArray[0]));

}

protected Matrix P4(Matrix m) {

return _matrixArray[3].multi(m._matrixArray[2]).minus(_matrixArray[3].multi(m._matrixArray[0]));

}

protected Matrix P5(Matrix m) {

return (_matrixArray[0].add(_matrixArray[3])).multi(m._matrixArray[0].add(m._matrixArray[3]));

}

protected Matrix P6(Matrix m) {

return (_matrixArray[1].minus(_matrixArray[3])).multi(m._matrixArray[2].add(m._matrixArray[3]));

}

protected Matrix P7(Matrix m) {

return (_matrixArray[0].minus(_matrixArray[2])).multi(m._matrixArray[0].add(m._matrixArray[1]));

}

public int get(int i, int j) {

if (n == 1) {

return element;

} else {

int size = n / 2;

return this._matrixArray[(i / size) * 2 + (j / size)].get(i % size, j % size);

}

}

public void display() {

for (int i = 0; i < n; i++) {

for (int j = 0; j < n; j++) {

System.out.print(get(i, j));

System.out.print(" ");

}

System.out.println();

}

}

public static void main(String[] args) {

Matrix m = new Matrix(2);

Matrix n = new Matrix(2);

m.set(0, 0, 1);

m.set(0, 1, 3);

m.set(1, 0, 5);

m.set(1, 1, 7);

n.set(0, 0, 8);

n.set(0, 1, 4);

n.set(1, 0, 6);

n.set(1, 1, 2);

Matrix res = m.multi(n);

res.display();

}

}

总结

到此这篇关于使用java写的矩阵乘法的文章就介绍到这了,更多相关java矩阵乘法(Strassen算法)内容请搜索得牛网以前的文章或继续浏览下面的相关文章希望大家以后多多支持得牛网!

java矩阵连乘算法_使用java写的矩阵乘法实例(Strassen算法)相关推荐

  1. 【源码+图片素材】Java王者荣耀游戏开发_开发Java游戏项目【王者荣耀】1天搞定!!!腾讯游戏_Java课程设计_Java实战项目_Java初级项目

    王者荣耀是当下热门手游之一,小伙伴们是否想过如何制作一款属于自己的王者荣耀游戏呢? 本课程讲解了一个王者荣耀游戏的详细编写流程,即使你是刚入门Java的新手,只要你简单掌握了该游戏所需要的JavaSE ...

  2. 《算法导论》——矩阵乘法的Strassen算法

    前言: 很多朋友看到我写的<算法导论>系列,可能会觉得云里雾里,不知所云.这里我再次说明,本系列博文时配合<算法导论>一书,给出该书涉及的算法的c++实现.请结合<算法导 ...

  3. 矩阵相乘的strassen算法_4-2.矩阵乘法的Strassen算法详解

    题目描述 请编程实现矩阵乘法,并考虑当矩阵规模较大时的优化方法. 思路分析 根据wikipedia上的介绍:两个矩阵的乘法仅当第一个矩阵B的列数和另一个矩阵A的行数相等时才能定义.如A是m×n矩阵和B ...

  4. 6种java垃圾回收算法_学习java垃圾回收

    垃圾回收(GC)一直是Java受欢迎背后的重要特性之一.垃圾回收是Java中用于释放未使用的内存的机制.本质上,它追踪所有仍在使用的对象,并将剩下的标记为垃圾.Java的垃圾回收被认为是一种自动内存管 ...

  5. java编写类骑士游历_[基于Java的骑士游历问题的预见算法]骑士游历问题

    摘要:骑士游历问题是经典的NP问题.在骑士游历问题常规算法的基础上,提出一个新的算法――预见算法,用Java实现该算法,提高程序的运行效率. 关键词:骑士游历:预见:Java算法 1 骑士游历问题 在 ...

  6. Java如何让小球随机运动_用java模拟两球的随机运动及碰撞

    前面已经实现了一个球在一个窗口中随机运动,下面将在前面的基础上实现两个球的随机运动及碰撞,此次的代码中用到的算法参考了Twinsen写的一文中关于两球碰撞时的算法.程序仍旧有两个类,一个Ball类,一 ...

  7. java数组给名字排序_用Java给数组排序

    public class BubbleDemo { public static void main(String[] args) { int arr[]={1,3,5,7,2,4,6,8,9}; bu ...

  8. java内存分析详解_深入java内存查看与分析详解

    1:gc日志输出在jvm启动参数中加入 -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimestamps -XX:+PrintGCApplicationS ...

  9. java web 开发之道_《Java Web开发之道》PDF 下载

    图书目录: 第1篇  编程 经验与 感悟篇 第1章  编程 经验谈6则 经验01  乐不思蜀--寻找编程的乐趣 经验02  水滴石穿--编程学习 经验谈 经验03  举足轻重--代码规范 经验谈 经验 ...

最新文章

  1. android 下的网络图片加载
  2. 微服务架构在云端的应用
  3. mtd-utils编译
  4. 北斗导航 | GPS原理与接收机设计——琉璃剑之剑气回肠
  5. php 覆盖写文件内容,php写入文件不覆盖的实例讲解
  6. C#:ref和out的联系及区别。
  7. 数学建模灵敏度分析_数学建模中的灵敏度分析,到底在分析什么?
  8. error LNK2019: 无法解析的外部符号 WinMain,该符号在函数 int __cdecl invoke_main(void)”中被引用
  9. python怎么读取石墨表格_Python用Pandas读写Excel
  10. python炒股日记_自学python的日记分享
  11. 新特性:英特尔® 线程构建模块 4.2
  12. 根据on,获取选中的元素
  13. 常用的Linux操作命令
  14. mac 您没有权限打开应用程序_Mac应用程序无法打开或文件损坏的解决方法
  15. 用inno 打包程序 学习之路(转载)
  16. 使用PHP输出中文JSON字符串
  17. STM32程序下载1:通过keil-ST-Link方式下载
  18. 都2022年了,这11个Java开发工具你还不知道?
  19. 如何裁剪动图的大小?教你一分钟快速裁剪gif
  20. 预算三万配一台电脑,要全套,包括显示器,音箱,耳机,键盘鼠标这些,怎么搭配才好?

热门文章

  1. CometD:Java Web应用程序的Facebook类似聊天
  2. 使用Struts 2的查询网格(无插件)
  3. 线程故事:关于健壮的线程池
  4. android console命令,我们可以通过两种方式进入Android的console: 1. 直接执行命令emulator -shell; 2....
  5. 很高兴加入 英文_XR车载公司Holoride加入高通XR计划
  6. 道路交通安全违法行为记分管理办法的重大调整(2022版)
  7. Java变量(静态变量/成员变量/局部变量)初始化的问题
  8. visual2019没有勾选的在如何加入_发票管理系统完成升级,勾选认证平台改头换面,你所有的问题都在这里!...
  9. python float 精度_浅谈Python里面小数点精度的控制
  10. word一键生成ppt 分页_如何一键把Word转换为PPT?