收藏 分享(赏)

贪心算法-ppt.ppt

上传人:精品资料 文档编号:9930424 上传时间:2019-09-19 格式:PPT 页数:77 大小:2.08MB
下载 相关 举报
贪心算法-ppt.ppt_第1页
第1页 / 共77页
贪心算法-ppt.ppt_第2页
第2页 / 共77页
贪心算法-ppt.ppt_第3页
第3页 / 共77页
贪心算法-ppt.ppt_第4页
第4页 / 共77页
贪心算法-ppt.ppt_第5页
第5页 / 共77页
点击查看更多>>
资源描述

1、第四章.贪心算法(Greed method),例 题,算法设计与分析 贪心算法,顾名思义,贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。当然,希望贪心算法得到的最终结果也是整体最优的。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。如单源最短路经问题,最小生成树问题等。在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似。目的:用以求解最优化问题,将问题的求解过程看作是一系列选择,每次选择一个输入,每次选择都是当前状态下的最好选择(局部最优解).每作一次选择后,所求问题

2、会简化为一个规模更小的子问题.从而通过每一步的最优解逐步达到整体的最优解。,4.1 基本思想,算法优点求解速度快,时间复杂性有较低的阶.,算法缺点需证明是最优解.,常见应用,背包问题,最小生成树,最短路径,作业调度等等,适用问题 具备贪心选择和最优子结构性质的最优化问题 贪心选择性质:整体的最优解可通过一系列局部最优解达到,即贪心选择到达。贪心算法通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每做一次贪心选择就将所求解的问题化简为规模更小的问题对于一个具体问题,要确定它是否具有贪心选择的性质,我们必须证明每一步所作的贪心选择最终导致问题的最优解。通常可以首先证明问题的一个整体最优解

3、,是从 贪心选择开始的,而且作了贪心选择后,原问题简化为一个规模更小的类似子问题。然后,用数学归纳法证明,通过每一步作贪心选择,最终可得到问题的一个整体 最优解。 最优子结构性质:当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。,某一问题的n个输入,该问题的一种解(可行解),是A的一 个子集,满足一定 的条件,约束条件,目标函数,取极值,最优解,算法设计与分析 贪心算法,4.2.活动安排问题,算法设计与分析 贪心算法,活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合,是可以用贪心算法有效求解的很好例子。该问题要求高效地安排一系列争用某一公共资源的活动。贪心算法

4、提供了一个简单、漂亮的方法使得尽可能多的活动能兼容地使用公共资源。,问题陈述设有n个活动的集合E=1,2,n,其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si fi 。如果选择了活动i,则它在半开时间区间si, fi)内占用资源。若区间si, fi)与区间sj, fj)不相交,则称活动i与活动j是相容的。也就是说,当sifj或sjfi时,活动i与活动j相容。,1 2 3 4 5 6 7 8 9 10 11,例,1 3 0 5 3 5 6 8 8 2 12,4 5 6 7 8 9 10

5、 11 12 13 14,i,si,fi,设待安排的11个活动起止时间按结束时间的非减序排列,最大相容活动子集(1, 4, 8, 11),也可表示为等长n元数组:(1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1),算法思路将n个活动按结束时间非减序排列,依次考虑活动i, 若i与已选择的活动相容,则添加此活动到相容活动子集.,活动安排问题贪心算法,template void GreedySelector(int n, Type s , Type f , bool A ) A 1 = true;int j = 1;/从第二个活动开始检查是否与前一个相容for (int i=2;i=

6、fj) Ai = true;j=i;else A i = false; ,算法设计与分析 贪心算法,各活动的起始时间和结束时间存储于数组s和f中且按结束时间的非减序排列,算法greedySelector 的计算过程如左图所示。图中每行相应于算法的一次迭代。阴影长条表示的活动是已选入集合A的活动,而空白长条表示的活动是当前正在检查相容性的活动。,由于输入的活动以其完成时间的非减序排列,所以算法greedySelector每次总是选择具有最早完成时间的相容活动加入集合A中。直观上,按这种方法选择相容活动为未安排活动留下尽可能多的时间。也就是说,该算法的贪心选择的意义是使剩余的可安排时间段极大化,以

