矩阵链乘最优化实现

矩阵链乘最优化算法(括号化算法),关键要找到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

时间: 2024-10-05 18:55:10

矩阵链乘最优化实现的相关文章

矩阵链乘(Matrix Chain Multiplication)

输入n个矩阵的维度和一些矩阵链乘表达式,输出乘法的次数.如果乘法无法进行,则输出error.假定A是m*n矩阵,B是n*p矩阵,那么A*B是m*p矩阵,乘法次数为m*n*p.如果A的列数不等于B的行数,则乘法无法进行. 例如,A是50*10的,B是10*20的,C是20*5的,则(A(BC))的乘法次数为10*20*5(BC的乘法次数) +50*10*5(A(BC)的乘法次数) = 3500. #include<cstdio> #include<stack> #include<

矩阵链乘

矩阵链乘之结构体构造函数 struct构造函数,和构造函数的重载函数长这个样子,和C++的构造函数差不过. struct Dog { Dog() { name = "wangwang"; age = 10; } string name; int age; }; struct Dog { Dog() { name = "Ao di"; age = 2; } Dog(string n) { name = n; age = 10; } Car(string n, int

POJ 0016 20603矩阵链乘

传送门:http://oj.cnuschool.org.cn/oj/home/solution.htm?solutionID=35454 20603矩阵链乘 难度级别:B: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 输入n个矩阵的维度和一些矩阵链乘的表达式,输出乘法的次数.如果乘法无法进行,输出error.假定A是m*n矩阵,B是n*p矩阵,则乘法的次数为m*n*p.如果矩阵A的列数不等于矩阵B的行数,则这两个矩阵无法进行乘法运算.例

动态规划之矩阵链

dp有很多个经典应用,矩阵链是其中一个. 对于我这种数学不好的人,需要回顾矩阵性质. 若矩阵A的维数是p×q,矩阵B的维数是q×r,则A与B相乘后所得矩阵AB的维数是p×r.按照矩阵相乘的定义,求出矩阵AB中的一个元素需要做q次乘法(及q-1次加法).这样,要计算出AB就需要做p×q×r次乘法.由于加法比同样数量的乘法所用时间要少得多,故不考虑加法的计算量. 看下面一个例子,计算三个矩阵连乘{A1,A2,A3}:维数分别为10*100 , 100*5 , 5*50 按此顺序计算需要的次数((A1

UVa 442 矩阵链乘及scanf说明符中的\n

题目:计算题给矩阵相乘次序所需的相乘次数.   我们已知的m*n和n*k矩阵相乘,得到的是m*k矩阵,但需要的相乘次数是m*n*k(开始当成了m*k %>_<%).evaluate,求值 思路:每个矩阵用结构体表示,有名字.行.列.需要计算的次数.矩阵相乘的过程用栈来模拟.遇到左括号(,压栈这是自然的.遇到一个矩阵时,检查栈顶,如果栈顶元素是左括号,则压栈,否则就是矩阵,则比较栈顶矩阵和输入矩阵是否匹配,如果匹配则修改栈顶矩阵的列.计算次数,这样输入矩阵对栈顶进行了修改,相当于完成了相乘,这时

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

一.矩阵乘法 1 struct datatype 2 { 3 int a[2][2]; 4 }; 5 datatype multiple(datatype x,datatype y) 6 { 7 datatype res; 8 memset(res.a,0,sizeof(res.a)); 9 for(int i=0;i<=1;i++) 10 { 11 for(int j=0;j<=1;j++) 12 { 13 for(int k=0;k<=1;k++) 14 { 15 res.a[i][

矩阵链相乘问题

问题描述 给定n个矩阵A1,A2 ,...,An,相邻的矩阵是可乘的,如何确定一个最优计算次序,使得以此次序计算需要的数乘次数最少? 计算次序对计算性能的影响: 假设n=3,A1,A2,A3的维数分别为10×100,100×5,5×50.考察A1×A2×A3需要的数乘次数,有以下 两种计算方式: (1)(A1×A2)×A3:10×100×5+10×5×50=7500 (2) A1×(A2×A3):100×5×50+10×100×50=75000 通过这个简单的例子足以说明,矩阵的计算次序对计算性

算法13---动态规划矩阵链乘法

算法13---动态规划矩阵链乘法 矩阵链乘法是动态规划里面使用到的一个例子 1 两个矩阵的计算 那么对于一个矩阵的乘法,首先如果是两个矩阵的乘法,那么如何实现呢? 注意到我们使用二维数组表示矩阵,但是二维数组不能作为函数的返回值.具体实现如下 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <math.h> 4 5 #define a_rows 3 6 #define a_columns 4 7 #define

动态规划-矩阵链乘法

问题描述: 给定由n个要相乘的矩阵构成的序列(链)<A1,A2,...,An>,要计算乘积A1A2...An,可以将两个矩阵相乘的标准算法作为一个子程序,通过加括号确定计算的顺序(对同一矩阵链,不同的计算顺序所需要的计算次数大不相同). 目标问题:给定n个矩阵构成的矩阵链<A1,A2,...,An>,其中,i=1,2,...,n,矩阵Ai的维数为pi-1×pi,对乘积A1A2...An以一种最小计算次数加全部括号. 穷尽搜索: 令P(n)表示一串n个矩阵可能的加全部方案数.当n=1