矩阵连乘实验报告

合集下载

10计本算法实验矩阵连乘算法

10计本算法实验矩阵连乘算法

实验报告4课程数据结构与算法实验名称动态规划(一) 第页班级10计本学号105032010111 姓名陈兴灶实验日期:2012年3月20日报告退发(订正、重做)一、实验目的掌握递归及分治策略的原理和应用。

二、实验环境1、微型计算机一台2、WINDOWS操作系统,Java SDK,Eclipse开发环境三、实验内容必做题:1、编程实现矩阵连乘算法,求出最优值及一个最优解。

附加题:1、开车从a到b会经过n个加油站,给定这n个加油站的距离和油价,及汽车耗油量,汽车油箱的容量为v,编程计算从a到b至少需要花费多少油费。

四、实验步骤和结果第一题:矩阵连乘算法package shiyan4;import java.util.Scanner;public class matrixChain {public static int [][]a;public static int [][]b;public static void matrixchain(int []p,int [][]m,int [][]s){int n=p.length-1;for(int i=1;i<n;i++)m[i][i]=0;for(int r=2;r<=n;r++)for(int i=1;i<=n-r+1;i++){int j=i+r-1;m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];s[i][j]=i;for(int k=i+1;k<j;k++){int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];if(t<m[i][j]){m[i][j]=t;s[i][j]=k;}}}}public static void traceback(int [][]s,int i,int j){if(i==j)return ;traceback(s,i,s[i][j]);traceback(s,s[i][j]+1,j);System.out.println("Multiply A"+i+","+s[i][j]+" and A"+(s[i][j]+1)+","+j);}public static void main(String []args){Scanner sc=new Scanner(System.in);System.out.println("输入矩阵个数");int n=sc.nextInt();int []p=new int[n+1];a=new int [n+1][n+1];b=new int [n+1][n+1];System.out.println("输入各矩阵的行数和列数");for(int i=0;i<=n;i++)p[i]=sc.nextInt();matrixchain(p,a,b);System.out.println("最少次数为");System.out.println(a[1][a.length-1]+" ");System.out.println("最优解为");traceback(b,1,n);}}结果:第二题:计算从a到b至少需要花费多少油费package shiyan4;import java.util.Scanner;public class MinPertrolFee {public static float []fee;public static float []distance;public static float v;public static float vh;public static float vs;float money;MinPertrolFee(){Scanner sc=new Scanner(System.in);System.out.println("输入加油站个数");int n=sc.nextInt();fee=new float[n];System.out.println("输入每个加油站油的单价");distance=new float[n];for(int i=1;i<fee.length;i++)fee[i]=sc.nextFloat();System.out.println("输入两两相邻加油站间的距离");for(int i=1;i<distance.length;i++)distance[i]=sc.nextFloat();System.out.println("输入油箱容量");v=sc.nextFloat();System.out.println("输入每公里的耗油量");vh=sc.nextFloat();vs=0;money=0;}public static void minpertrolfee(MinPertrolFee e) {float s=e.v/e.vh,s2;int j,l,k;for(int i=1;i<e.fee.length;i++){float vj=e.distance[i]/e.vh-e.vs;if(vj>0){e.money+=addpertrol(vj,i);e.vs+=vj;}float s1=0;for( j=i;j<e.fee.length&&s>=s1;j++)s1+=e.distance[j];for( l=i,k=i;l<(e.fee.length-1)&&l<=j;l++) {if(e.fee[k]>=e.fee[l+1])break;else continue;}if(l==j&&j!=e.distance.length)s2=e.v/e.vh;else s2=e.distance[l]-e.distance[i];float vj1=s2/e.vh-e.vs;if(vj1>0){e.money+=addpertrol(vj1,i);e.vs+=vj1;}e.vs-=e.distance[i]/e.vh;}System.out.println("所须要最少的钱为"+e.money); }public static float addpertrol(float vj,int i) {return vj*fee[i];}public static void main(String []args){MinPertrolFee e=new MinPertrolFee();minpertrolfee(e);}}结果:五、实验总结1.第二题算法是错的。

矩阵连乘算法

矩阵连乘算法

福州大学数学与计算机科学学院《计算机算法设计与分析》上机实验报告(2)i<=k<j,则:m[i][j]=m[i][k]+m[k+1][j]+pi-1pkpj。

由于在计算是并不知道断开点k 的位置,所以k还未定。

不过k的位置只有j-i个可能。

因此,k是这j-i个位置使计算量达到最小的那个位置。

综上,有递推关系如下:若将对应m[i][j]的断开位置k记为s[i][j],在计算出最优值m[i][j]后,可递归地由s[i][j]构造出相应的最优解。