7、便安排尽可能多的相容活动。 算法greedySelector的效率极高。当输入的活动已按结束时间的非减序排列,算法只需O(n)的时间安排n个活动,使最多的活动能相容地使用公共资源。如果所给出的活动未按非减序排列,可以用O(nlogn)的时间重排。,T(n)=O(nlogn) (未排序时),算法分析,T(n)=O(n) (排序时),算法证明 算法达到最优解.,问题描述 输入:(x1,x2,.xn), xi=0,货箱i不装船; xi=1,货箱i装船可行解: 满足约束条件 c 的输入优化函数:最优解:使优化函数达到最大值的一种输入.,4.3 最优装载,算法设计与分析 贪心算法,算法思路 将装船过程划

8、为多步选择,每步装一个货箱,每次从剩下的货箱中选择重量最轻的货箱.如此下去直到所有货箱均装上船或船上不能再容纳其他任何一个货箱。,例 设n=8,w1,w8=100, 200, 50, 90, 150, 50, 20, 80,c=400。 所考察货箱的次序为 :7, 3, 6, 8, 4, 1, 5, 2。货箱7, 3, 6, 8, 4, 1的 总重量为390个单位且已被装载, 剩下的装载能力为10 ,小于任意 货箱.所以得到解x1,.x8= 1, 0, 1, 1, 0, 1, 1, 1,1、最优装载的贪心算法,算法设计与分析 贪心算法,template void Loading(int x,

9、Type w, Type c, int n ) int *t = new int n + 1;Sort(w, t, n) ; /按货箱重量排序/for (int i = 1; i = n; i +)xi = 0;for (int i = 1;i= n /调整剩余空间 ,2、贪心选择性质可以证明最优装载问题具有贪心选择性质。 3、最优子结构性质最优装载问题具有最优子结构性质。算法证明:由最优装载问题的贪心选择性质和最优子结构性质,容易证明算法loading的正确性。算法分析:算法loading的主要计算量在于将集装箱依其重量从小到大排序,故算法所需的计算时间为 O(nlogn)。,最优化描述 找

10、一个n元向量(x1,xn) 0 xi 1 使得且 .其中 C, Wi, vi0 , 1 i n,4-4 背包问题 (Knapsack Problem),问题描述设有n个物体和一个背包,物体i的重量为wi ,价值为vi ,背包的容量为C.若将物体i的xi部分(1in, 0xi1)装入背包,则具有价值为vi xi. 目标是找到一个方案,使放入背包的物体总价值最高.,约 束 条 件,优化函数,算法设计与分析 贪心算法,背包问题实例,考虑下列情况的背包问题 n=3,M=20,(v1,v2,v3)=(25,24,15),(w1,w2,w3)=(18,15,10) 其中的4个可行解是:,算法设计与分析 贪

11、心算法,贪心方法的数据选择策略(1),1、用贪心策略求解背包问题时,首先要选出最优的度量标准。可以选取目标函数为量度标准,每装入一件物品就使背包获得最大可能的效益值增量。在这种量度标准下的贪心方法就是按效益值的非增次序将物品一件件放到背包中。 如上面的实例所示,可将物品按效益量非增次序排序: (v1,v2,v3)=(25,24,15)。先装入物品1重量为18,即x1=1;然后再装物品2,由于约束条为wi xi M=20,所以物品2只能装入重量为2的一小部分,即x2=2/15。 按上述的数据选择策略,装入顺序是按照物品的效益值从大到小的输入,由刚才的方法可得这种情况下的总效益值为vixi = 2

12、5+24*2/15=28.2,显然是一个次优解,原因是背包容量消耗过快。,算法设计与分析 贪心算法,贪心方法的数据选择策略(2),2、若以容量作为量度,可让背包容量尽可能慢地被消耗。这就要求按物品重量的非降次序来把物品放入背包,即(w3,w2,w1)=(10,15,18)。 先装入物品3, x3=1, p3x3 =15,再装入重量为10的物品2, vixi =15+24*10/15=31。 由刚才的方法可得这种情况下的总效益值为31,仍是一个次优解,原因是容量在漫漫消耗的过程中,效益值却没有迅速的增加。,算法设计与分析 贪心算法,贪心方法的数据选择策略(3),3、采用在效益值的增长速率和容量的

13、消耗速率之间取得平衡的量度标准。即每一次装入的物品应使它占用的每一单位容量获得当前最大的单位效益。这就需使物品的装入次序按vi/wi比值的非增次序来考虑。 这种策略下的量度是已装入物品的累计效益值与所用容量之比。 (v2/w2 , v3/w3 , v1/w1 )=(24/15,15/10, 25/18) 先装入重量为15的物品2,再装入重量为5的物品3, pixi =24+15*5/10=31.5。此结果为最优解。,算法设计与分析 贪心算法,算法思路1).将各物体按单位价值由高到低排序. 2).取价值最高者放入背包.3).计算背包剩余空间.4).在剩余物体中取价值最高者放入背包.若背包剩余容量

