计算机常用算法与程序设计教程 第5章 贪心算法.ppt
《计算机常用算法与程序设计教程 第5章 贪心算法.ppt》由会员分享,可在线阅读,更多相关《计算机常用算法与程序设计教程 第5章 贪心算法.ppt(42页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、1常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计5.1贪心算法概述贪心算法概述5.2贪心算法的理论基础贪心算法的理论基础5.3删数字问题删数字问题5.4背包问题背包问题5.5覆盖问题覆盖问题5.6图的着色问题图的着色问题5.7遍历问题遍历问题5.8最小生成树最小生成树5.9哈夫曼编码哈夫曼编码2常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计5.1贪心算法概述贪心算法概述5.1.1贪心算法贪心算法 有一艘大船准备用来装载货物。所有待装货物都装在有一艘大船准备用来装载货物。所有待装货物都装在货箱中且所有货箱的大小都一样,但货箱的重量都各不货箱中且
2、所有货箱的大小都一样,但货箱的重量都各不相同。设第相同。设第i个货箱的重量为个货箱的重量为wi(1in),而货船的最大),而货船的最大载重量为载重量为c,我们的目的是在货船上装入最多的货物。,我们的目的是在货船上装入最多的货物。这个问题可以作为最优化问题进行描述:设存在一组这个问题可以作为最优化问题进行描述:设存在一组变量变量xi,其可能取值为,其可能取值为0或或1。如。如xi为为0,则货箱,则货箱i将不被装将不被装上船;如上船;如xi为为1,则货箱,则货箱i将被装上船。我们的目的是找到将被装上船。我们的目的是找到一组一组xi,使它满足限制条件,使它满足限制条件ni=wixic且且xi0,1,
3、1in。相应的优化函数是。相应的优化函数是ni=wixi取极值取极值。满足限制条。满足限制条件的每一组件的每一组xi都是一个可行解,能使都是一个可行解,能使ni=wixi取得极大值取得极大值的方案是最优解。的方案是最优解。3常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计贪心算法(也称贪心策略)总是作出在当前看来是最好贪心算法(也称贪心策略)总是作出在当前看来是最好的选择。如上面的找硬币问题本身具有最优子结构性质,的选择。如上面的找硬币问题本身具有最优子结构性质,它可以用动态规划算法来解。但我们看到,用贪心算法更它可以用动态规划算法来解。但我们看到,用贪心算法更简单,更
4、直接且解题效率更高。这利用了问题本身的一些简单,更直接且解题效率更高。这利用了问题本身的一些特性。特性。贪心算法在求解最优化问题时,从初始阶段开始,每一贪心算法在求解最优化问题时,从初始阶段开始,每一个阶段总是作一个使局部最优的贪心选择,不断把将问题个阶段总是作一个使局部最优的贪心选择,不断把将问题转化为规模更小的子问题。也就是说贪心算法并不从整体转化为规模更小的子问题。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优最优考虑,它所作出的选择只是在某种意义上的局部最优选择。这样处理,对大多数优化问题来说能得到最优解,选择。这样处理,对大多数优化问题来说能得到最优解,
5、但也并不总是这样。从求解效率来说,贪心算法比动态规但也并不总是这样。从求解效率来说,贪心算法比动态规划更高,且不存在空间限制的影响。另外,对一些划更高,且不存在空间限制的影响。另外,对一些NP完全完全问题或规模很大的优化问题,可通过仿贪心算法能得到很问题或规模很大的优化问题,可通过仿贪心算法能得到很好的近世解,而用动态规划根本无法解。好的近世解,而用动态规划根本无法解。4常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计5.1.2.贪心算法的基本思想贪心算法的基本思想 贪心算法的基本思想是通过一系列选择步骤来构造问题贪心算法的基本思想是通过一系列选择步骤来构造问题的解,每
6、一步都是对当前部分解的一个扩展,直至获得问题的解,每一步都是对当前部分解的一个扩展,直至获得问题的完整解。所做的每一步选择都必须满足:的完整解。所做的每一步选择都必须满足:(1)可行的:必须满足问题的约束。可行的:必须满足问题的约束。(2)局部最优:当前所有可能的选择中最佳的局部选择。局部最优:当前所有可能的选择中最佳的局部选择。(3)不可取消不可取消:选择一旦做出,在后面的步骤中就无法选择一旦做出,在后面的步骤中就无法改变了。改变了。贪心算法是通过做一系列的选择来给出某一问题的最优贪心算法是通过做一系列的选择来给出某一问题的最优解,对算法的每一个决策点,做一个当时(看起来)是最佳解,对算法的
7、每一个决策点,做一个当时(看起来)是最佳的选择。这种启发式策略并不总是能产生出最优解。的选择。这种启发式策略并不总是能产生出最优解。5常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计5.2贪心算法的理论基础贪心算法的理论基础1.“矩阵胚矩阵胚”理论理论 2.2.“矩阵胚矩阵胚”理论是一种能够确定贪心算法理论是一种能够确定贪心算法何时能够产生最优解的理论,虽然这套理论还何时能够产生最优解的理论,虽然这套理论还很不完善,但在求解最优化问题时发挥着越来很不完善,但在求解最优化问题时发挥着越来越重要的作用。越重要的作用。定义定义矩阵胚是一个序对矩阵胚是一个序对M=S,I,其中,
8、其中S是是一个有序非空集合,一个有序非空集合,I是是S的一个非空子集,成的一个非空子集,成为为S的一个独立子集。的一个独立子集。6常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计如果如果M是一个是一个NM的矩阵的话,即的矩阵的话,即:若若M是无向图是无向图G的矩阵胚的话,则的矩阵胚的话,则S为图的边为图的边集,集,I是所有构成森林的一组边的子集。是所有构成森林的一组边的子集。如果对如果对S的每一个元素的每一个元素X(XS)赋予一个正)赋予一个正的权值的权值W(X),则称矩阵胚),则称矩阵胚M=(S,I)为一)为一个加权矩阵胚。个加权矩阵胚。7常用算法与程序设计常用算法与
9、程序设计常用算法与程序设计常用算法与程序设计适宜于用贪心算法来求解的许多问题都可以归结为适宜于用贪心算法来求解的许多问题都可以归结为在加权矩阵胚中找一个具有最大权值的独立子集的在加权矩阵胚中找一个具有最大权值的独立子集的问题,即给定一个加权矩阵胚,问题,即给定一个加权矩阵胚,M=(S,I),若能),若能找出一个独立且具有最大可能权值的子集找出一个独立且具有最大可能权值的子集A,且,且A不不被被M中比它更大的独立子集所包含,那么中比它更大的独立子集所包含,那么A为最优为最优子集,也是一个最大的独立子集。子集,也是一个最大的独立子集。矩阵胚理论对于我们判断贪心算法是否适用于某一矩阵胚理论对于我们判
10、断贪心算法是否适用于某一复杂问题是十分有效的。复杂问题是十分有效的。8常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计对给定的对给定的n位高精度正整数位高精度正整数,去掉其中去掉其中k(k1(当然小于当然小于n),按上述操作一个一个删除。按上述操作一个一个删除。删除一个达到最大后删除一个达到最大后,再从头即从串首开始再从头即从串首开始,删除第删除第2个个,依此分解为依此分解为k次完成。次完成。若删除不到若删除不到k个后已无左边小于右边的增序个后已无左边小于右边的增序,则停止删除操作则停止删除操作,打印剩下串的左边打印剩下串的左边n-k个数个数字即可字即可(相当于删除了若
11、干个最右边的数字相当于删除了若干个最右边的数字)。下面我们给出采用贪心算法的删数字问题下面我们给出采用贪心算法的删数字问题的的部分部分c语言代码:语言代码:10常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计 while(kx&m=0)i=i+1;if(ai-1ai)/*出现递增,删除递增的首数字*/printf(%d,ai-1);for(j=i-1;j=n-x-2;j+)aj=aj+1;x=x+1;/*x统计删除数字的个数*/i=0;/*从头开始查递增区间*/if(i=n-x-1)/*已无递增区间,m=1脱离循环*/m=1;printf(n删除后所得最大数:);for
12、(i=1;i=n-k;i+)/*打印剩下的左边n-k个数字*/printf(%d,ai-1);11常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计 5.4背包问题背包问题已知已知n种物品和一个可容纳种物品和一个可容纳c重量的背包,物品重量的背包,物品i的重量的重量为,产生的效益为。装包时物品可拆,即可只装每种物为,产生的效益为。装包时物品可拆,即可只装每种物品的一部分。显然物品品的一部分。显然物品i的一部分放入背包可产生的效的一部分放入背包可产生的效益为,这里。问如何装包,使所得整体效益最大。益为,这里。问如何装包,使所得整体效益最大。(1)算法设计算法设计应用贪心算法
13、求解。每一种物品装包,由可以整个装入,应用贪心算法求解。每一种物品装包,由可以整个装入,也可以只装一部分,也可以不装。也可以只装一部分,也可以不装。约束条件:目标函数:要使整体效益即目标函数最大,约束条件:目标函数:要使整体效益即目标函数最大,按单位重量的效益非增次序一件件物品装包,直至某一按单位重量的效益非增次序一件件物品装包,直至某一件物品装不下时,装这种物品的一部分把包装满。件物品装不下时,装这种物品的一部分把包装满。解背包问题贪心算法的时间复杂度为解背包问题贪心算法的时间复杂度为O(n)。12常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计物品可拆背包问题物品可
14、拆背包问题C程序设计代码如下:程序设计代码如下:for(i=1;i=n-1;i+)/*对对n件物品按单位重量的效益从件物品按单位重量的效益从大到小排序大到小排序*/for(j=i+1;j=n;j+)if(pi/wipj/wj)h=pi;pi=pj;pj=h;h=wi;wi=wj;wj=h;cw=c;s=0;/*cw为背包还可装的重量为背包还可装的重量*/for(i=1;icw)break;xi=1.0;/*若若w(i)cw,装入一部分装入一部分x(i)*/s=s+pi*xi;13常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计printf(装包:装包:);/*输出装包结
15、果输出装包结果*/for(i=1;i=n;i+)if(xi0&xi0)设设v是具有最大的是具有最大的Newi的顶点;的顶点;Cm+=v;for(所有邻接于所有邻接于v的顶点的顶点j)if(!Covj)Covj=true;对于所有邻接于对于所有邻接于j的顶点,使其的顶点,使其Newk减减117常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计if(有些顶点未被覆盖有些顶点未被覆盖)失败失败else找到一个覆盖找到一个覆盖该算法的时间复杂度取决于数据的存储方式,该算法的时间复杂度取决于数据的存储方式,若使用邻接矩阵,则需花若使用邻接矩阵,则需花(n2)的时间来寻找的时间来寻找
16、图中的边,若用邻接链表,则需图中的边,若用邻接链表,则需(n+e)的时的时间。故覆盖算法总的复杂性为间。故覆盖算法总的复杂性为O(n2)或或O(n+e)18常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计图着色问题是其实对应很多应用的例子,假设要在图着色问题是其实对应很多应用的例子,假设要在足够多的会场里安排一批活动,并希望使用尽可能少足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的贪心算法进行安排。的会场。设计一个有效的贪心算法进行安排。(这个问这个问题实际上是著名的图着色问题。若将每一个活动作为题实际上是著名的图着色问题。若将每一个活动作为图的一
17、个顶点,不相容活动间用边相连。使相邻顶点图的一个顶点,不相容活动间用边相连。使相邻顶点着有不同颜色的最小着色数,相应于要找的最小会场着有不同颜色的最小着色数,相应于要找的最小会场数。数。)活动安排问题:设有活动安排问题:设有n个活动个活动a1,a2,an,每个活每个活动都要求使用同一资源,而同一时间内只允许一个活动都要求使用同一资源,而同一时间内只允许一个活动使用这一资源。已知活动动使用这一资源。已知活动ai要求使用该资源的起始要求使用该资源的起始时间为时间为si,结束时间为,结束时间为fi,且,且si=fi。要求在。要求在a1,a2,an中选出最大的相容活动子集。中选出最大的相容活动子集。两
18、活动两活动ai,aj(ij)相容是指:相容是指:5.6图的着色问题图的着色问题19常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计例:例:n=4,活动:活动:a1a2a3a4si:4218fi:74510贪心选择策略:贪心选择策略:按结束时间从早到晚安排活动,每按结束时间从早到晚安排活动,每次选择与已选出的活动相容的结束时间尽可能早的次选择与已选出的活动相容的结束时间尽可能早的活动。活动。局部最优性:局部最优性:每次为资源留下尽可能多的时间以容每次为资源留下尽可能多的时间以容纳其它活动。纳其它活动。该算法的时间复杂性:该算法的时间复杂性:(nlogn)。使用贪心算法求解
19、图的着色问题并不总能得到最优使用贪心算法求解图的着色问题并不总能得到最优解解,只保证得到近似最优解。其实,顶点的编号方只保证得到近似最优解。其实,顶点的编号方法决定了这种算法的结果。至少存在一种编号方法法决定了这种算法的结果。至少存在一种编号方法使这个贪心算法能得到最优解。使这个贪心算法能得到最优解。20常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计voidcolor_up(intnodes)/着色函数着色函数inti,j,k=1;int*color;color=(int*)malloc(sizeof(int)*(nodes+1);/初始初始化颜色数化颜色数for(i
20、=1;i=nodes;i+)colori=0;color1=1;dofor(i=2;i0)continue;下面给出图的着色问题的下面给出图的着色问题的c语言程序语言程序:21常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计for(j=1;j0)&(j=nodes)j+;k+;while(j=nodes);for(i=1;i64输出一个解,返回上一步骤输出一个解,返回上一步骤c-(x,y)c计算计算(x,y)的八个方位的子结点,选出那此可行的的八个方位的子结点,选出那此可行的子结点子结点循环遍历所有可行子结点,循环遍历所有可行子结点,c+重复重复25.7遍历问题遍历问题
21、23常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计显然()是一个递归调用的过程,大致如下:显然()是一个递归调用的过程,大致如下:voiddfs(intx,inty,intcount)inti,tx,ty;if(countN*N)output_solution();/输入一个解输入一个解return;for(I=0;i8;+i)tx=hni.x;/hn保存八个方位子结点保存八个方位子结点ty=hni.y;stxty=count;dfs(tx,ty,count+1);/递归调用递归调用stxty=0;24常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程
22、序设计这样做是完全可行的,它输入的是全部解,但是马遍历当这样做是完全可行的,它输入的是全部解,但是马遍历当时解是非常之多的,用天文数字形容也不为过,这时解是非常之多的,用天文数字形容也不为过,这样一来求解的过程就非常慢,并且出一个解也非常慢。样一来求解的过程就非常慢,并且出一个解也非常慢。怎么才能快速地得到部分解呢?怎么才能快速地得到部分解呢?其实马踏棋盘的问题很早就有人提出,且早在其实马踏棋盘的问题很早就有人提出,且早在1823年,年,J.C.Warnsdorff就提出了一个有名的算就提出了一个有名的算法。在每个结点对其子结点进行选取时,优先选法。在每个结点对其子结点进行选取时,优先选择择出
23、口出口最小的进行搜索,最小的进行搜索,出口出口的意思是的意思是在这些子结点中它们的可行子结点的个数,也就在这些子结点中它们的可行子结点的个数,也就是是孙子孙子结点越少的越优先跳,为什么要这样结点越少的越优先跳,为什么要这样选取,这是一种局部调整最优的做法选取,这是一种局部调整最优的做法.25常用算法与程序设计常用算法与程序设计常用算法与程序设计常用算法与程序设计 其实这种求解就是利用了贪心算法,它对整个求其实这种求解就是利用了贪心算法,它对整个求解过程的局部做最优调整,它只适用于求较优解或解过程的局部做最优调整,它只适用于求较优解或者部分解,而不能求最优解。这样的调整方法叫贪者部分解,而不能求
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机常用算法与程序设计教程 第5章 贪心算法 计算机 常用 算法 程序设计 教程 贪心
限制150内