s[i][j]中的数表明,计算矩阵链A[i:j]的最佳方式应在矩阵Ak和Ak+1之间断开,即最优的加括号方式应为(A[i:k])(A[k+1:j)。

从s[1][n]记录的信息可知计算A[1:n]的最优加括号方式为(A[1:s[1][n]])(A[s[1][n]+1:n]),进一步递推,A[1:s[1][n]]的最优加括号方式为(A[1:s[1][s[1][n]]])(A[s[1][s[1][n]]+1:s[1][s[1][n]]])。

同理可以确定A[s[1][n]+1:n]的最优加括号方式在s[s[1][n]+1][n]处断开...照此递推下去,最终可以确定A[1:n]的最优完全加括号方式,及构造出问题的一个最优解。

3、动态规划迭代算法设计:用动态规划迭代方式解决此问题,可依据其递归式自底向上的方式进行计算。

在计算过程中,保存已解决的子问题的答案。

每个子问题只计算一次,而在后面需要时只需简单检查一下,从而避免了大量的重复计算,最终得到多项式时间的算法。

4、算法代码:1. //3d1-2 矩阵连乘动态规划迭代实现2. //A1 30*35 A2 35*15 A3 15*5 A4 5*10 A5 10*20 A6 20*253. //p[0-6]={30,35,15,5,10,20,25}4. #include "stdafx.h"5. #include <iostream>6. using namespace std;7.8. const int L = 7;9.10. int MatrixChain(int n,int **m,int **s,int *p); 11. void Traceback(int i,int j,int **s);//构造最优解 12.13. int main()14. {15. int p[L]={30,35,15,5,10,20,25};16.17. int **s = new int *[L];18. int **m = new int *[L];19. for(int i=0;i<L;i++)20. {21. s[i] = new int[L];22. m[i] = new int[L];23. }24.25. cout<<"矩阵的最少计算次数为:"<<MatrixChain(6,m,s,p)<<endl;26. cout<<"矩阵最优计算次序为:"<<endl;27. Traceback(1,6,s);28. return 0;29. }30.31. int MatrixChain(int n,int **m,int **s,int *p) 32. {33. for(int i=1; i<=n; i++)34. {35. m[i][i] = 0;36. }37. for(int r=2; r<=n; r++) //r为当前计算的链长(子问题规模)38. {39. for(int i=1; i<=n-r+1; i++)//n-r+1为最后一个r链的前边界40. {41. int j = i+r-1;//计算前边界为r,链长为r的链的后边界42.43. m[i][j] = m[i+1][j] + p[i-1]*p[i]*p[j];//将链ij划分为A(i) * ( A[i+1:j] )44.45. s[i][j] = i;46.47. for(int k=i+1; k<j; k++)48. {49. //将链ij划分为( A[i:k] )* (A[k+1:j]) 50. int t = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];51. if(t<m[i][j])52. {53. m[i][j] = t;54. s[i][j] = k;55. }56. }57. }58. }59. return m[1][L-1];60. }61.62. void Traceback(int i,int j,int **s)63. {64. if(i==j) return;65. Traceback(i,s[i][j],s);66. Traceback(s[i][j]+1,j,s);67. cout<<"Multiply A"<<i<<","<<s[i][j];68. cout<<" and A"<<(s[i][j]+1)<<","<<j<<endl;69. }上述迭代算法的运行过程如下图所示:当R=2时,先迭代计算出: m[1:2]=m[1:1]+m[2:2}+p[0]*p[1]*p[2]; m[2:3]=m[2:2]+m[3:3]+p[1]*p[2]*p[3];。

实验一、矩阵连乘问题

实验一、矩阵连乘问题

实验一、矩阵连乘问题问题描述与实验目的:给定n个矩阵A1,A2,…,A n,其中,A i与A j+1是可乘的,i=1,2,…,n-l。

你的任务是要确定矩阵连乘的运算次序,使计算这n个矩阵的连乘积A1A2…A n时总的元素乘法次数达到最少。

例如:3个矩阵A1,A2,A3,阶分别为10×100、100×5、5×50,计算连乘积A1A2A3时按(A1A2)A3所需的元素乘法次数达到最少,为7500次。

输入测试数据有若干组,每组测试数据有2行。

每组测试数据的第1行是一个整数n,(0<n<20),第2行是n+1个正整数p、p 1、p2、…、pn,这些整数不超过100,相邻两个整数之间空一格,他们表示n个矩阵A1,A2,…,A n,的阶pi-1 pi,i=1,2,…,n。

输入直到文件结束。

输出对输入中的每组测试数据,输出2行。

先在一行上输出“Case #”,其中“#”是测试数据的组号(从1开始),再在第2行上输出计算这n个矩阵的连乘积A1A2…An时最少的总的元素乘法次数,再空一格,接着在同一行上输出矩阵连乘的添括号形式。

注意:最外层括号应去掉。

实验结果:输入样例310 100 5 50450 10 40 30 5输出样例Case 17500 (A1A2)A3Case 210500 A1(A2(A3A4))实验报告要求:1.先分析要点、写出动态方程2.提供能正确运行的程序。

要有一般性,即可同时处理若干组数据,每组2行。

3.设计、调试中的问题及实验体会。

矩阵连乘问题实验报告

矩阵连乘问题实验报告

一、实验目的通过本次实验,加深对动态规划算法的理解和应用,掌握解决矩阵连乘问题的方法,提高算法分析和设计能力。

二、实验原理矩阵连乘问题是指给定n个矩阵,每个矩阵都与它的前一个矩阵可乘,求计算这些矩阵连乘积的最优计算次序,以使计算过程中所需的数乘次数最少。

由于矩阵乘法满足结合律,因此可以通过加括号的方式确定不同的计算次序。

三、实验步骤1. 问题描述:给定n个矩阵A1, A2, ..., An,其中Ai与Ai-1是可乘的。

求计算矩阵连乘积A1A2...An的最优计算次序,使得计算过程中所需的数乘次数最少。

2. 输入数据:矩阵个数n,每个矩阵的规模。

3. 输出结果:计算矩阵连乘积的最优计算次序和最少数乘次数。

4. 算法设计:- 定义一个二维数组m[i][j],其中m[i][j]表示计算矩阵AiAi-1...Aj的最少数乘次数。

- 初始化m[i][i] = 0,因为单个矩阵无需计算。

- 对于每个子问题A[i:j],计算m[i][j]的最小值:- 遍历k从i到j-1,将问题分解为A[i:k]和Ak+1:j,计算m[i][k]和m[k+1][j]的和,并加上k个矩阵的维度乘积。

- 取上述和的最小值作为m[i][j]的值。

5. 递归关系:- 当i = j时,m[i][j] = 0。

- 当i < j时,m[i][j] = min(m[i][k] + m[k+1][j] + p[i-1]p[k]p[j]),其中k从i到j-1,p[i-1]表示矩阵Ai-1的行数,p[j]表示矩阵Aj的列数。

6. 自底向上计算:- 从m[1][1]开始,按照递归关系计算m[1][2],m[1][3],...,m[1][n]。

- 然后计算m[2][3],m[2][4],...,m[2][n],以此类推,直到计算m[1][n]。

7. 输出最优计算次序:- 从m[1][n]开始,根据递归关系和子问题的最优解,逐步确定每个子问题的最优计算次序,直到得到整个问题的最优计算次序。

矩阵连乘实验报告总结

矩阵连乘实验报告总结

一、实验背景与目的矩阵连乘问题是一个经典的算法问题,它涉及给定一系列矩阵,确定这些矩阵的最佳乘积顺序,以最小化乘法操作的次数。

本实验旨在通过动态规划算法解决矩阵连乘问题,加深对动态规划方法的理解,并提高算法分析与设计的能力。

二、实验内容与步骤1. 问题描述与理解:- 给定n个矩阵A1, A2, ..., An,其中任意两个相邻矩阵都是可乘的。

- 目标是确定计算这些矩阵连乘积的最佳顺序,以最小化所需的乘法次数。

2. 算法分析:- 使用动态规划方法,通过将问题分解为子问题并存储子问题的解来求解。

- 设定m[i, j]表示矩阵Ai到Aj的最佳乘积顺序的乘法次数。

3. 动态规划过程:- 初始化m[i, i] = 0,因为单个矩阵不需要乘法。

- 对于长度为k的矩阵序列,通过遍历所有可能的分割点,计算m[i, j]的最小值。

- 具体步骤包括:- 对于每个可能的k(1 ≤ k ≤ n-1),- 对于每个起始矩阵i(1 ≤ i ≤ n-k),- 计算m[i, i+k-1]和m[i+k, j],- 更新m[i, j]为m[i, i+k-1] + m[i+k, j] + p[i-1] p[i] p[i+k]。

4. 代码实现:- 使用C或Java等编程语言实现动态规划算法。

- 编写辅助函数来计算矩阵的乘法次数。

三、实验结果与分析1. 实验结果:- 通过实验,成功实现了矩阵连乘问题的动态规划算法。

- 得到了计算给定矩阵序列连乘积所需的最小乘法次数。

2. 结果分析:- 动态规划方法有效地解决了矩阵连乘问题,避免了穷举法的指数级时间复杂度。

- 通过分析子问题的解,我们可以找到整个问题的最优解。

四、实验总结与反思1. 实验收获:- 加深了对动态规划方法的理解,特别是如何通过子问题的解来构建整个问题的解。

- 学会了如何将实际问题转化为动态规划问题,并使用代码实现算法。

2. 反思与展望:- 实验过程中遇到了一些挑战,如理解子问题的定义和计算最优子结构的策略。

矩阵乘法实验报告总结

矩阵乘法实验报告总结

矩阵乘法是线性代数中一个基础且重要的运算,广泛应用于科学计算、数据分析和工程领域。

为了深入了解矩阵乘法的并行化实现,提高计算效率,本实验旨在通过MPI(Message Passing Interface)并行编程技术,实现矩阵乘法的并行计算,并分析其性能。

二、实验内容与方法1. 实验环境操作系统:Ubuntu Linux编译器:gcc并行计算平台:632核CPU、400GB内存的分布内存并行计算平台2. 实验方法(1)矩阵乘法算法本实验采用经典的矩阵乘法算法,即按行优先顺序进行计算。

具体步骤如下:① 将矩阵A、B、C划分为p个块,每个块包含m/p行和n/p列。

② 每个进程负责计算C的一个子块,即计算A的m/p行与B的n/p列的乘积。

③ 进程间通过MPI通信进行数据交换,实现并行计算。

(2)MPI编程本实验采用MPI编程实现矩阵乘法。

主要使用以下MPI语句:① MPI_Init:初始化MPI环境。

② MPI_Comm_size:获取进程总数。

③ MPI_Comm_rank:获取进程编号。

④ MPI_Send:发送数据。

⑤ MPI_Recv:接收数据。

⑥ MPI_Finalize:结束MPI环境。

1. 矩阵乘法结果验证通过比较串行计算和并行计算的结果,验证了程序的正确性。

2. 性能分析(1)执行时间在固定矩阵规模n=1000的情况下,分别测试进程数取1、2、4、8、16、32、64时的执行时间。

结果表明,随着进程数的增加,执行时间逐渐减少,且呈近似线性关系。

(2)加速比加速比是指并行计算时间与串行计算时间的比值。

本实验计算了不同进程数下的加速比,发现随着进程数的增加,加速比逐渐提高,且在进程数达到一定数量后,加速比趋于稳定。

(3)并行效率并行效率是指实际加速比与理论加速比之比。

本实验计算了不同进程数下的并行效率,发现随着进程数的增加,并行效率逐渐提高,但存在一个峰值,之后逐渐降低。

四、实验结论与展望1. 结论本实验通过MPI并行编程技术实现了矩阵乘法的并行计算,验证了程序的正确性。

矩阵连乘实验报告

矩阵连乘实验报告

程序设计报告、 我保证没有抄袭别人作业!1. 题目内容问题:n 个矩阵<A1, A2, ..., An>相乘,称为‘矩阵连乘’,如何求积?如何确定运算顺序,可以使计算量达到最小化。

2. 算法分析枚举显然不可,如果枚举的话,相当于一个“完全加括号问题”,次数为卡特兰数,卡特兰数指数增长,必然不行。

于是进过分析,采用动态规划算法: 1 找出最优解的性质,并刻划其结构特征。

2 递归地定义最优值。

3 以自底向上的方式计算出最优值。

4 根据计算最优值时得到的信息,构造最优解。

于是动态规划的思想可以描述如下:将矩阵连乘积j i i A A A ...1+,简记为[]j i :A ,这里j i <, i A 是i i p p 1⨯-的矩阵。

1、考察计算[]j i :A 的最优计算次序。

设这个计算次序在矩阵k A 和1+k A 之间将矩阵链断开,j k <<i ,则其相应完全加括号方式为()()j k k k i i A A A A A ......A 211+++。

2、计算量:[]k i :A 的计算量加上[]j k A :1+的计算量。

再加上[]k i :A 和[]j k A :1+相乘的计算量[][]j k i p p p j k m k i m j i 1],1[,,m -+++=。

3、问题:找到一个k ,使得],[m j i 最优。

4、矩阵连乘积计算次序问题的最优解包含着其子问题的最优解。

5、基于最优子结构,可以从子问题的最优解构造原问题的最优解矩阵连乘问题的任何最优解必包含其子问题的最优解。

于是将问题分为两个子问题AiAi+1… Ak and Ak+1Ak+2…Aj);求子问题的最优解;合并子问题的最优解。