14、=0或物体全部装入背包为止,例 n=3,c=20 (v1,v2,v3)=(25,24,15),(w1,w2,w3)=(18,15,10),x1,x2,x3, 0,2/3,1,0,1,1/2,.,1,2/15,0,20,20,20,28.2,31,31.5,.,.,算法设计与分析 贪心算法,void Knapsack(int n,float M,float v ,float w ,float x ) Sort(n, v, w,t); /按单位价值排序/int i;for (i =1;i c)break;xti= 1;c-= wti; if(i= n) xti = c/wti; ,背包问题的贪心算

15、法,算法设计与分析 贪心算法,算法分析:,排序为主要算法时间,所以 T(n)=O(nlogn),背包问题中的物体不能分拆,只能整个装入称为0-1背包问题.,算法证明:该算法能得到在最优解,用贪心算法能得到0-1背包的最优解吗?,首先计算每种物品单位重量的价值Vi/Wi,然后,依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。若将这种物品全部装入背包后,背包内的物品总重量未超过C,则选择单位重量价值次高的物品并尽可能多地装入背包。依此策略一直地进行下去,直到背包装满为止。具体算法可描述如下页:,void Knapsack(int n,float M,float v,float w,fl

16、oat x) Sort(n,v,w);int i;for (i=1;ic) break;xi=1;c-=wi;if (i=n) xi=c/wi; ,算法knapsack的主要计算时间在于将各种物品依其单位重量的价值从大到小排序。因此,算法的计算时间上界为 O(nlogn)。 为了证明算法的正确性,还必须证明背包问题具有贪心选择性质。,对于0-1背包问题,贪心选择之所以不能得到最优解是因为在这种情况下,它无法保证最终能将背包装满,部分闲置的背包空间使每公斤背包空间的价值降低了。事实上,在考虑0-1背包问题时,应比较选择该物品和不选择该物品所导致的最终方案,然后再作出最好选择。由此就导出许多互相重

17、叠的子问题。这正是该问题可用动态规划算法求解的另一重要特征。 实际上也是如此,动态规划算法的确可以有效地解0-1背包问题。,思考题,0/1背包问题:在杂货店比赛中你获得了第一名,奖品是一车免费杂货。店中有n 种不同的货物。规则规定从每种货物中最多只能拿一件,车子的容量为c,物品i 需占用wi 的空间,价值为pi。你的目标是使车中装载的物品价值最大。当然,所装货物不能超过车的容量,且同一种物品不得拿走多件。如何选择量度标准才能找到最优解?,算法设计与分析 贪心算法,思考题,找零钱问题:一个小孩买了价值为33美分的糖,并将1美元的钱交给售货员。售货员希望用数目最少的硬币找给小孩。假设提供了数目不限

