算法导论——动态规划

动态规划

动态规划问题与分治问题类似。都可以通过组合子问题来求解问题的解。

什么是分治法?

分治法是指将问题划分为互不相交的子问题,然后通过递归或者迭代求解每个子问题,再将子问题的解组合起来得到原问题解的一种策略。

由于分治法的子问题是互斥的,所以解决此类问题应该用递归法,而不是动态规划。

研究问题

动态规划主要研究子问题重叠的情况,由于递归方法在求解子问题重叠的问题时,会将每一个分支产生的问题都计算一遍,而不考虑子问题是否重叠,这样会造成很多重复的计算,在子问题重复度比较高的的情况下,递归算法的时间复杂度可能很高。

而动态规划的产生就是为了克服这种问题,通过将重复子问题保存在一个表格中,在求解时遇到相同的子问题就可以直接取出前面计算的结果,而不用多次计算。

例如在求解斐波那契数列f(n)=f(n-1)+f(n-2) 时,如果采用递归的策略,计算f(n)时要计算f(n-2)的值,计算f(n-1)时还要计算f(n-2)的值,这样就会计算两次f(n-2)的值;

而采用动态规划求解时就可以将第一次计算f(n-2)的值保存下来,后面用到时直接提取即可。

应用场景

动态规划主要用来求解最优化问题

通常用以下4个步骤来设计一个动态规划算法:

①刻画一个最优解的结构特征。

②递归的定义最优解的值。

③计算最优解的值,通常采用自底向上的方法。

④利用计算出的信息构造一个最优解。

如果仅仅需要一个最优解的值,那么我们可以忽略步骤④,如果需要构造出一个最优解,那么我们就需要维护一些额外的信息,来构造出这个最优解。

钢条切割问题

长度12345678910
价格1589101717202430

给定一个长度为n英寸的钢条和一个价格表(如上图),求解切割钢条的方案,使得销售的收益R最大。

长度为n英尺的钢条总共有2^n种不同的切割方案,因为在距离钢条最左端i 英尺处我们总是可以选择切割或者不切割。

如果一个最优解将一个钢条分为k段,那么最优方案
在这里插入图片描述
将钢条分为
在这里插入图片描述
的小段得到最大收益

更为一般的我们可以得到
在这里插入图片描述
max中第一个参数对应不切割,后面的n-1个参数对应n-1中方案(子问题划分),由于不确定哪一种划分方案最优,所以我们将每一种划分都考虑在内,在计算每一种划分的最优解,最后比较所有划分的最优解即可得到原问题的解。

注:从以上中划分策略我们应该有一些对于动态规划问题应该怎么求解的初步感觉,动态规划最主要的三个步骤是:

①刻画一个最优解的结构特征。

②递归的定义最优解的值。

③计算最优解的值,通常采用自底向上的方法。

而其中前两个应该是求解动态规划问题的最核心内容。

刻画一个最优解的结构特征。

钢条最优切割的结构应该是
在这里插入图片描述
其中之一,而通常定义出最优解的结构后,很容易就可以发现递归的子结构,并且刻画最优解结构的本身就是一个子结构的划分过程,即将原始问题转化为几个子问题求解最优的过程,而这种转化有两个个最重要的条件

①转化的子结构是最终最优解的划分,如果这种划分不是最终最优解的划分,那么你即使求解了子问题的最优解,最后综合起来也不是最终问题的最优解,对于钢条切割来说就是要把所有的可能都考虑进去,才能确保最终会有其中一个得到最优解。

②子问题如何整合起来形成最终问题的最优解。对于钢条切割来说比较明显简单,简单相加即可。

递归的定义最优解

在刻画最优解结构时已经定义了递归结构。这里存在一个显而易见的事实,即递归结构内的每一个求解部分的最优解求解结构是相似的,例如斐波那契数列f(n)=f(n-1)+f(n-2) 中f(n),f(n-1),f(n-1),在不考虑其未知数时他们的函数是一样的,也就是说在不考虑n的大小时,这些问题本质都是一样的。

当然这个事实大家并不用去考虑,因为他一般情况下都是成立的,(原因我还没理清)而这一点也是产生状态转移方程的核心。

状态转移方程我理解的最重要的特点就是,如何用他的子问题组成他本身的问题,就像钢条切割中
在这里插入图片描述
本身就是状态转移方程,他本身又是一个递归的壳。

以上分析让我们很容易就类比到函数跟数列的问题当中去。

递归的结构就像是一个映射,也就是状态转移方程就是一个映射,而这种映射有一个特点就是,他的每一个自变量对应因变量也是其自变量,所以当确定自变量的上界时,因变量的上界即可确定。(或许也可以用来证明动态规划的最优解存在性吧,当然很明显也有其他的方法来证明,因为动态规划本质上还是遍历的方法,证明遍历可以求最优解,即证明动态规划的合理性。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值