前言
刷掘金时看到一篇文章
文章原地址:juejin.cn/post/695192...
很有启发,写这篇文章主要是想把自己思路记录下来,只去理解,不涉及代码,文章会有理解不对的地方,希望大佬帮忙指出!!!
- 问题示例
- 什么是动态规划 (Dynamic Programming)?
- 动态规划的核心思想
- 动态规划的解题步骤
- 动态规划与递归的关系
- 动态规划的优缺点
- 总结
问题示例
有人可能好奇为什么直接上例子,在我的习惯中,让我先去看或者理解抽象的概念性东西,还没看完就烦了,不愿意去了解更多,标签一关,下一篇。废话不说直接上例子
在另一篇文章中有一个 --- 青蛙跳阶问题(详情见开头文章链接)
这篇文章主要通过(经典问题)股票买卖问题 来理解动态规划
股票买卖问题--找出最佳的买入和卖出时机以获得最大利润 (模仿力扣121题)
在我不了解动态规划时候很好奇,为什么动态规划可以找出股票最佳的买入和卖出时机,明明股价不可预测,为什么???
js
假设我们有以下股票价格数据,表示未来10天的股价变动:
[7, 1, 5, 3, 6, 4, 8, 2, 9, 10]
我们的目标是找到最佳的买卖点,以获得最大利润。
当我看见这个问题时首先就想到的既然范围给出来了不就是找最大差值吗,遍历一遍不就出来了,但是 股票是不可预测的啊,我怎么知道明天是涨还是跌,是我没理解问题。
这个问题应该理解为这是未来10天的股价,但是我只知道今天的股价,我并不知道后九天的股价, [7] 这才是我现在知道的,我第二天的时候是知道 [7,1] ,以此类推的...
所以 我想要在未来10天找出股票最佳的买入和卖出时机怎么解决?我只能在第二天的时候根据当天的股价然后通过一定逻辑与第一天的股价相比较来得出我天的操作(假设交易次数是没有限制的),我只要保持最大利润就好了,第三天也一样,与利润比较,决定操作,保持最大利润,以此类推。
这样就把一个大问题分解成一个个小问题,然后去解决这一个个小问题,你是不是觉得这怎么和递归这么像,我也是这么觉得的,具体区别下面介绍。
其实介绍到这,这个问题就已经解决了。
什么???已经解决了???
总结:动态规划就是,通过把原问题(未来10天最大利润问题)分解为相对简单的子问题(每一天的最大利润)的方式求解复杂问题,而每一天的最大利润就是通过状态转移方程动态的决定来保持的
状态转移方程:就是上面提到的 "通过一定逻辑" 中的逻辑
是不是对动态规划基本了解了
一开始这个问题最困惑我的是为什么要给定范围,股价是不可预测的为什么会有范围,让我费了好大劲转过来弯。
其实限定范围只不过是为了让我们能直观了解某段问题的最优解,如果问题没有尽头,最优解是没有最终形态的,只是保持当前的最优状态。
一句话:动态规划的关键是在状态转移方程,然后通过问题重叠,动态计算问题最优解
现在我们再来看动态规划的定义!!!
动态规划(英语:Dynamic programming,简称DP)是一种在数学、管理科学、计算机科学、经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。 动态规划常常适用于有重叠子问题和最优子结构性质的问题,动态规划方法所耗时间往往远少于朴素解法。
是不是清晰明了
动态规划的核心思想
- 初始条件
- 分阶段求解
- 最优子结构
- 重叠子问题
- 状态转移方程
- 自底向上计算
是不是也能看懂一点,过于详细的我也不懂,嘿嘿
动态规划的解题步骤
- 定义状态
例如在这个问题中需要定义两个状态分别表示持有股票和不持有股票时的最大利润
- 状态转移方程
你得有判断今天是买还是卖的逻辑吧
- 初始化条件
参数都定义好了你得赋初始值把
- 迭代计算
开始解决问题,计算了吧
- 最终答案
算完了,得输出结果吧
动态规划与递归的关系
在我的理解中,这两个差不太多,会有一些区别
动态规划可以被视为一种更高效的递归方法,因为它在解决问题时避免了重复计算
举个例子:
js
F(5) = F(4) + F(3)
F(4) = F(3) + F(2)
F(3) = F(2) + F(1)
F(2) = F(1) + F(0)
你看F(3),F(2)是不是重复计算了好几次
还有就是递归是从上往下计算,动态规划是自底向上地计算问题的最优解
这么理解:上面的例子用递归是不是先算F(5),再算F(4)这样往下去算,算到最后有值了在往上返回
而动态规划:股票例子中会先分解问题,从第一天开始算然后将每天的最优结果缓存起来直到地十天得出结果。
我是这样理解的不知道对不对,希望大佬指正。
动态规划的优缺点
优点:
- 高效
不用多说吧,肯定高效
- 最优性
它通常能够找到问题的最优解,即全局最优解,而不仅仅是一个可行解。
- 可解决复杂问题
动态规划可以帮助解决一些复杂的组合问题
缺点:
- 难以理解和实现
说了这么多,也能感觉到状态转移方程是核心,也是最难的。
- 内存消耗
需要存储大量中间结果所以内存消耗大一些
- 问题建模难度
怎么去将问题分解为子问题
总结:动态规划通过将问题分解为子问题、定义状态和状态转移方程,以及通过缓存已计算的中间结果来实现高效的问题求解。在解决优化问题方面是个好帮手,但是拆解问题,定义状态转移方程比较困难。
最后,理解不对的地方,望不吝赐教