算法分析与设计[4].ppt_第1页
算法分析与设计[4].ppt_第2页
算法分析与设计[4].ppt_第3页
算法分析与设计[4].ppt_第4页
算法分析与设计[4].ppt_第5页
已阅读5页,还剩38页未读 继续免费阅读

下载本文档

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

文档简介

1、第四章 贪心方法,什么是贪心方法 背包问题 单源点最短路径 最优归并模式 活动安排问题,实例: 找硬币 假设有三种硬币,面值分别为5分, 2分和1分, 给顾客找零钱时希望拿出的硬币个数最少,找零1角2分: 2个5分, 1个2分 2个5分, 2个1分 6个2分,找零算法: 先找出一个面值不超过1角2分的最大硬币(5分) 从1角2分中减去5分, 剩7分 再找出一个面值不超过7分的最大硬币(5分) 从7分中减去5分, 剩2分 最后找出一个面值不超过2分的最大硬币(2分),贪心算法的思想: 贪心算法总是作出在当前看来最好的选择。 贪心算法并不从整体最优考虑,因此它所作出的选择是 在某种意义上的局部最优

2、选择,贪心算法通常包含一个用以寻找局部最优解的迭代过程 对于某些实例, 这些局部最优解转变为全局最优解 而对于另外一些实例, 贪心算法不能找到全局最优解,贪心算法求解问题的速度比较快, 因为算法的每一步都是 在少量信息的基础上考虑局部最优解, 这样使得每一步的 计算量比较小, 所以算法效率比较高,4.1 什么是贪心方法,某一问题的n个输入,该问题的一种解(可行解),是A的一 个子集,满足一定 的条件,约束条件,目标函数,取极值,最优解,4.1 什么是贪心方法,根据题意,选取一种量度标准,然后按量度标准对n个输入排序,按顺序一次输入一个量。如果这个输入和当前已构成在这种量度意义下的部分最优解加在

3、一起不能产生一个可行解,则不把此输入加到这部分解中,这种能够得到某种量度意义下的最优解的分级处理方法就是贪心方法。,量度标准,量度标准意义下的部分最优解,原问题的 n 个输入,排序后的 n 个输入,A(j),贪心方法的抽象化控制,int *GREEDY(int *A,int n) solution=; for (i=1 ;i= n;i+) x=SELECT(A) if (FEASIBLE(solution,x)=1) solution=UNION(solution,x); return (solution); ,按某种最优量度标准从集合A中选择一个输入赋给x,并从A中除去,判断x是否可以包含在

4、解向量中,将x与解集合合并并修改目标函数,4.1 背包问题的贪心算法,问题描述 已知有n种物品和一个可容纳M重量的背包,每种物品i的重量为wi,假定将物品i的某一部分xi放入背包就会得到pixi的效益(0 xi1, pi0) ,采用怎样的装包方法才会使装入背包物品的总效益为最大呢? 问题的形式描述 极大化 pixi 约束条件 wi xi M 0 xi1, pi0, wi0, 1in,1in,1in,目标函数,背包问题实例,其中的4个可行解:,有3个物品, 即n=3, 背包能容纳的最大重量为20, 即c=20 物品的价值和重量: (v1,v2,v3)=(25,24,15), (w1,w2,w3)

5、=(18,15,10),最优解,贪心算法求解背包问题,确定贪心选择策略, 选择价值高的物品放入背包,将物品按价值的降序排列: (v1,v2,v3)=(25,24,15) 按该次序将物品一件件放到背包中, 先装物品1, 即x1=1, w1=18, v1x1 =25; 再装物品2, 因约束条件为wi xi c=20, 所以物品2只能装入重量为2的一小部分, 即x2=2/15; 最后得到总价值为vixi = 25+24*2/15=28.2,实例:n=3, c=20 (v1,v2,v3)=(25,24,15) (w1,w2,w3)=(18,15,10),这是一个次优解,原因是背包容量消耗的过快,确定贪

