C++(数据结构与算法)76:---贪婪算法(贪心算法)

  • 贪婪算法又称贪心算法

一、最优化问题

  • 本文及后面介绍的算法例子都是“最优化问题”。每个最优化问题都包含一组“限制条件”和一个“优化函数”。符合限制条件的问题求解方案称为“可行解”。使优化函数可能取得最佳值的可行解称为“最优解”

二、贪婪算法思想

  • 在贪婪算法中,我们要逐步构造一个最优解。每一步,我们都在一定的标准下,作出一个最优决策。在每一步做出的决策,在以后的步骤中都不可更改。做出决策所依据的标准称为贪婪准则

三、实际应用之找零钱

问题描述

  • 顾客用美元来购买糖果,售货员希望用数目最少的硬币找给小孩零钱。假设有面值为25美分、10美分、5美分以及1美分的硬币,而且数目不限
  • 售货员每次选择一枚硬币,凑成要找的零钱。选择时所依据的是贪婪准则:在不超过要找的零钱总数的条件下,每一次都选择面试尽可能最大的硬币,直到凑成的零钱总数等于要找的零钱总数
  • 问题描述:假设要找给顾客67美分

贪婪算法解决步骤

  • 假设要找给顾客67美分:
    • 前两步选择的是两个25美元的硬币(第三步就不能选择25美元了,否则总数就超过67美分了)
    • 第三步选择10美分的硬币
    • 第四步选择5美分的硬币
    • 最后一步是两个1美分的硬币
  • 贪婪算法使我们有一种感觉:这样凑出来的零钱,硬币数目最少或接近最少

四、实际应用之机器调度

应用分析

  • 有任务n个,机器不限,任务在机器上处理。每个任务的开始时间为Si,任务的完成时间为Fi,Si处理时段
  • 任务重叠:两个任务i和j重叠,当且仅当两个任务的处理时段有重叠。例如时段[1,4]与时段[2,4]有重叠,而[1,4]与时段[4,7]不算重叠
  • 一人任务分配方案是可行的:是指没有两个时段重叠的任务分配给同一台机器,即每台机器在任何时刻最多只处理一个任务
  • 最优分配:是指使用机器最少的可行分配方案

实际问题描述

  • 假设n=7个任务,标号从a到g,它们的处理时段如下图所示:

  • 问题描述:机器不限,现在要把这个7个任务分配到机器上运行,且要求总共使用的机器数目是最少的(时间不做要求)

贪婪算法解决步骤

  • 贪婪准则步骤:根据任务的开始时间,若有“旧”机器可用,则将任务分配给它。否则,将任务分配给一台“新”机器
    • 旧机器是指:已经被使用过的
    • 新机器:重来没有被使用过的机器
  • 根据任务的开始与结束时间,最终的执行结果如下图所示,所有的任务总在执行的过程中,共使用过3台机器

C++(数据结构与算法)76:---贪婪算法(贪心算法)_第1张图片

五、实际应用之最短路径

问题描述

  • 一个有向网如下图所示,图中的数字代表两个节点之间的距离
  • 现在有这样一个需求:从某一个点开始达到另外一个点,每一步都向路径上加入一个订单。假设当前的路径已经达到顶点q,但还未达到终点。要求下一次选择路径时:选择一个关联于q最近,且目前不在路径中的顶点

C++(数据结构与算法)76:---贪婪算法(贪心算法)_第2张图片

贪婪算法解决步骤

  • 假设从顶点1达到顶点5,贪婪算法的解决办法为:
    • 第一步选择1->3的路径,长度为2
    • 第二步选择3->2的路径,长度为2
    • 第三步选择4->2的路径,长度为1
    • 第四步选择2->5的路径,长度为5
    • 因此总共的长度为10
  • 备注(重点):根据问题描述与贪婪算法,最终选择出的路径为10,但是不是最短路径(不是最优的)。例如可以执行1->4->5这条路径,长度总共为6。因此贪婪算法不一定是最优解

六、其他案例

  • 例如,在哈夫曼树算法中(https://blog.csdn.net/qq_41453285/article/details/103649092),利用n-1步建立加权外部路径长最小的二叉树,每一步都将两个二叉树合并为一棵。算法所使用的贪婪算法为:从可用的二叉树中把权最小的两棵树组合为一棵树
  • 例如,在LPT调度规则(https://blog.csdn.net/qq_41453285/article/details/103649089)也是一种贪婪算法。它用n步来调度n个作业。首先将作业按时间长短排序。然后每一步为下一个任务分配一台机器。依据的贪婪准则为:使目前的调度时间最短。将新作业调度到最先完成的机器上(即最先空闲的机器)。注意,这种问题中,贪婪算法并不能保证最优解

七、一些其他属于概念

  • 通过上面一些问题可以知道,贪婪法则虽然不能保证最优解(例如上面的最短路径问题),但是一般情况下它的解总是接近最优的。这是一种经验法则。所得的结果通常都接近最优解,这种算法称为“启发式方法”
  • 如果启发式方法与最佳犯法之间还有一种限定关系,那么我们我们称这种启发式方法具有“限定性能”
  • 具有限定限定性能的启发式方法称为“近似算法”

八、贪婪算法实际应用

  • 见下一篇文章:https://blog.csdn.net/qq_41453285/article/details/104447962

你可能感兴趣的:(C++(数据结构与算法))