- 问题
设A1,A2•••An为n个矩阵的序列,其中Ai为Pi-1*Pi阶矩阵,这个矩阵链的输入用向量P=<P0,P1,•••Pn>给出;给定向量P,确定一种乘法次序,使得基本运算的总次数达到最小。
例如:P=<10,100,5,50> 则A1:10×100 A2:100×5 A3:5×50
(1)(A1 A2)A3=10×100×5+10×5×50=7500
(2)A1(A2A3):10×100×50+100×5×50=75000
2. 解析
1)最优加全部括号的结构
动态规划第一步是寻找一个最优的子结构。假设现在要计算AiAi+1…Aj的值,计算Ai…j过程当中肯定会存在某个k值(i<=k<j)将Ai…j分成两部分,使得Ai…j的计算量最小。分成两个子问题Ai…k和Ak+1…j,需要继续递归寻找这两个子问题的最优解。
有分析可以到最优子结构为:假设AiAi+1…Aj的一个最优加全括号把乘积在Ak和Ak+1之间分开,则Ai…k和Ak+1…j也都是最优加全括号的。
2)一个递归解
设m[i,j]为计算机矩阵Ai…j所需的标量乘法运算次数的最小值,对此计算A1…n的最小代价就是m[1,n]。现在需要来递归定义m[i,j],分两种情况进行讨论如下:
当i==j时:m[i,j] = 0,(此时只包含一个矩阵)
当i<j 时:从步骤1中需要寻找一个k(i≤k<j)值,使得m[i,j] =min{m[i,k]+m[k+1,j]+pi-1pkpj} (i≤k<j)。
3)计算最优代价
虽然给出了递归解的过程,但是在实现的时候不采用递归实现,而是借助辅助空间,使用自底向上的表格进行实现。设矩阵Ai的维数为pi-1pi,i=1,2…n。输入序列为:p=<p0,p1,…pn>,length[p] = n+1。使用m[n][n]保存m[i,j]的代价,s[n][n]保存计算m[i,j]时取得最优代价处k的值,最后可以用s中的记录构造一个最优解
3. 设计
MAXTRIX_CHAIN_ORDER§
n = length[p]-1;
for i=1 to n
do m[i][i] = 0;
for t = 2 to n //t is the chain length
do for i=1 to n-t+1
j=i+t-1;
m[i][j] = MAXLIMIT;
for k=i to j-1
q = m[i][k] + m[k+1][i] + qi-1qkqj;
if q < m[i][j]
then m[i][j] = q;
s[i][j] = k;
return m and s;
4. 分析
MATRIX_CHAIN_ORDER具有循环嵌套,深度为3层,运行时间为O(n3)。如果采用递归进行实现,则需要指数级时间Ω(2n)
5. 源码
https://github.com/FPhoenixtree/-/blob/main/%E7%AE%97%E6%B3%95%E5%88%86%E6%9E%90%E4%B8%8E%E8%AE%BE%E8%AE%A1%E7%AC%AC%E5%85%AB%E6%AC%A1%E4%BD%9C%E4%B8%9A.cpp