18、的面值为25美分、10美分、5美分、及1美分的硬币。使用贪心算法求解最优结果。并证明找零钱问题的贪心算法总能产生具有最少硬币数的零钱。,算法设计与分析 贪心算法,类似于背包问题!,问题:通讯过程中需将传输的信息转换为二进制码.由于英文字母使用频率不同,若频率高的字母对应短的编码,频率低的字母对应长的编码,传输的数据总量就会降低.要求找到一个编码方案,使传输的数据量最少. 见P109-表4-1,算法设计与分析 贪心算法,1、前缀码为能正确译码,编码需采用前缀码,对每一个字符规定一个0,1串作为其代码,并要求任一字符的代码都不是其它字符代码的前缀。这种编码称为前缀码。表示最优前缀码的二叉树总是一棵

19、完全二叉树,即树中任一结点都有2个儿子结点。 平均码长定义为:使平均码长达到最小的前缀码编码方案称为给定编码字符集C的最优前缀码。,4.4 哈夫曼编码,算法思路: 1)以n个字母为结点构成n棵仅含一个点的二叉树集合,字母的频率 即为结点的权 2)每次从二叉树集合中找出两个权最小者合并为一棵二叉树:增加一个根结点将这两棵树作为左右子树.新树的权为两棵子树的权之和. 3) 反复进行步骤2)直到只剩一棵树为止.,2、构造哈夫曼编码 哈夫曼提出构造最优前缀码的贪心算法,由此产生的编码方案称为哈夫曼编码。 哈夫曼算法以自底向上的方式构造表示最优前缀码的二叉树T。 算法以|C|个叶结点开始,执行|C|1次

20、的“合并”运算后产生最终所要求的树T。,算法设计与分析 贪心算法 哈夫曼编码,templateBinaryTreeHuffmanTree(T f, int n)/根据权f1:n构造霍夫曼树/创建一个单节点树的数组Huffman *W=newHuffman n+1;BinaryTree z,zero;for(int i=1;iQ(1);Q.Initialize(w,n,n);/将堆中的树不断合并Huffman x, yfor(i=1;in;i+),Q.DeleteMin(x);Q.DeleteMin(y);z.MakeTree(0, x.tree, y.tree);x.weight+=y.wei

21、ght;x.tree=z;Q.Insert(x); Q. DeleteMin(x);/最后的树Q. Deactivate();delete w;return x.tree;,哈夫曼树算法,算法设计与分析 贪心算法 哈夫曼编码,在书上给出的算法huffmanTree中,编码字符集中每一字符c的频率是f(c)。以f为键值的优先队列Q用在贪心选择时有效地确定算法当前要合并的2棵具有最小频率的树。一旦2棵具有最小频率的树合并后,产生一棵新的树,其频率为合并的2棵树的频率之和,并将新树插入优先队列Q。经过n1次的合并后,优先队列中只剩下一棵树,即所要求的树T。算法huffmanTree用最小堆实现优先队

22、列Q。初始化优先队列需要O(n)计算时间,由于最小堆的removeMin和put运算均需O(logn)时间,n1次的合并总共需要O(nlogn)计算时间。因此,关于n个字符的哈夫曼算法的计算时间为O(nlogn) 。,最优子结构: 设T为带权w1w2. wt的最优树,若将以带权w1和w2的树叶为儿子的分枝点改为带权w1+w2的树叶,得到一棵新树T, 则T也是最优树。,贪心选择性 : 设T为带权w1w2. wt的最优树, a).带权w1和w2的树叶vw1和vw2是兄弟. b).以vw1和vw2为儿子的分枝点,其通路长度最长.,算法证明,算法分析,HuffmanTree初始化优先队列Q需要O(n)

23、 DeleteMin和Insert需O(logn). n-1次的合并总共需要O(nlogn) 所以n个字符的哈夫曼算法的计算时间为O(nlogn),算法设计与分析 贪心算法 哈夫曼编码,4.5 单源最短路径 问题: 给定带权有向图G=(V,E), 其中每条边的权是一个非负实数.要计算从V的一点v0(源)到所有其他各顶点的最短路长度. 路长指路上各边权之和。,算法设计与分析 贪心算法,算法思路(Dijkstra) :设最短路长已知的终点集合为S,初始时v0S, 其最短路长为0,然后用贪心选择逐步扩充S :每次在V-S中,选择路径长度值最小的一条最短路径的终点x加入S.,例 题,构造路长最短的最短

