动态规划(也称DP算法)是一种算法设计技术。作为一种使多阶段决策过程最优的通用方法,动态规划是在20世纪50年代由美国数学家理查德-贝尔曼(Richard Bellman)发明的。注意,技术名称“programming”是计划和规划的意思,而不是通常意义上的编程。

动态规划和递归

相同的问题,如果支持使用朴素递归算法和动态规划算法,那么优先使用动态规划算法。这是因为,朴素递归算法需要反复求解相同的子问题。而动态规划方法仔细安排求解顺序,对每个子问题只求解一次,并将结果保存起来。如果随后再次需要此子问题的解,只需查找保存的结果,而不必重新计算。因此,动态规划方法是付出额外的内存空间来节省计算时间,是典型的时空权衡(time memory trade-off)的例子。

递归的等价实现方法

(1)自顶向下法此方法按照自然的递归形式编写过程。在过程中每个子问题的解,依赖子子问题的解。递归算法对每个子问题,每当在递归树(递归调用)中遇到它,都要重新计算一次。

动态规划的两种等价实现方法

动态规划有两种等价实现方法:带备忘的自顶向下法自底向上法
(1)带备忘的自顶向下法。此方法按照自然的递归形式编写过程,但在过程中会保存每个子问题的解(通常保存在一个数组或散列表中)。当需要一个子问题的解时,首先检测是否已经保存过此解。如果是,则直接返回保存的值,从而节省了计算时间;否则,按通常方式计算这个子问题并将计算的结果保存起来。这个递归的过程是“带备忘的”,因为它“记住”了之前已经计算出的结果。
(2)自底向上法。这种方法一般需要恰当定义子问题的“规模”,使得任何子问题的求解都只依赖于“更小的”子问题的求解。因为我们可以将子问题按规模排序,按从小到大的顺序进行求解。当求解某个子问题时,它所依赖的那些更小的子问题都已求解完毕,结果已经保存。每个子问题只需求解一次,当我们求解它(也是第一次遇到它)时,它的所有前提子问题都已求解完成。
两种方法得到的算法具有相同的渐近运行时间,仅有的差异是在某些特殊情况下,自顶向下方法并未真正递归地考察所有可能的子问题。由于没有频繁的递归函数调用的开销,自底向上方法的时间复杂性函数通常具有更小的系数。
如果子问题空间中某些子问题完全不必求解,备忘方法因只会求解那些绝对必要的子问题,所以是一种更好的选择。
如果子问题空间中所有子问题都需求解,自底向上方法因可减少递归调用的开销,所以是一种更好的选择。

动态规划和分治法使用场景

分治法将问题划分为互不相交的子问题,递归地求解子问题,再将它们的解组合起来,求出原问题的解。
动态规划应用于子问题重叠的情况(不同的子问题具有公共的子子问题) 或含最优子结构的问题。
设计一个动态规划算法:
(1) 刻画一个最优解的结构特征;
(2) 递归地定义最优解的值;
(3) 计算最优解的值,通常采用自底向上的方法;
(4) 利用计算出的信息构造一个最优解。
步骤1-3是动态规划算法求解问题的基础。如果仅仅需要一个最优解的值,而非解本身,可以忽略步骤4。如果确实需要步骤4,有时则需要在执行步骤3的过程中维护一些额外信息,以便用来构造一个最优解。

最优子结构性质

用动态规划方法求解最优化问题的第一步就是刻画最优解的结构。(寻找最优子结构)
如果一个问题的最优解包含其子问题的最优解,那么这个问题就具有最优子结构性质。
判断是否包含最优子结构的通用模式:
(1) 做出一个选择。做出这个选择后,会产生一个或多个待解的子问题。
(2) 在做出选择时,假定已经知道哪种选择才能得到最优解。
(3) 给定可获得最优解的选择后,确定这次选择会产生哪些子问题,以及如何最好的刻画子问题空间。
(4) 重复步骤一。作为构成原问题最优解的组成部分,每个子问题的解就是它本身的最优解。
问题的最优解由相关子问题的最优解组合而成,而这些子问题可以独立求解。
一个刻画最优子问题空间的好经验是:保持子问题空间尽可能简单,只在必要时才扩展它。
对不同问题领域,最优子结构的不同体现在两个方面:
(1) 原问题的最优解中涉及多少个子问题;
(2) 在确定最优解使用哪些子问题时,我们需要考察多少种选择。
我们可以用子问题的总数每个子问题需要考察多少种选择这两个因素的乘积来粗略分析动态规划算法的运行时间。

使用最优子结构

在动态规划中,通常自底向上地使用最优结构。也就是说,首先求得子问题的最优解,然后求原问题的最优解。在求解原问题过程中,需要在涉及的子问题中选出可得到原问题最优解的子问题。所以,原问题的最优解通常是子问题的最优解的代价再加上由此次选择直接产生的代价

子问题无关性质

同一个原问题的一个子问题的解不影响另一个子问题的解。

重叠子问题性质

如果问题的递归算法会反复地求解相同的子问题,而不是一直生成新的子问题,那么这个问题具有重叠子问题性质。
动态规划算法通常这样利用重叠子问题的性质:对每个子问题求解一次,将解存入一个表中,当再次需要这个子问题时,可直接查表,每次查表的代价为常量时间(O(1))。

重叠子问题和子问题无关

