1.问题描述
对n个矩阵进行矩阵乘法运算,矩阵乘法满足结合律,对于不同的结合方法,得到的乘法次数不同,求n个矩阵进行矩阵乘法时的最少乘法次数。
例:有三个矩阵A、B、C,其中A(2×30),B(30×2),C(2×1)
如果按照(AB)C计算,则乘法次数为2×30×2+2×2×1=120+4=124
如果按照A(BC)计算,则乘法次数为30×2×1+2×30×1=60+60=120
2.问题解决
我们用一个大小为n+1的一维数组data记录n个矩阵的大小。上面给出的例子中,有3个矩阵,则data的大小为4,内容为2,30,2,1。
(1)对于Mi×M(i+1)只有一种结合方式,因此乘法次数是唯一的,我们记录在一个二维数组cost中,cost[ i ][ i+1 ]表示Mi×M(i+1)的花销。
(2)对于M(i-1)×Mi×M(i+1)有两种结合方式。
① 当计算顺序为( M(i-1)×Mi )×M(i+1)时,花销为计算M(i-1)×Mi的花销加M(i+1)的花销(0)加计算最终等式的开销,即
cost[ i-1 ][ i ]+data[i-1]×data[i]×data[i+1]+cost[i+1][i+1];
② 当计算顺序为M(i-1)×( Mi×M(i+1) )时,花销为
cost[i-1][i-1]+data[i-1]×data[i]×data[i+1]+cost[i][i+1]
我们选择两种结合方式中花销较小的一个存入cost[i-1][i+1]中。
(3)对于四个矩阵的式子,比如M1×M2×M3×M4
结合方式有M1×(M2×M3×M4)、(M1×M2)×(M3×M4)、(M1×M2×M3)×M4三种
(有读者可能疑问比如M1×((M2×M3)×M4))这种结合方式呢,其实这种方式已经包含在了上面给出的第一种结合方式里了,其他结合方式也是类似。)
到这里,我们就很容易写出递推关系式了
cost[ i ][ j ]=min
{ cost[ i ][ k ]+cost[ k+1 ][ j ]+data[ i -1]×data[ k ]×data[ j ] } 其中i≤k<j。
初始条件为cost[ i ][ i ]=0。
3.代码实现
int minMatrix(vectr<int>& data)
{
int len=data.size();//len=矩阵个数+1
vector<vector<int>> cost(len,vector<int>(len));
//初始化cost数组
for(int i=0;i<len;i++)
{
cost[0][i]=0;
cost[i][0]=0;
cost[i][i]=0;
}
//计算cost数组
for(int k=1;k<len;k++)
{
for(int i=1;i<len;i++)
{
int j=i+k;
if(j<len)
{
int min=cost[i][i]+cost[i+1][j]+data[i-1]*data[i]*data[j];
for(int m=i+1;m<j;m++)
{
if(min>cost[i][m]+cost[m+1][j]+data[i-1]*data[m]*data[j])
min=cost[i][m]+cost[m+1][j]+data[i-1]*data[m]*data[j];
}
cost[i][j]=min;
}
}
}
return cost[1][len-1];
}
4.时间复杂度
程序中有三层循环嵌套,因此时间复杂度为O(n^3)。