由于种种原因(看这一章间隔的时间太长,弄不清动态规划、分治、递归是什么关系),导致这章内容看了三遍才基本看懂动态规划是什么。动态规划适合解决可分阶段的组合优化问题,但它又不同于贪心算法,动态规划所解决的问题的各个阶段是相互关联的,一个阶段的选择会影响其它阶段的选择。动态规划有两个优点:一是可以排除一些解,另一个是可以帮助我们系统化的解决问题,使问题变得清晰。
下面就说一下我对动态规划、分治、递归这三者的理解。分治算法是将原问题分解成两个较小的问题,而动态规划是将问题分成不同的阶段(步骤),当然,正如上面所说的,我们要注意加以区别动态规划和贪心算法所解决问题的类型。使我(们)把动态规划和分治混在一起的就是它们都有递归函数,那么递归和它们是什么关系呢?我的理解是动态规划和分治算法是一种抽象的算法,而递归是一种具体的实现手段。说了这么多,下面就举两个例子来说明动态规划方法具体是怎样实现的。
求两点之间的最短路径问题。请大家稍微观察一下下图:
我们注意到,从S到F的最短路径一定经过A、B、C中的一点和D、E中的一点,因此,我们可以将该问题分成多个阶段,第一阶段是求D、E分别到F的最短距离,第二阶段是求A、B、C经过D、E中的一点到F的最短距离,第三阶段是求S经过A、B、C中的一点到F的最短距离,具体步骤如下:
- 第一阶段:(D,F)=2,(E,F)=3(其中(D,E)表示D到F的最短距离,其它类推)
- 第二阶段:(A,F)=min{(A,D)+(D,F),(A,E)+(E,F)}=min{3+2,4+3}=5
(B,F)=min{(B,D)+(D,F),(B,E)+(E,F)}=min{2+2,5+3}=5
(C,F)=min{(C,E)+(E,F)}=min{1+3}=4 - 第三阶段:(S,F)=min{(S,A)+(A,F),(S,B)+(B,F),(S,C)+(C,F)}=min{1+5,3+4,6+4}=6
所以从S到F的最短路径距离是6,通过上面的步骤能很容易得到从S到F的最短路径为S->A->D->F。从这个例子中,也许我们不能很好地体会动态规划是怎样运用递归的,那我们就从下面的例子中简单说明递归在动态规划中的作用。
最长公共子序列问题。在这就不介绍什么是最长公共子序列问题了。运用动态规划的思想,我们依然考虑将问题分成多个阶段,并从后往前想。我们应该能想到最长公共子序列问题最后一个阶段是判断两个字符串和的最后一个字符是否相同。
- 若相同,则最长公共子序列一定包含这个字符,我们只需判断 和 的最长公共子序列即可。
- 若不同,最长公共子序列一定是在 和,和 中。
用表达式表达如下:
算法设计与分析这门课就学到这了,抛去用编程语言具体实现,整体来说还是很好理解的。接下来我将对计算机的其他课程进行复习,希望自己能坚持学习,在学习的过程中能有当初上课时不一样的收获。