矩阵链乘最优化实现

Posted Y_SL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了矩阵链乘最优化实现相关的知识,希望对你有一定的参考价值。

矩阵链乘最优化算法(括号化算法),关键要找到A[i]...A[j]矩阵链相乘做最少乘法次数(存在m[][]中)的相乘顺序,记录在矩阵s[][]中。再利用递归定义矩阵链乘算法。递归的出口是只有一个矩阵(直接返回)或者两个矩阵(返回相乘后的结果矩阵)的情况。
  1 //#include"OptimalMatrixMultiplication.h"
  2 #include<iostream.h>
  3 #include<stdio.h>
  4 #include<stdlib.h>
  5 #include<memory.h>
  6 #include<fstream.h>
  7 
  8 //using namespace std;
  9 
 10 #define N 6  //N Matrices
 11 #define MAX 15 // Biggest number of elements in row/column of matrices
 12 typedef long (*Mat)[MAX];       ////////////!!! define a 2dim array pointer
 13 int num;
 14 Mat pp[N]; // To store the result matrix of any two matrices\' multiplication
 15 long A[N+1][MAX][MAX]; // store matrices to be calculated, A[0] is not used !!!
 16 
 17 //find m[][] and s[][]
 18 void Matrix_Chain_Order(int *p,int m[N+1][N+1],int s[N+1][N+1])
 19 {
 20     for (int i=1;i<=N;i++)
 21     {
 22         m[i][i] = 0;
 23     }
 24     for(int L=2;L<=N;L++)
 25     {
 26         for(i=1;i<=N-L+1;i++)
 27         {
 28             int j = i+L-1;
 29             m[i][j] = (1<<30);            ////m[i][j] can\'t be bigger than 2^31-1  !!!
 30             for(int k=i;k<j;k++)        /// There is no " ^ " symbol in C/C++ language  !!!
 31             {                            //////////// pow(x,y) -> x^y
 32                 int q = m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
 33                 if(q<m[i][j])
 34                 {
 35                     m[i][j] = q;
 36                     s[i][j] = k;
 37                 }
 38             }
 39         }
 40     }
 41     
 42 }
 43 
 44 //print the multiplication order
 45 void Print_OptimalParens(int s[N+1][N+1],int i,int j)
 46 {
 47     if(i == j)
 48     {
 49         cout<<"A"<<i;    
 50     }
 51     else
 52     {
 53         cout<<"(";
 54         Print_OptimalParens(s,i,s[i][j]);
 55         Print_OptimalParens(s,s[i][j]+1,j);
 56         cout<<")";
 57     }
 58 }
 59 
 60 // To generate matrices, all matrices have "the same" size
 61 void Init_Matrix(long A[][MAX][MAX],int *p)
 62 {    
 63     //read metrix data from file "MetrixData" generated by rand();
 64     ifstream fin("MetrixData.txt");
 65     //vector<int> vec;
 66     long idata;
 67     fin>>idata;
 68     for(int i=1;i<=N;i++)
 69     {
 70         for(int j=0;j<p[i-1];j++) //matrices have different size!
 71         {
 72             for(int k=0;k<p[i];k++)
 73             {                
 74                 A[i][j][k] = idata;
 75                 fin>>idata;    
 76             }
 77         }
 78     }
 79 }
 80 
 81 Mat Matrix_Multiplication(Mat a,Mat b,Mat c)
 82 {
 83     for(int i=0;i<MAX;i++)
 84     {    
 85         for(int j=0;j<MAX;j++)
 86         {
 87             for(int k=0;k<MAX;k++)
 88             {
 89                 c[i][j]+=a[i][k]*b[k][j];
 90             }
 91         }
 92     }
 93     return c;
 94 }
 95 
 96 Mat Matrix_Chain_Multiplication(int i,int j,int s[N+1][N+1])
 97 {
 98     if(i == j)
 99     {
100         return A[i];
101     }
102     else if(i+1 == j)
103     {
104         pp[num] = (Mat)malloc(MAX*MAX*sizeof(long));
105         if(pp[num] == NULL)
106         {
107             cout<<"Can\'t allocate memory!";
108             exit(1);
109         }
110         memset(pp[num],0,MAX*MAX*sizeof(long));
111         return Matrix_Multiplication(A[i],A[j],pp[num ++]);    
112         // num ++; // This line can\'t be excuted !!!
113     }
114     else
115     {    
116         Mat l_Mat = Matrix_Chain_Multiplication(i,s[i][j],s);
117         Mat r_Mat = Matrix_Chain_Multiplication(s[i][j]+1,j,s);
118         
119         pp[num] = (Mat)malloc(MAX*MAX*sizeof(long));
120         if(pp[num] == NULL)
121         {
122             cout<<"Can\'t allocate memory!";
123             exit(1);
124         }
125         memset(pp[num],0,MAX*MAX*sizeof(long));
126         
127         return Matrix_Multiplication(l_Mat,r_Mat,pp[num ++]);
128     }
129 }
130 
131 //print 2_Dim array
132 void Print_Array(long b[][MAX])
133 {
134     for(int i=0;i<MAX;i++)
135     {    
136         for(int j=0;j<MAX;j++)
137         {
138             cout<<b[i][j]<<" ";
139         }
140         cout<<endl;
141     }
142 }
143 
144 void main()
145 {
146     int m[N+1][N+1];
147     int s[N+1][N+1];
148     int p[N+1]={10,8,5,7,6,12,9}; //store the size of matrices
149     Matrix_Chain_Order(p,m,s);
150         
151     // print m[][]
152     for(int i=1;i<=N;i++)
153     {
154         for(int j=i+1;j<=N;j++)
155         {
156             cout<<" m["<<i<<"]["<<j<<"]: "<<m[i][j];
157         }
158         cout<<endl;
159     }
160     //print s[][]
161     for(i=1;i<=N;i++)
162     {
163         for(int j=i+1;j<=N;j++)
164         {
165             cout<<" s["<<i<<"]["<<j<<"]: "<<s[i][j];
166         }
167         cout<<endl;
168     }
169 
170     Print_OptimalParens(s,1,6);
171     cout<<endl;
172 
173     Init_Matrix(A,p);
174     //Print_Array(A[1]);
175     Matrix_Chain_Multiplication(1,6,s);
176     Print_Array(pp[--num]);
177     
178     for(i=0;i<=num;i++)
179     {
180         free(pp[i]);
181     }
182     
183 }
OptimalMatrixMultiplication.cpp

 

以上是关于矩阵链乘最优化实现的主要内容,如果未能解决你的问题,请参考以下文章

最优矩阵链乘

矩阵乘法及矩阵链乘的快速幂优化

dp-最优矩阵链乘

矩阵链乘(解析表达式)

矩阵链乘

动态规划—矩阵链乘法