6、心选择策略, 选择重量轻的物品放入背包,将物品按重量的升序排列: (w3,w2,w1)=(10,15,18) 按该次序将物品放到背包中, 让容量尽可能慢的被消耗 先装物品3, 即x3=1, w3=10, v3x3 =15; 再装入物品2, 因约束条件为wixic=20, 所以物品2 只能装入重量为10的一部分, 即x2=10/15=2/3; 最后得到总价值为vixi =15+24*2/3=31,这仍是一个次优解, 原因是容量在慢慢消耗的过程中, 效益值却没有迅速的增加,实例:n=3, c=20 (v1,v2,v3)=(25,24,15) (w1,w2,w3)=(18,15,10), 选择单位重

7、量价值高的物品放入背包,将物品按vi/wi比值的降序排列: (v2/w2 , v3/w3 , v1/w1 )=(24/15, 15/10, 25/18) 即每一次装入的物品使它占用的单位重量获得当前最大的单位价值 先装入物品2, 即x2=1, w2=15, v2x2 =24; 再装入物品3, 因约束条件为wi xi c=20, 所以物品3只能装入重量为5的一部分, 即x3=5/10=1/2; 最后得到总价值为vixi =24+15*1/2=31.5,这是最优解, 因为每一单位重量的增加将获得最大的单位价值,确定贪心选择策略,实例:n=3, c=20 (v1,v2,v3)=(25,24,15)

8、(w1,w2,w3)=(18,15,10),贪心算法求解背包问题的步骤,计算每个物品的单位重量的价值, 即vi/wi 按vi/wi的值对物品进行降序排列 按贪心选择策略将物品依次放入背包 按顺序依次选择单位重量价值高的物品i , 若wi当前背包的剩余容量, 则放入该物品, 并从背包的剩余容量中减去wi (即背包的剩余容量减小) 若wi当前背包的剩余容量, 则放入该物品的一部分, 即放入剩余容量/wi,void Knapsack(int n,float M,float v ,float w ,float x ) Sort(n,v,w); int i; for (i=1; i=n; i+) xi=

9、0; float c=M; for (i=1; i=n; i+) if (i=n) ,求解背包问题的贪心算法描述,/ 按v/w的值对物品进行排序,/ 设置初始值,/ M为背包容量, c为当前背包的剩余容量,/ 依次对物品进行处理,/ 若wic, 则物品i不能全部放入背包,/ 若wic, 则物品i能放入背包,/ 修改当前背包的剩余容量,/ 将物品i的一部分放入背包,if (wic) break;,xi=1;,c=c-wi;,xi= c/wi;,算法Knapsack的主要计算时间在于将各种物品依其单位重量的价值从大到小排序。因此算法的时间上界为O(nlogn),算法分析,贪心算法可以求解背包问题,

10、 并得到最优解,课后思考题,0/1背包问题:在杂货店比赛中你获得了第一名,奖品是一车免费的商品。店中有n种不同的货物。规则规定从每种货物中最多只能拿一件,车子的容量为C,物品i需占用的空间为Wi,价值为Pi。你的目标是使车中装载的物品价值最大。(注意:所装货物不能超过车的容量,且同一种物品不得拿走多件。)利用贪心策略,如何选择量度标准才能找到最优解?,4.4 单源点最短路径,问题描述: 给定带权有向图G=(V,E),其中每条边的权是非负实数。另外给定V中的一个顶点,称为源点。现要计算从源点到所有其它各顶点的最短路长度(路的长度是指路上各边权之和)。该问题通常称为单源点最短路径问题。,求解单源点

11、最短路径的算法 在数据结构中我们学习过迪杰斯特拉(Dijkstra)算法, 该算法实际是求解单源点最短路径的一个贪心算法。,Dijkstra算法的基本思想:,设置一个顶点集合S, 并不断地作贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源点到该顶点的最短路径长度已知。 初始时S中仅含有源点。 设u是G的某一个顶点, 把从源点到顶点u且中间只经过S中顶点的路称为从源点到顶点u的特殊路径, 并用数组dist记录当前每个顶点所对应的最短特殊路径长度。 算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中, 同时对数组dist作必要的修改。 一旦S包含了V中所有的顶点,dist就记录

