算法-贪心法

感谢华北电力大学王墨玉老师的ppt

贪心法

基础知识
  • 贪心算法总是做出在当前阶段看来最好的选择,而并不从整体最优考虑。因此他做出的选择都是局部最优解。
  • 贪心算法只能在某些问题上得到整体最优解
  • 对于一些特殊的问题,若要求得最优解,需要花费的代价(时间、空间)很大。这时作为一个平衡,花费较小代价获得一个比较好的解就成了另一个选择。(这并不是说贪心法就不能获得最优解)
  • 贪心方法是一种分级处理方法,它首先根据题意,选取一种量度标准,然后根据量度标准对成本(以图为例,路径的长度就是成本)进行排序,再根据题目的约束条件进行选择。
  • 能够得到某种量度意义下的最优解的处理方法就是贪心法
应用条件
  • 贪心选择性质:所求问题的整体最优解,可以通过一系列局部最优的选择(贪心选择)来达到。

    • 贪心选择可以依赖以往所做过的选择,但绝不依赖于将来所作的选择,也不依赖于子问题的解(所以叫贪心,只看眼前,不管未来)
    • 上面的选择方式是贪心法和动态规划法的主要区别
    • 贪心算法通常以自顶向下的方式进行,不断迭代多出贪心选择,每做一次贪心选择就将问题简化为规模更小的问题。从全局来看,贪心法解决问题的过程中没有回溯过程。(动态规划算法通常是以底向上的方式)
  • 最优子结构性质:原问题包含了其子问题的最优解

  • 对于一个问题可能会有不同的量度标准,选择其中可以获得最优解的量度标准是贪心法设计的核心问题

例题
活动安排问题(可求得最优解)
  • 问题描述:
    设有n个活动的集合 E={1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只允许一个活动使用这一资源。每个活动i都有一个要求使用该资源的起始时间 si 和一个结束时间 fi,且 si<fi。如果选择了活动 i,则它在半开的时间区间 [si,fi) 内占用资源。在一定时间内,如何安排尽可能多的活动?
  • 问题分析:总时间固定,安排尽可能多的活动,那么活动的持续时间越短,安排的活动肯定越多,如果活动的开始结束时间任意安排的话,这样想没问题。但如果活动的开始和结束时间是固定的,那么就不能以活动的持续时间为量度标准了。
  • (1)最早开始时间:这样可以增大资源的利用率。
    (2)最早结束时间:这样可以使下一个活动尽早开始。
  • 我们的目标是安排最多的活动,那么一定是优先选择结束时间早的活动,这样才能使剩下的时间最长,才有可能安排更多的活动。
  • 算法代码:
int greedySelector(int s[ ], int f[ ], int a[ ])
{
  int n=s.length, j=1,  count=1, i ;
  a[1]=1;
  for (i=2; i<=n; i++)
  {
	   if (s[i]>=f[j])
	    {    a[i]=1;
	         j=i;
	         count++;
	    }
	    else 
		     a[i]=0;
   }
   return count;
 }

  • 时间复杂性:1)已按结束时间降序排序,O(n);2)未排序,O(n+nlogn)(nlogn 是快速排序的时间复杂度)
背包问题(非 0/1 背包)(可求得最优解)
  • 问题描述:
    给定 n 种物品和一个容量为 M 的背包。物品 i 的重量是 Wi,其价值为 pi。假定将物品i的一部分 xi 放入背包产生 pixi 的效益,这里 0≤xi≤1,pi>0。应如何选择装入背包的物品,使得装入背包中物品的总价值最大?
  • 说明:在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部装入背包,1≤i≤n
  • 这种背包问题还是很简单的,容量固定,要想装入的总价值最大,那肯定先装单位重量最贵的物品啦。很简单。
  • 时间复杂性:算法的主要计算时间在于将各种物品依其单位重量的价值从大到小排序。因此,算法的计算时间上界为 O(nlogn)
最优装载问题(可求得最优解)
  • 问题描述:
    有一批集装箱要装上一艘载重量为 c 的轮船。其中集装箱 i 的重量为 Wi。最优装载问题要求确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船。
  • 注意,装载体积不限,但是有总重量的限制
  • 其实和背包问题一样,“背包容量相当于船的载重量为 c,物品的重量相当于集装箱的重量,物品的价值都相当于集装箱的体积(不在考虑范围内,看作都相等)”,这不就是个背包问题了吗?
  • 也很简单,不用考虑体积,按重量从小到大一个个放进去就好了
  • 当然,这样做最终的转入的集装箱总重量可能小于 c,注意题目问的是“将尽可能多的集装箱装上轮船”。
  • 时间复杂性:算法的主要计算量在于将集装箱依其重量从小到大排序,故算法所需的计算时间为 O(nlogn)
多处理机调度问题(非最优解)
  • 问题描述:
    若有 n 台相同的处理机 P1,P2,…,Pn,处理 m 个独立的作业J1,J2,…,Jm,已知作业 Ji 需要的处理机时间为 ti,i=1,2,…,m。以互不相关的方式工作。现约定:任何作业可以在任何一台处理机上运行,但未完工前不允许中断作业;作业也不能拆分成更小的子作业。如何在最短时间内完成所有任务?
  • 这是一 NP 完全问题,目前还没有一个有效的解决办法,但是利用贪心法可以得到一个较好的解。
  • 最优解可以想象,每个处理机的运行时间应该是都接近 (t1 + t2 +…+tm)/n(为什么说接近呢?因为每个任务只能在一台处理机上运行直至完成),而且各处理机的运行时间的差距最小。
  • 因为这是一个 NP 完全问题,想要获得最优解需要求出所有可能的情况,花费太大。这时,我们可以考虑用贪心法来求一个比较好的解。
  • 解决办法:将任务按需要时间从大到小排序,依次安排给各空闲处理机(谁先处理完了,就给谁安排余下任务中需要时间最长的,这样可以缩小各处理机运行时间的差距)。
  • 思路:为什么说这样安排,可以使假如处理机上都在运行着任务,现在其中一个处理机的任务完成了,那么应该给这个处理机再安排一个需要时间最长的任务,还是最短的任务呢?那肯定是最长的,对吧。(在纸上画一画就可以明白)
  • 例题:设有三台处理机和九个作业。这些作业需要的运行时间分别是81,40,26,4,65,98,53,71,15。
  • 按上述解决办法,最终的结果如下图:
  • 贪心法求得的最终完工时间是 160 (最佳调度方案的完工时间是 151)
  • 时间复杂度:
    • m<=n(任务数小于处理机数),一次全部分配完,时间复杂度 O(1)
    • m>n,先按所需时间给任务降序排序,然后按上述策略分配,时间复杂度 O(mlogm) (就是快速排序的时间复杂度)
    带限期的作业排序
    • 问题描述:
      假定只能在一台机器上处理 n 个作业,每个作业均可在单位时间内完成;且每个作业 i 都有一个截止期限 di>0 (是整数),当且仅当作业i在它各自的期限截止之前被完成时,则获得 pj>0 的效益,求可获得的最大效益。
    • 这个挺复杂,考完试回来再继续整理。。。。。。。。。。。。。。。。。。。。。
    • 时间复杂度:
二路归并模式(最优解)(后续补充)
  • 一个最优二路归并模式(哈夫曼归并树)与一颗具有最小外部路径的二元树想对应
  • 时间复杂度:O(n2) (其中外层循环 n-1 次,插入操作 O(n))
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值