算法之动态规划
目录:
定义
每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划。
思想与策略
基本思想与分治法类似,也是将待求的问题分解为若干个子问题,按顺序求子问题的解。前一子问题的解,为后一子问题提供有用信息,在求解任意一子问题时,列出所有可能的局部解,通过决策保留那些有可能达到最优的局部解,丢弃其他局部解。依次解决各个子问题,最后一个子问题就是初始问题的解。
由于动态规划的问题多数有重叠子问题这个特点,为减少计算,对每一个子问题,只解一次,将不同阶段的不同状态保存在一个二维数组中
思路:
将以复杂问题分解为多个子问题,无论该子问题是否被用到,只要它被计算过,就将其填入表中。
与分治法的区别
分治法产生的子问题之间相互独立,而动态规划算法产生的子问题之间不是相互独立的,即下一个子阶段的求解是在上一子阶段的求解的基础上,进一步求解
适用情况
- 最优化原理:如果问题的最优解所包含的子问题也是最优的,就称该问题具有最优子结构,即满足最优化原理。
- 无后效性:即某阶段状态一旦确定,就不受这个状态以后决策的影响。也就是说,某状态以后的过程不会影响以前的状态,只与当前状态有关。
- 有重叠子问题:即子问题之间是不独立的,一个子问题在下一阶段决策中可能被多次使用到。(该性质并不是动态规划适用的必要条件,但是如果没有这条性质,动态规划算法同其他算法相比就不具备优势)
基本步骤
初始状态→│决策1│→│决策2│→…→│决策n│→结束状态
- 划分:按照问题的特征,把问题分为若干阶段。注意:划分后的阶段一定是有序的或者可排序的
- 确定状态和状态变量:将问题发展到各个阶段时所处的各种不同的客观情况表现出来。状态的选择要满足无后续性
- 确定决策并写出状态转移方程:状态转移就是根据上一阶段的决策和状态来导出本阶段的状态。根据相邻两个阶段状态之间的联系来确定决策方法和状态转移方程
- 边界条件:状态转移方程是一个递推式,因此需要找到递推终止的条件
算法实现
动态规划三要素:
- 问题的阶段
- 每个阶段的状态
- 相邻两个阶段之间的递推关系
整个求解过程可以用一张最优决策表来描述,最优决策表是一张二维表(行:决策阶段,列:问题的状态)表格需要填写的数据一般对应此问题的在某个阶段某个状态下的最优值(如最短路径,最长公共子序列,最大价值等),填表的过程就是根据递推关系,最后根据整个表格的数据通过简单的取舍或者运算求得问题的最优解。
例如:f(n,m)=max{f(n-1,m), f(n-1,m-w[n])+P(n,m)}
总结下自己想法
注意
这部分是我自己个人想法,可能会实时过来更新,请大家看的时候,带着批判精神,如果有不对,请留言指针
自己理解动态规划
-
需要将问题规模降下来(类似归并),发现子问题
-
发现子问题的最优解,尝试去找到这些最优解的关系(递推式)
-
然后保存这些子问题最优解,拿到递推式,去求更大规模的问题
-
其实这些和高中数学里面 数列很类似
- 例子:
1,1,2,3,5,8 这个数列,让你求 a n a_n an项值
解决问题思路:- 找到通项式
- 前n项和公式 a n = S n + 1 − S n a_n=S_n+1-S_n an=Sn+1−Sn
- 一些复杂数列,是没有通项式和前n项和公式的,这个时候找出n项和前几项之间关系
- 例子:
怎么去找递归式
个人将划为2个等级
1. 能具体数字化整个过程问题,最终结果也是数字
1. 这类问题教简单,可以自己写错一些子问题的最优解结果,然后查看直接关系,找出递推式,下面例子说明
2. 复杂业务场景,不能数字化
1. 目前我也没有比较好的方案找出递推式,摸索中,后续会更新
能具体数字化整个过程问题
爬楼梯
- 题目:
假设你正在爬楼梯。需要 n 步你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
问题:我现在告诉你,这个问题,可以用动态规划,去解决,怎么去找这个递推式呢?. - 我的思路:
-
写出自己能计算出来的子问题最优解
-
猜测子问题最优解的关系
-
用个例证明这部分关系
-
复杂业务场景,不能数字化
例题
- 例子: 爬楼梯