24、路径:设已构造i条最短路径,则下一个加入S的终点u必是V-S中具有最小路径长度的终点, 其长度或者是弧(v0,u), 或者是中间只经过S中的顶点而最后到达顶点u的路径.,例 题,已知一个n 结点的有向图G=(V,E)和边的权函数c(e),求由G中某指定结点v0到其他各个结点的最短路径。,v0,v2,v1,v3,v4,v5,20,45,50,10,15,15,20,10,35,30,3,算法设计与分析 贪心算法,产生最短路径的贪心方法,逐条构造这些最短路径,使用迄今已生成的所有路径长度之和作为一种量度标准。 为了使这一量度达到最小,其单独的每一条路径都必须具有最小长度。 使用这标准时,假定已构造

25、了i条最短路径,则下面要构造的路径应该是下一条最短的最小长度路径。 生成从v0到所有其它结点的最短路径的贪心方法就是按照路径长度的非降次序生成这些路径。,算法设计与分析 贪心算法,产生最短路径的贪心方法,设S表示对其已经生成了最短路径的那些结点(包括v0)的集合。 扩张S的过程:对于不在S中的结点w,设DIST(w)是从v0开始只经过S中的结点而在结点w结束的那条最短路径的长度,则有: 如果下一条最短路径是到结点u,则这条路径是从v0处开始而在u处终止,并且只通过那些在S中的结点。 所生成的下一条路径的终点u必定是所有不在S内的结点中具有最小距离DIST(u)的结点。,算法设计与分析 贪心算法

26、,产生最短路径的贪心方法,选出了结点u并生成了从v0到u的最短路径之后,结点u就成为S中的一个成员。 此时,那些从v0开始,只通过S中的结点并且在S外的结点w处结束的最短路径可能会减小。 如果长度改变了,则它必定是由一条从v0开始,经过u然后到w的更短路径所造成的。 其中从v0到u的路径是一条最短路径,从u到w的路径是边,于是这条路径的长度就是:DIST(u)+c(u,w),算法设计与分析 贪心算法,算法设计与分析 贪心算法,算法描述:(1) 用带权的邻接矩阵c来表示带权有向图, cij表示弧上的权值. 若 V,则置cij为设S为已知最短路径的终点的集合,它的初始状态为空集.从源点v到图上其余

27、各点vi的当前最短路径长度的初值为:disti=cvi ,viV(2) 选择vj, 使得distj=Mindisti | viV-Svj就是长度最短的最短路径的终点。令S=SUj/更新S(3) 修改从v到集合V-S上任一顶点vk的当前最短路径长度:如果 distj+cjk distk 则修改 distK= distj+cjk /更新dist和prev(4) 重复操作(2),(3)共n-1次.,算法设计与分析 贪心算法 单源最短路径,例 题,1) v1 v2: 10,2) v1 v3: 50,3) v1 v4: 30,4) v1 v5: 60,算法设计与分析 贪心算法,voidDijkstra(

28、int n, int v,Type dist, int prev, Type *c) bool smaxint;for (int i=1;i=n; i+)disti=cvi;si=false;if(disti= =maxint) previ=0;else previ=v ; distv=0;sv=true; for (int i=1;in;i+) int temp=maxint;int u= v; for (int j = 1;j=n;j+),if (!sj) ,单源最短路径问题的Dijkstra算法,分析:用带权邻接矩阵表示有n个顶点和e条边的带权有向图,主循环体需要O(n)时间,循环需要执

29、行n-1次,所以完成循环需要O(n2).,算法设计与分析 贪心算法 单源最短路径,例 题,1) v1 v2: 10,2) v1 v3: 50,3) v1 v4: 30,4) v1 v5: 60,算法实例,求下图中v1到其余各结点的最短路径,v1,v4,v2,v3,v6,v7,v5,20,30,50,40,55,25,70,50,25,10,70,50,0 20 50 30 0 25 70 0 40 25 50 0 55 0 10 70 0 50 0,算法设计与分析 贪心算法,算法实例,SHORTEST-PATHS执行踪迹,算法设计与分析 贪心算法,算法设计与分析 贪心算法 最小生成树,问题陈述

