您的位置:首页 > 其它

动态规划:矩阵连乘问题

2017-04-11 15:09 267 查看

问题描述

给定n个矩阵{A1,A2,A3,⋯,An}, 其中Ai与Ai+1是可乘的, i = 1, 2, ⋯ , n-1.考察这n个矩阵的连乘积A1A2,⋯,An.由于矩阵乘法满足结合律,所以计算矩阵的连乘积可有多种不同的计算次序,而不同的计算次序有不同的计算量。设计算法求得多个矩阵连乘时的最小计算量。

解决方案

分析最优解的性质 (thinking top-dwon)

为方便起见,将矩阵连乘积AiAi+1⋯Aj简记为A[i:j]。考察计算A[1:n]的最优计算次序。设这个计算次序在矩阵Ak和Ak+1之间将矩阵链断开, 1 <= k < n, 则其相应的完全加括号方式为((A1⋯AK)(Ak+1⋯An))。依此次序,先计算A[1:k]和A[k+1:n],然后将计算结果相乘得到A[1:n],依此计算顺序总计算量为A[1:k]的计算量加上A[k+1:n]的计算量,再加上A[1:k]和A[k+1:n]相乘的计算量。

关键特征:计算A[1:n]的最优次序所包含的计算矩阵子链A[1:k]和A[k+1:n]的次序也是最优的。即满足最优子结构性质。

建立递归关系

对于矩阵连乘积的最优计算次序问题,设计算A[i:j],1<=i<=j<=n,所需的最少数乘次数为m[i][j],则原问题的最优值为m[1]
。可以将m[i][j]递归的定义为

m[i][j]={0min{m[i][k]+m[k+1][j]+Pi−1PkPj}i = ji < j且i<=k<j

m[i][j]给出了最优值,即计算A[i:j]所需最少数乘次数。同时还确定了计算A[i:j]的最优次序中的断开位置k,也就是说,对于这个k有

m[i][j]=m[i][k]+m[k+1][j]+Pi−1PkPj

若将对应于m[i][j]的断开位置k记为s[i][j],在计算出最优值m[i][j]后,可递归地由s[i][j]构造出相应的最优解。

计算最优值(solving bottom-up)

由于该问题满足子问题重叠的性质,如果采用递归方式求解,将大量重复计算,因此需要自底向上进行求解。在计算过程中,保存已解决的子问题答案。每个子问题只计算一次,而在后面需要时只要简单查一下,从而避免大量重复计算,最终得到多项式时间的算法。用数组p表示矩阵的维数,用二维数组m来保存最优解,用二维数组s记录最优断开位置k。

构造最优解

上面给出了计算最优解的递推式,可以通过查表m[1]
即可得到最优值。如果需要构造最优解,需要利用二维数组s中保存的信息,即矩阵链断开的位置。具体算法在下面的Traceback函数中给出。

实现代码

/*
**动态规划——矩阵连乘
*/
#include <stdio.h>
#include <stdlib.h>

#define n 7

void MartixChain(int p[], int m[]
, int s[]
);
void Traceback(int i, int j, int s[]
);

int main()
{
int p
= {30, 35, 15, 5, 10, 20, 25};
int m

;
int s

;
MartixChain(p, m, s);
Traceback(1, 6, s);
return 0;
}

void MartixChain(int p[], int m[]
, int s[]
)
{ //计算最优值
int i, r, j, k;
for (i = 1; i <= n - 1; i++)
m[i][i] = 0;
for (r = 2; r <= n - 1; r++)
{
for (i = 1; i <= n - r; i++)
{
j = i + r - 1;
m[i][j] = m[i + 1][j] + p[i - 1] * p[i] * p[j];     //k=i
s[i][j] = i;
for (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;
}
}
}
}
}

void Traceback(int i, int j, int s[]
)
{ //构造最优解
if (i == j)
return;
Traceback(i, s[i][j], s);
Traceback(s[i][j] + 1, j, s);
printf("Multiply A %d, %d", i, s[i][j]);
printf("and A %d, %d\n", s[i][j] + 1, j);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: