第4章 贪心算法_第1页
第4章 贪心算法_第2页
第4章 贪心算法_第3页
第4章 贪心算法_第4页
第4章 贪心算法_第5页
已阅读5页,还剩67页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1,第4章 贪心算法,4.1 贪心算法的基本要素 4.2 活动安排问题 4.3 最优装载 4.4 单源最短路径 4.5 哈夫曼编码 4.6 多机调度问题,贪心算法,顾名思义,贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。当然,希望贪心算法得到的最终结果也是整体最优的。 虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。如单源最短路经问题,最小生成树问题等。在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。,2,例:用贪心法求解付款问题。 假设有面值为5元、2元、1元、

2、5角、2角、1角的货币,需要找给顾客4元6角现金,为使付出的货币的数量最少,首先选出1张面值不超过4元6角的最大面值的货币,即2元,再选出1张面值不超过2元6角的最大面值的货币,即2元,再选出1张面值不超过6角的最大面值的货币,即5角,再选出1张面值不超过1角的最大面值的货币,即1角,总共付出4张货币。,在付款问题每一步的贪心选择中,在不超过应付款金额的条件下,只选择面值最大的货币,而不去考虑在后面看来这种选择是否合理,而且它还不会改变决定:一旦选出了一张货币,就永远选定。付款问题的贪心选择策略是尽可能使付出的货币最快地满足支付要求,其目的是使付出的货币张数最慢地增加,这正体现了贪心法的设计思

3、想。,5,贪心算法的设计思路,贪心算法的设计思路是:总是做出在当前看来最好的选择,即贪心算法并不是从整体最优考虑,它所做的选择只是在某种意义上的局部最优选择。,贪心算法框架,Greedy(A,n) /A为输入集合 solution = ; / 解空间初始化为空 for (i = 1; i =n; i+) /对每个输入进行检测 x = select(A); / 选择一个输入 if (feasible(solution,x) / 如果可行 solution = union(solution,x); / 添至解空间 return solution; ,6,7,4.1 贪心算法的基本要素,利用贪心算法

4、求解最优解的两个前提条件: 贪心选择性质和最优子结构性质。 1.贪心选择性质 所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是利用贪心算法求解最优解的第一个基本要素,也是贪心算法与动态规划算法的主要区别。,8,2.最优子结构性质 当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。,9,3.贪心算法与动态规划算法的差异 共同点:求解的问题都具有最优子结构性质 差异点:动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出

5、相继的贪心选择,每做一次贪心选择就将所求问题简化为规模更小的子问题。,10,0-1背包问题: 给定n种物品和一个背包。物品i的重量是Wi,其价值为Vi,背包最大承载重量为C。应如何选择装入背包的物品,使得装入背包中物品的总价值最大?,在选择装入背包的物品时,对每种物品i只有2种选择,即装入背包或不装入背包。不能将物品i装入背包多次,也不能只装入部分的物品i。,背包问题: 与0-1背包问题类似,所不同的是在选择物品i装入背包时,可以选择物品i的一部分,而不一定要全部装入背包,1in。,11,0-1背包与背包问题都具有最优子结构,已知背包最大承载重量为C,共有n个物品,每个物品的重量分别为Wi(i

6、=1,2,.,n),价值为Vi(i=1,2,.n)。 证明: 假设第k个物品是最优解中的一个物品,则 从中拿出Wk对应的物品后所对应的解一定是其余n-1个物品,装入背包最大承载重量为C-Wk的最优解,否则与假设矛盾。,0-1背包问题不具有贪心选择性质。原因是无法保证能够将背包装满,而所剩空间将会降低总价值。 背包问题具有贪心选择性质。,12,13,0-1背包问题不具有贪心选择特性,14,背包问题具有贪心选择特性,15,用贪心算法解背包问题的基本步骤: 1.计算每种物品单位重量的价值Vi/Wi; 2.按照单位重量的价值从高到低的顺序排序; 3.依据贪心选择策略,按照单位价值从高到低的顺序,依次将

7、尽可能多的物品装入背包中。 直到背包装满为止。 是否可以将物品装入背包的条件是: 有空间,16,背包问题的贪心算法,void knapsack(float c,float w, float v,float x,int n) 将各种物品依其单位重量的价值从高到低排序 初始化 xi=0; for (i=0;in;i+) /贪心选择 if (不能放) break; 放入背包中 if (背包没满 ,wi重量 vi单位价值 xi结果,17,背包问题的贪心算法,float knapsack(float c,float w, float v,float x,int n) ITEMTYPE dn; for (

8、int i = 0; i c) break; xdi.i=1; opt+=di.v; c-=di.w; if (c0 ,x,算法knapsack的主要计算时间是将各种物品依其单位重量的价值从大到小排序。因此,算法的计算时间上界为O(nlogn)。,typedef struct float w,v; int i; ITEMTYPE;,D :,18,4.2 活动安排问题,设有n个活动的集合E=1,2,n,其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si fi。如果选择了活动i,则它在半开

9、时间区间si, fi)内占用资源。若区间si, fi)与区间sj, fj)不相交,则称活动i与活动j是相容的。,19,各活动占用资源情况,假设按照11个活动的结束时间的非减序排列如下:,按照每个活动完成时间的顺序排列,20,(1)活动安排具有最优子结构性质,Sij表示第i个任务结束之后,第j个任务开始之前的任务集合。 假设子问题Sij的最优解集合为Aij且包含任务ak,则在最优解集合里的子问题Sik的解Aik以及子问题Skj的解Akj也一定是最优的。 证明: 假设子问题Sik存在一个更优的解Aik,则 |Aik|+1+|Akj|Aik|+1+|Akj|=|Aij| 与假设矛盾!,21,令子问题

10、Sij 且a1为子问题Sij中具有最早完成时间的任务,则a1一定包含在子问题Sij中某个任务相互兼容的最大子集中。 结论:具有贪心选择特性。,(2)活动安排具有贪心选择特性,证明: 假设子问题Sij的最优解为Aij,其中的任务按照完成时间由小到大排列;且第一个任务为ak。如果ak = a1,成立。 如果ak a1 ,由于a1完成时间较ak早,所以,可以将ak去掉,换成a1,仍然相容,所含任务数量一样。,22,23,活动安排问题举例,假设待安排的11个活动的开始时间和结束时间按结束时间的非减序排列如下:,若被检查的活动i的开始时间Si小于最近 选择的活动j的结束时间fi,则不选择活 动i,否则选

11、择活动i加入集合A中,24,图中每行相应于算法的一次迭代。阴影长条表示的活动是已选入集合A的活动,而空白长条表示的活动是当前正在检查相容性的活动。,25,结果:选中的任务为:1、4、8、11,26,解活动安排问题的贪心算法 int greedySelector(int s, int f, boolean a,int n) a1=true; / 初始化 int j = 1, count = 1; for (int i = 2; i = fj) ai = true; j = i; count+; else ai = false; return count; ,各活动的起始时间和结束时间存储于数组s

12、和f中且按结束时间的非减序排列,27,假设输入的活动以其完成时间的非减序排列,则算法greedySelector总选择最早完成时间的相容活动加入集合A中。该算法的贪心选择的意义是使剩余的可安排时间段极大化,以便安排尽可能多的相容活动。 算法greedySelector的效率极高。当输入的活动已按结束时间的非减序排列,算法只需O(n)的时间安排n个活动,使最多的活动能相容地使用公共资源。如果所给出的活动未按非减序排列,可以用O(nlogn)的时间重排。,28,4.3 最优装载,有一批集装箱要装上一艘载重量为c的轮船。其中,集装箱i的重量为Wi。最优装载问题要求确定在装载体积不受限制的情况下,将尽

13、可能多的集装箱装上轮船。,29,最优装载问题可用贪心算法求解。采用重量最轻者先装的贪心选择策略,可产生最优装载问题的最优解。,30,(1)最优子结构的性质,设 (x1,x2,.,xn)是最优装载问题满足贪心选择的最优解,则可知, x1=1,且(x2,.,xn)是轮船重量为c-w1,待装船集装箱为2,3,.,n时相应最优装载问题的最优解。 利用反证法证明。,31,(2)贪心选择性质,设集装箱依重量从小到大排序,(x1,x2,.,xn)是最优装载问题的一个最优解。设,x:(0,0,1,1,1,0,0,0) k = 3 y:(1,0,0,1,1,0,0,0),32,最优装载贪心算法,float lo

