动态规划 算法(DP)

时间:2021-07-12 21:41:33

多阶段决策过程(multistep decision process)是指这样一类特殊的活动过程,过程可以按时间顺序分解成若干个相互联系的阶段,在每一个阶段都需要做出决策,全部过程的决策是一个决策序列。动态规划(dynamic programming)算法是解决多阶段决策过程最优化问题的一种常用方法,难度比较大,技巧性也很强。利用动态规划算法,可以优雅而高效地解决很多贪婪算法或分治算法不能解决的问题。动态规划算法的基本思想是:将待求解的问题分解成若干个相互联系的子问题,先求解子问题,然后从这些子问题的解得到原问题的解;对于重复出现的子问题,只在第一次遇到的时候对它进行求解,并把答案保存起来,让以后再次遇到时直接引用答案,不必重新求解。动态规划算法将问题的解决方案视为一系列决策的结果,与贪婪算法不同的是,在贪婪算法中,每采用一次贪婪准则,便做出一个不可撤回的决策;而在动态规划算法中,还要考察每个最优决策序列中是否包含一个最优决策子序列,即问题是否具有最优子结构性质。

动态规划算法的有效性依赖于待求解问题本身具有的两个重要性质:最优子结构性质和子问题重叠性质。

1、最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。

2、子问题重叠性质。子问题重叠性质是指在用递归算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的解题效率。

当我们已经确定待解决的问题需要用动态规划算法求解时,通常可以按照以下步骤设计动态规划算法:

1、分析问题的最优解,找出最优解的性质,并刻画其结构特征;

2、递归地定义最优值;

3、采用自底向上的方式计算问题的最优值;

4、根据计算最优值时得到的信息,构造最优解。

1~3步是动态规划算法解决问题的基本步骤,在只需要计算最优值的问题中,完成这三个基本步骤就可以了。如果问题需要构造最优解,还要执行第4步;此时,在第3步通常需要记录更多的信息,以便在步骤4中,有足够的信息快速地构造出最优解。

下面通过对具体实例的分析,帮助大家领会可用动态规划算法求解的问题应具有的两个性质以及动态规划算法的设计思想。

例:拦截导弹(问题来源:1999年全国青少年信息学(计算机)奥林匹克分区联赛高中组复赛试题第一题)

某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。

输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000 的正整数),计算这套系统最多能拦截多少导弹,并依次输出被拦截的导弹飞来时候的高度。

样例:

INPUT

389 207 155 300 299 170 158 65

OUTPUT

6(最多能拦截的导弹数)

389 300 299 170 158 65

分析:因为只有一套导弹拦截系统,并且这套系统除了第一发炮弹能到达任意高度外,以后的每一发炮弹都不能高于前一发炮弹的高度;所以,被拦截的导弹应该按飞来的高度组成一个非递增序列。题目要求我们计算这套系统最多能拦截的导弹数,并依次输出被拦截导弹的高度,实际上就是要求我们在导弹依次飞来的高度序列中寻找一个最长非递增子序列。

设X={x1,x2,…,xn}为依次飞来的导弹序列,Y={y1,y2,…,yk}为问题的最优解(即X的最长非递增子序列),s为问题的状态(表示导弹拦截系统当前发送炮弹能够到达的最大高度,初值为s=∞——第一发炮弹能够到达任意的高度)。如果y1= x1,即飞来的第一枚导弹被成功拦截。那么,根据题意“每一发炮弹都不能高于前一发的高度”,问题的状态将由s=∞变成s≤x1(x1为第一枚导弹的高度);在当前状态下,序列Y1={y2,…,yk}也应该是序列X1={x2,…,xn}的最长非递增子序列(大家用反证法很容易证明)。也就是说,在当前状态s≤x1下,问题的最优解Y所包含的子问题(序列X1)的解(序列Y1)也是最优的。这就是拦截导弹问题的最优子结构性质。

