动态规划和贪心算法

一、动态规划

1、动态规划与分治方法相似,都是通过组合子问题的解来求解原问题的解。分治法将互不相交的子问题分别求解,再组合起来;与之相反,动态规划应用于子问题重叠的情况,即不同的子问题有公共的子子问题,在这种情况下,分治法会做许多不必要的工作(对重复的子问题反复求解)

2、动态规划方法通常用来求解最优化问题,这类问题可以有很多可行解,每个解都有一个值,我们希望寻找具有最优值的解,我们称这样的解为问题的一个最优解

3、动态规划的两个性质:

(1)、最优子结构:如果一个问题的最优解包含其问题的最优解,我们就称子问题具有最优子结构性质,也正是由于这个性质,我们通常用子问题的最优解来构造原问题的最优解

在发掘最优子结构的过程中,有如下的通用模式:

[1]、证明问题最优解的第一个组成部分是做出一个选择,例如,要不要拿第i个物品(01背包),做出这次选择会产生一个或多个待解的子问题

[2]、假定我已经知道了何种选择是得到最优解的,确定这次选择会产生哪些子问题,以及如何最好地刻画子问题空间(尽量保证子问题空间简单,必要时扩展它)

[3]、证明作为构成原问题最优解的组成部分,每个子问题的解就是他本身的最优解

注意问题是否有最优子结构性质,有如下例题:

无权最短路径、无权最长简单路径

对于无权最短路径来说,从某一点的最优解依赖于下一点的最优解

而对无权最长简单路径来说,某一点的最长路不依赖于下一个点

 如图,从A->D最长路是ABD,而对于子问题A->B来说,最长路是ACDB,B->D是BACD,合并得到ACDBACD,不满足简单路径这一条件

两个问题都用到了子问题,而最长简单子路径的子问题是相关的,而最短路径的子问题是无关的,这里无关是指:同一个原问题的一个子问题不影响另一个子问题的解。

例如在刚刚的最长简单路径中,A->B的最长路经过了CD,在“简单”的影响下,B->D不可以经过CD(子问题相互影响)

(2)、重叠子问题:动态规划问题的第二个性质是子问题空间必须足够“小”,也就是说,问题的递归算法会求解相同的子问题,而不是一直生成新的子问题(分治法求解的问题在每一步递归都生成全新的子问题)

4、使用动态规划求解问题:

(1)、带备忘的自顶向下法,简而言之,就是暴力递归+缓存表。对重复的问题不再重复求解

(2)、自底向上法,由于子问题的求解依赖于更小的子问题的求解,我们将子问题的规模按大小排序,按由小至大的顺序进行求解,这样在求解某一个子问题时会依赖于上一个求解的子问题

两种方法拥有相同的渐进运行时间,由于没有频繁的递归函数调用的开销,自底向上的方法复杂度较低

二、贪心算法

1、求解最优化问题的算法通常需要经过一系列的步骤,在每个步骤都面临多种选择,有很多最优化问题使用动态规划有些杀鸡用牛刀了,此时就需要我们的贪心算法

2.贪心算法的两个性质:

(1)、最优子结构:这是能否应用动态规划和贪心算法的关键要素。当应用于贪心算法时,我们通常使用更为直接的最优子结构,通过对原问题应用贪心选择就可以得到子问题,我们需要证明的是:将子问题的最优解与贪心选择组合在一起就可以生成原问题的最优解

(2)、贪心选择性质:我们可以通过做出局部最优(贪心)选择来构造全局最优解,换句话说,当进行选择时,我们直接做出在当前问题中看来最优的选择,而不必考虑子问题的解

这也是贪心算法与动态规划的不同,在动态规划中,每个步骤都要进行一次选择,但选择通常依赖于子问题的解,因此我们通常以自底向上的方式求解动态规划(先小后大);在贪心算法中,我们总是做出当前最优,然后求解剩下的唯一的子问题,贪心算法在进行选择时可能依赖之前做出的选择,但不依赖于将来的选择或子问题的解。

因此,动态规划先求解最问题才能进行第一次选择不同,而贪心在第一次选择之前不需要求解子问题,一个动态规划往往是自底向上计算的,而贪心算法通常是自顶向下,进行一次又一次选择,将给定问题实例变得更小

以下例子很明显地展现出动态规划和贪心算法的区别与联系:

01背包问题与分数背包问题(物品可拆分)

零钱问题两种求解方法

在进行贪心选择时,我们不得不考虑众多选择,这通常意味着可以同排序或者其他数据结构(优先队列)改进贪心选择

其实贪心算法是一种特殊的动态规划,由于其具有贪心选择性质,保证了子问题只会被计算一次,不会被多次计算,因此贪心算法其实是最简单的动态规划。、

3、使用贪心算法求问题步骤:

(1)、将最优化问题转化为这样的形式:对其做出一次选择后,只剩下一个子问题需要求解

(2)、证明做出贪心选择后,原问题总是存在最优解,即贪心算法是安全的

(3)、证明做出贪心选择后,剩余的子问题满足性质:其最优解和贪心选择组合即可得到原问题的最优解,这样就得到了最优子结构

很明显,在每个贪心算法之下,几乎总有一个更繁琐的动态规划算法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值