14、ading(float c, float w, int x,int n) ITREMTYPE dn; for (int i = 0; i n; i+) di = (wi,i); mergeSort(d); / 排序 O(nlogn) float opt=0; for (int i = 0; i n; i+) xi = 0; for (int i = 0; i n ,typedef struct float w; int i; ITEMTYPE;,33,34,4.4 单源最短路径,问题提出:给定带权有向图G =(V,E),其中每条边的权是非负实数。另外,还给定V中的一个顶点,称为源。现在要计算从

15、源到所有其他各顶点的最短路经长度。这里路径长度是指路上各边权之和。这个问题通常称为单源最短路径问题。,35,v0v1 :无 v0v2:10 v0 v4 v3:50 v0 v4:30 v0 v4 v3 v5:60,36,(1)Dijkstra算法,Dijkstra算法是解单源最短路径问题的贪心算法。其基本思想是设置一个已经确定最短路径的顶点集合S,并通过不断地贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。,37,Dijkstra算法基本过程,初始时,S中仅含有源。设u是V-S中的一个顶点。把从源到u且中间只经过S中顶点的路称为从源到u的特殊路径,并用数组dis

16、t记录当前每个顶点所对应的最短特殊路径长度。,u,S,V-S,38,Dijkstra算法基本过程,Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组dist作必要的修改。一旦S包含了所有V中顶点,dist就记录了从源到所有其他顶点之间的最短路径长度。,u,V-S,S,39,Dijkstra算法的迭代过程,40,算法,置S为空; 将源点v0加入S; 初始化dist,即对每个非源点i令disti为边的权,不存在令disti为。 while (S中没有包含全部顶点) /贪心选择 选择V-S结点u, distu=mindistv|vV-S; 将u加入S; fo

17、r (V-S中每个结点v) distv=mindistv,distu+cost(u,v); ,41,(2)Dijkstra算法具有最优子结构性质,证明算法中每步确定的disti是当前从源点到顶点i的最短特殊路径长度。,证明:采用数学归纳法。 当|S|=1时,显然成立。 假设在第k次贪心选择之前disti存放着从源点到顶点i的最短特殊路径长度。 需要证明(第k+1次贪心选择):根据贪心选择策略,将顶点u添加到S之后,disti仍然是当前从源点到顶点i的最短特殊路径长度。,42,假设根据贪心选择策略,第k+1选 择将顶点u添加到S中,对于顶点i 可能会增加一条从源点到达顶点i 的新的特殊路径。 这

18、条新的特殊路径由两种可能: 情况1:这条路径先由源点到达顶点u,再由顶点u直接到达i,则这条特殊路径的长度为: distu+aui 如果这条路径更短,替换disti;否则不变。,43,情况2:如果新增加的特殊路径先 由源点到达顶点u,再由顶点 u途径另一顶点x到达i。由于x早 于u进入S中,所以distxdistu, 即distx+axi distu+aux+axi, 故:这条新特殊路径不会影响disti,因此不需要考虑。 结论:在任何时候,disti都存放着当前从源点到i点的最短特殊路径长度。,44,(3) Dijkstra算法具有贪心选择性质,按照贪心选择方式得到的distu一定是从源点s

19、到顶点u的最短路径长度。 证明:假设存在一条从源点s到u的更短路径。,d(s,x) 是从s 到x的路径长度 d(s,u) 是从s 到u的路径长度 d(x,u) 是从x 到u的路径长度 则 distx d(s,x) d(s,x)+d(x,u)=d(s,u)distu 由于d(x,u) 0, 所以distxdistu 按照贪心选择策略,x不应该位于S之外,矛盾!,45,计算复杂性,对于具有n个顶点和e条边的带权有向图,如果用带权邻接矩阵表示图,Dijkstra算法的时间复杂度O(n2)。,46,4.5 哈夫曼编码,如果文本中包含100,000个字符, 固定长度的编码: 100,0003=300,0

20、00(位) 变长编码: 145,000+341,000+414,000=224,000(位) 结论:节省25%,47,哈夫曼编码广泛应用于数据文件压缩中。其压缩率通常在20%90%之间。哈夫曼编码算法用字符在文件中出现的频率表来建立一个用0,1串表示各字符的最优表示方式。给出现频率高的字符较短的编码,出现频率较低的字符以较长的编码,可以大大缩短总码长。 1.前缀码 对每一个字符规定一个0,1串作为其代码,并要求任一字符的代码都不是其他字符代码的前缀,称为前缀码。,48,编码的前缀性质可以使译码方法非常简单。 可以采用二叉树表示前缀编码,平均码长定义为: 使平均码长达到最小的前缀码编码方案称为给

21、定编码字符集C的最优前缀码。,编码指:将文件中各个代表各个字符的编码连接起来。例如:abc0 101 100 0101100 因为任何一个 编码码字都不是其他编码码字的前缀,因此,解码一个文件的码字是明确的。例如: 001011101 00 101 1101 aabe 解码过程需要一种方便的形式来表示前缀码,二叉树就是一种好的表示方式。,49,二叉树作为前缀码的数据结构:树叶表示给定字符;从树根到树叶的路径当作该字符的前缀码; 代码中每一位的0或1分别作为指示某节点到左儿子或右儿子的“路标”。 其中(a)为固定长度编码的二叉树表示; (b)为变长编码的二叉树表示;,51,2.构造哈夫曼编码 哈

22、夫曼提出构造最优前缀码的贪心算法,由此产生的编码方案称为哈夫曼编码。 哈夫曼算法以自底向上的方式构造表示最优前缀码的二叉树T。 算法以|C|个叶结点开始,执行|C|1次的“合并”运算后产生最终所要求的树T。,假设编码字符集中每一字符c的频率是f(c)。以f为键值的优先队列Q用在贪心选择时有效地确定算法当前要合并的2棵具有最小频率的树。一旦2棵具有最小频率的树合并后,产生一棵新的树,其频率为合并的2棵树的频率之和,并将新树插入优先队列Q。经过n1次的合并后,优先队列中只剩下一棵树,即所要求的树T。,52,53,(1)最优子结构性质,设 x 和 y 是二叉树T中的两个叶子且兄弟,z 是双亲。若将

23、z 看作是具有f(z) = f(x)+f(y)的字符,则树 T=T-x,y 表示字符集 C=C-x,y z 的一个最优前缀编码。 利用反证法证明T是一个最优前缀编码。,54,(2)贪心选择性质,令 C 为一个字符表。对 cC,字符 c在文件中出现的频率为f(c)。令 x 和 y 为 C 中出现频率最小的两个字符,则对 C 存在一个最优前缀编码。在这个编码中,x 和 y 的编码长度最长,且长度相等,只有最后一位不同。 假设有字符b,c,x,y,其中,x,y是具有最小频率 的两个字符,且f(b) f(c), f(x) f(y) 故f(x) f(b), f(y) f(c)。,55,f(b) f(c)

24、, f(x) f(y) f(x) f(b), f(y) f(c),说明:贪心选择得到最优前缀编码。,哈夫曼编码举例,57,(a)给出了每个字符出现的频率,并初始化为一座森林。然后,选择两个最小的节点x和y,产生一个新节点z,从而得到一棵新的子树。,哈夫曼算法的正确性 要证明哈夫曼算法的正确性,只要证明最优前缀码问题具有贪心选择性质和最优子结构性质。,贪心选择性质-二叉树T表示字符集C的一个最优前缀码,证明可以对T作适当修改后得到一棵新的二叉树T”,在T”中x和y是最深叶子且为兄弟,同时T”表示的前缀码也是C的最优前缀码。,最优子结构性质-二叉树T表示字符集C的一个最优前缀码,x和y是树T中的两

25、个叶子且为兄弟,z是它们的父亲。若将z当作是具有频率f(z)=f(x)+f(y)的字符,则树T=T-x,y表示字符集C=C-x, y z的一个最优前缀码。,贪心选择性质-二叉树T表示字符集C的一个最优前缀码,证明可以对T作适当修改后得到一棵新的二叉树T”,在T”中x和y是最深叶子且为兄弟,同时T”表示的前缀码也是C的最优前缀码。,60,4.6 多机调度问题,问题提出:多机调度问题要求给出一种作业调度方案,使所给的n个作业在尽可能短的时间内由m台机器加工处理完成。 约定:每个作业均可在任何一台机器上加工处理,但未完工前不允许中断处理。作业不能拆分成更小的子作业。 这个问题是NP完全问题,到目前为

26、止还没有有效的解法。对于这一类问题,用贪心选择策略有时可以设计出较好的近似算法。,61,解决方案,采用最长处理时间作业优先的贪心选择策略可以设计出解多机调度问题的较好的近似算法。 当nm 时,首先将n个作业依其所需的处理时间从大到小排序。然后依此顺序将作业分配给空闲的处理机。算法所需的计算时间为O(nlogn)。,62,多机调度问题举例,假设7个独立作业1,2,3,4,5,6,7由3台机器M1,M2和M3加工处理。各作业所需的处理时间分别为2,14,4,16,6,5,3。按算法greedy产生的作业调度如下图所示,所需的加工时间为17。,63,4.7 最小生成树,设G =(V,E)是无向连通带

27、权图,即一个网络。E中每条边(v,w)的权为cvw。如果G的子图G是一棵包含G的所有顶点的树,则称G为G的生成树。生成树上各边权的总和称为该生成树的耗费。在G的所有生成树中,耗费最小的生成树称为G的最小生成树。 网络的最小生成树在实际中有广泛应用。例如,在设计通信网络时,用图的顶点表示城市,用边(v,w)的权cvw表示建立城市v和城市w之间的通信线路所需的费用,则最小生成树就给出了建立通信网络的最经济的方案。,64,1.最小生成树性质 用贪心算法设计策略可以设计出构造最小生成树的有效算法。本节介绍的构造最小生成树的Prim算法和Kruskal算法都可以看作是应用贪心算法设计策略的例子。尽管这2个算法做贪心选择的方式不同,它们都利用了下面的最小生成树性质: 设G=(V,E)是连通带权图,U是V的真子集。如果(u,v)E,且uU,vV-U,且在所有这样的边中,(u,v)的权cuv最小,那么一定存在G的一棵最小生成树,它以(u,v)为其中一条边。这个性质有时也称为MST性质。,65,2.Prim算法 设G=(V,E)是连通带权图,V=1,2,n。 构造G的最小生成树的Prim算法的基本思想是:首先置S=1,然后,只要S是V的真子集,就作如下的贪心选择:选取满足

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论