设D(i) 为第i枚导弹被拦截之后,这套系统最多还能拦截的导弹数(包含被拦截的第i枚)。我们可以设想,当系统拦截了第k枚导弹xk,而xk又是序列X={x1, x2,…,xn}中的最小值,即第k枚导弹为所有飞来的导弹中高度最低的,则有D(k)=1;当系统拦截了最后一枚导弹xn,那么,系统最多也只能拦截这一枚导弹了,即D(n)=1;其它情况下,也应该有D(i)≥1。根据以上分析,可归纳出问题的动态规划递归方程为:

假设系统最多能拦截的导弹数为dmax(即问题的最优值),则

dmax   (i为被系统拦截的第一枚导弹的顺序号) 

所以,要计算问题的最优值dmax,需要分别计算出D(1)、D(2)、……D(n)的值,然后将它们进行比较,找出其中的最大值。根据上面分析出来的递归方程,我们完全可以设计一个递归函数,采用自顶向下的方法计算D(i)的值。然后,对i从1到n分别调用这个递归函数,就可以计算出D(1)、D (2)、……D(n)。但这样将会有大量的子问题被重复计算。比如在调用递归函数计算D(1)的时候,可能需要先计算D(5)的值;之后在分别调用递归函数计算D(2)、D(3)、D(4)的时候,都有可能需要先计算D(5)的值。如此一来,在整个问题的求解过程中,D(5)可能会被重复计算很多次,从而造成了冗余,降低了程序的效率。

其实,通过以上分析,我们已经知道:D(n)=1。如果将n作为阶段对问题进行划分,根据问题的动态规划递归方程,我们可以采用自底向上的方法依次计算出D(n-1)、D(n-2)、……D(1)的值。这样,每个D(i)的值只计算一次,并在计算的同时把计算结果保存下来,从而避免了有些子问题被重复计算的情况发生,提高了程序的效率。算法代码如下:

for i=1 to n

D(i)=1

next i

for i=n-1 to 1 step -1

for j=i+1 to n

if x(j)<=x(i) and D(i)<D(j)+1 then

D(i)=D(j)+1

endif

next j

next i

dmax=0:xh=1

rem dmax用来保存问题的最优值(系统最多能拦截的导弹数);xh用来保存第一枚被拦截的导弹的顺序号,以便后面构造最优解

for i=1 to n

if D(i)>dmax then

dmax=D(i)

xh=i

endif

next i

我们在计算最优值时保存了被拦截的第一枚导弹的顺序号xh。接下来通过这个信息构造问题的最优解(由所有被拦截的导弹的高度组成的非递增序列)。算法代码如下:

print x(xh)

for i=xh+1 to n

if x(i)<=x(i-1) then

print x(i)

endif

next i

结束语:动态规划算法和贪婪算法都是构造最优解的常用方法。动态规划算法没有一个固定的解题模式,技巧性很强。可以说,动态规划算法在实际生活中的每一次应用都是一种创造。大家要多练习,多实践,从实践中领会动态规划算法的精髓,不断提高自己的应用能力

