算法设计与分析(3)——动态规划

博客内容主要是以 北京大学 屈婉玲老师的 MOOC 视频来写的。视频共是十周的内容,我决定用篇博客完成。

温馨提示:这个课程不仅适用于 算法设计与分析 的学习,也非常适用于 数学建模 的学习,如果是学习 数学建模的基础部分,前两周的内容是非常适合的,如果要进一步学习 建模思想,建议把这十周视频好好看一遍。( •̀ ω •́ )y

我们还是先来看一下这十周视频的思维导图:在这里插入图片描述
在这篇博客中写的是五、六周的内容:动态规划。

第五周

知识点

动态规划算法:
多阶段决策过程。每步求解的问题是后面阶段求解问题的子问题。每步决策将依赖于以前步骤的决策结果。可用于求解组合优化问题。

优化原则:
最优子结构性质
一个最优决策序列的任何子序列本身一定是相对于子序列的初始和结束状态的最优决策序列

适用条件:
问题要满足优化原则或最优子结构性质,即:一个最优决策序列的任何子序列本身一定是相对于子序列的初始和结束状态的最优决策序列

动态规划设计要素:
1.问题建模,优化的目标函数是什么?约束条件是什么?
2.如何划分子问题(边界) ?
3.问题的优化函数值与子问题的优化函数值存在着什么依赖关系?(递推方程)
4.是否满足优化原则?
5.最小子问题怎样界定?其优化函数值,即初值等于什么?

动态规划算法的递归实现:
与蛮力算法相比较,动态规划算法利用了子问题优化函数间的依赖关系,时间复杂度有所降低。

但是动态规划算法的递归实现效率不高,原因在于同一个子问题多次重复出现,每次出现都需要重新计算一遍。

继续优化:采用空间换时间策略,记录每个子问题首次计算结果,后面再用时就直接取值,每个子问题只算一次。

动态规划算法的迭代实现:
迭代计算的关键:
每个子问题只计算一次。

迭代过程:
(1)从最小的子问题算起;
(2)考虑计算顺序,以保证后面用到的值前面已经计算好;
(3)存储结构保存计算结果——备忘录。

解的追踪:
(1)设计标记函数 标记每步的决策
(2)考虑根据标记函数 追踪解的算法

动态规划递归实现与迭代实现的比较:
递归实现:时间复杂性高,空间较小
迭代实现:时间复杂性低,空间消耗多

原因:
递归实现子问题多次重复计算,子问题计算次数呈指数增长。
迭代实现每个子问题只计算一次。

动态规划时间复杂度:
备忘录各项计算量之和 + 追踪解工作量
通常追踪工作量是问题规模 的多项式函数,不超过计算工作量。

动态规划算法的步骤:
(1)划分子问题,确定子问题边界,将问题求解转变成多步判断的过程。
(2)定义优化函数,以该函数极大(或极小)值作为依据,确定是否满足优化原则
(3)列优化函数的递推方程和边界条件。
(4)自底向上计算,设计备忘录(表格)。
(5)考虑是否需要设立标记函数
(6)用递推方程或备忘录估计时间复杂度

矩阵链相乘

蛮力算法时间复杂度:是指数级别;
动态规划递归时间复杂度:指数级别;
动态规划迭代时间复杂度:O(n^3)。

投资问题

投资问题的动态规划算法:
用两个不同类型的参数界定子问题
优化函数的递推方程及初值
根据备忘录中项的计算估计时间复杂度
时间复杂度为:O(n*m^2)

问题描述:




背包问题

动态规划算法解背包问题时间复杂度:O(nb)

最长公共子序列

注意:子序列与子串是不同的

蛮力算法:
最坏情况下时间复杂度:O(n*2^m)

动态规划算法的时空复杂度:
算法时间复杂度:θ(mn)
空间复杂度:θ(mn)

小结

小结部分可参考上面的知识点。
核心部分就是动态规划的优先原则和适用条件,也可以说是性质。

第六周

图像压缩

追踪解的时间复杂度是:O(n)

最大子段和

问题描述

算法一:蛮力算法
思路:对所有的(i,j)对,顺序求和,比较得出最大的和。

时间复杂度:O(n^3)

算法二:分治策略
思路:将数组分成左右两半,分别计算左边的最大和、右边的最大和、跨边界的最大和,然后比较其中最大者。

时间复杂度:O(nlogn)

算法三:动态规划
思路:
子问题界定
列优化函数的递推方程和边界条件(不一定是原函数的优化函数)
自底向上计算,设计备忘录(表格)
如何根据动态规划的解找原问题的解

时间复杂度:O(n)
空间复杂度:O(n)



最优二叉检索树的概念

最优二叉检索树的算法

关键问题:
子问题边界界定
如何将该问题归结为更小的子问题
优化函数的递推方程及初值
计算顺序
是否需要标记函数
时间复杂度分析

思路:
(1)划分子问题,以数据结点作为树根
(2)定义优化函数,列出递推方程与边界条件
(3)自底向上计算,设计备忘录(表格)
(4)设立标记函数记录构成最优二叉搜索树或子树时根的位置
(5)时间复杂度估计

时间复杂度:T(n) = O(n^3)
空间复杂度:S(n) = O(n^2)

RNA二级结构预测

思路:
(1)划分子问题,确定子问题边界 i,j 与归约方法
(2)定义优化函数,列递推方程和初值
(3)自底向上计算,设计备忘录(表格)
(4)设立标记函数,记下最优划分位置
(5)时间复杂度估计

算法的时间复杂度:O(n^3)

序列比对

意义:
为确定两个序列之间的相似性或同源性,将它们按照一定的规律排列,进行比对。

应用:
生物信息学中用于研究同源性,如蛋白质序列或DNA序列。在比对中,错配与突变相对应,空位与插入或缺失相对应。
计算语言学中用于语言进化或文本相似性的研究。

序列之间的编辑距离:
给定两个序列 S1 和 S2 ,通过一系列字符编辑(插入、删除、替换)等操作,将 S1 转变成 S2。完成这种转换所需要的最少的编辑操作个数称为 S1 和 S2 的编辑距离。

算法时间度:O(nm)

实例:



五六周小结

动态规划算法设计要点:
(1)引入参数来界定子问题的边界。注意子问题的重叠程度。
(2)给出带边界参数的优化函数定义与优化函数的递推关系,找到递推关系的初值。
(3)判断该优化问题是否满足优化原则。
(4)考虑是否需要标记函数。
(5)采用自底向上的实现技术,从最小的子问题开始迭代计算,计算中用备忘录保留优化函数和标记函数的值。
(6)动态规划算法的时间复杂度是对所有子问题(备忘录)的计算工作量求和(可能需要追踪解的工作量)
(7)动态规划算法一般使用较多的存储空间,这往往成为限制动态规划算法使用的瓶颈因素。

适用条件:
问题要满足优化原则或最优子结构性质,即:一个最优决策序列的任何子序列本身一定是相对于子序列的初始和结束状态的最优决策序列

动态规划递归实现与迭代实现的比较:
递归实现:时间复杂性高,空间较小
迭代实现:时间复杂性低,空间消耗多

原因:
递归实现子问题多次重复计算,子问题计算次数呈指数增长。
迭代实现每个子问题只计算一次。

动态规划时间复杂度:
备忘录各项计算量之和 + 追踪解工作量
通常追踪工作量是问题规模 的多项式函数,不超过计算工作量。

猜你喜欢

转载自blog.csdn.net/xiaobai_qian/article/details/106455022