6、根据子问题的最优解可以递归地定义原问题的最优解a. 子问题:确定矩阵连乘问题的子问题的形式为j i i A A ...A 1+,for 1≤i ≤j ≤n.b.设计算[]j i :A , 1≤i ≤n ,所需要的最少数乘数 ,乘次数],[m j i ,则原问题(计算A1..n )的最优值为]n ,[m i 。

矩阵运算实验报告

矩阵运算实验报告

矩阵运算实验报告实验目的:通过矩阵运算实验,探究矩阵的基本运算规则、性质及应用,并加深对矩阵运算的理解。

实验原理:矩阵是一个由元素按照行和列排列成的矩形阵列,可以进行加法、减法、乘法等基本的运算。

矩阵的加法与减法满足交换律、结合律和分配律;矩阵的乘法满足结合律、分配律和左乘右乘不一定相等的性质。

实验步骤:1. 实验前的准备:准备两个矩阵A和B,并确定其维度。

2. 进行矩阵加法运算:将矩阵A与矩阵B的对应元素相加,得到新的矩阵C。

3. 进行矩阵减法运算:将矩阵A与矩阵B的对应元素相减,得到新的矩阵D。

4. 进行矩阵乘法运算:将矩阵A的行元素与矩阵B的列元素对应相乘,并将结果相加,得到新的矩阵E。

5. 对矩阵进行转置:将矩阵A的行与列互换,得到新的矩阵F。

6. 求矩阵的逆:若矩阵A可逆,则找到矩阵A的逆矩阵G。

实验结果:1. 矩阵加法运算的结果:得到新的矩阵C,其维度与矩阵A和B相同,且C(i,j) = A(i,j) + B(i,j)。

2. 矩阵减法运算的结果:得到新的矩阵D,其维度与矩阵A和B相同,且D(i,j) = A(i,j) - B(i,j)。

3. 矩阵乘法运算的结果:得到新的矩阵E,其维度为A的行数乘以B的列数,且E(i,j) = Σ(A(i,k)*B(k,j)),k的取值范围为1到B的行数(或A的列数)。

4. 矩阵转置的结果:得到新的矩阵F,其维度与矩阵A相反,即F的行数等于A的列数,F的列数等于A的行数,且F(i,j) = A(j,i)。

5. 矩阵逆矩阵的结果:得到新的矩阵G,其与矩阵A的乘积为单位矩阵,即A*G = G*A = I,其中I为单位矩阵。

实验分析:1. 从矩阵加法与减法运算的结果可以看出,矩阵的加法和减法满足交换律、结合律和分配律。

这说明矩阵加法和减法具有良好的运算性质。

2. 从矩阵乘法运算的结果可以看出,矩阵的乘法满足结合律和分配律,但左乘右乘不一定相等,即AB≠BA。

矩阵连乘java实验报告

矩阵连乘java实验报告

矩阵连乘java实验报告1. 实验目的本实验通过使用Java编程实现矩阵的连乘运算,旨在让学生理解矩阵的乘法规则以及动态规划的思想,并掌握使用动态规划算法解决问题的方法。

2. 实验原理2.1 矩阵乘法规则两个矩阵相乘的规则如下:设A为m行n列的矩阵,B为n行p列的矩阵,其乘积C为m行p列的矩阵。

C的第i行第j列元素可以通过以下公式计算得到:C\[i][j] = A\[i]\[1] \* B\[1]\[j] + A\[i]\[2] \* B\[2]\[j] + ... + A\[i]\[n] \*B\[n]\[j]2.2 动态规划算法对于矩阵乘法问题,使用动态规划算法可以有效地解决。

动态规划算法的基本思想是将一个大问题划分为多个子问题,并记忆子问题的解,以避免重复计算。

在矩阵连乘问题中,我们可以定义一个二维数组dp,其中dp\[i]\[j]表示从第i 个矩阵乘到第j个矩阵的最小乘法次数。

通过不断更新dp数组的值,最终可以得到整个矩阵连乘的最小乘法次数。

3. 实验步骤3.1 构建矩阵类首先,我们需要构建一个矩阵类Matrix,用于表示和操作矩阵。

Matrix类应包含以下成员变量和方法:- 成员变量:- int rows:矩阵的行数- int cols:矩阵的列数- int[][] data:矩阵的数据存储- 方法:- Matrix(int rows, int cols):构造函数,创建一个指定行数和列数的空矩阵- void setValue(int row, int col, int value):设置矩阵指定位置的值- int getValue(int row, int col):获取矩阵指定位置的值- int getRows():获取矩阵的行数- int getCols():获取矩阵的列数- static Matrix multiply(Matrix a, Matrix b):静态方法,用于计算两个矩阵的乘积3.2 实现矩阵连乘算法在主程序中,我们先创建一个Matrix类型的数组来保存需要连乘的矩阵。

矩阵相乘问题实验报告

矩阵相乘问题实验报告

一、实验目的1. 理解矩阵相乘的基本原理。

2. 掌握矩阵相乘的算法实现。

3. 分析不同算法的效率差异。

4. 优化矩阵相乘算法,提高计算效率。

二、实验环境1. 操作系统:Windows 102. 编程语言:Python3. 库:NumPy三、实验原理矩阵相乘是线性代数中一个重要的运算,其基本原理如下:设矩阵A是一个m×n的矩阵,矩阵B是一个n×p的矩阵,则矩阵C=AB是一个m×p的矩阵。

矩阵C的第i行第j列的元素c_ij等于矩阵A的第i行与矩阵B的第j列对应元素的乘积之和。

即:c_ij = Σ(a_ij b_jk),其中i=1,2,...,m;j=1,2,...,p;k=1,2,...,n四、实验内容1. 实现矩阵相乘的基本算法。

2. 分析不同算法的效率差异。

3. 优化矩阵相乘算法,提高计算效率。

五、实验步骤1. 导入NumPy库。

```pythonimport numpy as np```2. 定义一个矩阵相乘的函数。

```pythondef matrix_multiply(A, B):m, n = A.shapep = B.shape[1]C = np.zeros((m, p))for i in range(m):for j in range(p):for k in range(n):C[i, j] += A[i, k] B[k, j] return C```3. 创建两个矩阵A和B。

```pythonA = np.array([[1, 2], [3, 4]])B = np.array([[5, 6], [7, 8]])```4. 调用矩阵相乘函数,计算C。

```pythonC = matrix_multiply(A, B)print("矩阵C:", C)```5. 分析不同算法的效率差异。

- 暴力算法:使用嵌套循环实现矩阵相乘,计算复杂度为O(mnp)。

矩阵相乘实验报告

矩阵相乘实验报告

一、实验目的1. 理解矩阵乘法的概念和运算规则。

2. 掌握C语言实现矩阵乘法的基本方法。

3. 学习并运用多线程技术优化矩阵乘法运算效率。

4. 熟悉Linux操作系统下多线程编程的使用。

二、实验环境1. 操作系统:Linux2. 编程语言:C语言3. 开发工具:GCC编译器三、实验内容1. 矩阵乘法原理矩阵乘法是指两个矩阵相乘的结果形成一个新的矩阵。

设矩阵A为m×k维,矩阵B为k×n维,则它们的乘积C为m×n维。

矩阵C中第i行、第j列的元素Ci,j等于矩阵A第i行元素与矩阵B第j列元素对应元素的乘积之和。

2. 矩阵乘法算法(1)单线程矩阵乘法单线程矩阵乘法是最基本的矩阵乘法算法,其核心思想是遍历矩阵A的每一行,同时遍历矩阵B的每一列,计算乘积之和。

具体步骤如下:① 初始化矩阵C为m×n维,将所有元素置为0。

② 遍历矩阵A的行i和矩阵B的列j,计算乘积之和C[i][j]。

③ 将计算得到的乘积之和C[i][j]赋值给矩阵C。

(2)多线程矩阵乘法多线程矩阵乘法利用多线程技术并行计算矩阵乘法,提高运算效率。

具体步骤如下:① 将矩阵A和矩阵B分割成若干个子矩阵,每个子矩阵由一个线程负责计算。

② 创建多个线程,每个线程分别计算一个子矩阵的乘积。

③ 等待所有线程计算完毕,将各个子矩阵的结果合并,得到最终的矩阵C。

3. 实验步骤(1)编写单线程矩阵乘法程序,实现矩阵乘法运算。

(2)编写多线程矩阵乘法程序,利用pthread库实现多线程编程。

(3)比较单线程和多线程矩阵乘法的运行时间,分析多线程优化效果。

四、实验结果与分析1. 实验数据实验中,我们选择两个4×4的矩阵A和B进行乘法运算,矩阵元素随机生成。

2. 实验结果(1)单线程矩阵乘法运行时间:约0.001秒(2)多线程矩阵乘法运行时间:约0.0008秒3. 分析通过实验结果可以看出,多线程矩阵乘法相较于单线程矩阵乘法,运行时间有显著提高。

指针矩阵相乘实验报告

指针矩阵相乘实验报告

一、实验目的1. 理解指针在C语言中的作用,掌握指针的使用方法。

2. 学习矩阵相乘的基本原理,并利用指针实现矩阵相乘。

3. 提高编程能力和问题解决能力。

二、实验内容本次实验主要实现了两个矩阵的相乘,要求使用指针操作完成。

假设两个矩阵分别为A和B,其中A为m×k矩阵,B为k×n矩阵,乘积矩阵C为m×n矩阵。

三、实验原理矩阵相乘的原理如下:C[i][j] = Σ(A[i][k] B[k][j]) (k从0到k-1)其中,C[i][j]表示乘积矩阵C的第i行第j列的元素,A[i][k]表示矩阵A的第i 行第k列的元素,B[k][j]表示矩阵B的第k行第j列的元素。

四、实验步骤1. 定义两个二维数组A和B,分别代表两个矩阵。

2. 定义一个二维数组C,用于存储乘积矩阵。

3. 使用指针遍历两个矩阵,并计算乘积矩阵C的元素。

4. 输出乘积矩阵C。

五、实验代码```c#include <stdio.h>#define M 3 // 矩阵A的行数#define N 3 // 矩阵B的列数#define K 3 // 矩阵A的列数和矩阵B的行数int main() {int A[M][K] = {{1, 2, 3},{4, 5, 6},{7, 8, 9}};int B[K][N] = {{9, 8, 7},{6, 5, 4},{3, 2, 1}};int C[M][N];// 计算乘积矩阵Cfor (int i = 0; i < M; i++) {for (int j = 0; j < N; j++) {for (int k = 0; k < K; k++) {(C + i N + j) += (A + i K + k) (B + k N + j); }}}// 输出乘积矩阵Cfor (int i = 0; i < M; i++) {for (int j = 0; j < N; j++) {printf("%d ", (C + i N + j));}printf("\n");}return 0;}```六、实验结果执行上述代码,输出乘积矩阵C为:```30 24 1884 69 54138 114 90```七、实验总结通过本次实验,我们掌握了指针在C语言中的使用方法,并成功实现了矩阵相乘。

04实验四动态规划矩阵连乘问题

04实验四动态规划矩阵连乘问题

04实验四动态规划矩阵连乘问题实验四动态规划矩阵连乘问题一、实验目的1、掌握动态规划算法的基本思想。

2、掌握设计动态规划算法的基本步骤。

3、掌握用动态规划算法求矩阵连乘问题。

二、实验环境Windows XP以上版本的操作系统,Visual Studio 2010编程环境。

三、实验内容【问题】:矩阵链乘问题:给定n个矩阵{A1,A2,...,An},其中Ai与Ai+1是可乘的,i=1,2...,n-1。

如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。

1、按设计动态规划算法的步骤解题。

(1)找出最优解的性质,并刻划其结构特征。

(2)递归地定义最优值。

(3)以自底向上的方式计算出最优值。

(4)根据计算最优值时得到的信息,构造最优解(由子结构的最优解得到原先大问题的最优解)。

2、求算法的时间复杂性,和空间复杂性3、体会动态规划和穷举法在解决该问题中的本质差异。

(1)问题的描述给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2,…,n-1。

要算出这n 个矩阵的连乘积A1A2…An。

由于矩阵乘法满足结合律,故计算矩阵的连乘积可以有许多不同的计算次序。

这种计算次序可以用加括号的方式来确定。

若一个矩阵连乘积的计算次序完全确定,也就是说该连乘积已完全加括号,则可以依此次序反复调用2个矩阵相乘的标准算法计算出矩阵连乘积。

完全加括号的矩阵连乘积可递归地定义为:(1)单个矩阵是完全加括号的;(2)矩阵连乘积A是完全加括号的,则A可表示为2个完全加括号的矩阵连乘积B和C的乘积并加括号,即A=(BC)。

例如,矩阵连乘积A1A2A3A4有5种不同的完全加括号的方式:(A1(A2(A3A4))),(A1((A2A3)A4)),((A1A2)(A3A4)),((A1(A2A3))A4),(((A1A2)A3)A4)。

每一种完全加括号的方式对应于一个矩阵连乘积的计算次序,这决定着作乘积所需要的计算量。

实验3-矩阵连乘

实验3-矩阵连乘

实验3 矩阵连乘一、 实验目的1. 理解动态规划的OS1和OS2原则OS1: Overlapping Subproblems; OS2: Optimal Substructure.2. 进一步理解先做证明、再做设计、最后写程序的算法设计过程对于矩阵连乘的效率提高问题,要求实验者按步骤给出从最初的思路到最终的程序,这一算法设计与实现过程。

3. 矩阵连乘动态规划算法的优化在格子设计、观察程序输出等的基础上,探讨提高矩阵连乘动态规划算法效率的技术。

二、 实验环境C/C++编程环境 或 任何编程语言环境三、 实验内容1. 矩阵连乘问题的描述输入:n 个矩阵12n A ,A ,...,A输出:×××12n A A ...A 所需要的最少乘法次数OptimalMC (按蛮力法计算矩阵m nA ×与n pB ×相乘所需标量乘法次数=m n p ××),并给出得到这个OptimalMC 的12n A ,A ,...,A 乘法次序。

若以二叉树形式表示乘法次序,对于234×××1A A A A ,一种乘法次序,如图1所示:图1 矩阵连乘的乘法次序示例上图表示()()234×××1A A A A2. 矩阵连乘问题的算法设计请实验者按下述步骤设计矩阵连乘问题的动态规划算法:2.1 写出求解OptimalMC 的递推式注意:应指出递推式中的哪些部分表示状态变量、哪些部分表示动作、哪些部分表示最优解。

并给出递推式的初始条件。

2.2 证明2.1中给出的递推式的正确性证明方法,可采用Copy & Paste 方法。

若递推式成立,则称递推式满足OS2: Optimal Substructure 原则。

2.3 格子设计依据递推式:1)画出二维内存单元格的计算规则若子问题(由单元格表示)之间存在重叠(即按计算规则,单元格中的数据存在依赖关系),则称本问题满足OS1: Overlapping Subproblems 。

