第4章 贪心算法-1.ppt

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第四章 贪心算法 Greedy method;主要内容;贪心算法概述;贪心算法常常用于求解某些问题的最优解。 这类问题一般有n个输入,而其解由这n个输入的某个子集组成,要求该子集满足预先给定的约束条件。这一子集称为该问题的一个可行解。其中使目标函数取得极值的可行解称为最优解。;如果这个输入和当前的部分解加起来不能产生一个可行解,则不把此输入加入到部分解当中。;一般地,选取最优度量标准并非易事,因此贪心法得到的解往往不是最优解,而是次优解。而一旦找到最优度量标准,则贪心法特别有效。 贪心法逐步给出解的各部分,在每一步“贪婪地”选择最好的部分解,而不顾及这样选择对整体的影响,因此未必得到最优解。 贪心法应用的成功示例有:单源最短路径问题、最小生成树问题以及作业调度等。即使得不到最优解,往往能得到较好的近似解。;例1[找零钱]: 一个小孩买了价值少于1美元的糖,并将1美元的钱交给售货员。售货员希望用数目最少的硬币找给小孩。假设提供了数目不限的面值为2 5、1 0、5、1美分的硬币。售货员分步骤组成要找的零钱数,每次加入一个硬币。选择硬币时所采用的贪心准则如下:每一次选择应使零钱数尽量增大。为保证解法的可行性(即:所给的零钱等于要找的零钱数),所选择的硬币不应使零钱总数超过最终所需的数目。;假设需要找给小孩6 7美分,首先入选的是两枚2 5美分的硬币,第三枚入选的不能是2 5美分的硬币,否则硬币的选择将不可行(零钱总数超过6 7美分),第三枚应选择1 0美分的硬币,然后是5美分的,最后加入两个1美分的硬币。 贪婪算法有种直觉的倾向,在找零钱时,直觉告诉我们应使找出的硬币数目最少(至少是接近最少的数目)。可以证明采用上述贪婪算法找零钱时所用的硬币数目的确最少。;例2:找零钱问题与硬币面值的设定有关。 比如:要找给顾客3角7分钱, 如果硬币面值为1角、5分、2分、1分, 那么按照贪心算法: 1角:3枚; 5分:1枚;2分:1枚 合计:5枚 能得到最优解。 如果硬币面值为11分、7分、5分、1分, 那么按照贪心算法: 11分: 3枚; 1分:4枚 合计:7枚 但最优解应该是5枚,贪心法不成功。;背包问题;用贪心算法求解背包问题的步骤: 1)计算每种物品的单价vi/wi 2)按物品的单价,从大到小排序 3)单价高的物品优先装包,直至装满。 (最后一种物品可能装入一部分) 时间复杂性 排序:O(n log n) 其它:O(n) 为什么采用贪心策略能得到最优解?;0 / 1背包问题的几种贪婪策略: 1)从剩余的物品中,选出可以装入背包的价值最大的物品 2)从剩下的物品中选择可装入背包的重量最小的物品 3)从剩余物品中选择可装入包的pi /wi 值最大的物品 这三种策略都不能保证得到最优解。 我们不必因所考察的几个贪婪算法都不能保证得到最优解而沮丧, 0 / 1背包问题是一个NP复杂问题。对于这类问题,也许根本就不可能找到具有多项式时间的算法。;虽然按pi /wi 非递增的次序装入物品不能保证得到最优解,但它是一个直觉上近似的解。我们希望它是一个好的启发式算法,且大多数时候能很好地接近最后算法。 据统计,在600个随机产生的背包问题中,用这种启发式贪婪算法来解有239题为最优解。有583个例子与最优解相差10%,所有600个答案与最优解之差全在25%以内。该算法能在O(n log n)时间内获得如此好的性能。我们也许会???,是否存在一个x (x100 ),使得贪婪启发法的结果与最优值相差在x%以内。答案是否定的。;为什么贪心策略不适用于0/1背包问题? 例:c=50, w=(10,20,30), V=(60,100,120) 单价 v/w=(6,5,4) 按贪心策略,应装入前两个物品,价值160; 而最优解应为装入后两种物品,价值220。 原因:贪心法不能保证0/1背包装满,闲置部分使背包价值降低。 考虑0/1背包问题,应比较选择wi与不选择wi所导致的结果,然后作出选择,由此导致相互重叠的子问题。所以可用动态规划法。;void Knapsack(int n,float M,float v[ ],float w[ ] ,float x[ ]) { Sort(n, v, w); //按单位价值排序/ int i; for (i =1;i = n;i++) x[i] = 0; float c = M; //c为背包剩余空间/ for (i =1;i = n;i ++) { if (w[i] c) break; x[i]= 1; c-= w

文档评论(0)

糖糖 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档