动态规划(DP)

文章目录

  • 动态规划(DP)
    • 1.动态规划概念
    • 2.最短路径问题
    • 3.动态规划和分治区别
    • 4.为什么动态规划往往从后往前?

1.动态规划概念

在现实生活中,有一类活动的过程,由于它的特殊性,可将过程分成若干个互相联系的阶段,在它的每一阶段都需要作出决策,从而使整个过程达到最好的活动效果。因此各个阶段决策的选取不能任意确定,它依赖于当前面临的状态,又影响以后的发展。当各个阶段决策确定后,就组成一个决策序列,因而也就确定了整个过程的一条活动路线.这种把一个问题看作是一个前后关联具有链状结构的多阶段过程就称为多阶段决策过程,这种问题称为多阶段决策问题。在多阶段决策问题中,各个阶段采取的决策,一般来说是与时间有关的,决策依赖于当前状态,又随即引起状态的转移,一个决策序列就是在变化的状态中产生出来的,故有“动态”的含义,称这种解决多阶段决策最优化的过程为动态规划方法

动态规划核心思想:化繁为简,将大问题拆解成一堆小问题,该小问题的解会被重复调用,动态规划通过保存子问题最优解,避免了重复计算,提高了效率,降低时间复杂度,但同时增加了空间复杂度。

2.最短路径问题

问题描述:给定一个矩阵m,从左上角开始每次只能(上下左右)走一步,如遇边界则不可走,最后达到右下角的位置,路径中所有数字累加起来就是路径和,返回所有路径的最小路径和。

为方便描述按XY方向编号,假设从起始点(0,0)到目标点(4,4)需要走n步(在不考虑回头的情况下,不选择已经走过的路,从表格中可以看出总共就是走6步),每一步路径长度对应表格中的数值,记为 C n {C_n} Cn​,每一步在p位置上对应的总路径长度 f ( p ) ( n ) {f_{(p)}}(n) f(p)​(n),直接看一下动态规划的过程。

动态规划过程:

从目标终点往回看。
n = 6
f ( 4 , 4 ) ( 6 ) = 0 {f_{(4,4)}}(6) = 0 f(4,4)​(6)=0,从目标点(4,4)出发,有两个选择。

n = 5

f ( 3 , 4 ) ( 5 ) = f ( 4 , 4 ) ( 6 ) + 1 = 1 {f_{(3,4)}}(5) = {f_{(4,4)}}(6) + 1=1 f(3,4)​(5)=f(4,4)​(6)+1=1
f ( 4 , 3 ) ( 5 ) = f ( 4 , 4 ) ( 6 ) + 4 = 4 {f_{(4,3)}}(5) = {f_{(4,4)}}(6) + 4=4 f(4,3)​(5)=f(4,4)​(6)+4=4

n=4

对于(3,3),可以从(4,3)到达,总路径为: f ( 4 , 3 ) → ( 3 , 3 ) ( 5 ) = f ( 4 , 3 ) ( 5 ) + 6 = 10 {f_{(4,3) \to (3,3)}}(5) = {f_{(4,3)}}(5) + 6=10 f(4,3)→(3,3)​(5)=f(4,3)​(5)+6=10
也可以从(3,4)到达,总路径为: f ( 3 , 4 ) → ( 3 , 3 ) ( 5 ) = f ( 3 , 4 ) ( 5 ) + 1 = 7 {f_{(3,4) \to (3,3)}}(5) = {f_{(3,4)}}(5) + 1=7 f(3,4)→(3,3)​(5)=f(3,4)​(5)+1=7
显然,想要从目标点(4,4)到达(3,3),最优的选择是从(3,4)这一点,所以放弃另外路线。
f ( 2 , 4 ) ( 4 ) = f ( 3 , 4 ) ( 5 ) + 2 = 3 {f_{(2,4)}}(4) = {f_{(3,4)}}(5) + 2=3 f(2,4)​(4)=f(3,4)​(5)+2=3
f ( 3 , 3 ) ( 4 ) = f ( 3 , 4 ) ( 5 ) + 6 = 7 {f_{(3,3)}}(4) = {f_{(3,4)}}(5) + 6=7 f(3,3)​(4)=f(3,4)​(5)+6=7
f ( 4 , 2 ) ( 4 ) = f ( 4 , 3 ) ( 5 ) + 8 = 12 {f_{(4,2)}}(4) = {f_{(4,3)}}(5) + 8=12 f(4,2)​(4)=f(4,3)​(5)+8=12