矩阵式实验报告

矩阵式实验报告

一、实验目的1. 理解矩阵的基本概念和性质。

2. 掌握矩阵的运算方法,包括加法、减法、乘法等。

3. 学习矩阵的应用,如线性方程组的求解。

4. 提高数学建模和解决问题的能力。

二、实验内容本次实验主要围绕矩阵的运算和应用展开,具体内容包括:1. 矩阵的加法与减法2. 矩阵的乘法3. 矩阵的逆4. 线性方程组的求解三、实验步骤1. 矩阵的加法与减法(1)选择两个矩阵A和B,确保它们具有相同的行数和列数。

(2)将矩阵A和B对应位置的元素相加或相减,得到新的矩阵C。

(3)验证矩阵C的行数和列数与矩阵A和B相同。

2. 矩阵的乘法(1)选择两个矩阵A和B,确保矩阵A的列数等于矩阵B的行数。

(2)计算矩阵A的每一行与矩阵B的每一列的点积,得到新的矩阵C。

(3)验证矩阵C的行数等于矩阵A的行数,列数等于矩阵B的列数。

3. 矩阵的逆(1)选择一个可逆矩阵A。

(2)使用高斯-约当消元法求解矩阵A的逆。

(3)验证矩阵A与其逆矩阵的乘积为单位矩阵。