一个问题是否适合用动态规划求解同时依赖于子问题的无关性和重叠性。虽然这两个要求听起来似乎是矛盾的,但它们描述的是不同的概念而不是同一个坐标轴上的两个点。两个子问题如果不共享资源,它们是独立的、无关的。而重叠是指两个子问题实际是同一个子问题,只是作为不同问题的子问题出现

参考

《算法导论》 第十五章 动态规划 第三版 Tomas H. Cormen etc. 殷建平 等译
《算法设计与分析基础》 第八章 动态规划 第三版 Anany Levitin 著 潘彦 译

动态规划(Dynamic Programming)理论篇相关推荐

  1. 动态规划(Dynamic Programming)的一些事一些情

    References <算法导论> 最近在回顾算法的知识,特将一些动态规划的重点记录下来,好让以后自己不要忘记. 基本概念 动态规划(Dynamic Programming,简称为DP,下 ...

  2. 动态规划 dynamic programming

    动态规划dynamic programming June,7, 2015 作者:swanGooseMan 出处:http://www.cnblogs.com/swanGooseMan/p/455658 ...

  3. 运筹学状态转移方程例子_动态规划 Dynamic Programming

    从运筹学和算法的角度综合介绍动态规划 规划论 Mathematical Programming / Mathematical Optimization In mathematics, computer ...

  4. [欠驱动机器人]4,动态规划(Dynamic Programming)

    目录 前言 控制问题变成优化问题 新增成本(Additive cost) 图搜索的最优控制 连续动力学方程 HJB 方程 求出最小控制 数值求解J 方程逼近与数值迭代 线性方程逼近 网格上的值迭代 连 ...

  5. 动态规划|Dynamic Programming

    由于最近课设要用动态规划,翻阅资料学习一下. 动态规划 解决复杂问题的方法,把它们分解成更简单的子问题. 一旦我们看到一些例子,这个定义就有意义了.实际上,我们今天只看解问题的例子 解决DP问题的步骤 ...

  6. 动态规划(Dynamic Programming)与贪心算法(Greedy Algorithm)

    文章目录 动态规划算法(Dynamic Programming) 动态规划问题的属性 应用实例:最长公共子序列问题(Longest Common Subsequence, LCS) 贪心算法(Gree ...

  7. 算法导论-动态规划(dynamic programming)

    动态规划:通过组合子问题的解来解决整个问题. 动态规划的四个步骤: 1)描述最优解的结构: 2)递归定义最优解的值: 3)按自低向上的方式计算最优解的值(首先找到子问题的最优解,解决子问题,最后找到问 ...

  8. 关于简单动态规划(Dynamic Programming)的总结

    Instructions 综上所述(好像没有上)我的DP真的垃圾的一批... 动态规划是用来避免重复计算状态导致效率低的情况,实现动规有记忆化搜索和填表两种方法,但记忆化搜索不能优化空间,所以常用的是 ...

  9. 算法初探-动态规划(Dynamic Programming)

    编程之中接触到很多关于算法的知识,想来整理一番,算是对自己记忆的一个提醒 1.Coin11Problem  问题为:使用最少的三种面值为1,3,5的硬币组合出11元. 重要的是状态以及状态转移方程 d ...

  10. ADPRL - 近似动态规划和强化学习 - Note 7 - Approximate Dynamic Programming

    Note 7 - 近似动态规划 Approximate Dynamic Programming 7. 近似动态规划 (Approximate Dynamic Programming) 7.1 近似架构 ...

最新文章

  1. 数据中心机房夏日降温措施
  2. (2)zynq FPGA AXI_Lite总线介绍
  3. 计算机里的本地安全策略在哪找,本地安全策略哪里去了?
  4. 查找数组最大值五种方式
  5. 我和计算机专业的故事
  6. AcWing 292 炮兵阵地
  7. Android system_server无法访问sdcard目录问题记录(Android 4.4 mtk平台)
  8. 计算机联锁系统工程设计论文,计算机联锁控制系统论文
  9. 电锤、冲击钻和空心钻的使用方法
  10. SQL语句之操作表记录(CRUD)
  11. 声音驱动提示不完整或已损坏 (代码 19)
  12. Go语言下载安装教程|Goland配置教程|2021|Windows
  13. Cytoskeleton / 艾美捷——泛素化亲和珠
  14. Vue的Watch事件-如何监听对象的属性(字段中间带有点)
  15. 自学Java-day01(初学Java)
  16. 新浪微博,腾讯微博mysql数据库主表猜想
  17. 手把手教你用Scrapy 爬取斗鱼妹子头像 下载图片
  18. adams软件Linux,ADAMS仿真过程中如何提高计算效率,缩短计算时间,相应其他软件也可以类似操作。(原创)...
  19. 珠海化学分析实验室建设思路
  20. Я пpoшý eró гoвоpйть мéдленно.的翻译和不定式成份和不定式做的句子成份...

热门文章

  1. 自动驾驶 9-2: 卡尔曼滤波器和偏置BLUEs Kalman Filter and The Bias BLUEs
  2. 容器技术Docker K8s 1 云原生技术概述
  3. 181.超过经理收入的员工
  4. 关系模型的完整性约束
  5. an argument for principle #1:thoreau's new economics 36-38
  6. CS231n李飞飞计算机视觉 迁移学习之物体定位与检测上
  7. Playing Atari with Deep Reinforcement Learning 中文 讲解2
  8. idf逆文档频率为什么要用log??
  9. 计算机网络超详细笔记(六):传输层
  10. 易语言锐浪报表连接mysql_学习锐浪报表之MySQL连接字符串的实际操作步骤汇总...