到这里其实动态规划的优势已初见端倪,我们将整个大的问题,切分成了若干个小的子问题,通过迭代的方式依次求出子问题最优解,所有子问题的最优解之和不一定是全局最优解,但全局最优解一定包含着若干局部最优解。当我们计算每一阶段的目标函数 f ( n ) f(n) f(n)时,只需要用上一阶段的目标函数值加上对应路径长度,即 f ( n ) = f ( n + 1 ) + C ( n ) f(n) = f(n + 1) + C(n) f(n)=f(n+1)+C(n)。
你可能会说:“这有啥,跟暴力搜索有啥区别?”
示例很简单,可以一眼看出下一节点的目标函数值 f ( n ) f(n) f(n),想象一下如果f(6)后面还有10万个节点,那么每一次前进都要遍历一遍前面的路径,这包含了很多重复的计算,计算量也是无法接受的。可以想象如果要从(3,3)前往(4,4)(子问题),中间有很多条路线,我们只需要计算一遍并记住最短的一条(最优解)即可,从而避免了重复的计算(搜索)。

小结一下,动态规划通过将问题切分,化繁为简,使得每一个子问题小到可以轻松计算,记录节点(子问题的最优解)的值,快速迭代产生下一节点的值,免去了重复的计算(搜索)。当然这也付出一定代价,需要(内存)记住节点上所有的可行解,当可行解多到(内存)记不住时,这又是另一话题了。

动态规划算法的关键在于解决冗余,这是动态规划算法的根本目的。动态规划实质上是一种以空间换时间的技术,它在实现的过程中,不得不存储产生过程中的各种状态,所以它的空间复杂度要大于其他的算法。选择动态规划算法是因为动态规划算法在空间上可以承受,而搜索算法在时间上却无法承受,所以我们舍空间而取时间。

n=3
同理,根据 f ( n ) = f ( n + 1 ) + C ( n ) f(n) = f(n + 1) + C(n) f(n)=f(n+1)+C(n)依次计算各个目标函数值。
f ( 1 , 4 ) ( 3 ) = f ( 2 , 4 ) ( 4 ) + 9 = 12 {f_{(1,4)}}(3) = {f_{(2,4)}}(4) + 9=12 f(1,4)​(3)=f(2,4)​(4)+9=12
f ( 2 , 3 ) ( 3 ) = f ( 2 , 4 ) ( 4 ) + 3 = 6 {f_{(2,3)}}(3) = {f_{(2,4)}}(4) + 3=6 f(2,3)​(3)=f(2,4)​(4)+3=6
f ( 3 , 2 ) ( 3 ) = f ( 3 , 3 ) ( 4 ) + 1 = 8 {f_{(3,2)}}(3) = {f_{(3,3)}}(4) + 1=8 f(3,2)​(3)=f(3,3)​(4)+1=8
f ( 4 , 1 ) ( 3 ) = f ( 4 , 2 ) ( 4 ) + 8 = 20 {f_{(4,1)}}(3) = {f_{(4,2)}}(4) + 8=20 f(4,1)​(3)=f(4,2)​(4)+8=20

n=2
f ( 1 , 3 ) ( 2 ) = f ( 2 , 3 ) ( 3 ) + 5 = 11 {f_{(1,3)}}(2) = {f_{(2,3)}}(3) + 5=11 f(1,3)​(2)=f(2,3)​(3)+5=11
f ( 2 , 2 ) ( 2 ) = f ( 2 , 3 ) ( 3 ) + 1 = 7 {f_{(2,2)}}(2) = {f_{(2,3)}}(3) + 1=7 f(2,2)​(2)=f(2,3)​(3)+1=7
f ( 3 , 1 ) ( 2 ) = f ( 3 , 2 ) ( 3 ) + 5 = 13 {f_{(3,1)}}(2) = {f_{(3,2)}}(3) + 5=13 f(3,1)​(2)=f(3,2)​(3)+5=13

n=1
f ( 1 , 2 ) ( 1 ) = f ( 2 , 2 ) ( 2 ) + 3 = 10 {f_{(1,2)}}(1) = {f_{(2,2)}}(2) + 3=10 f(1,2)​(1)=f(2,2)​(2)+3=10
f ( 2 , 1 ) ( 1 ) = f ( 2 , 2 ) ( 2 ) + 6 = 13 {f_{(2,1)}}(1) = {f_{(2,2)}}(2) + 6=13 f(2,1)​(1)=f(2,2)​(2)+6=13

至此,可以得到最短路径:0-3-1-3-2-1-0, f = 10 f=10 f=10

3.动态规划和分治区别

动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
动态规划算法:它通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应于一个值,我们希望找到具有最优值的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。

分治法:若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。

总而言之就是,只要之前计算过的结果,动态规划都会保存结果,而再次用到时不会再算一遍,而是直接调用结果。

4.为什么动态规划往往从后往前?


两种方法得到的算法具有相同的渐近运行时间,仅有的差异是在某些特殊情况下,自顶向下方法有可能并未真正递归地考察所有可能的子问题。由于没有频繁的递归函数调用的开销,自底向上的方法的时间复杂性函数通常具有更小的系数。
(以上图片来自 算法导论 第15章动态规划。)

简单的来说,带备忘的自顶向下法即遇到什么就求什么,求完把结果保存起来,下次用到的时候直接读取结果。自底向上也类似,不过是按参数顺序求解函数,从结果反推,先求小的再求大的。

