1 问题描述
1.1实验题目
设M1和M2是两个n×n的矩阵,设计算法计算M1×M2 的乘积。

1.2实验目的
(1)提高应用蛮力法设计算法的技能;

(2)深刻理解并掌握分治法的设计思想;(3)理解这样一个观点:用蛮力法设计的算法,一般来说,经过适度的努力后,都可以对其进行改进,以提高算法的效率。

1.3实验要求
(1)设计并实现用BF(Brute-Force,即蛮力法)方法求解矩阵相乘问题的算法;

(2)设计并实现用DAC(Divide-And-Conquer,即分治法)方法求解矩阵相乘问题的算法;(3)以上两种算法的输入既可以手动输入,也可以自动生成;(4)对上述两个算法进行时间复杂性分析,并设计实验程序验证分析结果;(5)设计可供用户选择算法的交互式菜单(放在相应的主菜单下)。

2 解决方案
2.1 分治法原理简述
分治法的设计思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。

分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。如果原问题可分割成k个子问题,1<k≤n ,且这些子问题都可解并可利用这些子问题的解求出原问题的解,那么这种分治法就是可行的。由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。这自然导致递归过程的产生。分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。分治法所能解决的问题一般具有以下几个特征:
  1. 该问题的规模缩小到一定的程度就可以容易地解决

  2. 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。

  3. 利用该问题分解出的子问题的解可以合并为该问题的解;

  4. 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。

2.2 分治法求解矩阵相乘原理
首先了解一下传统计算矩阵相乘的原理:


其次,看一下优化后的矩阵相乘法原理:

最后,看一下本文利用分治法求解矩阵相乘的原理(PS:本文求解其效率不是最高,主要是体验一下分治法,重点在于分治法):

注意:使用分治法求解两个nxn阶矩阵相乘,其中n值为2的幂值,否则只能使用蛮力法计算。



本文具体源码主要根据以上分块矩阵方法,先分块(即使用分治法),然后递归求解。

2.3 具体实现源码