4. 线性方程组的求解(1)选择一个线性方程组,例如:AX = B,其中A是系数矩阵,X是未知数矩阵,B是常数矩阵。

(2)使用高斯-约当消元法求解线性方程组。

(3)验证求解得到的X矩阵是否满足原方程组。

四、实验结果与分析1. 矩阵的加法与减法通过实验,我们发现矩阵的加法与减法运算满足交换律和结合律,且结果矩阵的行数和列数与原矩阵相同。

2. 矩阵的乘法实验结果表明,矩阵的乘法运算满足交换律和结合律,且结果矩阵的行数等于第一个矩阵的行数,列数等于第二个矩阵的列数。

3. 矩阵的逆实验发现,对于可逆矩阵,其逆矩阵存在,且满足A A^(-1) = A^(-1) A = E(单位矩阵)。

4. 线性方程组的求解通过高斯-约当消元法,我们成功求解了线性方程组,并验证了求解结果的正确性。

五、实验结论1. 理解了矩阵的基本概念和性质,掌握了矩阵的运算方法。

2. 学会了使用矩阵求解线性方程组,提高了数学建模和解决问题的能力。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

华北电力大学科技学院
实验报告
实验名称矩阵连乘问题
课程名称计算机算法设计与分析
专业班级:软件12K1 学生姓名:吴旭
学号:************ 成绩:
指导老师:刘老师实验日期:2014.11.14
一、实验内容
矩阵连乘问题,给定n个矩阵{A1,A2,…,A n},其中A i与A i+1是可乘的,i=1,2,3…,n-1。