30、:设G(V,E)是一个无向连通带权图。E中每条边(v, w)的权为cvw,若G的一个子图G是一棵包含G的所有顶点的树,则称G为G的生成树。生成树各边权的总和称为该生成树的耗费。在G的所有生成树中,耗费最小的生成树称为G的最小生成树.,抽象描述: 输入:任一连通生成子图 (该子图的边集合)可行解:图的生成树, 优化函数:生成树的各边权值之和最优解:使优化函数达到最小的生成树.,4. 6 最小生成树,算法设计与分析 贪心算法 最小生成树,应用领域与图模型,算法思路: 首先置S=1, T= .若SV, 就作如下的贪心选择:选取满足条件iS, jV-S,且cij最小的边(i, j),将顶点j添加到S中

31、边(i, j)添加到T中.这个过程一直进行到S=V时为止. T中的所有边构成G的一棵最小生成树。,void Prim(int n, Type * * c) T= ;S =1;while (S!= V) (i, j) = i S且 jV- S的最小权边;T=TU(i,j);S= S Uj; ,算法描述,Prim算法,设G=(V,E)是一个连通带权图, y=l, 2, , n。,例 题,算法设计与分析 贪心算法 最小生成树,问题:如何选取满足条件iS, jV-S,且cij最小的边(i, j), 成了算法难点问题。 解决方法:设置两个数组closest和lowcost。对于每个j V-S,close

32、stj是j在S中的邻接顶点,它与j在S中的其他邻接顶点k相比较有cjclosetj cjk。lowcostj的值就是cjclosestj,图 Prim算法的执行过程,注:灰色部分表示集合S每个结点的上的数字表示S中的结点到该结点的最小消耗,即lowcost用图示的边的连接表示closest,图 Prim算法的执行过程,图 Prim算法的执行过程,图 Prim算法的执行过程,图 4-16Prim算法的执行过程,图 4-16Prim算法的执行过程,template void Prim(int n, Type * * c) Type lowcostmaxint;int closest maxim;b

33、ool smaxint;s1 = true;for(int i = 2;i= n; i+)lowcosti = cli;closest i = 1;si= false; for (int i = 1; i n; i+),Type min = inf;int j = 1;for (int k = 2;k= n; k+)if (lowcostk min) ,Prim算法,算法分析: O(n2).,算法设计与分析 贪心算法 最小生成树,算法思路:首先将G的n个顶点看成n个孤立的连通分支, 将所有的边按权从小到大排序,然后从第一条边开始, 依边权递增的顺序查看每一条边,并按下述方法连接两个通分支:当查

34、看到第k条边(v,w)时, 如果端点u和w分别是当前两个不同的连通分支T1, T2中的顶点时,就用边(u,w)将TI和T2连接成一个连通分支,然后继续查看第k+1条边;如果端点v和w在当前的同一个连通分支中,就直接再查看第k十1条边。直到只剩下一个连通分支为止。此时,这个连通分枝就是G的一颗最小生成树,Kruskal算法,G=(V, E), V=1, 2, , n。,例 题,算法设计与分析 贪心算法 最小生成树,e1(1),e2(6),e8(9),e6 (2),e9(4),e5(5),e4(7),e10(8),e11(3),e7(10),e3(11),1) 以G 中全部点为点作图,2) 按权的

35、大小次序依次添加 各边,若出 现回路则忽略此边.,3) 加入n-1条边后就得到最小生成树.,1,2,5,3,7,求最小生成树(Kruscal),最优解: (e1, e6, e11, e5, e4),例 题,算法设计与分析 贪心算法 最小生成树,优先队列,定义:优先队列中元素出队列的顺序由元素的优先级决定。从优先队列中删除元素是根据优先权高或低的次序,而不是元素进入队列的次序。 可以利用堆数据结构来高效地实现优先队列。 实现:优先队列(priority queue)是0个或多个元素的集合,每个元素都有一个优先权或值,对优先队列执行的操作有1) 查找;2) 插入一个新元素;3) 删除。在最小优先队

