算法导论(十五)——动态规划

作者:disappearedgod
时间:2014-6-10

前言

本文从《算法导论》入手,然后加上一些自己的见解。
首先,先来谈一谈我们为什么需要动态规划。
其实,对于计算机能解决的问题的讨论一直没有个定理,而关于计算机解决的问题的这个话题也成为了一门学科,笼统的认识就是P类问题可解,NP问题不可解。而动态规划的解决范围又比计算机能解决的范围来的少,那么我们为什么将DP作为我们计算机领域的一个认知常识来学习呢?
我认为,DP得到了计算机视角解释解决问题的真谛。对于算法可以解决的问题来说,它节省了递归算法的重算的费力的时间实在太多,而且比贪心算法更在乎全局性最优,而不是局部。
从思考问题来说,用DP的想法来看,对于世界的理解也许能上升一个档次。
从写论文来看,DP是一切解释动态性问题的基本,是Evolution类算法的鼻祖。随着计算社会学的研究深入,DP成为不可或缺的一个算法。

目录

正文


15 动态规划

动态规划(dynamic programming)是通过组合子问题的解而解决整个问题的。动态规划只求解一次,将其结果保存在一张表中,从而避免每次到各个子问题时重新计算答案。

动态规划算法的设计可以分为下列4个步骤:
  • 描述最优解的结构。
  • 递归定义最优解的值。
  • 按自底向上的方法计算最优解的值。
  • 由计算的结果构造一个最优解。

15.1 装配线调度

算法导论上给出了一个求解工厂流水线问题的解法
步骤1:通过工厂最快路线的结构
步骤2:一个递归的解
步骤3:计算最快时间
步骤4:构造通过工厂的最快路线

15.2 矩阵链乘法

计算全部括号的重数
15.2.1 步骤一:最优加全部括号的结构
15.2.2 步骤二:一个递归解
15.2.3 步骤三:计算最优代价
15.2.4 步骤四:构造一个最优解
 

15.3 动态规划基础

什么时候需要动态规划?——适合采用动态规划方法的最优化问题中的两个要素:最优子结构和重叠子问题。另外,还要分析一种不同的方法:成为备忘录(memoization ),以充分利用重叠子问题性质。

最优子结构

用动态规划求解优化问题的第一步是描述最优解的结构。
在找寻最优子结构时,可以遵循一种共同的模式:
  • 问题的一个解可以是一个选择。
  • 假设对一个给定的问题,已知的是一个可以导致最优解的选择。
  • 在已知这个选择后,要确定那些子问题会随之发生,以及如何最好的描述所得到的子问题空间。
  • 利用一种cut-and-paste技术,来证明在问题的一个最优解中,使用的子问题的姐本身必须是最优的。(通过假设每一个子问题的姐都不是最优解,然后导出矛盾,即可做到这一点)
最优子结构在问题域中以两种方式变化:
  • 有多少个子问题被使用在原问题的一个最优解中
  • 在决定一个最优解中适用哪些子问题时有多少个选择。
非正式地,一个动态规划算法的运行时间依赖于两个因素的乘积:子问题的总个数和每个子问题中有多少种选择。

Tips:贪心算法与动态规划有着很多相似之处。特别地,贪心算法适用的问题也具有最优子结构。贪心算法与动态规划有一个显著的区别:贪心算法中,是以自顶向下的方式使用最优子结构的。


一些细微之处

这里想说的就是:要注意在不能应用最优子结构的时候,就一定不能假设它能够应用。
无权最短路径:
找出一条从u到v的包含最少边数的路径。这样的一条路径必须是简单路径,因为从路径中去掉一个回路后,会产生变数更少的路径。
无权最长简单路径:
找出一条从u到v的包含最多变数的简单路径(无环)。我们需要加入简单性的要求,否则,就可以随意地遍历一个回路任意多次来得到有任意多的边数的路径。
对于这两个问题,无权最短路径具有最优子结构(可以用剪贴法来论证);而后者没有,而它是一个NP-Complete事件。


重叠子问题

这个问题其实是DP比递归具有优势的重要原因。

重新构造一个最优解



做备忘录




15.4 最长公共子序列
15.4.1 步骤一:描述一个最长公共子序列
定理15.1 (LSC的最优子结构)
15.4.2 步骤二:一个递归解
15.4.3 步骤三:计算LCS的长度
15.4.4 步骤四:构造一个:LCS

练习题与面试题


后记


相关链接




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值