package com.liuzhen.dac;public class Matrix {//初始化一个随机nxn阶矩阵public static int[][] initializationMatrix(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] = (int)(Math.random()*10); //采用随机函数随机生成1~10之间的数}}            return result;            }//蛮力法求解两个nxn和nxn阶矩阵相乘public static int[][] BruteForce(int[][] p,int[][] q,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] += p[i][k]*q[k][j];}}}                return result;}//分治法求解两个nxn和nxn阶矩阵相乘public static int[][] DivideAndConquer(int[][] p,int[][] q,int n){int[][] result = new int[n][n];//当n为2时,返回矩阵相乘结果if(n == 2){result = BruteForce(p,q,n);            return result;}//当n大于3时,采用采用分治法,递归求最终结果if(n > 2){int m = n/2;int[][] p1 = QuarterMatrix(p,n,1);int[][] p2 = QuarterMatrix(p,n,2);int[][] p3 = QuarterMatrix(p,n,3);int[][] p4 = QuarterMatrix(p,n,4);
//            System.out.println();
//            System.out.print("矩阵p1值为:");
//            PrintfMatrix(p1,m);
//            System.out.println();
//            System.out.print("矩阵p2值为:");
//            PrintfMatrix(p2,m);
//            System.out.println();
//            System.out.print("矩阵p3值为:");
//            PrintfMatrix(p3,m);
//            System.out.println();
//            System.out.print("矩阵p4值为:");
//            PrintfMatrix(p4,m);int[][] q1 = QuarterMatrix(q,n,1);int[][] q2 = QuarterMatrix(q,n,2);int[][] q3 = QuarterMatrix(q,n,3);int[][] q4 = QuarterMatrix(q,n,4);int[][] result1 = QuarterMatrix(result,n,1);int[][] result2 = QuarterMatrix(result,n,2);int[][] result3 = QuarterMatrix(result,n,3);int[][] result4 = QuarterMatrix(result,n,4);result1 = AddMatrix(DivideAndConquer(p1,q1,m),DivideAndConquer(p2,q3,m),m);result2 = AddMatrix(DivideAndConquer(p1,q2,m),DivideAndConquer(p2,q4,m),m);result3 = AddMatrix(DivideAndConquer(p3,q1,m),DivideAndConquer(p4,q3,m),m);result4 = AddMatrix(DivideAndConquer(p3,q2,m),DivideAndConquer(p4,q4,m),m);result = TogetherMatrix(result1,result2,result3,result4,m);}return result;}//获取矩阵的四分之一,并决定返回哪一个四分之一public static int[][] QuarterMatrix(int[][] p,int n,int number){int rows = n/2;   //行数减半int cols = n/2;   //列数减半int[][] result = new int[rows][cols];switch(number){case 1 :{// result = new int[rows][cols];for(int i=0;i<rows;i++){for(int j=0;j<cols;j++){result[i][j] = p[i][j];}}break;}case 2 :{// result = new int[rows][n-cols];for(int i=0;i<rows;i++){for(int j=0;j<n-cols;j++){result[i][j] = p[i][j+cols];}}break;}case 3 :{// result = new int[n-rows][cols];for(int i=0;i<n-rows;i++){for(int j=0;j<cols;j++){result[i][j] = p[i+rows][j];}}break;}case 4 :{// result = new int[n-rows][n-cols];for(int i=0;i<n-rows;i++){for(int j=0;j<n-cols;j++){result[i][j] = p[i+rows][j+cols];}}break;}default:break;}return result;}//把均分为四分之一的矩阵,聚合成一个矩阵,其中矩阵a,b,c,d分别对应原完整矩阵的四分中1、2、3、4public static int[][] TogetherMatrix(int[][] a,int[][] b,int[][] c,int[][] d,int n){int[][] result = new int[2*n][2*n];for(int i=0;i<2*n;i++){for(int j=0;j<2*n;j++){if(i<n){if(j<n){result[i][j] = a[i][j];}elseresult[i][j] = b[i][j-n];}else{if(j<n){result[i][j] = c[i-n][j];}else{result[i][j] = d[i-n][j-n];}}}}return result;}//求两个矩阵相加结果public static int[][] AddMatrix(int[][] p,int[][] q,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] = p[i][j]+q[i][j];}}return result;}//控制台输出矩阵public static void PrintfMatrix(int[][] matrix,int n){for(int i=0;i<n;i++){System.out.println();for(int j=0;j<n;j++){System.out.print("\t");System.out.print(matrix[i][j]);}}}public static void main(String args[]){int[][] p = initializationMatrix(8);int[][] q = initializationMatrix(8);System.out.print("矩阵p初始化值为:");PrintfMatrix(p,8);System.out.println();System.out.print("矩阵q初始化值为:");PrintfMatrix(q,8);int[][] bf_result = BruteForce(p,q,8);System.out.println();System.out.print("蛮力法计算矩阵p*q结果为:");PrintfMatrix(bf_result,8);int[][] dac_result = DivideAndConquer(p,q,8);System.out.println();System.out.print("分治法计算矩阵p*q结果为:");PrintfMatrix(dac_result,8);}}

2.4 运算结果截图

Java实现矩阵相乘问题相关推荐

  1. java实现矩阵相乘

    众所周知,矩阵的乘法就是矩阵的行列相乘再相加.话不多说,直接上代码: package test;public class matrixMultiply {public static void prin ...

  2. 转圈显示的Java程序和两矩阵相乘

    1.转圈显示的Java程序,将N x N的方阵转圈赋值并显示输出.如图:N=8,8x8方阵转圈填数结果. 解析:这是一个依靠矩阵中每个元素的下标对其进行操作的典型事例.其要求将1~NXN之间的整数按照 ...

  3. 蓝桥杯-矩阵相乘(java)

    算法提高 矩阵相乘 时间限制:1.0s 内存限制:256.0MB问题描述小明最近在为线性代数而头疼,线性代数确实很抽象(也很无聊),可惜他的老师正在讲这矩阵乘法这一段内容.当然,小明上课打瞌睡也没问题 ...

  4. Java黑皮书课后题第8章:**8.6(代数:两个矩阵相乘)编写两个矩阵相乘的方法。编写一个测试程序,提示用户输入两个3*3的矩阵,然后显示它们的乘积

    **8.6(代数:两个矩阵相乘)编写两个矩阵相乘的方法.编写一个测试程序,提示用户输入两个3*3的矩阵,然后显示它们的乘积 题目 题目描述与运行示例 破题 代码 题目 题目描述与运行示例 **8.6( ...

  5. 矩阵相乘Java版(第一个java程序)

    import java.util.Scanner;public class Matrix {public static void main(String args[]) {Scanner in = n ...

  6. 实现两个矩阵相乘(Java)

    矩阵乘法(Java实现) 矩阵可以用二维数组来表示:比如arr[n][m],其中n表示矩阵的行数m代表矩阵的列数,根据矩阵相乘的特性,两个矩阵相乘生成的那个新矩阵的行列是第一个矩阵的行和第二个矩阵的列 ...

  7. Java设计两个矩阵相乘的方法

    新建一个类名matrix,包名为:cn.xx.xx,两个矩阵相乘的程序源代码如下: import java.util.Scanner; public class Matrix { /*      矩阵 ...

  8. 【JAVA】小米集团-2021校招-算法方向在线考试(矩阵相乘+盒子包裹问题)

    前言 楼主参加笔试之前去字节面试了,又是被虐的一次,所以笔试迟到40分钟,而且被字节虐的脑子转不动了,今天笔试很简单,但是我做得不是很理想,希望大家多多说一下自己的思路.祝大家都有心仪的offer. ...

  9. Java、两个矩阵相乘

    编写两个矩阵相乘的方法:         public static double[][] multiplyMatrix(double[][] a, double[][] b) 编写一个测试程序,提示 ...

最新文章

  1. vue2路由移除#号(Apache)
  2. AngularJS分层开发
  3. python非阻塞输入_Python 命令行非阻塞输入的小例子
  4. Linux 多核下绑定硬件中断到不同 CPU(IRQ Affinity)
  5. vue实战学习第二天
  6. [MFC]关于Visual studio 2012的AfxGetMainWnd
  7. java timer 返回值,如何让计时器返回java时间
  8. 一场分销裂变活动,不止是发发朋友圈这么简单
  9. 树莓派系统安装 3.5寸LCD驱动安装 ssh远程链接
  10. oracle导入dmp文件数据不全,oracle导入dmp文件(恢复数据)
  11. kotlin实现的简单个人账户管理APP(三) 自定义View仿支付宝的密码输入框/密码相关逻辑
  12. mysql数据库常见的错误_MySQL数据库常见错误及解决方案
  13. 第三届世界5G大会召开之前,我们来复习一下这本6G白皮书
  14. 南京邮电大学计算机学硕2021,南京邮电大学2021年硕士研究生拟录取名单
  15. 纽脉医疗冲刺港交所上市:核心人员从微创医疗出走,创业后被起诉
  16. 范特西公司面试2012/10/23
  17. 第十四届蓝桥杯三月真题刷题训练——第 20 天
  18. ARM64内存虚拟化分析(7)stage2异常处理
  19. ubuntu服务器版安装桌面
  20. python调用libvirt_libvirt

热门文章

  1. 蓝桥杯java组多少分能拿奖_记 2019蓝桥杯校内预选赛(JAVA组) 赛后总结
  2. 可取消的定时倒计时关机
  3. 禁止windows系统创建快捷方式时添加文字“- 快捷方式”
  4. vue js 打印 去掉页脚的链接,去掉页眉页脚
  5. modbus4j异常TimeoutException: request=com.serotonin.modbus4j.ip.encap.EncapMessageRequest
  6. 华南理工软件学院复试2017年机试题
  7. Qt实现一个连连看小游戏
  8. excel函数学习整理
  9. 基于梵·高《向日葵》的 图像阈值处理专题(二值处理、反二值处理、截断处理、自适应处理及Otsu方法)【Python-Open_CV系列(六)】
  10. highcharts环形图