36、列( min priority q u e u e)中,查找操作用来搜索优先权最小的元素,删除操作用来删除该元素;对于最大优先队列(max priority queue),查找操作用来搜索优先权最大的元素,删除操作用来删除该元素。 处理:优先权队列中的元素可以有相同的优先权,查找与删除操作可根据任意优先权进行。,I n i t i a l i z e函数:使用数组a中的元素对最大堆进行初始化。 DeleteMin (x):从队列中删除具有最小优先权的元素,并将该元素返回至x I n s e rt (x):将x 插入队列,并查集,在一些应用问题中,我们需要划分n个不同的元素成若干组,每一组的元素

37、构成一个集合。这种问题的一个解决办法是,在开始时,让每个元素自成一个单元素集合,然后按一定顺序将属于同一组的元素所在的集合合并。其间要反复用到查找一个元素在哪一个集合的运算。适合于描述这类问题的抽象数据类型称为并查集(给出各个元素之间的联系,要求将这些元素分成几个集合,每个集合中的元素直接或间接有联系。在这类问题中主要涉及的是对集合的合并和查找,因此将这种集合称为并查集。),并查集的数学模型,并查集的数学模型是若干不相交的动态集合的集合SA,B,C,.,它支持以下的运算:(1)INITIAL(A,x):构造一个取名为A的集合,它只包含一个元素x;(2)MERGE(A,B):将集合A和B合并,其

38、结果取名为A或B;(3)FIND(x):找出元素x的所在集合,并返回该集合的名字。,template bool Kruskal(int n, int e, EdgeNode E , EdgeNode t )MinHeap H(1);H. Initialize(E, e, e);UnionFind U(n);iht k = 0;while (e ,e-; int a = U.Find(x.u);int b = U.Eind(x.v);if (a! = b) tk + = x;U. Union(a, b);H. Deactivate( ) renturn (k = = n-1),Kruska算法,

39、算法设计与分析 贪心算法 最小生成树,A=(选出的边),E =(h,g,1),(g,f,2),(c,i,2),(a,b,4),(c,f,4),(g,I,6),(c,d,7),(a,h,8),(b,c,8), (d,e,9), (e,f,10),(b,h,11),(d,f,14)(原图中的边),初始状态 森林由9棵树组成,A=(h,g),E =(g,f,2),(c,i,2),(a,b,4),(c,f,4),(g,I,6),(c,d,7),(a,h,8),(b,c,8), (d,e,9), (e,f,10),(b,h,11),(d,f,14),接受边(h,g) UNION(g,h) 森林由8棵树组

40、成,(a),(b),图 Kruskal算法的执行过程,E =(c,i,2),(a,b,4),(c,f,4),(g,I,6),(c,d,7),(a,h,8),(b,c,8), (d,e,9), (e,f,10), (b,h,11),(d,f,14),(c),E =(c,i,2),(a,b,4),(c,f,4),(g,I,6),(c,d,7),(a,h,8),(b,c,8), (d,e,9), (e,f,10), (b,h,11),(d,f,14),(d),接受边(c,i) UNION(c,i) 森林由6棵树组成,接受边(g,f) UNION(g,f) 森林由7棵树组成,图 Kruskal算法的执

41、行过程,E =(c,f,4),(g,I,6),(c,d,7),(a,h,8),(b,c,8), (d,e,9), (e,f,10), (b,h,11),(d,f,14),接受边(a,b) UNION(a,b) 森林由5棵树组成,图 Kruskal算法的执行过程,E =(g,I,6),(c,d,7),(a,h,8),(b,c,8), (d,e,9), (e,f,10), (b,h,11),(d,f,14),E =(a,h,8),(b,c,8), (d,e,9), (e,f,10), (b,h,11),(d,f,14),接受边(c,f) UNION(c,f) 森林由4棵树组成,选取边(g,I,6)

42、但因为g和i在一个连通子图中,即U.Find(g)和U.Find(i)相同,所以拒绝边(g,i)接受边(c,d)UNION(c,d)森林由3棵树组成,图 Kruskal算法的执行过程(续),拒绝边(h,i)接受边(a,h)UNION(a,h)森林由2棵树组成,拒绝边(b,c)接受边(d,e)UNION(d,e)森林由1棵树组成,图 Kruskal算法的执行过程(续),正确性证明,1、需要证明以下两点: 1) 只要存在生成树,K r u s k a l算法总能产生一棵生成树; 2) 产生的生成树具有最小耗费。 2、证明1:令G为任意加权无向图(即G是一个无向网络)。从1 2 . 11 . 3节可

