`
hojor
  • 浏览: 106468 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

贪婪算法(二)

阅读更多

1.2 算法思想


在贪婪算法(greedy method)中采用逐步构造最优解的方法。在每个阶段,都作出一个看上去最优的决策(在一定的标准下)。决策一旦作出,就不可再更改。作出贪婪决策的依据称为贪婪准则(greedy criterion)。

例1-4 [找零钱] 一个小孩买了价值少于1美元的糖,并将1美元的钱交给售货员。售货员希望用数目最少的硬币找给小孩。假设提供了数目不限的面值为2 5美分、1 0美分、5美分、及1美分的硬币。售货员分步骤组成要找的零钱数,每次加入一个硬币。选择硬币时所采用的贪婪准则如下:每一次选择应使零钱数尽量增大。为保证解法的可行性(即:所给的零钱等于要找的零钱数),所选择的硬币不应使零钱总数超过最终所需的数目。

假设需要找给小孩6 7美分,首先入选的是两枚2 5美分的硬币,第三枚入选的不能是2 5美分的硬币,否则硬币的选择将不可行(零钱总数超过6 7美分),第三枚应选择1 0美分的硬币,然后是5美分的,最后加入两个1美分的硬币。

贪婪算法有种直觉的倾向,在找零钱时,直觉告诉我们应使找出的硬币数目最少(至少是接近最少的数目)。可以证明采用上述贪婪算法找零钱时所用的硬币数目的确最少(见练习1)。

例1-5 [机器调度] 现有n 件任务和无限多台的机器,任务可以在机器上得到处理。每件任务的开始时间为si,完成时间为fi ,si < fi 。[si , fi ] 为处理任务i 的时间范围。两个任务i,j 重指两个任务的时间范围区间有重叠,而并非是指i,j 的起点或终点重合。例如:区间[ 1,4 ]与区间[ 2,4 ]重叠,而与区间[ 4,7 ]不重叠。一个可行的任务分配是指在分配中没有两件重叠的任务分配给同一台机器。因此,在可行的分配中每台机器在任何时刻最多只处理一个任务。最优分配是指使用的机器最少的可行分配方案。

假设有n= 7件任务,标号为a 到g。它们的开始与完成时间如图13-1a 所示。若将任务a分给机器M1,任务b 分给机器M2,. . .,任务g 分给机器M7,这种分配是可行的分配,共使用了七台机器。但它不是最优分配,因为有其他分配方案可使利用的机器数目更少,例如:可以将任务a、b、d分配给同一台机器,则机器的数目降为五台。

一种获得最优分配的贪婪方法是逐步分配任务。每步分配一件任务,且按任务开始时间的非递减次序进行分配。若已经至少有一件任务分配给某台机器,则称这台机器是旧的;若机器非旧,则它是新的。在选择机器时,采用以下贪婪准则:根据欲分配任务的开始时间,若此时有旧的机器可用,则将任务分给旧的机器。否则,将任务分配给一台新的机器。根据例子中的数据,贪婪算法共分为n = 7步,任务分配的顺序为a、f、b、c、g、e、d。第一步没有旧机器,因此将a 分配给一台新机器(比如M1)。这台机器在0到2时刻处于忙状态。在第二步,考虑任务f。由于当f 启动时旧机器仍处于忙状态,因此将f 分配给一台新机器(设为M2 )。第三步考虑任务b, 由于旧机器M1在Sb = 3时刻已处于闲状态,因此将b分配给M1执行,M1下一次可用时刻变成fb = 7,M2的可用时刻变成ff = 5。第四步,考虑任务c。由于没有旧机器在Sc = 4时刻可用,因此将c 分配给一台新机器(M3),这台机器下一次可用时间为fc = 7。第五步考虑任务g,将其分配给机器M2,第六步将任务e 分配给机器M1, 最后在第七步,任务2分配给机器M3。(注意:任务d 也可分配给机器M2)。

上述贪婪算法能导致最优机器分配的证明留作练习(练习7)。可按如下方式实现一个复杂性为O (nl o gn)的贪婪算法:首先采用一个复杂性为O (nl o gn)的排序算法(如堆排序)按Si 的递增次序排列各个任务,然后使用一个关于旧机器可用时间的最小堆。

例1-6 [最短路径] 给出一个有向网络,路径的长度定义为路径所经过的各边的耗费之和。要求找一条从初始顶点s 到达目的顶点d 的最短路径。

贪婪算法分步构造这条路径,每一步在路径中加入一个顶点。假设当前路径已到达顶点q, 且顶点q 并不是目的顶点d。加入下一个顶点所采用的贪婪准则为:选择离q 最近且目前不在路径中的顶点。

这种贪婪算法并不一定能获得最短路径。例如,假设在图1 3 - 2中希望构造从顶点1到顶点5的最短路径,利用上述贪婪算法,从顶点1开始并寻找目前不在路径中的离顶点1最近的顶点。到达顶点3,长度仅为2个单位,从顶点3可以到达的最近顶点为4,从顶点4到达顶点2,最后到达目的顶点5。所建立的路径为1 , 3 , 4 , 2 , 5,其长度为1 0。这条路径并不是有向图中从1到5的最短路径。事实上,有几条更短的路径存在,例如路径1,4,5的长度为6。

根据上面三个例子,回想一下前几章所考察的一些应用,其中有几种算法也是贪婪算法。例如,霍夫曼树算法,利用n- 1步来建立最小加权外部路径的二叉树,每一步都将两棵二叉树合并为一棵,算法中所使用的贪婪准则为:从可用的二叉树中选出权重最小的两棵。L P T调度规则也是一种贪婪算法,它用n 步来调度n 个作业。首先将作业按时间长短排序,然后在每一步中为一个任务分配一台机器。选择机器所利用的贪婪准则为:使目前的调度时间最短。将新作业调度到最先完成的机器上(即最先空闲的机器)。

注意到在机器调度问题中,贪婪算法并不能保证最优,然而,那是一种直觉的倾向且一般情况下结果总是非常接近最优值。它利 虽然设计一个好的求解算法更像是一门艺术,而不像是技术,但仍然存在一些行之有效的能够用于解决许多问题的算法设计方法,你可以使用这些方法来设计算法,并观察这些算法是如何工作的。一般情况下,为了获得较好的性能,必须对算法进行细致的调整。但是在某些情况下,算法经过调整之后性能仍无法达到要求,这时就必须寻求另外的方法来求解该问题。
 本章首先引入最优化的概念,然后介绍一种直观的问题求解方法:贪婪算法。最后,应用该算法给出货箱装船问题、背包问题、拓扑排序问题、二分覆盖问题、最短路径问题、最小代价生成树等问题的求解方案。

1.1 最优化问题

 本章及后续章节中的许多例子都是最优化问题( optimization problem),每个最优化问题都包含一组限制条件( c o n s t r a i n t)和一个优化函数( optimization function),符合限制条件的问题求解方案称为可行解( feasible solution),使优化函数取得最佳值的可行解称为最优解(optimal solution)。

 例1-1 [ 渴婴问题] 有一个非常渴的、聪明的小婴儿,她可能得到的东西包括一杯水、一桶牛奶、多罐不同种类的果汁、许多不同的装在瓶子或罐子中的苏打水,即婴儿可得到n 种不同的饮料。根据以前关于这n 种饮料的不同体验,此婴儿知道这其中某些饮料更合自己的胃口,因此,婴儿采取如下方法为每一种饮料赋予一个满意度值:饮用1盎司第i 种饮料,对它作出相对评价,将一个数值si 作为满意度赋予第i 种饮料。

 通常,这个婴儿都会尽量饮用具有最大满意度值的饮料来最大限度地满足她解渴的需要,但是不幸的是:具有最大满意度值的饮料有时并没有足够的量来满足此婴儿解渴的需要。设ai是第i 种饮料的总量(以盎司为单位),而此婴儿需要t 盎司的饮料来解渴,那么,需要饮用n种不同的饮料各多少量才能满足婴儿解渴的需求呢?

 设各种饮料的满意度已知。令xi 为婴儿将要饮用的第i 种饮料的量,则需要解决的问题是:

 找到一组实数xi(1≤i≤n),使n ?i = 1si xi 最大,并满足:n ?i=1xi =t 及0≤xi≤ai 。

 需要指出的是:如果n ?i = 1ai < t,则不可能找到问题的求解方案,因为即使喝光所有的饮料也不能使婴儿解渴。

 对上述问题精确的数学描述明确地指出了程序必须完成的工作,根据这些数学公式,可以对输入/ 输出作如下形式的描述:

 输入:n,t,si ,ai(其中1≤i≤n,n 为整数,t、si 、ai 为正实数)。

 输出:实数xi(1≤i≤n),使n ?i= 1si xi 最大且n ?i=1xi =t(0≤xi≤ai)。如果n ?i = 1ai <t,则输出适当的错误信息。

 在这个问题中,限制条件是n ?i= 1xi =t 且0≤xi≤ai,1≤i≤n。而优化函数是n ?i= 1si xi 。任何满足限制条件的一组实数xi 都是可行解,而使n ?i= 1si xi 最大的可行解是最优解。

 例1-2 [装载问题] 有一艘大船准备用来装载货物。所有待装货物都装在货箱中且所有货箱的大小都一样,但货箱的重量都各不相同。设第i 个货箱的重量为wi(1≤i≤n),而货船的最大载重量为c,我们的目的是在货船上装入最多的货物。

 这个问题可以作为最优化问题进行描述:设存在一组变量xi ,其可能取值为0或1。如xi 为0,则货箱i 将不被装上船;如xi 为1,则货箱i 将被装上船。我们的目的是找到一组xi ,使它满足限制条件n ?i = 1wi xi ≤c 且x i ? {0, 1}, 1 ≤i≤n。相应的优化函数是n ?i= 1xi 。 满足限制条件的每一组xi 都是一个可行解,能使n ?i= 1xi 取得最大值的方案是最优解。

 例1-3 [最小代价通讯网络] 城市及城市之间所有可能的通信连接可被视作一个无向图,图的每条边都被赋予一个权值,权值表示建成由这条边所表示的通信连接所要付出的代价。包含图中所有顶点(城市)的连通子图都是一个可行解。设所有的权值都非负,则所有可能的可行解都可表示成无向图的一组生成树,而最优解是其中具有最小代价的生成树。

 在这个问题中,需要选择一个无向图中的边集合的子集,这个子集必须满足如下限制条件:所有的边构成一个生成树。而优化函数是子集中所有边的权值之和。 
1.2 算法思想


在贪婪算法(greedy method)中采用逐步构造最优解的方法。在每个阶段,都作出一个看上去最优的决策(在一定的标准下)。决策一旦作出,就不可再更改。作出贪婪决策的依据称为贪婪准则(greedy criterion)。

例1-4 [找零钱] 一个小孩买了价值少于1美元的糖,并将1美元的钱交给售货员。售货员希望用数目最少的硬币找给小孩。假设提供了数目不限的面值为2 5美分、1 0美分、5美分、及1美分的硬币。售货员分步骤组成要找的零钱数,每次加入一个硬币。选择硬币时所采用的贪婪准则如下:每一次选择应使零钱数尽量增大。为保证解法的可行性(即:所给的零钱等于要找的零钱数),所选择的硬币不应使零钱总数超过最终所需的数目。

假设需要找给小孩6 7美分,首先入选的是两枚2 5美分的硬币,第三枚入选的不能是2 5美分的硬币,否则硬币的选择将不可行(零钱总数超过6 7美分),第三枚应选择1 0美分的硬币,然后是5美分的,最后加入两个1美分的硬币。

贪婪算法有种直觉的倾向,在找零钱时,直觉告诉我们应使找出的硬币数目最少(至少是接近最少的数目)。可以证明采用上述贪婪算法找零钱时所用的硬币数目的确最少(见练习1)。

例1-5 [机器调度] 现有n 件任务和无限多台的机器,任务可以在机器上得到处理。每件任务的开始时间为si,完成时间为fi ,si < fi 。[si , fi ] 为处理任务i 的时间范围。两个任务i,j 重指两个任务的时间范围区间有重叠,而并非是指i,j 的起点或终点重合。例如:区间[ 1,4 ]与区间[ 2,4 ]重叠,而与区间[ 4,7 ]不重叠。一个可行的任务分配是指在分配中没有两件重叠的任务分配给同一台机器。因此,在可行的分配中每台机器在任何时刻最多只处理一个任务。最优分配是指使用的机器最少的可行分配方案。

假设有n= 7件任务,标号为a 到g。它们的开始与完成时间如图13-1a 所示。若将任务a分给机器M1,任务b 分给机器M2,. . .,任务g 分给机器M7,这种分配是可行的分配,共使用了七台机器。但它不是最优分配,因为有其他分配方案可使利用的机器数目更少,例如:可以将任务a、b、d分配给同一台机器,则机器的数目降为五台。

一种获得最优分配的贪婪方法是逐步分配任务。每步分配一件任务,且按任务开始时间的非递减次序进行分配。若已经至少有一件任务分配给某台机器,则称这台机器是旧的;若机器非旧,则它是新的。在选择机器时,采用以下贪婪准则:根据欲分配任务的开始时间,若此时有旧的机器可用,则将任务分给旧的机器。否则,将任务分配给一台新的机器。根据例子中的数据,贪婪算法共分为n = 7步,任务分配的顺序为a、f、b、c、g、e、d。第一步没有旧机器,因此将a 分配给一台新机器(比如M1)。这台机器在0到2时刻处于忙状态。在第二步,考虑任务f。由于当f 启动时旧机器仍处于忙状态,因此将f 分配给一台新机器(设为M2 )。第三步考虑任务b, 由于旧机器M1在Sb = 3时刻已处于闲状态,因此将b分配给M1执行,M1下一次可用时刻变成fb = 7,M2的可用时刻变成ff = 5。第四步,考虑任务c。由于没有旧机器在Sc = 4时刻可用,因此将c 分配给一台新机器(M3),这台机器下一次可用时间为fc = 7。第五步考虑任务g,将其分配给机器M2,第六步将任务e 分配给机器M1, 最后在第七步,任务2分配给机器M3。(注意:任务d 也可分配给机器M2)。

分享到:
评论

相关推荐

    贪婪算法的代码

    并能对分页式存储的页面置换算法进行编写和计算各个算法的缺页率。 二、程序设计: 假定一个能够存放M个页面的内存,当发生缺页时,调入一个页面, 通过LRU算法求出应该置换出的页面号。输入一连串的页面号, 程序...

    遗传算法和贪婪算法结合解决背包问题,matlab程序

    本算法用遗传算法和贪婪算法解决了背包问题,产生解得方法用贪婪算法,然后引入了一个错解的修复算法,搜索的时候用遗传算法。保证了快速收敛和解的完备性。包含源程序,算法介绍以及一份详细的报告,希望对读者有很...

    有关贪婪算法的一篇文章

    关于贪婪算法的一篇文章, 虽然设计一个好的求解算法更像是一门艺术,而不像是技术,但仍然存在一些行之有效的能够用于解决许多问题的算法设计方法,你可以使用这些方法来设计算法,并观察这些算法是如何工作的。...

    tanlan.rar_贪婪算法

    使用贪婪算法来优化二十个点的最短路径的方法

    理解和掌握贪婪算法的基本思想

    1)理解和掌握贪婪算法的基本思想; 2)使用贪婪算法求解背包问题以及最小花费生成树问题。 二、方法原理 贪心算法就是做出一系列选择,使原问题达到最优解。在每一个决策点,都是做出当前看来的最优选择。 三、实验...

    c算法(贪婪、二分、排序、拓扑等)

    贪婪算法、分而治之算法、排序算法、拓扑算法;背包问题、货箱装船。

    敏捷供应链静态调度模型及其贪婪算法 (2010年)

    针对确定性市场需求下的敏捷供应链(ASC)调度具有批量和时间双重约束的问题,根据供应...第二阶段的精益调度贪婪算法求解以最小化供应链库存成本为目标的最优调度方案。最后通过算例验证了模型和算法的实用性和有效性。

    WPF编写的罗马尼亚度假问题

    WPF下的罗马尼亚度假问题,支持宽度优先、深度优先、贪婪、A*算法。贪婪算法可能有些问题,有些情况求不出解。无法绘制二维的动态地图,只有简单的输出,需要改善。

    贪婪算法在InSAR相位解缠中的应用 (2007年)

    针对干涉SAR二维相位解缠问题,提出了一种利用贪婪算法提高解缠精度的新方法,首先从理论上推导了贪婪算法相位解缠的基本原理,然后提出了一种迭代加权的贪婪算法,以克服传统贪婪算法解缠结果收敛于局部最优解的...

    多分类贪婪算法的一致性 (2005年)

    学习理论中,许多学习算法可以描述为一个最小化适当损失函数的贪婪...本文研究基于凸风险最小化方法的多分类贪婪算法,推广二分类的学习问题到多分类的情形.建立了多分类贪婪算法的估计误差,证明了该学习算法的一致性.

    基于贪婪算法的文档图像中干扰线的去除

    接着通过一种改进的贪婪算法计算横、竖两个方向线段的权重,判断权重较高的线段为干扰线;最后通过与干扰线距离的大小判断图像中每个前景像素的归属,从而获得一个完整的文档恢复图.仿真实验表明,本文提出的算法...

    算法设计 贪婪法实验 报告

    实验一 一、实验目的 通过用“贪婪法”解决一个应用问题来深化对“贪婪法”算法思想的理解,熟悉用算法设计来解决问题的流程。 二、算法原理 选用贪婪法解决背包问题。

    基于动态规划和贪婪算法的停车楼智能停车优化方法* (2015年)

    针对各种类型的立体停车楼停车管理系统混乱、无序导致泊车及出车过程费时并易引起停车楼通道阻塞等问题,根据停车楼布局、历史停车数据库及待停车辆的信息,建立了二维背包模型,并将动态规划算法和贪婪算法相融合,...

    数据结构与算法分析第二版 ---C语言描述(附加答案)

    算法设计技巧10.1 贪婪算法10.1.1 一个简单的调度问题10.1.2 Huffman编码10.1.3 近似装箱问题10.2 分治算法10.2.1 分治算法的运行时间10.2.2 最近点问题10.2.3 选择问题10.2.4 一些运算问题的理论改进10.3 动态规划...

    算法导论(第2版)参考答案

     第十六章 贪婪算法(Greedy Algorithms)  第十七章 分摊分析(Amortized Analysis)  第五部分(Part V) 高级的数据结构(Advanced Data Structures)  第十八章 B-树(B-Trees)  第十九章 二项式堆...

    一种最速下降的贪婪迭代算法 (2014年)

    结合凸优化算法中的最速下降法及贪婪迭代算法中的正交匹配算法(OMP),提出了一种新的算法,并应用于一维信号和二维图像信号的压缩重构实验,且深入对比分析了不同降采样矩阵对新算法的影响。结果发现,对同一降...

    C++数据结构与算法设计

    很好很清晰的一本C++算法书籍,先从C++程序设计基本开始,再到数据结构,最后上升到算法设计。适合新人新手学习和有经验的老手更深层次了解学习深入。...13 贪婪算法 14 分而治之算法 15 动态规划 16 回朔 17 分支定界

    算法导论(中文 第二版)答案

     第十六章 贪婪算法(Greedy Algorithms)  第十七章 分摊分析(Amortized Analysis)  第五部分(Part V) 高级的数据结构(Advanced Data Structures)  第十八章 B-树(B-Trees)  第十九章 二项式堆...

    基于压缩感知的信号恢复算法研究

    近年来,随着现代信息技术的飞速发展,人们对信息量的巨量需求与传统的信号处理 理论之间的矛盾日益加剧。传统的奈奎斯特采样定理要求采样速率必须大于信号最高带宽 的两倍以上才能精确恢复出原始信号,然而在实际...

Global site tag (gtag.js) - Google Analytics