贪心算法和动态规划

贪心算法和动态规划 (1)
                                                                                                                                                         ----by  C_xiaobao
1.贪心算法
引例:大家都会遇到找钱的问题。买4块钱的东西,付款20,店家会找你16元。一般情况下,这16元是这样的16=10+5+1.这其中就用到了贪心
算法: 每次用尽量大的面值(当前最优)但又不超过所需找零的总数。
         
     或许这个时候你会觉得,哦~ 原来这就是贪心算法,我懂了,然后你就不再继续了。 (如果你之前对此 一无所知的话) 那么你就
大错特错了。
因为你仅仅是 感性 上了感觉到了一点点 贪心算法 而已。想要掌握一个知识的话,“感性层面的懂”只是了解它的开始,真正要掌握还必须在
理性上 对它进行整理加深。不然你会有这样一种“ 书到用时方恨少 ”的感觉:明明这个问题我懂的呀,为什么到用的时候 我貌似又不能完
全的驾驭它,好多地方都有欠缺。 那么我们就来理性上的认识它吧(此部分在c.贪心算法的求解过程)

a.贪心思想

所谓“ 贪心算法 ”就是在求解问题时,把它分为若干个子问题然后对每个子问题作出目前看来是最优(或者说是 最贪心 )的选择。
认为:  整体最优解 =∑(局部最优解) (即: 优+优+优+...=整体最优 )。

    b.不要贪心
但是我要说这种算法是“ 鼠目寸光 ”的。 它的每一次“最优”(最贪心)只是根据当前的情况作出的选择。( 不考虑之后的情况,也不允
退回)。如此便导致了一个问题:贪心算法得到的最优解并不一定是 整体最优解  [也就是说:很多问题,用贪心算法来求最优解是不合适
的]
比如:依然找钱问题,但是这次仅提供面值1,3,4元的钱币让店家给顾客找回6块钱。根据贪心算法,应该是6=4+1+1.此时用了三张纸币。显然最
优解是6=3+3.只需要两种纸币。

    c.贪心算法的求解过程(那么我们就来理性上的认识它吧)
呀! 原来贪心算法存在这么大的隐患。那么我们如何知道正确的运用贪心算法。别急,我们得先了解一下贪心算法的求解过程,从对它的感
性认识到对它理性上的深入掌握。这样才。。。。
此部分参考了 http://blog.csdn.net/xywlpo/article/details/6439048

用贪心法求解问题应该考虑如下几个方面:
(1)候选集合C:为了构造问题的解决方案,有一个候选集合C作为问题的可能解,即问题的最终解均取自于候选集合C。例如,在找钱问题
中,各种面值的货币构成候选集合。
(2)解集合S:随着贪心选择的进行,解集合S不断扩展,直到构成一个满足问题的完整解。例如,在找钱问题中,已找出的货币构成解集合。
(3)解决函数solution:检查解集合S是否构成问题的完整解。例如,在找钱问题中,解决函数是已付出的货币金额恰好等于应付款。
(4)选择函数select:即贪心策略,这是贪心法的关键,它指出哪个候选对象最有希望构成问题的解,选择函数通常和目标函数有关。例如,
在找钱问题中,贪心策略就是在候选集合中选择面值最大的货币。
(5)可行函数feasible:检查解集合中加入一个候选对象是否可行,即解集合扩展后是否满足约束条件。例如,在找钱问题中,可行函数是
每一步选择的货币和已付出的货币相加不超过应付款。
算法流程
Greedy(C)  //C是问题的输入集合即候选集合
{
    S={ };  //初始解集合为空集
    while (not solution(S))  //集合S没有构成问题的一个解
    {
       x=select(C);    //在候选集合C中做贪心选择
       if feasible(S, x)  //判断集合S中加入x后的解是否可行
          S=S+{x}; //不断的扩展解集合
          C=C-{x}; //不断的缩小问题集合,即从问题->子问题->子问题的子问题。。。。找16块钱的问题->找6块钱的问题->找1块钱的问题
    }
   return S; //返回解

d.要贪心还是不要贪心
现在回到之前的问题,到底是“要贪心”还是“不要贪心”。虽然我说贪心算法“鼠目寸光”, 但是不得不说的是一旦遇到了适合用贪心算法的
问题,那么贪心算法必定是最简单高效的算法,没有之一。比如之前的找钱问题。
因此,一定要证明问题是否适合贪心算法策略。即就是证明:是不是我们每一步的最优选择就能得到我要求的整体最优呢?
这里我们看一下 “ 整体最优解 ”和“ 局部最优解 ”的关系: 整体最优解 <-> 局部最优解  
整体最优解 <-> 局部最优解  两者关系用专业的术语来讲分别是: 贪心选择性质 最优子结构性质
每一步所做的贪心选择(局部最优解)最终会导致整体最优解。
整体最优解中一定包含了子问题的最优解。
实际上, 贪心算法使用的情况比较少 。判断一个问题是否适合贪心算法,可以对该问题试着先用几个测试数据来分析一下是否适合。

ALL In ALL , 评价: 小 而 美 //适用的情况比较少,但是一旦适用就是最高效简单的方法。
重要: 这么说吧,在现在 贪心算法或许就不是用来求最优解了,只是提供一个快速的方法求次优解偶尔事情的条件合适才会求出来最优解。  

贪心法的应用

哈夫曼编码
0-1背包问题
磁盘文件的存储
生产调度问题
信息查询


当然,仅仅是这一点,对贪心算法想要整体全面的了解还是不够的。可以参见以下两篇我的文章:
想要了解动态规划 请点击 这里


贪心算法和动态规划的对比认识 请点击这里










  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
贪心算法动态规划都是解决最优化问题的算法,但它们的思想和实现方式有所不同。 贪心算法是一种贪心选择策略的算法,它总是做出当前最优的选择,并希望通过这种选择能够得到全局最优解贪心算法通常适用于问题具有最优子结构性质的情况,即问题的最优解可以通过子问题的最优解来构造。贪心算法的时间复杂度通常比较低,但是它不能保证得到全局最优解动态规划算法则是一种将问题分解成子问题并将子问题的解缓存起来的算法动态规划算法通常适用于问题具有重叠子问题和最优子结构性质的情况,即问题的最优解可以通过子问题的最优解来构造,并且子问题之间存在重叠。动态规划算法的时间复杂度通常比较高,但是它可以保证得到全局最优解。 下面是一个使用贪心算法动态规划算法解决背包问题的例子: 假设有一个背包,它的容量为C,有n个物品,每个物品有一个重量w和一个价值v。现在需要选择一些物品放入背包中,使得它们的总重量不超过C,且总价值最大。 使用贪心算法,我们可以按照每个物品的单位价值(即价值/重量)从大到小排序,然后依次将单位价值最大的物品放入背包中,直到背包无法再放入物品为止。 使用动态规划算法,我们可以定义一个二维数组dp[i][j],其中dp[i][j]表示在前i个物品中选择一些物品放入容量为j的背包中所能获得的最大价值。然后我们可以根据以下递推式来计算dp数组: dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]) 其中w[i]和v[i]分别表示第i个物品的重量和价值。最终的答案即为dp[n][C]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值