43、知当且仅当一个无向图连通时它有生成树。而且在Kruskal 算法中被拒绝(丢弃)的边是那些会产生环路的边。删除连通图环路中的一条边所形成的图仍是连通图,因此如果G在开始时是连通的,则T与E中的边总能形成一个连通图。也就是若G开始时是连通的,算法不会终止于E= 和| T | n- 1。,3、证明2:现在来证明所建立的生成树T具有最小耗费。由于G具有有限棵生成树,所以它至少具有一棵最小生成树。令U为这样的一棵最小生成树, T与U都刚好有n- 1条边。如果T=U, 则T就具有最小耗费,那么不必再证明下去。因此假设TU,令k(k 0) 为在T中而不在U中的边的个数,当然k 也是在U中而不在T中的边的数

44、目。通过把U变换为T来证明U与T具有相同的耗费,这种转化可在k 步内完成。每一步使在T而不在U中的边的数目刚好减1。而且U的耗费不会因为转化而改变。经过k 步的转化得到的U将与原来的U具有相同的耗费,且转化后U中的边就是T中的边。由此可知, T具有最小耗费。,算法分析:当图的边数为e时,将其组成优先队列需要时间O(e)。while循环中,DeleteMin需要O(loge)时间因此关于优先队列所作运算需时间O(eloge)。 实现UnionFind所需的时间为O(eloge)。 所以Kruska的时间是O(eloge),适合求边数较少的最小生成树。 反之,用Prim算法,最小代价通讯网络 在N

45、城市之间架设通讯线路,要求造价最低. 城市之间所有可能的通讯连接视作一个无向图G,G中每边的权值表示建成这段线路的代价. 问题转化为求一棵最小生成树.,问题描述: 输入:任一连通图G (该图的边集合)可行解:图G的生成树优化函数:生成树的各边权值之和最优解:使优化函数达到最小值的生成树.,最优化问题(optimization problem): 问题可描述为有n个输入(x1,x2,.xn),一组约束条件和一个优化(目标)函数。满足约束条件的输入称为可行解,它是输入的一个子集.使优化函数取得极值的可行解称为最优解.,算法设计与分析 贪心算法,例1,*旅行商问题(货郎担问题) 问题: 设一个由N个

46、城市v1,v2,vn组成的网络, ci,j 为从vi 到vj的代价不妨设ci,j = cj,i ,且ci,i= .一推销员要从某城市出发经过每城市一次且仅一次后返回出发地问如何选择路线使代价最小。,5,1,4,3,1,7,3,4,2,2,算法设计与分析 贪心算法,抽象描述:将城市以及之间的道路抽象为一个无向图G, G中每边的权值表示这段线路的代价. 问题转化为求一条最佳周游路线:从一点出发,经过每点一次且仅一次并返回原点,且该路线的总代价最小.,v1,v5,v2,v4,v3,C=,输入:城市的数目n,代价矩阵c=c(1n,1n). 输出: 最小代价路线 1. tour:=0; / tour 纪录路线/ 2. cost:=0; / cost 纪录到目前为止的花费/ 3. v:=N; / N为起点城市, v为当前出发城市/ 4. for k:=1 to N-1 do 5. tour:= tour+(v,w) /(v,w)为从v到其余城市代价中值最小的边/ 6. cost:= cost+c(v,w) 7 v:=w 8 tour:= tour+(v,N) 9 cost:= cost+c(v,N) print tour, cost ,算法的最坏时间复杂性为O(n2),*该算法不能求的最优解.,算法设计与分析 贪心算法,该问题为NP难问题.,算法设计与分析 贪心算法,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报