12、了从源点到所有其它顶点之间的最短路径长度。,10,实例计算,2,1,2,1,2,4,1,2,4,3,1,2,4,3,5,4,10 60 30 100,10 50 30 90,10 50 30 60,10 50 30 60,3,5,60,50,30,算法求出了从源点到其他顶点的最短路径长度, 如果要求出相应的最短路径, 还需要借助一个数组prev来记录从源点到顶点i的最短路径上i的前一个顶点, 这样可以根据数组prev的信息求出最短路径,Dijkstra算法描述,void Dijkstra(int n, int v, Type dist, int prev, Type *c) int i, j;

13、 bool sn; for(i=1; i=n; i+) disti=cvi; si=false; if(disti=maxint) previ=0; else previ=v; distv=0; sv=true;,初始化工作,/ si的值为true, 表示顶点i属于集合S,设源点v=1,修改源点的初始值,0,true,for(i=1; in; i+) int temp=maxint; int u=v; for(j=1; j=n; j+) su=true; for(j=1; j=n; j+) if(!sj) ,/ 进行迭代计算,找出dist的最小值,/ 将顶点u加入到集合S中,重新计算加入顶点u

14、之后的dist的值,如果新的dist的值小于原来的值,则修改数组dist和prev中的数据,if(!sj) ,if(newdistdistj) distj=newdist; prevj=u; ,for(i=1; in; i+) int temp=maxint; int u=v; for(j=1; j=n; j+) if(!sj) ,/ 进行迭代计算,找出dist的最小值,/ 将顶点u加入到集合S中,重新计算加入顶点u之后的dist的值,如果新的dist的值小于原来的值,则修改数组dist和prev中的数据,实例计算过程:,i=1时 temp=maxint; u=v=1;,设源点v=1,for(

15、j=1; j=5; j+) j=1, !sj为假, if条件不满足 j=2, u=2; temp=dist2=10; j=3, !sj为真,但dist3temp为假 j=4,5的情况与j=3时一样,s2=true;,for(j=1; j=n; j+) j=1,2时, !sj为假, if条件不满足 j=3, 满足条件(!s3) ,true,60,2,j=4,5时, c24=c25=maxint, if条件不满足,实例计算过程:,i=2时 temp=maxint; u=v=1;,设源点v=1,for(j=1; j=5; j+) j=1,2时, !sj为假, if条件不满足 j=3, u=3; te

16、mp=dist3=60; j=4, u=4; temp=dist4=30; j=5, !sj为真,但dist5temp为假,s4=true;,for(j=1; j=n; j+) j=1,2时, !sj为假, if条件不满足 j=3, 满足条件(!s3) ,true,50,4,j=4时, !sj为假, if条件不满足 j=5, 满足条件(!s5) ,90,4,经计算最后得到:,由数组prev的值可以得到由源点1到其他各个顶点的最短路径:,最优归并模式,X1,X2,X3,X4,第二章中学习了如何用分治法将两个分别包含n个和m个记录的已排序的数据在O(n+m)时间内归并成一个包含(n+m)个数据的有

17、序文件。下面是两种将4个文件进行归并的方法。不同的配对法要求不同的计算时间。,什么是归并模式,给出n个文件,则有许多种把这些文件成对地归并成一个单一分类文件的方法 不同的配对方法要求不同的计算时间 问题的关键是:确定一个把n个已分类文件归并在一起的最优方法(即需要最少的比较的方法),例3.5 :X1,X2和X3是各自有30个数据、20个数据和10个数据的三个已排序文件,归并X1和X2需要50次数据比较,再与X3归并则还要60次比较,其所需要的数据比较次数总量为110。 如果首先归并X2和X3,需要30次比较,然后再归并X1,需要60次比较,则所要比较数据的总量为90。 因此,第二个归并模式比第

18、一个要好。,最优归并模式的实现,由于归并一个具有n个数据的文件和一个具有m个数据的文件可能需要m+n次数据比较,因此对于量度标准的一种很明显的选择是:每一步都归并尺寸比较小的两个文件 例如有五个文件长度分别是(F1,F5)=(20,30,10,5,30),5,F4,10,F3,二元归并树,二路归并模式,上面所描述的归并模式称为二路归并模式。二路归并模式可以用二元归并树来表示。 二元归并树中叶结点被画成方块,表示五个已知的文件。这些结点称为外部结点。 剩下的结点被画成圆圈,称为内部结点。每个内部结点恰好有两个儿子,表示它是将两个儿子所表示的文件归并在一起而得到的文件。 每个结点中的数字都是那个结