考察这n个矩阵的连乘A1,A2,…,A n。

二、主要思想
由于矩阵乘法满足结合律,故计算矩阵的连乘积可以有许多不同的计算次序。

这种计算次序可以用加括号的方式来确定。

若一个矩阵连乘积的计算次序完全确定,也就是说该连乘积已经完全加括号,则可依此次序反复调用2个矩阵相乘的标准算法计算出矩阵连乘积。

完全加括号的矩阵连乘积可递归的定义为:
(1)单个矩阵是完全加括号的;
(2)矩阵连乘积A是完全加括号的,则A可表示为2个完全加括号
的矩阵连乘积B和C的乘积并加括号,即A=(BC)。

运用动态规划法解矩阵连乘积的最优计算次序问题。

按以下几个步骤进行
1、分析最优解的结构
设计求解具体问题的动态规划算法的第1步是刻画该问题的最优解的结构特征。

为方便起见,将矩阵连乘积简记为A[i:j]。

考察计算A[1:n]的最优计算次序。

设这个计算次序矩阵在A k和A k+1之间将矩阵链断开,1≤k≤n,则其相应的完全加括号方式为((A1…A k)(A k+1…A n))。

依此次序,先计算A[1:k]和A[k+1:n],然后将计算结果相乘得到A[1:n]。

