动态规划
2023-3-15
| 2023-8-2
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 

动态规划(Dynamic Programming):简称 DP,是一种求解多阶段决策过程最优化问题的方法。在动态规划中,通过把原问题分解为相对简单的子问题,先求解子问题,再由子问题的解而得到原问题的解。
 
动态规划的核心思想:
  • 把「原问题」分解为「若干个重叠的子问题」,每个子问题的求解过程都构成一个 「阶段」。在完成一个阶段的计算之后,动态规划方法才会执行下一个阶段的计算。
  • 在求解子问题的过程中,按照「自顶向下的记忆化搜索方法」或者「自底向上的递推方法」求解出「子问题的解」,把结果存储在表格中,当需要再次求解此子问题时,直接从表格中查询该子问题的解,从而避免了大量的重复计算。
 
这看起来很像是分治算法,但动态规划与分治算法的不同点在于:
  1. 适用于动态规划求解的问题,在分解之后得到的子问题往往是相互联系的,会出现若干个重叠子问题
  1. 使用动态规划方法会将这些重叠子问题的解保存到表格里,供随后的计算查询使用,从而避免大量的重复计算
 
比如斐波那契数列:
通过公式,可以将原问题递归地划分为这两个子问题:
notion image
如果使用传统递归算法计算,需要先计算,而在计算时还需要计算,这样就进行了多次计算。同理都进行了多次计算,从而导致了重复计算问题。
为了避免重复计算,可以使用动态规划中的「表格处理方法」来处理。这里使用「自底向上的递推方法」求解出子问题的解,然后把结果存储在表格中,供随后的计算查询使用。具体过程如下:
  1. 定义一个数组,用于记录斐波那契数列中的值。
  1. 初始化
  1. 根据斐波那契数列的递推公式 ,从 开始递推计算斐波那契数列的每个数,直到计算出
  1. 最后返回 即可得到第 项斐波那契数。
 

动态规划的特征

什么样的问题才可以使用动态规划算法解决呢?能够使用动态规划方法解决的问题必须满足以下三个特征:
  1. 最优子结构性质
    1. 如下图所示,原问题 ,在步选出一个当前最优解之后,问题就转换为求解子问题。如果原问题的最优解可以由「第步得到的局部最优解」和「的最优解」构成,则说明该问题满足最优子结构性质。 也就是说,如果原问题的最优解包含子问题的最优解,则说明该问题满足最优子结构性质。
      notion image
  1. 重叠子问题性质
    1. 指的是在求解子问题的过程中,有大量的子问题是重复的,一个子问题在下一阶段的决策中可能会被多次用到。如果有大量重复的子问题,那么只需要对其求解一次,然后用表格将结果存储下来,以后使用时可以直接查询,不需要再次求解。
      notion image
  1. 无后效性
    1. 指的是子问题的解(状态值)只与之前阶段有关,而与后面阶段无关。当前阶段的若干状态值一旦确定,就不再改变,不会再受到后续阶段决策的影响。也就是说,一旦某一个子问题的求解结果确定以后,就不会再被修改
      举个例子,下图是一个有向无环带权图,在求解从点到点的最短路径问题时,假设当前已知从点到点的最短路径()。那么无论之后的路径如何选择,都不会影响之前从 点到 点的最短路径长度。这就是「无后效性」。
      notion image
      而如果一个问题具有「后效性」,则可能需要先将其转化或者逆向求解来消除后效性,然后才可以使用动态规划算法。
 

动态规划的基本思路

在使用动态规划方法解决某些最优化问题时,可以将解决问题的过程按照一定顺序(时间顺序、空间顺序或其他顺序)分解为若干个相互联系的「阶段」。然后按照顺序对每一个阶段做出「决策」,这个决策既决定了本阶段的效益,也决定了下一阶段的初始状态。依次做完每个阶段的决策之后,就得到了一个整个问题的决策序列。
这样就将一个原问题分解为了一系列的子问题,再通过逐步求解从而获得最终结果。
notion image
这种前后关联、具有链状结构的多阶段进行决策的问题也叫做「多阶段决策问题」。
通常使用动态规划方法来解决问题的基本思路如下:
  1. 划分阶段:将原问题按顺序(时间顺序、空间顺序或其他顺序)分解为若干个相互联系的「阶段」。划分后的阶段⼀定是有序或可排序的,否则问题无法求解。
      • 这里的「阶段」指的是子问题的求解过程。每个子问题的求解过程都构成⼀个「阶段」,在完成前⼀阶段的求解后才会进行后一阶段的求解。
  1. 定义状态:将和子问题相关的某些变量(位置、数量、体积、空间等等)作为一个「状态」表示出来。状态的选择要满足无后效性。
      • 一个「状态」对应一个或多个子问题,所谓某个「状态」下的值,指的就是这个「状态」所对应的子问题的解。
  1. 状态转移:根据「上一阶段的状态」和「该状态下所能做出的决策」,推导出「下一阶段的状态」。或者说根据相邻两个阶段各个状态之间的关系,确定决策,然后推导出状态间的相互转移方式(即「状态转移方程」)。
  1. 初始条件和边界条件:根据问题描述、状态定义和状态转移方程,确定初始条件和边界条件。
  1. 最终结果:确定问题的求解目标,然后按照一定顺序求解每一个阶段的问题。最后根据状态转移方程的递推结果,确定最终结果。
 
 
 
 
 

爬楼梯

题目:假设你正在爬楼梯。需要 n 阶你才能到达楼顶。每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例:
表示爬到第级台阶的方案数,考虑最后一步可能跨了一级台阶,也可能跨了两级台阶,可以列出如下式子:
爬到第 级台阶的方案数是爬到第级台阶的方案数和爬到第级台阶的方案数的和。因为每次只能爬级或级,所以只能从转移过来,要统计方案总数,就需要对这两项的贡献求和。
 
 

不同路径

题目:一个机器人位于一个mxn网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。问总共有多少条不同的路径?
notion image
示例:
表示从左上角走到 的路径数量,其中的范围分别是
由于每一步只能从向下或者向右移动一步,因此要想走到,如果向下走一步,那么会从走过来;如果向右走一步,那么会从走过来。因此可以写出动态规划转移方程:
如果 ,那么 并不是一个满足要求的状态,需要忽略这一项;同理,如果,那么并不是一个满足要求的状态,需要忽略这一项。初始条件为,即从左上角走到左上角有一种方法。最终的答案即为
 
 
 
 
 
  • 计算机基础
  • 数据结构与算法
  • 二分搜索记忆化搜索
    目录