19、点所表示文件的长度(即记录数)。,最优归并模式的实现,带权外部路径长度 如果di表示从根到代表文件Fi的外部节点的距离,qi表示Fi的长度,则这棵二元归并树的记录比较总量是: diqi 这个和数叫做这棵树的带权外部路径长度 一个最优二路归并模式与一棵具有最小外部路径的二元树相对应。,i=1,n,二元归并树算法,二元归并树算法把n个树的表L作为输入。树中的每一个结点有三个信息段(LCHILD,RCHILD,WEIGHT)。 起初,L中的每一棵树正好有一个结点。这个结点是一个外部结点,而且其LCHILD和RCHILD信息段为0,而WEIGHT是要归并的n个文件之一的长度。 算法运行期间,对于L中的

20、任何一棵具有根结点T的树, WEIGHT(T)表示要归并的文件的长度。 WEIGHT(T) = 树T中外部结点的长度和,二元归并树算法,Struct node * TREE(Struct node * L,int n) for( i=1; in ;i+) GETNODE(T); LCHILD(T)LEAST(L) RCHILD(T)LEAST(L) WEIGHT(T)WEUGHT(LCHILD(T)+WEUGHT(RCHILD(T) INSERT(L,T) return (LEAST(L) ,每个节点有三个信息:LCHILD,RCHILD,WEIGHT,构造一个新的根结点T,找出L中一棵具有最

21、小WEIGHT的树,并删除 将其加入T的左子树,把根为T的树插入到表L中,最后留在L中的树就是最优归并树,二元归并树算法的实例,例:L最初有6个文件,长度分别为:2 , 3 , 5 , 7 , 9 , 13 L=2 , 3 , 5 , 7 , 9 , 13,生成一个新的根结点,选长度最小文件的作为新树的左右子女,并从L中删除 将新生成的树加入到L中, L=5, 5 , 7 , 9 , 13,2,3,5,二元归并树算法的实例,L=5, 5 , 7 , 9 , 13,再生成一个新的根结点,选长度最小文件的作为新树的左右子女,并从L中删除 将新生成的树加入到L中, L= 10, 7 , 9 , 13

22、,5,10,二元归并树算法的实例,L= 10, 7 , 9 , 13 ,再生成一个新的根结点,选长度最小文件的作为新树的左右子女,并从L中删除 将新生成的树加入到L中, L= 10, 16 , 13,7,9,16,二元归并树算法的实例,L= 10, 16 , 13 ,再生成一个新的根结点,选长度最小文件的作为新树的左右子女,并从L中删除. 将新生成的树加入到L中, L= 23, 16,13,23,二元归并树算法的实例,L= 23, 16 ,再生成一个新的根结点,选长度最小文件的作为新树的左右子女,并从L中删除. 将新生成的树加入到L中, L= 39,39,二元归并树算法分析,Struct no

23、de * TREE(Struct node * L,int n) for( i=1; in ;i+) GETNODE(T); LCHILD(T)LEAST(L) RCHILD(T)LEAST(L) WEIGHT(T)WEUGHT(LCHILD(T)+WEUGHT(RCHILD(T) INSERT(L,T) return (LEAST(L) ,主循环执行n-1次,如果L中WEIGHT的值为非降次序,则LEAST(L)只需要O(1)的时间,INSERT(L,T)在O(n)时间内被执行,此算法的计算是总量为:O(n2),活动安排问题,实例: 毕业设计答辩会场安排 2006年本科毕业生分为8个小组进行毕业答辩, 答辩小组都想使用有投影设备和空调的会议室, 因为各答辩小组教师的上课时间不同, 因此他们选择不同的时间段进行工作, 请在一天当中安排尽可能多的答辩小组,安排方案 第一天: 4, 1, 7, 6 第二天: 2,

温馨提示

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

评论

0/150

提交评论