2、建立递归关系
设计动态规划算法的第二步是递归定义最优值。

对于矩阵连乘积的最优计算次序问题,设计算A[i:j],1≤i≤j≤n,所需的最少数乘次数为m[i][j],原问题的最优值为m[1][n]。

当i=j时,A[i:j]=A i为单一矩阵,无需计算,因此m[i][i]=0,i=1,2,…n。

当i<j时,可利用最优子结构性质来计算m[i][j]。

m[i][j]=m[i][k]+m[k+1][j]+p i-1p k p j。

由于在计算时并不知道断开点k的位置,所以k还未定。

3、计算最优值
根据计算m[i][j]的递归式,容易写一个递归算法计算m[1][n]。

动态规划法解决此问题,可依据递归式以自底向上的方式进行计算,在计算过程中保存已解决的子问题答案。

每个子问题只计算一次,而在后面需要时只要简单查一下,从而避免大量的重复计算,最终得到多项式时间的算法matrixChain。

(见实验代码部分)
4、构造最优解
算法matrixChain只计算出最优值,并没有给出最优解。

但是matrixChain已经记录了构造最优解所需的全部信息。

S[i][j]中的数表明,计算矩阵链A[i:j]的最佳方式应在矩阵A k和A k+1之间断开,最优加括号方式为(A[i:k])(A[k+1:j])。

