题 目:贪心法与动态规划的对比分析
作者姓名:
作者学号:
专业班级:
提交时间: 2023/6/3
目 录
1 引言 1
2 分析过程 2
2.1多段图的最短路径问题 2
2.2最小生成树问题 4
3动态规划与贪心法的对比 7
3.1使用条件 8
3.2解 8
3.3计算过程 8
3.4处理策略 8
3.5关键问题 8
4小结 9
参考文献 10
贪心法与动态规划的对比分析
(湖北师范大学计算机与信息工程学院 中国 黄石 435002)
摘 要:动态规划与贪心法是算法设计中比较重要的方法,它们都是采用分治思想把大问题分小,在降低成本的基础上达到最优;这两种方法有许多相似的地方,容易使人混淆;以求解最小生成树的Prim算法和多段图的最短路径问题为例,通过详细对比分析,指出动态规划与贪心法的差异性,帮助人们理解掌握二者之间的差别。
关键词:动态规划;贪心法;对比分析
Comparative Analysis of Greedy Method and Dynamic Programming
(College of Computer and Information Engineering, Hubei Normal University, Huangshi,China,435002)
Abstract:Dynamic programming and greedy method are more important methods in algorithm design, they both adopt the idea of division and rule to divide big problems into small ones, and achieve the best on the basis of reducing costs; These two methods have many similarities and are easily confusing; Taking the Prim algorithm of minimum spanning tree and the shortest path problem of multi-segment graph as examples, through detailed comparative analysis, the difference between dynamic programming and greedy method is pointed out, and the difference between the two is helped to understand and grasp the difference between the two.
Keywords:Dynamic Programming;Greedy Method;Comparative Analysis
贪心法与动态规划的对比分析
(湖北师范大学计算机与信息工程学院 中国 黄石 435002)
1 引言
动态规划和贪心法是一种解决问题的策略与方法,其解决问题的基础均是将待求解的问题分解成若干个子问题,再按不同的处理策略对子问题进行优化[1]。动态规划和贪心x法有许多相似的地方,但在具体的行为上不相同,有时容易混淆起来。因此,本文以求解最小生成树的Prim算法和多段图的最短路径问题为例,对动态规划与贪心法的差异性进行对比分析。
动态规划是运筹学的一个分支,20世纪50年代初美国数学家Bellman等人在研究多阶段决策过程的优化问题时,提出了著名的最优性原理,创立了解决这类过程优化问题的新方法——动态规划法。多阶段决策问题:求解的问题可以划分为一系列相互联系的阶段,每个阶段都需要做出决策,而且一个阶段决策的选择会影响下一个阶段的决策,从而影响整个过程的活动路线,求解的目标是选择各个阶段的决策是整个过程达到最优。动态规划主要用于求解以时间划分阶段的动态过程的优化问题,但是一些与时间无关的静态规划(如线性规划、非线性规划),可以人为地引进时间因素,把它视为多阶段决策过程,也可以用动态规划方法方便地求解。动态规划是考察问题的一种途径,或是求解某类问题的一种方法。动态规划问世以来,在经济管理、生产调度、工程技术和最优控制等方面得到了广泛的应用。例如最短路线、库存管理、资源分配、设备更新、排序、装载等问题,用动态规划方法比其它方法求解更为方便。
贪心法是一种简单有效的方法。它在解决问题的策略上只根据当前已有的信息就做出选择,而且一旦做出了选择,不管将来有什么结果,这个选择都不会改变。贪心法并不是从整体最优考虑,它所做出的选择只是在某种意义上的局部最优。这种局部最优选择并不总能获得整体最优解,但通常能获得近似最优解。如果一个问题的最优解只能用蛮力法穷举得到,则贪心法不失为寻找问题近似最优解的一个较好办法。
2 分析过程
2.1多段图的最短路径问题
动态规划的思想是将待求解的问题分解成若干个子问题,这些子问题间往往不是相互独立的,而是构成互相联系的多个阶段,并从全局的角度出发,依次对每一个阶段进行计算,再根据当前阶段计算出来的值做出决策,从而使整个过程达到最优[2]。动态规划最高明的地方是发现了分解出来的子问题有重叠,使用表格记录前面的计算结果,当需要再次求解此子问题时,只是简单地通过查表获得该子问题的解,从而避免了大量的重复计算而大大节省时间[3]。设G=(V,E)是一个赋权有向图,其顶点集合V被划分成5个不相交的阶段,图中所有的边(u,v)的始点和终点都在相邻的两个子集Vi和Vi+1中,如图1所示。其中,第一个阶段只有一个顶点1,称为源点s,第二个阶段由2、3、4、5四个顶点组成,第三个阶段由6、7、8三个顶点组成,第四个阶段由9、10、11三个顶点组成,第五个阶段只有一个顶点12,称为汇点t。图中所有的边(u,v)的始点和终点都在相邻的两个子集Vi和Vi+1中,u∈Vi,v∈V i+1, 若用w(j,m)表示边(j,m)上的代价函数,D(i,j)表示这条路径上的代价,则该问题由后向前的递推公式为:D(i,j)=min{w(j,m)+D(i+1,m)},m∈Vi +1,(j,m)∈E。
图2-1 一个五阶段图
特别是当(j,t)∈E时,D(k-1,j)=w(j,t);若(j,t)埸E时,定义D(k-1,j)=∞。因此,利用递推公式D(i,j)=min{w(j,m)+D(i+1,m)},从k-2(k表示总的阶段数)个阶段开始,可以求出第k-2阶段D(k-2,j),第k-3阶段D(k-3,j),第k-4阶段D(k-4,j),直到第1个阶段D(1,s)为止的当前最短路径,就是图1中从s到t的一条道路上的最短路径[2]。2.1.1计算第3阶段顶点上的路径代价
(1)计算D(3,6)的路径代价
D(3,6)=min{w(6,9)+D(4,9),w(6,10)+D(4,10)}=min{6+D(4,9),5+D(4,10)},又因为,D(4,9)=min{w(9,12)+D(5,12)},而此时(9,12)∈E,D(4,9)=w(9,12)=4;同理,D(4,10) =w(10,12)=2,所以,D(3,6)=min{6+D(4,9),5+D(4,10)}=min{6+4,5+2}=7
(2)计算D(3,7)的路径代价D(3,7)=min{w(7,9)+D(4,9),w(7,10)+D(4,10)}=min{4+D(4,9),3+D(4,10)} 因为D(4,9) =4,D(4,10)=2,已经在计算D(3,6)的路径代价时计算出来,并保存在表格中,现在用到,只需要简单地通过查表获得该子问题的解,从而避免了大量的重复计算,这就是动态规划最明显的优化策略,因此,D(3,7)=min{4+4,3+2}=5 (3)计算D(3,8)的路径代价D(3,8)=min{w(8,10)+D(4,10),w(8,11)+D(4,11)}=min{5+D(4,10),6+D(4,11)} 又因为,D(4,10)=2,已经在计算D(3,6)的路径代价时计算出来,而D(4,11)=min{w(11,12) +D(5,12)},而此时(11,12)∈E,D(4,11)=w(11,12)=5;所以,D(3,8)=min{w(8,10)
+D(4,10),w(8,11)+D(4,11)}=min{5+2,6+5}=7 通过第3阶段6、7、8三个顶点的计算值,选择值最小的5作为这个阶段的极值,即D(3,7)=w(7,10)+D(4,10)=5。
2.1.2计算第2阶段顶点上的路径代价
(1)计算D(2,2)的路径代价
D(2,2)=min{w(2,6)+D(3,6),w(2,7)+D(3,7),w =min{4+D(3,6),2+D(3,7),1+D(3,8)} 又因为,D(3,6)=7,D(3,7) =5,D(3,8)=7,均在计算第3阶段顶点上的代价中计算出来,所以,D(2,2) =min{4+7,2+5,1+7}=7
(2)计算D(2,3)的路径代价
D(2,3)=min{w(3,6)+D(3,6),w(3,7)+D(3,7)}=min{2+D(3,6),7+D(3,7)} 又因为,D(3,6)=7,D(3,7)=5,均在计算第3阶段顶点上的代价中计算出来,所以,D(2,3) =min{2+7,7+5}=9
(3)计算D(2,4)的路径代价
D(2,4)=min{w(4,8)+D(3,8)},又因为,D(3,8)=7已在计算第3阶段的顶点中计算出来,所以,D(2,4) =min{11+7}=18(4)计算D(2,5)的路径代价D(2,5)=min{w(5,7)
+D(3,7),w(5,8)+D(3,8)}=min{11+D(3,7),8+D(3,8)} 又因为,D(3,7)=5,D(3,8)=7,均在计算第3阶段顶点上的代价中计算出来,所以,D(2,5)=min{11+5,8+7}=15。同理,通过第2阶段2、3、4、5四个顶点的计算值,选择值最小的7作为这个阶段的极值,即D(2,2)=w(2,7)+D(3,7)=7。
2.1.3计算第1阶段顶点上的路径代价
D(1,1)=min{w(1,2)+D(2,2),w(1,3)+D(2,3),w (1,4)+D(2,4),w(1,5)+D(2,5)}
=min{9+D(2,2),7+D(2,3),3+D(2,4),2+D (2,5)}又因为,D(2,2)=7,D(2,3)=9,D=18,D(2,5)=15,均在计算第2阶段顶点上的代价中计算出来,所以,D(1,1)=min{9+7,7+9,3+18,2+15}={16,16,21,17}=16。
同理,通过第1阶段上的1顶点的计算值,选择值最小的16作为这个阶段的极值,即D(1,1)=w(1,2)+D(2,2)=16,或者D(1,1)=w(1,3)+D(2,3)=16。
在图2-1中这些顶点被分成5个阶段,因为当(j,t)∈E时,D(k-1,j)=w(j,t),因此,第4个阶段的顶点9、10、11不需要计算,直接根据w(j,t)的值,得出顶点10最短,计算第3个阶段的6、7、8三个顶点上的路径代价,选择这个阶段最短的路径代价D(3,7)=w(7,10)+D(4,10)=5,再计算第2阶段的顶点2、3、4、5四个顶点上的路径代价,选择这个阶段最短的路径代价D(2,2)=w(2,7)+D(3,7)=7,最后计算第1个阶段顶点上的路径代价,选择这个阶段最短的路径代价D(1,1)=w(1,2)+D(2,2)=16,或者D(1,1)=w(1,3)+D(2,3)=16,从而得出从源点s到汇点t的最短路径是1->2->7->10->12,或者1->3->6->10->12,其最短路径长度均是16。
由此,可把动态规划的求解过程归纳为:先把图划分成互相联系的k(k>2)个阶段,并从第k-2阶段开始,依次计算每个阶段上各顶点的路径代价,再根据该阶段计算出来各顶点的路径代价中选择最短路径,在每个阶段上都是遵从先计算,再选择的原则,直到逆序倒退到过程起点s时为止,就得到了从源点s到t的最短路径。
2.2最小生成树问题
贪心法是动态规划的特殊情况,其思想也是将待求解的问题分解成若干个子问题,从局部的角度出发,依次对每一步都做出一个局部最优的选择,以期在总体上仍然达到最优[3]。贪心法最明显的特性是,不是搜遍所有的解空间,而是每一步只在局部范围内选择看上去最好的那个,因而获得比较惊人的效果[2]。设G=(V,E)是一个赋权的无向连通图,把顶点集合V分成集合里S和集合外V-S两部分,如图2-2所示。开始时,任选一个顶点放到集合里,若选择V1,则S={V1},集合外的顶点{V2,V3,V4,V5,V6},若用一个结构体数组closedge[]来存储相关信息,closedge[].adjvex表示当前加入到集合里的顶点,closedge[].lowcost表示集合外顶点到集合里顶点当前的最短路径,如表2-1所示。
图2-2 带权的无向图
表2-1 设顶点V1为起点
第一步开始,先从集合外所有顶点{V2,V3,V4,V5,V6}中选择一个离集合里顶点S={V1}当前最近的顶点V3加入集合里,则S={V1,V3},再用公式:
若closedge[j].lowcost!=0,则closedge[j].lowcost=G.arcs[k][j](j表示集合外顶点的存储位置,k表示加入到集合里的顶点存储位置),计算顶点V3到集合外顶点{V2,V4,V5,V6}的当前值,并把顶点V3的权值改为0,表示顶点V3已经加入集合里。
(1)计算顶点V3到集合外顶点V2的当前值
因为closedge[1].lowcost!=0&&G.arcs[2][1]
因为closedge[3].lowcost!=0&&G.arcs[2][3]
因为closedge[4].lowcost!=0&&G.arcs[2][4]
因为closedge[5].lowcost!=0&&G.arcs[2][5]
表2-2 选顶点V3加入集合中
第二步,仍然采用第一步的方法,在表2-2所示中,先从集合外所有顶点{V2,V4,V5,V6}中选择一个离集合里顶点S={V1,V3}当前最短的顶点V6加入集合里,则S={V1,V3},再用公式closedge[j].lowcost!=0&&G.arcs[k][j]
第三步,第四步,第五步,用同样的方法操作,依次计算得出集合里与集合外顶点当前的最短路径,如表3-4,表3-5,表3-6所示。
表3-4 选顶点V4加入集合里
表3-5 选顶点V5加入集合里
表3-6 选顶点V2加入集合里
由此,可把贪心思想的Prim算法构造最小生成树的过程归纳为:在每一步中总是从集合外选择一个离集合里顶点最短的顶点加入集合里,然后再依次计算此顶点离集合外顶点的当前值,是先选择,后计算的过程,一直重复到把集合外所有顶点都加入到集合里为止,从而在每一步的局部最优中期待获得全局最优。
3动态规划与贪心法的对比
3.1使用条件
动态规划的使用条件是优化原则,多步判断,而贪心法,除了具备动态规划的使用条件外,还要具有贪心选择,即每次总是选择当前认为最好的那个。
3.2解
动态规划是先求出了每一阶段子问题的解,再从这些解中选择最优,各个阶段之间有明确的优先关系,不能跨越某个阶段,因而总能得到一个最优解,而贪心法是在每一个阶段上只考虑局部最优,是当前状态到下一个状态或者从当前状态到目标状态,是两个状态之间的优化,不一定能找到最佳值,所以,只能得到一个最优解,或者是近似解。比如大家熟悉的选择男女朋友的问题就是贪心选择,不一定获得最优解。
3.3计算过程
动态规划是在每个阶段上先进行计算,然后根据计算出来的结果选择最优的,而贪心法是先在当前状态中选择认为最好的,然后根据选择结果进行计算。
3.4处理策略
动态规划发现分解出来的子问题有重叠时,使用表格记录前面的计算结果,当需要再次求解此子问题时,只是简单地通过查表获得该子问题的解,从而避免了大量的重复计算提高速度,而贪心法不是搜遍所有的解空间,而是每一步只在局部范围内选择看上去最好的那个,因而获得惊人的效率。
3.5关键问题
动态规划的关键问题是递推方程和空间复杂度高,而贪心法是贪心选择性质证明和近似解的误差估计。动态规划(Dynamic Programming,DP)是通过把原问题分解成相对简单的子问题的方式来解决复杂问题的方法。它的基本思想是将待求解问题分解成不同部分(即子问题),然后依据子问题的解以得出原问题的解,而子问题又可递归地分解为子子问题(到此跟分治法的思想类似,后面是不同)。通常许多子问题可能会重复出现(重复子问题),DP试图仅仅解每个子问题一次,在求得每个子问题的解后将其保存起来,下次再需要求解相同子问题时,直接查表得到,从而减少计算量,它的精髓在于记住求过的解来节省时间,体现了以空间换时间的算法思想,这也是其与分治法最大的区别。
此外,还看到有资料对DP思路的阐述是将问题分解为多个阶段,每个阶段对应一个决策。我们记录每个阶段可达的状态集合(去掉重复的),然后通过当前阶段的状态集合推导下一个阶段的状态集合,动态地往前推进,直至到达最终阶段,这一阐述和DP的名字更贴合,也指出DP适用的问题是多阶段决策最优解模型。贪心算法与动态规划算法一样具有最优子结构,但是相比动态规化问题,状态之间的转移有多种选择,而贪心算法通常具有贪心选择性,即从一个状态转移到另一个状态,往往具有唯一的最优选择。 我们知道解动态规划的核⼼问题是穷举,其解法往往就是穷举所有的可能解。 而贪心算法则是在穷举过程中直接进行了剪枝,仅仅选择可以导向最优解的支路,因此效率⽐动态规划要⾼。
4小结
动态规划和贪心法都是采用分治思想把大问题分小,在降低成本的基础上达到最优。动态规划是从整体上考虑最优,把分解出来有重叠的子问题,使用表格记录前面的计算结果,避免大量的重复计算提高效率,而贪心法不是搜遍所有的解空间,而是每一步只在局部范围内择优选择,因而获得惊人的速度。两种策略各有优势,学习时注意区分它们的处理策略,并弄清楚它们之间的差异性,才能在使用中做到游刃有余。
参考文献:
[1]邹恒明.算法之道[M].北京:机械工业出版社,2012.
[2]许少华.算法设计与分析[M].哈尔滨:哈尔滨工业出版社,2011.
[3]张铭,赵海燕,等.数据结构与算法实验教程[M].北京:高等教育出版社,2011.
[4]杨智明,李艳.动态规划与贪心法的对比分析[J].保山学院学报,2016,35(05):73-76+101.
[5] 数据结构[M].严蔚敏,吴伟良, 编著.清华大学出版社.2007
[6] 数据结构简明教程[M].徐孝凯编著.清华大学出版社.1995