动态规划
Dynamic Programming
动态规划是用于解决多阶段决策最优化问题的算法设计方法。该术语是1957年Richard Bellman在描述一类最优控制问题时提出的。
该术语描述的是问题特征,而非方法特征。该类问题的特征是,它的活动过程可以分为有序的若干阶段,而且在任一阶段i,过程在阶段i以后的行为仅依赖与阶段i的过程状态,与阶段i以前过程如何到达这种状态无关(这儿是不是有点类似于马尔科夫过程)。
它满足所谓的最优性原理(和贪心法类似)。最优性原理指的是,过程的最优决策序列具有如下性质:无论过程的初始状态和初始决策时什么,其余的决策必须相对于初始决策产生的状态构成一个最优决策序列。
动态决策时建立在最优性原理基础上的枚举法,该问题的解可被看作k个阶段决策的结果,其子问题解相应地可被看作
j
(
下面来举几个具体的例子:
- 矩阵连乘
- 求最小路径
矩阵连乘
考虑n个矩阵连乘积问题:
M1⋅M2⋅...⋅Mn=? 任意A,B两个矩阵相乘,必须满足A 的列数等于B的行数。
设A的大小为 p×q ,B的大小为 q×r ,那么求AB矩阵乘积的运算量为 pqr 。(包括 pqr 次乘法, pqr 次加法, pqr 次赋值。)事实上不同的矩阵结合方式会带来不同的运算量,怎么利用动态规划求使得运算量最小的矩阵连乘方案呢。
先来估算结合方式数目,规模为n的矩阵连乘结合方式数目为 p(n) :
p(1)=1
p(n)=p(1)p(n−1)+p(2)p(n−2)+⋯+p(n−1)p(1),当n≥2 ¥ p(n)=12Cn−12(n−1),p(n)≥2n−2。 这就是Catalan数。用动态规划法求解该问题,假设最优结合法最后一次乘法是 M1,i和Mi+1,n ,即 M1,n=M1,i+Mi+1,n ,且 M1,i和Mi+1,n 各自的结合法也是最优的,满足最优性原理。设 mi,j为Mi,j 所需要的最小运算量,则
mi,i=0,1≤i≤n
mi,j=mini≤k<j{mi,k+mk+1,j+ri−1rkrj},1≤i<j≤n
可以通过一个n阶方阵来表示出各个最小运算量 mi,j 及分割矩阵 Mi,j 的最佳分割点k。伪代码:
procedure MatMultiply(N,R,D) //N是矩阵连乘的个数 //R(N+1)存放N个矩阵的行列树 //D是N阶方阵,D(i,j)=mij(i<j) //D(j,i)=(M^{i,j} = M^{i,k}M^{k+1,j})的最优分割点k integer N,I,J,K,T,R(N+1),D(N,N) for I<- 1 to N do D(I,I)=0 repeat for I<- 1 to N-1 do for J<- 1 to N-1 do D(J,J+I) = MAXINT for K<- 0 to I-1 T = D(J,J+K)+D(J+K+1,J+I)+R(J-1)R(J+K)R(J+I) if T<D(J,J+I) then D(J,J+I)<- T;D(J+I,J)<- J+K endif repeat repeat repeat end MatMultiply
由 D(j,i)(i<j) 确定N个矩阵的最佳结合方式,这由一个递归过程来完成。
procedure P(I,J) //过程P给出矩阵M^{I},...,M^{J}连乘的最佳结合方式, //也就是在M^{I},...,M^{J}中添加表示结合的括弧 case :I=J:write('(M^{I})') :I+1=J:write('(M^{I}M^{J})') :else: { K<- D(J,I) write('(') call P(I,K) call P(K+1,J) write(')') } endcase end P
算法复杂度主要在计算MatMultiply( n3 ),而添加括弧只用了线性复杂度的时间。
最短路径
图G=(V,E,W)是一个带边权的有向图,边权可以为负,但不存在负回路,给定图中节点 i,j 求 i到j 最小路径(长度及道路)。
主要采用Floyd-Warshall算法。
在这里直接给出伪代码:
procedure initial(n,w,d,Q) //initializing //n节点数 //w边权 //d(i,j)最小路径长度 //Q(i,j):j的直接前驱(i-j路径上位于j前一个的点) for i<-1 to n do for j<-1 to n do d(i,j)<- w((i,j)) Q(i,j)<-i repeat repeat end initial
procedure MinPath(d,Q) for k<- 1 to n do for i<-1 to n do for j<-1 to n do if d(i,k)+d(k,j)<d(i,j) then d(i,j)<-d(i,k)+d(k,j) Q(i,j)<-Q(k,j) endif repeat repeat repeat end MinPath
来自北京大学杨老师的算法设计与分析课程笔记整理。