贪心算法简介

贪心算法
  • 贪心算法的基本要素
       贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。
      当然,希望贪心算法得到的最终结果也是整体最优的。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。如单源最短路经问题,最小生成树问题等。而在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。、

  • 贪心算法的两个主要性质
    贪心选择性质最优子结构性质

    • 贪心的选择性质
        所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。
    • 最优子结构性质
        当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。

  • 贪心算法

    • 适用的最优化问题:
      问题有n个输入,问题的解是由这n个输入的某个子集组成,而子集必须满足某些事先给定的条件。
      1.约 束 条 件:子集必须满足的条件;
      2.可 行 解:满足约束条件的子集;可行解可能不唯一;
      3.目标函数:用来衡量可行解优劣的标准,一般以函数的形式给出;
      4.最 优 解:能够使目标函数取极值(极大或极小)的可行解。最优解也可能不唯一。
    • 贪心算法的求解步骤
      1.初始化:已知问题有n个输入,置问题的解集合J为空;
      2.选度量标准:根据题意,选取一种度量标准,按照这种度量标准对n个输入排序;
      3.考察输入:按序一次输入一个量,看该量能否和J中已选出来的元素(称为该量度意义下的部分最优解)加在一起构成新的可行解:如果可以,则把该量并入J集合,从而得到一个新的部分解集合;如果不可以,则丢弃该量,J集合保持不变。之后,继续上述过程,考察下一输入量,直到所有的输入都考察完毕。
      4.获得贪心解:所有的n个输入都被考虑完毕,则被记入到集合J中的输入量构成了这种量度意义下的问题的最优解。
    • 贪心方法的求解关键
      选取能够得到问题最优解的度量标准
  • 贪心算法·背包问题
    【问题描述】已知n种物品,各具有重量(w1,w2,…,wn)和效益值(p1,p2,…,pn) ,及一个可容纳M重量的背包。问:怎样装包才能使装入背包的物品的总效益最大?(问题的解用向量(x1,x2,…,xn)表示,每个xi表示物品i被放入背包的比例,0≤xi≤1)

    • 分析
      1.如果所有物品的总重量不超过M,则只有把所有的物品都装入背包中才可获得最大的效益值。
      2.如果物品的总重量大于M,则将有物品可能无法装入背包。而此时,由于0≤xi≤1,所以可以把物品的全部或部分装入背包,最终背包中刚好装入重量为M的若干物品(整体或一部分)。这种情况下,如果背包没有被装满,则显然不能获得最大的效益值。
      3.问题的形式化,描述如下:
    • 最优的度量标准的选择
      1.按物品的单位效益值(即pi/wi 值)的非降次序将物品装入到背包;
      2.如果正在考虑的物品放不进去,则只取其一部分装满背包即可;
    • 实例分析(M=20,(p1,p2,p3) = (25,24,15),(w1,w2,w3) = (18,15,10))
      p2/w2>p3/w3>p1/w1
      首先将物品2放入背包,x2=1,背包获得p2=24的效益增量,容量消耗w2=15个单位,剩余容量ΔM=5。
      然后考虑物品3,就ΔM=5而言,只能放入物品3的5/10,即,x3=5/10=1/2
      最后,ΔM=0,背包装满,物品1不能装入背包,x1=0
      得到的解:(x1,x2,x3)=(0,1,1/2),可以证明该算法得到的就是最优解(证明略)。
    • 算法伪代码
    procedure GREEDYKNAPSACK(P,W,M,X,n)
        //P(1:n)W(1:n)分别含有按P(i)/W(i)P(i+1)/W(i+1)排序的n
          件物品的效益值和重量。M是背包的容量大小,而X(1:n)是解向量//
        real P(1:n), W(1:n), X(1:n), M, cu;
        integer i,n
        X←0 //将解向量初始化为0//
        cu←M //cu是背包的剩余容量//
        for i←1 to n do  
            if W(i) > cu then exit endif
            X(i) ←1
            cu ←cu-W(i)
        repeat
        if i≤n then X(i) ←cu/W(i)  endif
    end GREEDY-KNAPSACK
    
  • 贪心算法·带有限期的作业排序
    【问题描述】单机无资源约束的单元任务非抢占调度问题:假定在一台单CPU、资源无约束的机器上处理n个非抢占式作业,每个作业均可在单位时间内完成,同时每个作业i都有一个截止期限di>0,当且仅当作业i在其截止期限以前被完成时,则获得pi>0的效益。同时,由于有CPU和作业期限的限制,并不是每个作业都有机会执行。现求这n个作业的一个子集J,使其中的所有作业都可在其截止期限内完成。这样的J称为问题的一个可行解。求可获得的最大效益值。

    • 最忧的度量标准
        这里,以目标函数作为量度。为使达到最大,下一个要计入J的作业应是在保证所产生的J是一个可行解的条件下让得到最大增加的作业。
      处理规则
      1.按pi的非增次序来考虑这些作业;
      2.利用作业的期限决定作业的“去留”,同时为作业安排一个合理的处理顺序,保证作业按照该顺序可以如期完成。
      可以证明是最有解。
    • 实例分析
      求解((p1,p2,p3,p4)=(100,10,15,20), (d1,d2,d3,d4)=(2,1,2,1))
      ① 首先令J=Φ。
      ② 因为p1>p4 > p3 > p2,所以首先选择作业1,此时J并上{1}是可行的,所以作业1被计入J={1}。
      ③ 作业4是具有其次大效益值的作业,且{1,4}是可行解,故作业4计入J,得J={1,4};
      ④ 继续考察作业3和2,但{1,3,4}和{1,2,4}均不能构成新的可行解,故作业3和2被舍弃。
      最后得J={1,4},加工顺序是:4,1。
    • 算法伪代码
    procedure GREEDY-JOB(D,J,n)
     //作业按p1p2≥…≥pn的次序输入,它们的期限值D(i)≥1, 
       1≤in,n≥1。J是在它们的截止期限前完成的作业的集合//
      J{1}      //用作业序号代表作业//
      for i←2 to n do 
         if J{i}的所有作业能在它们的截止期限前完成
           then JJ{i}
         endif
      repeat
    end GREEDY-JOB
  • 贪心算法·具有不同执行时间的作业调度问题

    • 【问题描述(有开始时间和结束时间的要求)】在一台单CPU、资源无约束的机器上执行n个非抢占式作业,每个作业有不同的执行时间,si是作业i的起始时间,fi是作业i的结束时间,且si<fi。若执行作业i,则在时间区间[si, fi)内作业i占用CPU,其它作业必须等待。若区间[si, fi)与区间[sj, fj)不相交(si≥fj或sj≥fi ),则称作业i与作业j是相容的。求可相容的最大作业集合。

      • 策略
        按作业结束时间的非降次序排序。从排序后的作业1开始依次考查 。若作业i能够和前一个被选中的作业相容,则保留,否则舍去。
    • 【问题描述(作业只有执行时间的要求)】在一台单CPU、资源无约束的机器上执行n个非抢占式作业,作业有不同的执行时间t1,t2,… tn,但没有起止时间的要求。求这些作业的最短平均完成时间。

      • 策略(短作业优先)
        对于上述问题,按作业执行时间的非降次序执行,可以得到n个作业最短平均完成时间。
    • 【问题描述(在上述问题的基础上)】多机调度问题:多个CPU,怎么让最后完成时间(MakeSpan)最小?——NP问题。
      • 策略(长作业调度)
        采用长作业优先的贪心选择策略可以设计出解多机调度问题的较好的近似算法。
  • 贪心算法·归并问题的优化

    • 归并
      如MergeSort中的Merge过程, 两个已知文件的归并,计算时间=O(两个文件的元素总数),如下:

      二路归并
        已知X1,X2,X3是分别为30、20、10个记录长度的已分类文件。将这3个文件归并成长度为60的文件。可能的归并过程和相应的记录移动次数如下:

      • 度量标准
          这里以目标函数做为度量。为使其达到最小,每次归并应使目标函数有最小的增加。由于任意两个文件的归并所需的元素移动次数与这两个文件的长度之和成正比,故得处理规则如下:每次选择长度最小的两个文件进行归并
      • 伪代码
      procedure TREE(L,n)
      //Ln个单结点的二元树表//
      for i←1 to n-1 do
      call GETNODE(T)       //构造一颗新树T// 
      LCHILD(T)LEAST(L)  //从L中选当前根WEIGHT最小的树,并从中删除// 
      RCHILD(T)LEAST(L)  
      WEIGHT(T)WEIGHT(LCHILD(T))+WEIGHT(RCHILD(T))
      call INSERT(L,T)      //将归并的树T加入到表L中// 
      repeat
      return (LEAST(L))     //此时,L中的树即为归并的结果// 
      end TREE
      

    k路归并
    - 度量标准
    k路归并模式:每次归并k个文件的归并模式。
    - 策略
    k路最优归并模式的贪心规则:每一步选取k个具有最小长度的文件归并。
    哈夫曼编码
    - 策略
      二路归并模式中,视文件为数据(字符),文件长度为权(字符的使用频率),每个结点的左分支编码为0,右分支编码为1,可以得到哈夫曼编码问题的求解算法。

  • 贪心算法·最优装载
    【问题描述】有一批集装箱要装上一艘载重量为C的轮船。其中集装箱i的重量为Wi。最优装载问题要求确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船。
    • 策略
      采用重量最轻者先装的贪心选择策略,可产生最优装载问题的最优解。
  • 贪心算法·常用算法
    • 最小生成树
    • 单源最短路径
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值