依次构造最优解。

(算法见实验代码部分)
三、实验结果
四、结果验证
对实验结果进行验证,4个矩阵分别是A1[35*15],A2[15*5],A3[5*10],A4[10*20]。

依递归式有:
M[1][4]=min{0+2500+35×15×20=13000
2625+1000+35×5×20=7125
4375+0+35×10×20=11375
=7125
且k=3。

计算结果正确,证明所编写的程序可正确算出最优解。

五、实验代码
#include<stdio.h>
#define N 100//定义最大连乘的矩阵个数是100
void matrixChain(int p[],int m[N+1][N+1],int s[N+1][N+1])/*用m[i][j]二维数组来存储Ai*.....Aj的最少数乘次数,
用s[i][j]来存储使Ai.....Aj获得最少数乘次数对应的断开位置k,需要注意的是此处的N+1非常关键,虽然只用到的行列下标只从1到N,
但是下标0对应的元素默认也属于该数组,所以数组的长度就应该为N+1*/ {
int n=N;//定义m,s数组的都是n*n的,不用行列下标为0的元素,但包括在该数组中
for(int i=1;i<=n;i++)
m[i][i]=0;/*将矩阵m的对角线位置上元素全部置0,此时应是r=1的情况,表示先计算第一层对角线上个元素的值*/
for(int r=2;r<=n;r++)//r表示斜对角线的层数,从2取到n
{
for(int i=1;i<=n-r+1;i++)//i表示计算第r层斜对角线上第i行元素的值
{
int j=i+r-1;//j表示当斜对角线层数为r,行下标为i时的列下标
m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];//计算当断开位置为i时对应的数乘次数
s[i][j]=i;//断开位置为i
for (int k=i+1;k<j;k++)
{
int t=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];/*计算断开位置k为从i 到j(不包括i和j)的所有取值对应的
(Ai*.....*Ak)*(Ak+1*.....Aj)的数乘次数*/
if(t<m[i][j])
{
m[i][j]=t;//将Ai*....Aj的最少数乘次数存入m[i][j]
s[i][j]=k;//将对应的断开位置k存入s[i][j]
}
}
}
}
}
void traceback(int i,int j,int s[][N+1])//用递归来实现输出得到最小数乘次数的表达式
{
if(i==j)
{
printf("A%d",i);
}
else
{
printf("(");
traceback(i,s[i][j],s);
traceback(s[i][j]+1,j,s);
printf(")");
}
}
void main()
{
int n;//用来存储矩阵的个数
int q[2*N];/*用q数组来存储最原始的输入(各矩阵的行和列),主要目的是为了检验这N个矩阵是否满足连乘的条件*/
int p[N+1],flag=1;/*用p[i-1],p[i]数组来存储A的阶数,flag用来判断这N个矩阵是否满足连乘*/
int m[N+1][N+1];// 用m[i][j]二维数组来存储Ai*......Aj的最小数乘次数int s[N+1][N+1];// 用s[i][j]来存储使Ai......Aj获得最小数乘次数对应的断开位置k
printf("输入矩阵的个数(注:小于100):");
scanf("%d",&n);
for(int i=0;i<=2*n-1;i++)//各矩阵的阶数的输入先存入数组q中接受检验{
if(i%2==0)
{
printf("————————\n");
printf("*输入A%d的行:",(i/2)+1);
}
else
{
printf(" ********列:");
}
scanf("%d",&q[i]);
}
for(i=1;i<=2*n-2;i++)//矩阵连乘条件的检验{
if(i%2!=0&&q[i]!=q[i+1])
{
flag=0;
break;
}
}
for(int j=1;j<=n-1;j++)
{
p[j]=q[2*j];
}
if(flag!=0)
{
p[0]=q[0];
p[n]=q[2*n-1];
matrixChain(p,m,s);
printf("式子如下:\n");
traceback(1,n,s);
printf("\n");
printf("最少数乘次数为%d\n",m[1][n]);
}
else
{
printf("这%d个矩阵不能连乘!\n",n);
}
}
六、实验心得
通过本次实验,我较为透彻的理解了动态规划算法的几个基本步骤。

完成实验后,我认为建立递归关系是很关键的一步,同时也是整个动态规划算法的精髓。

掌握了递归的思想,就可以完成很多不必要的重复计算。

具体到矩阵连乘问题,关键是解决断开点k的位置和最少数乘次数。

总体来说,这次实验不仅让我基本掌握递归的思想,而且进一步提高了自己的自学能力和编程能力,代码运用C语言写出,可以很好的体会C语言和C++的不同点和相同点。

我也体会到,想要理解一个新的算法,必须要通过自己不断的编写程序,不断的思考才能真正的领悟,因此我会不断朝着这个方向努力。

相关文档
最新文档