矩阵连乘最优顺序Java语言实现 给定n个矩阵{A1, A2, …,An},其中,Ai与Ai+1是可乘的,计算这n个矩阵的连乘积。从中找出一种乘次数最少的计算次序
问题描述:
矩阵连乘问题 给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2 ,…,n-1。如何确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少
import org.omg.CORBA.PUBLIC_MEMBER; public class MatrixMultiply { static int MN; //表示矩阵链中矩阵的数目 static int[]p; //存放各个矩阵的维数 static int [][][]A;//存放要进行连乘的多个矩阵 static int [][]m; //用来存放Ai到Aj的最少乘次数 static int [][]s; //用来存放Ai到Aj的最后断开位置 //构造函数 public MatrixMultiply() { MN=0; p=new int [MN]; } //构造函数,L为矩阵的数目 public MatrixMultiply(int L) { MN=L; p=new int [MN+1]; A=new int [MN][][]; m=new int [MN+1][MN+1]; s=new int [MN+1][MN+1]; //随机生成连乘矩阵的维数[1-11] for(int i=0;i<=MN;i++) { p[i]=(int) Math.round(Math.random()*10)+1; } //随机生成各个矩阵 for(int i=0;i<MN;i++) { A[i]=new int [p[i]][p[i+1]]; CreatMatrix(A[i],p[i],p[i+1]); } } //创建矩阵a,维数为m*n 随机数填充数组内容 public void CreatMatrix(int[][] a, int m, int n) { // TODO Auto-generated method stub for(int i=0;i<m;i++) for(int j=0;j<n;j++) a[i][j]=(int) Math.round(Math.random()*50)-10; } //输出连乘的所有矩阵 public void printAllM() { for (int i=0;i<this.MN;i++) { System.out.println("A"+(i+1)+": "+A[i].length +"*"+A[i][0].length ); printM(A[i]); } } //输出单个矩阵的值 public void printM(int[][] a) { // TODO Auto-generated method stub for(int i=0;i<a.length;i++) { System.out.print(" "); for(int j=0;j<a[i].length;j++) System.out.print(" "+a[i][j]); System.out.println(); } } public static void main(String[]args) { //构造函数分配内存空间 MatrixMultiply M=new MatrixMultiply(7); M.printAllM(); M.matrixChain(M.p,M.m,M.s); System.out.print("矩阵链所需的最少乘次数为:"+M.m[1][M.MN]); System.out.println(); String []s=new String[M.MN+1]; for(int i=1;i<=M.MN;i++) { s[i]="A"+i; } M.traceback(M.s,1,M.MN,s); System.out.print("矩阵连乘最优连乘顺序:"); for(int i=1;i<=M.MN;i++) { System.out.print(s[i]); } } public void traceback(int[][] s, int i, int j, String[] c) { // TODO Auto-generated method stub if(i==j)return; traceback(s,i,s[i][j],c); traceback(s,s[i][j]+1,j,c); c[i]="("+c[i]; c[j]=c[j]+")"; System.out.println("矩阵连乘 A"+i+","+s[i][j]+"和 A"+(s[i][j]+1)+","+j); } //作用:计算矩阵连乘时,矩阵链的最少乘次数 private void matrixChain(int[] p, int[][] m, int[][] s) { // TODO Auto-generated method stub int n=p.length-1;//矩阵链长度为1,不需要进行乘运算,即m[i][i]值为0 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; } } } } }