第六章动态规划6.1 动态规划的思想方法6.1.1 动态规划的最优决策原理活动过程划分为若干个阶段,每一阶段的决策,依赖于前一阶段的状态,由决策所采取的动作,使状态发生转移,成为下一阶段的决策依据。
P1P2 P nS0S1 S2┅┅S n-1 S n图6.1 动态规划的决策过程最优性原理:无论过程的初始状态和初始决策是什么,其余决策都必须相对于初始决策所产生的状态,构成一个最优决策序列。
S0p(1,1) p(1,2) p(1,r1)s(1,1)s(1,2) s(1,r1)s(2,11) p(2,12) s(2,1r2) p(2,21) s(2,22) s(2,2r2) s(2,r11) s(2,r12) s(2,r1r2) 令最优状态为)(s,由此倒推:22,2spp→,2(s→→s→))2,1(22)2,1(),2(22最优决策序列,)p→)2,1(p22,2(状态转移序列:)s22→0ss→,2()2,1(赖以决策的策略或目标,称为动态规划函数。
整个决策过程,可以递归地进行,或用循环迭代的方法进行。
动态规划函数可以递归地定义,也可以用递推公式来表达。
最优决策是在最后阶段形成的,然后向前倒推,直到初始阶段;而决策的具体结果及所产生的状态转移,却是由初始阶段开始进行计算的,然后向后递66归或迭代,直到最终结果。
6.1.2 动态规划实例、货郎担问题例6.1 货郎担问题。
在有向赋权图>=<E V G ,中,寻找路径最短的哈密尔顿回路问题。
一、解货郎担问题的过程令),(V i d :从顶点i 出发,经V 中各顶点一次,最终回到顶点i 的最短路径的长度, 开始时,}{i V V -=。
动态规划函数:})}{,({min ),()}{,(k V k d c V i d i V i d ik Vk -+==-∈(6.1.1)i k c k d ki≠=),(ϕ (6.1.2)4个城市的费用矩阵是:⎪⎪⎪⎪⎪⎭⎫⎝⎛∞∞∞∞==573246325763)(ij c C根据(6.1.1)式,由城市1出发,经城市2,3,4然后返回1的最短路径长度为:})}3,2{,4(,)}4,2{,3(,)}4,3{,2({min )}4,3,2{,1(141312d c d c d c d +++=它必须依据)}3,2{,4(,)}4,2{,3(,)}4,3{,2(d d d 的计算结果:})}3{,4(,)}4{,3({min )}4,3{,2(2423d c d c d ++= })}2{,4(,)}4{,2({min )}4,2{,3(3432d c d c d ++= })}2{,3(,)}3{,2({min )}3,2{,4(4342d c d c d ++=这一阶段的决策,又必须依据下面的计算结果:)}4{,2(,)}3{,4(,)}4{,3(d d d )}2{,3(,)}3{,2(,)}2{,4(,d d d再向前倒推,有:532),4()}4{,3(413434=+=+=+=c c d c d ϕ 1165),3()}3{,4(314343=+=+=+=c c d c d ϕ 633),4()}4{,2(412424=+=+=+=c c d c d ϕ 1257),2()}2{,4(214242=+=+=+=c c d c d ϕ 862),3()}3{,2(312323=+=+=+=c c d c d ϕ 954),2()}2{,3(213232=+=+=+=c c d c d ϕ有了这些结果,再向后计算,有:7}113,52{min )}4,3{,2(=++=d路径顺序是:2,3,4,1610}122,64{min )}4,2{,3(=++=d 路径顺序是:3,2,4,1 14}95,87{min )}3,2{,4(=++=d路径顺序是:4,3,2,1最后:10}147,106,73{min )}4,3,2{,1(=+++=d路径顺序是:1,2,3,4,1d (1,{2,3,4})d (2,{3,4}) d (3,{2,4}) d (4,{2,3})d (3,{4}) d (4,{3}) d (2,{4}) d (4,{2}) d (2,{3}) d (3,{2})d (4,φ) d (3,φ) d (4,φ) d (2,φ) d (3,φ) d (2,φ)图6.2 货郎担问题求解过程示意图二、复杂性分析令i N 是计算从顶点i 出发,返回顶点i 所需计算的形式为)}{,(k V k d -的个数。
开始计算)}{,(i V i d -时,集合}{i V -中有1-n 个城市。
以后,在计算)}{,(k V k d -时,集合}{k V -的城市数目,在不同的决策阶段,分别为2-n ,┅,0。
在整个计算中,需要计算大小为j 的不同城市集合的个数为j n C 1-,1,1,0-=n j 。
因此,总个数为:∑-=-=11n j j n i CN当}{k V -集合中的城市个数为j 时,为计算)}{,(k V k d -,需j 次加法, 1-j 次比较。
从i 城市出发,经其它城市再回到i ,总的运算时间i T 为:∑∑∑-=--=--=-=⋅<⋅=1110111n j j n n j j n n j j n i CnC n C j T由二项式定理:j n j nj j n ny xCy x -=∑=+0)(令1==y x ;可得:)2(21n n i n O n T =⋅<-则用动态规划方法求解货郎担问题,总的花费T 为:)2(22121n n ni in O n TT =⋅<=-=∑66.2 多段图的最短路径问题6.2.1 多段图的决策过程定义 6.1 有向连通赋权图),,(W E V G =,顶点集合V 划分成k 个不相交的子集i V ,k i ≤≤1,2≥k ,使得E 中的任一边),(v u ,必有i V u ∈,m i V v +∈,1≥m 。
称为多段图。
令1||||1==k V V ,称1V s ∈为源点,k V t ∈为收点。
多段图的最短路径问题,是求从源点s 到达收点t 的最小花费的通路 一、顶点编号:根据多段图的k 个不相交的子集i V ,把多段图划分为k 段,每一段包含顶点的一个子集。
把顶点集合V 中的所有顶点,按照段的顺序进行编号。
子集中的顶点互不邻接,它们之间的相互顺序无关紧要。
顶点个数为n ,顶点s 的编号为0,则收点t 的编号为1-n , 对E 中的任何一条边),(v u ,顶点u 的编号小于顶点v 的编号。
二、决策过程数组元素][cos i t :存放顶点i 到达收点t 的最小花费数组元素][i path :存放顶点i 到达收点t 的最小花费通路上的前方顶点编号 数组][n route :存放从源点s 出发,到达收点t 的最短通路上的顶点编号 第一阶段,确定第1-k 段的所有顶点到达收点t 的花费最小的通路。
第二阶段,用第一阶段的信息,确定第2-k 段的所有顶点到达收点t 的花费最小的通路。
如此依次进行,直到最后确定源点s 到达收点t 的花费最小的通路。
最后,从源点s 的path 信息中,确定它的前方顶点编号1p , 从1p 的path 信息中,确定1p 的前方顶点编号2p , 如此递推,直到收点t 。
动态规划函数:}][cos {min ][cos j t c i t ij nj i +=≤<(6.2.1) n j i jj t c i path ij ≤<+=最小的使][cos ][(6.2.2)三、步骤:(n 为顶点个数)1. 对所有的n i i <≤0,,把][cos i t 初始化为最大值,][i path 初始化为-1;]1[cos -n t 初始化为0;2. 令2-=n i ;3. 根据(6.2.1)式和(6.2.2)式计算][cos i t 和][i path ;4. 1-=i i ,若0≥i ,转3;否则,转5;5. 令0=i ,0][=i route ;6. 如果1][-=n i route ,算法结束;否则,转7;67. 1+=i i ,]]1[[][-=i route path i route ;转6; 例6.2 求解图6.3所示的最短路径问题。
图6.3 动态规划方法求解多段图的例子(i 表示顶点编号)8=i :303]9[cos ]8[cos 89=+=+=t c t9]8[=path 7=i :707]9[cos ]7[cos 79=+=+=t c t9]7[=path6=i :8}35,76{min }]8[cos ,]7[cos {min ]6[cos 6867=++=++=t c t c t8]6[=path5=i :9}36,78{min }]8[cos ,]7[cos {min ]5[cos 5857=++=++=t c t c t 8]5[=path4=i :9}36,75{min }]8[cos ,]7[cos {min ]4[cos 4847=++=++=t c t c t8]4[=path3=i :13}87,94{min }]6[cos ,]5[cos {min ]3[cos 3635=++=++=t c t c t5]3[=path2=i :]}6[cos ,]5[cos ,]4[cos ,]3[cos {min ]2[cos 26252423t c t c t c t c t ++++=14}88,97,96,131{min =++++=3]2[=path1=i :15}96,99{min }]5[cos ,]4[cos {min ]1[cos 1514=++=++=t c t c t5]1[=path0=i :}]3[cos ,]2[cos ,]1[cos {min ]0[cos 030201t c t c t c t +++=15}133,141,154{min =+++=2]0[=path 0]0[=route2]0[]]0[[]1[===path route path route 3]2[]]1[[]2[===path route path route 5]3[]]2[[]3[===path route path route=pathpathroute8=route]4[=]]3[[]5[route=pathroute=path]]4[9]8[[]5[=最后,得到最短的路径为0,2,3,5,8,9,费用是15。
6.2.2 多段图动态规划算法的实现struct NODE { /* 邻接表结点的数据结构 */int v_num; /* 邻接顶点的编号 */Type len; /* 邻接顶点与该顶点的费用 */struct NODE *next; /* 下一个邻接顶点 */};struct NODE node[n]; /* 多段图邻接表头结点 */Type cost[n]; /* 在阶段决策中,各个顶点到收点的最小费用 */ int route[n]; /* 从源点到收点的最短路径上的顶点编号 */ int path[n]; /* 在阶段决策中,各个顶点到收点的最短路径上的前方顶点编号 */ 算法6.1多段图的动态规划算法输入:多段图邻接表头结点node[],顶点个数n输出:最短路径费用,最短路径上的顶点编号顺序route[]1. template <class Type>2. #define MAX_TYPE max_value_of_Type3. #define ZERO_TYPE zero_value_of_Type4. Type fgraph(struct NODE node[],int route[],int n)5. {6. int i;7. struct NODE *pnode;8. int *path = new int[n];9. Type min_cost,*cost = new Type[n];10. for (i=0;i<n;i++) {11. cost[i] = MAX_TYPE; path[i] = -1; rouet[i] = 0;12. }13. cost[n-1] = ZERO_TYPE;14. for (i=n-2;i>=0;i--) {15. pnode = node[i]->next;16. while (pnode!=NULL) {17. if (pnode->len+cost[pnode->v_num]<cost[i]) {18. cost[i] = pnode->len + cost[pnode->v_num];19. path[i] = pnode->v_num;6620. }21. pnode = pnode->next; 22. } 23. } 24. i = 0;25. while ((route[i]!=n-1)&&(path[i]!=-1)) { 26. i++;27. route[i] = path[route[i-1]]; 28. }29. min_cost = cost[0];30. delete path; deleye cost; 31. return min_cost; 32. }时间复杂性:)(m n +Θ10~13行的初始化,花费)(n Θ时间。