动态规划 算法(DP)的更多相关文章

  1. 动态规划算法(Dynamic Programming,简称 DP)

    动态规划算法(Dynamic Programming,简称 DP) 浅谈动态规划 动态规划算法(Dynamic Programming,简称 DP)似乎是一种很高深莫测的算法,你会在一些面试或算法书籍 ...

  2. 从最长公共子序列问题理解动态规划算法(DP)

    一.动态规划(Dynamic Programming) 动态规划方法通常用于求解最优化问题.我们希望找到一个解使其取得最优值,而不是所有最优解,可能有多个解都达到最优值. 二.什么问题适合DP解法 如 ...

  3. 五大常用算法之二:动态规划算法(DP)

    一.基本概念 动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移.一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划. 二.基本思想与策略 基本 ...

  4. 剑指Offer——动态规划算法

    剑指Offer--动态规划算法 什么是动态规划? 和分治法一样,动态规划(dynamic programming)是通过组合子问题而解决整个问题的解. 分治法是将问题划分成一些独立的子问题,递归地求解 ...

  5. 多线程动态规划算法求解TSP&lpar;Traveling Salesman Problem&rpar; 并附C语言实现例程

    TSP问题描述: 旅行商问题,即TSP问题(Travelling Salesman Problem)又译为旅行推销员问题.货郎担问题,是数学领域中著名问题之一.假设有一个旅行商人要拜访n个城市,他必须 ...

  6. 强化学习(三)用动态规划(DP)求解

    在强化学习(二)马尔科夫决策过程(MDP)中,我们讨论了用马尔科夫假设来简化强化学习模型的复杂度,这一篇我们在马尔科夫假设和贝尔曼方程的基础上讨论使用动态规划(Dynamic Programming, ...

  7. 【转载】 强化学习(三)用动态规划(DP)求解

    原文地址: https://www.cnblogs.com/pinard/p/9463815.html ------------------------------------------------ ...

  8. 【学习笔记】动态规划—各种 DP 优化

    [学习笔记]动态规划-各种 DP 优化 [大前言] 个人认为贪心,\(dp\) 是最难的,每次遇到题完全不知道该怎么办,看了题解后又瞬间恍然大悟(TAT).这篇文章也是花了我差不多一个月时间才全部完成 ...

  9. 动态规划算法模板和demo

    366. 斐波纳契数列 中文 English 查找斐波纳契数列中第 N 个数. 所谓的斐波纳契数列是指: 前2个数是 0 和 1 . 第 i 个数是第 i-1 个数和第i-2 个数的和. 斐波纳契数列 ...

随机推荐

  1. Python-Django进阶

    1. 路由系统 浏览器会自动给url后加一个"/" django会自动给路由的正则表达式前面加一个"/" django会给任何不带"/"结尾 ...

  2. Web jquery表格组件 JQGrid 的使用 - 全部代码

    系列索引 Web jquery表格组件 JQGrid 的使用 - 从入门到精通 开篇及索引 Web jquery表格组件 JQGrid 的使用 - 4.JQGrid参数.ColModel API.事件 ...

  3. angularJs之&dollar;watch监听属性变化访问后台

  4. A20(Cubieboard2)启动过程浅析

    A20支持从NAND Flash.SPI NOR Flash.SD card(SDC 0/2)和USB启动.当系统上电时,首先检测Boot Select Pin(BSP)管脚,如果为低电平,则直接从U ...

  5. 分享我收集的引擎、图形学、WebGL方面的电子资料

    本文分享我这一年以来收集的我认为比较经典的电子资料,希望能对大家有所帮助! 本文会不断更新! 目录 WebGL Insights OpenGL Insights Game Programming Pa ...

  6. IOS 学习笔记&lpar;3&rpar; 视图UITabbarController

    1.UITabbarViewController标签试图控制器.由于标签页本就起着分类的作用,所以往往呈现的视图内容之间,可以是毫不相关的功能. UITabbarViewController仍然继承自 ...

  7. PHP系列目录

    原文:PHP系列目录 PHP系列的对象是已经熟悉了一门或多门语言的开发人员.如果你是其中一份子,而且你也打算学习PHP,相信你根据本系列会很快掌握PHP的.欢迎大家给出意见或建议.同时也欢迎大家的批评 ...

  8. 在Vue中通过自定义指令获取元素

    vue.js 是数据绑定的框架,大部分情况下我们都不需要直接操作 DOM Element,但在某些时候,我们还是有获取DOM Element的需求的: 在 vue.js 中,获取某个DOM Eleme ...

  9. VUE组件间数据方法的传递,初步了解

    父组件的数据传递到子组件: 子组件:(其中fMsg是要从父组件传递过来的数据,注意fMsg要在子组件props里先定义) 父组件:(使用v-bind,将自身数据绑定给中转属性fMsg,从而通过 子组件 ...

  10. JS中的一元操作符

    表达式 一元操作符 优先级 结合性 运算顺序 表达式是什么? 就是JS 中的一个短语,解释器遇到这个短语以后会把对它进行计算,得到一个结果参与运算,我们把这种要参与到运算中的各种各样的短语称为表达式. ...