算法导论—矩阵链乘法(动态规划)
Posted 之墨_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法导论—矩阵链乘法(动态规划)相关的知识,希望对你有一定的参考价值。
算法导论—矩阵链乘法(动态规划)
矩阵链乘法
矩阵相乘
矩阵相乘的括号化方案
设有四个矩阵
A
、
B
、
C
、
D
A、B、C、D
A、B、C、D,它们的维数分别是:
A
=
50
∗
10
、
B
=
10
∗
40
、
C
=
40
∗
30
、
D
=
30
∗
5
A=50*10、B=10*40、C=40*30、D=30*5
A=50∗10、B=10∗40、C=40∗30、D=30∗5总共有五种完全加括号的方式,如下:
(
A
(
(
B
C
)
D
)
)
、
(
A
(
B
(
C
D
)
)
)
、
(
(
A
B
)
(
C
D
)
)
、
(
(
(
A
B
)
C
)
D
)
、
(
(
A
(
B
C
)
)
D
)
.
(A((BC)D))、(A(B(CD)))、\\\\((AB)(CD))、(((AB)C)D)、((A(BC))D).
(A((BC)D))、(A(B(CD)))、((AB)(CD))、(((AB)C)D)、((A(BC))D).
不同计算代价
应用动态规划方法的步骤
- 刻划一个最优解的结构特征;
- 递归地定义最优解的值;
- 计算最优解的值,通常采用自底向上的方法;
- 利用计算出的信息构造一个最优解。
按照步骤分析问题
步骤
1
1
1:最优括号化方案的结构特征
我们用符号
A
i
⋅
j
(
i
<
=
j
)
Ai·j (i<=j)
Ai⋅j(i<=j)表示
A
i
A
i
+
1
⋅
⋅
⋅
A
j
AiAi+1···Aj
AiAi+1⋅⋅⋅Aj乘积的结果矩阵,如果问题是非凡的,即
i
<
j
i<j
i<j,那么为了对
A
i
A
i
+
1
⋅
⋅
⋅
A
j
AiAi+1···Aj
AiAi+1⋅⋅⋅Aj进行括号化,我们就必须在某个
A
k
Ak
Ak 和
A
k
+
1
Ak+1
Ak+1之间将矩阵链划分开(
k
k
k为
i
≤
k
<
j
i\\le k<j
i≤k<j之间的整数),也就是说我们首先计算矩阵
A
i
⋅
⋅
⋅
k
Ai···k
Ai⋅⋅⋅k和
A
k
+
1
⋅
⋅
⋅
j
Ak+1···j
Ak+1⋅⋅⋅j,然后再计算他们的乘积得到最终结果
A
i
⋅
⋅
⋅
j
Ai···j
Ai⋅⋅⋅j。现在问题就变成了对矩阵
A
i
⋅
⋅
⋅
k
Ai···k
Ai⋅⋅⋅k和
A
k
+
1
⋅
⋅
⋅
j
Ak+1···j
Ak+1⋅⋅⋅j进行独立求解,并且要满足最优括号化方案,最后将子问题的最优解合并就可以得到问题的最优解。
步骤
2
2
2:一个递归求解方案
令
m
[
i
,
j
]
m[i,j]
m[i,j]表示计算矩阵
A
i
⋅
⋅
⋅
j
Ai···j
Ai⋅⋅⋅j数乘次数的最小值,那么原问题的最优解——计算
A
1
⋅
⋅
⋅
n
A_1···n
A1⋅⋅⋅n所需的最低代价就是
m
[
1
,
n
]
m[1,n]
m[1,n]。
i
=
j
i=j
i=j时不需要做任何标量乘法运算,所以
m
[
i
,
i
]
=
0
m[i,i]=0
m[i,i]=0。若
i
<
j
i<j
i<j,利用步骤
1
1
1中得到的最优子结构来计算
m
[
i
,
j
]
m[i,j]
m[i,j]。设矩阵Ai···j 的大小为pi-1×pi ,那么
A
i
⋅
⋅
⋅
k
A_i···k
Ai⋅⋅⋅k和
A
k
+
1
⋅
⋅
⋅
j
A_k+1···j
Ak+1⋅⋅⋅j相乘的代价为
p
i
−
1
∗
p
k
∗
p
j
p_i-1*p_k*p_j
pi−1∗pk∗pj。因此可得.
m
[
i
,
j
]
=
m
[
i
,
k
]
+
m
[
k
+
1
,
j
]
+
p
i
−
1
p
k
p
j
.
m[i,j] = m[i,k]+ m[k+1,j]+p_i-1 p_kp_j.
m[i,j]=m[i,k]+m[k+1,j]+pi−1pkpj.
此递归公式假定最优分割点
k
k
k是已知的,但实际上我们并不知道。不过,
k
k
k只有
j
−
i
j-i
j−i种可能的取值,即
k
=
i
,
i
+
1
,
⋅
⋅
⋅
,
j
−
1
k=i,i+1,···,j-1
k=i,i+1,⋅⋅⋅,j−1.由于最优分割点必其中,我们只需要检查所有可能的情况,推到最优者即可。因此,
A
i
A
i
+
1
⋅
⋅
⋅
A
j
A_iA_i+1···A_j
AiAi+1⋅⋅⋅Aj 最小代价括号化方案的递归求解公式变为
伪代码
MATRIX-CHAIN-ORDER(p)
n=p.length-1
let m[1..n][1..n] and s[1..n-1][2..n] be new tables
for i=1 to n
m[i][i]=0 // 也就是把二维数组m中主对角线元素置为0
for l=2 to n // l is the chain lenth(即 2个矩阵相乘,3个相乘,...n个相乘)
for i=1 to n-l+1 // 控制行的变换,可以把数组m在纸上画出来,发现i是控制对角线上的行变换。
j=i+l-1 //即j=i+(l-1), 本来主对角线上是j=i的,但是,当矩阵链为l时,列(即j)右移(l-1)位,所以j=i+(l-1),也就是控制列的变化
m[i][j]=∞
for k=i to j-1
q=m[i] [k]+m[k+1] [j]+p[i-1]p[k]p[j]
if q< m[i][j]
m[i][j]=q
s[i][j]=k
return m and s
以上是关于算法导论—矩阵链乘法(动态规划)的主要内容,如果未能解决你的问题,请参考以下文章