『算法』——动态规划算法

动态规划

  • 1、概述
  • 2、原理
  • 3、适用条件
    • 3.1 最优子结构
    • 3.2 无后效性
    • 3.3 子问题重叠
  • 4、求解步骤

1、概述

\quad \quad 动态规划( dynamic programming )算法是解决多阶段决策过程最优化问题的一种常用方法,难度比较大,技巧性也很强。利用动态规划算法,可以优雅而高效地解决很多贪婪算法或分治算法不能解决的问题。动态规划就是将原问题拆解成若干子问题,同时保存子问题的答案,使得每个子问题只求解一次,最终获得原问题的答案。

\quad \quad 动态规划与分治方法相似,都是通过组合子问题的解来求解原问题。

  • 分治方法将问题划分为互不相交的子问题,递归地求解子问题,再将它们的解组合起来,求出原问题的解。
  • 与之相反,动态规划应用于子问题重叠的情况,即不同的子问题具有公共的子子问题(子问题的求解是递归进行的,将其划分为更小的子子问题)。在这种情况下,分治算法会做许多不必要的工作,它会反复的求解那些公共子子问题。而动态规划算法对每个子子问题只求解一次,将其解保存在一个表格中,从而无需每次求解一个子子问题时都重新计算,避免了这种不必要的计算工作。自我理解:动态规划法就是一个表格法,把之前子问题的解保存在表格里。

2、原理

\quad \quad 将待求解的问题分解成若干个相互联系的子问题,先求解子问题,然后从这些子问题的解得到原问题的解;对于重复出现的子问题,只在第一次遇到的时候对它进行求解,并把答案保存起来,让以后再次遇到时直接引用答案,不必重新求解。

3、适用条件

\quad \quad 适合应用动态规划方法求解的最优化问题应该具备以下三个特点:

3.1 最优子结构

\quad \quad 如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构,即满足最优化原理。

3.2 无后效性

\quad \quad 即某阶段状态一旦确定,就不受这个状态以后决策的影响。也就是说,某状态以后的过程不会影响以前的状态,只与当前状态有关。 一般情况下,树形分支结构由根到叶方向的决策都是满足无后效性的。

3.3 子问题重叠

\quad \quad 即子问题之间是不独立的,一个子问题在下一阶段决策中可能被多次使用到。(该性质并不是动态规划适用的必要条件,但是如果没有这条性质,动态规划算法同其他算法相比就不具备优势)。

4、求解步骤

一共有五大步骤。
『算法』——动态规划算法_第1张图片
一、确定动态规划的三要素(状态、状态转移方程、边界条件)

  • 状态:

    状态先尝试题目问什么,就把什么设置为状态。如果不行,就从状态转移方程去思考,状态怎样定义,状态转移方程会容易得出。也就是将题目抽象化。

  • 状态转移方程(核心、难点)

    状态转移就是根据上一阶段的决策和状态来导出本阶段的状态。根据相邻两个阶段状态之间的联系来确定决策方法和状态转移方程。

    技巧是分类讨论。即“对状态空间进行分类”,“大类”可以又“小类”转化而来。

  • 边界条件(初始化):

    边界条件的确定就是需要看哪些元素无法通过状态转移方程得到就是特殊情况的考虑

    角度 1:直接从状态的语义出发。

    角度 2:如果状态的语义不好思考,就考虑“状态转移方程”的边界需要什么样初始化的条件。

    角度 3:从“状态转移方程”方程的下标看是否需要多设置一行、一列表示“哨兵”,这样可以避免一些边界的讨论,使得代码变得比较长。

二、后续完善工作

  • 思考输出:
    输出有些时候是最后一个状态,有些时候可能会综合所有计算过的状态。
  • 思考状态压缩:
    “状态压缩”会使得代码难于理解,初学的时候可以不一步到位。先把代码写正确,然后再思考状态压缩。
    状态压缩在有一种情况下是很有必要的,那就是状态空间非常庞大的时候(处理海量数据),此时空间不够用,就必须状态压缩。

参考资料:
https://blog.csdn.net/lw_power/article/details/103801243

你可能感兴趣的:(数据结构与算法,#,算法,动态规划算法)