动态规划的理解(DP)相关推荐

  1. 算法模板:动态规划之线性DP【沈七】

    算法模板:动态规划之线性DP 前言 线性DP 数字三角形模型 摘花生 最小路径和 不同路径模型 不同路径(有障碍) 过河卒 (综合应用) 最长上升子序列模型 木棍加工 导弹拦截 完结散花 参考文献 前 ...

  2. 动态规划之线性DP题集

    动态规划之线性DP 文章目录 动态规划之线性DP (一)LIS问题 最长上升子序列 (朴素动规) (二分+贪心+动规) 最大子序和 (动规) (贪心) 最长连续递增序列 (动规) (双指针) 俄罗斯套 ...

  3. 蓝桥杯备考-刷题之路-动态规划算法(DP算法)Part1

    之前在刷力扣的时候就是浑浑噩噩的,照着评论区的答案写了一遍就万事大吉了,没有深度思考过.这次备考蓝桥杯看到DP算法的第一道题就不会,更难受的是看答案了依然完全不理解,所以决心把DP算法一次弄懂. 开始 ...

  4. 动态规划练习三:换钱问题(动态规划概念理解与记忆搜索法概念理解对比)

    题目描述 给定数组arr,数组中所有的值都为正数,且不为空不重复.数组中每个数代表一种货币的面值,每种面值的货币可以使用任意张,然后,给一个aim,代表要换钱的面值,请问,用数组中的面值换钱,总共有多 ...

  5. 【算法模板】动态规划(基础DP篇)

    [算法模板]动态规划(基础DP篇)

  6. 动态规划 —— 状压 DP

    [概述] 通常将以一个集合内的元素信息作为状态且状态总数为指数级别的动态规划称为状态压缩动态规划. 其是一类以集合信息为状态的特殊的动态规划问题,主要有传统集合动态规划与基于连通性状态压缩的动态规划两 ...

  7. 动态规划的理解与案例分析

    动态规划的本质 常用的五大算法,包含 动态规划.分治法.贪心求解法.回朔法.分支限界法. 动态规划(Dynamic Programming),与其说是一种算法,不如说是一种解决问题的思路. :peac ...

  8. ACM 动态规划(简称dp) 分类

    转载自:   http://blog.csdn.net/cc_again?viewmode=list          ----------  Accagain  2014年5月15日 动态规划博客地 ...

  9. 由NP完全问题引出动态规划——状态压缩DP

    " 所有部分都应当在非强制的情况下组合回一起.要记住,你重组的那部分原来就是你拆解的.因此,如果你不能让它们组合回来的话,那一定是有原因的.要想尽一切办法,除了用锤头." – IB ...

最新文章

  1. pandas dataframe bool索引的使用
  2. CSS学习笔记(二) ----盒子模型
  3. JDK/Java 14 正式发布!然而我还在用 Java 8...
  4. sql 获取两个月内数据_如何在3个月的时间内自学成为数据分析师?
  5. vuejs 过渡效果
  6. 我心中的MySQL DBA
  7. 我们多么想要新的Java日期/时间API?
  8. 作者:孟凡(1989-),男,中国科学院大学经济与管理学院、中国科学院大数据挖掘与知识管理重点实验室博士生...
  9. 带宽与码元的关系_再遇到码元、速率、、带宽【9】
  10. ROS入门 小乌龟跟随示例
  11. via浏览器下载路径_Via安卓浏览器(软件篇)
  12. prepareStatement的用法和解释
  13. 《从零开始学Swift》学习笔记(Day 13)——数据类型之整型和浮点型
  14. 谷粒商城:06. 前端开发基础知识
  15. SiTime硅晶振解决方案—汽车摄像头
  16. 用HTML5制作简单的个人简历
  17. Python打印2018年的日历(【问题描述】 打印2018年的日历 【输入形式】 【输出形式】 【样例输入】 【样例输出】)
  18. 如何使用xxl-job分布式任务调度平台 | 定时任务
  19. 鉴源丨车载ECU嵌入式设备的诊断测试 - 会话和安全控制
  20. speedoffice使用方法-word怎么添加边框

热门文章

  1. 大学计算机实验图灵机模型与计算机硬件,实验1图灵机模型与计算机硬件系统虚拟拆装实验报告.pdf...
  2. 浙大计算机专业是不是图灵班,浙大图灵班录取条件
  3. 如何划分测试集和训练集
  4. 游戏直播的下一站在哪?战旗TV开启线上线下联动
  5. Android 怎么防止多并发请求?比如说一个页面需要请求多个接口,可以跟后台网络交互能做哪些性能优化
  6. CentOS 7 最小化系统安装图形化桌面
  7. CodeForces - 1129C Morse Code
  8. 和平精英显示模拟服务器已满,和平精英模拟器注册已经达到了上限怎么办?原因及解决方法分享...
  9. 前端学习笔记--AJAX的应用(三)form表单改为AJAX提交
  10. 【基础】Flink -- DataStream API