收藏 分享(赏)

算法设计教程03.ppt

上传人:dzzj200808 文档编号:3655229 上传时间:2018-11-15 格式:PPT 页数:73 大小:814.50KB
下载 相关 举报
算法设计教程03.ppt_第1页
第1页 / 共73页
算法设计教程03.ppt_第2页
第2页 / 共73页
算法设计教程03.ppt_第3页
第3页 / 共73页
算法设计教程03.ppt_第4页
第4页 / 共73页
算法设计教程03.ppt_第5页
第5页 / 共73页
点击查看更多>>
资源描述

1、1,第三章 贪心算法,本章主要知识点(46学时): 3.1 活动安排问题 3.2 贪心算法的基本要素 3.3 最优装载 3.4 哈夫曼编码 3.5 单源最短路径 3.6 最小生成树 3.7 多机调度问题,2,引言,【找零钱问题】希望用数目最少的硬币找零 假设提供了数目不限的面值为2 5美分、1 0美分、5美分、及1美分的硬币。 假设需要找67美分,25+25+10+5+1+1,共6枚。 假设提供了数目不限的面值为1 1美分、5美分及1美分的硬币?找零15美分11+1+1+1+1,共5枚(贪心算法)5+5+5,共3枚(非贪心算法),在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优

2、解的很好近似。,3,引言,贪心算法:总是做出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择。,贪心法的基本思路: 从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止。,4,引言,贪心法存在的问题: 1. 不能保证求得的最后解是最佳的; 2. 不能用来求最大或最小解问题; 3. 只能求满足某些约束条件的可行解的范围。,5,3.1 活动安排问题,【活动安排问题】就是要在所给的活动集合中选出最大的相容活动子集合。该问题要求高效地安排一系列争用某一公共资源的活动。贪心算法提供了

3、一个简单、漂亮的方法使得尽可能多的活动能兼容地使用公共资源。,设有n个活动的集合E=1,2,n,其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si fi 。如果选择了活动i,则它在半开时间区间si, fi)内占用资源。若区间si, fi)与区间sj, fj)不相交,则称活动i与活动j是相容的。也就是说,当sjfi时,活动i与活动j相容。,6,复杂性分析,由于输入的活动以其完成时间的升序排列,所以算法greedySelector每次总是选择最早完成时间的相容活动加入集合A中。 为未安排活

4、动留下尽可能多的时间。 该算法的贪心选择的意义是使剩余的可安排时间段极大化,以便安排尽可能多的活动。,7,一个实例,例:设待安排的11个活动的开始时间和结束时间按结束时间的非减序排列如下:,8,说明,若被检查的活动i的开始时间Si小于最近选择的活动j的结束时间fi,则不选择活动i,否则选择活动i加入集合A中。 贪心算法并不总能求得问题的整体最优解。 对于活动安排问题,贪心算法greedySelector却总能求得的整体最优解,即它最终所确定的相容活动集合A的规模最大。这个结论可以用数学归纳法证明。,9,贪心算法描述,public static int greedySelector(int s,

5、 int f, boolean a) int n=s.length-1; a1=true; /选择最早结束活动 int j=1;/j表示已安排活动编号 int count=1;/已安排活动数 for (int i=2;i=fj) ai=true; j=i; count+; else ai=false; return count; ,各活动的起始时间和结束时间存储于数组s和f中且按结束时间的非减序排列,10,复杂性分析,算法greedySelector的效率极高。当输入的活动已按结束时间的升序排列,算法只需O(n)的时间安排n个活动,使最多的活动能相容地使用公共资源。 如果所给出的活动未按非减序

6、排列,可以用O(nlogn)的时间重排。,11,3.2 贪心算法的基本要素,对于一个具体的问题,怎么知道是否可用贪心算法解此问题,以及能否得到问题的最优解呢?这个问题很难给予肯定的回答。 但是,从许多可以用贪心算法求解的问题中看到这类问题一般具有2个重要的性质: 贪心选择性质 最优子结构性质。,12,1.贪心选择性质,所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。 动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,每作一次贪心选择就将所求问题简化为规

7、模更小的子问题。,13,2.最优子结构性质,当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用动态规划算法或贪心算法求解的关键特征。,14,0-1背包问题与背包问题,0-1背包问题: 给定n种物品和一个背包。物品i的重量是Wi,其价值为Vi,背包的容量为C。应如何选择装入背包的物品,使得装入背包中物品的总价值最大? 在选择装入背包的物品时,对每种物品i只有2种选择,即装入背包或不装入背包。不能将物品i装入背包多次,也不能只装入部分的物品i。 背包问题: 与0-1背包问题类似,所不同的是在选择物品i装入背包时,可以选择物品i的一部分,而不一定要

8、全部装入背包,1in。 这2类问题都具有最优子结构性质,但背包问题可以用贪心算法求解,而0-1背包问题却不能用贪心算法求解。,15,贪心方法的数据选择策略,1、以价值为量度标准 按价值从高到低的次序将物品一件件放到背包中。 2、以容量作为量度 按物品重量的从清到重次序来把物品放入背包。 3、采用单位价值为度量标准 使物品的装入次序按pi/wi比值的从大到小来考虑。,用贪心策略求解背包问题时,首先要选出最优的度量标准。,16,算法思路 1).将各物体按单位价值由高到低排序. 2).取价值最高者放入背包. 3).计算背包剩余空间. 4).重复2-3直到背包剩余容量=0或物体全部装入背包为止。,用贪

9、心算法解背包问题的基本步骤,17,考虑下列情况的背包问题 n=3,M=20,(p1,p2,p3)=(25,24,15), (w1,w2,w3)=(18,15,10) 其中的4个可行解是:,背包问题,18,void Knapsack(int n,float M,float v,float w,float x) Sort(n,v,w); /计算每种物品单位重量的价值Vi/Wi int i; for (i=1;ic) break; xi=1; c-=wi; if (i=n) xi=c/wi; /允许放入一个物品的一部分 ,void 0-1-Knapsack(int n,float M,float v

10、,float w,float x) /不一定是最优解 Sort(n,v,w); int i; for (i=1;ic) break; xi=1; c-=wi; ,0-1背包问题贪心选择之所以不能得到最优解:因为无法保证最终能将背包装满,部分闲置的背包空间使总价值降低了。,20,0-1背包问题与背包问题,21,思考题-0/1背包问题,在杂货店比赛中你获得了第一名,奖品是一车免费杂货。店中有N种不同的货物。规则规定从每种货物中最多只能拿一件,车子的容量为C,物品i需占用wi的空间,价值为pi。你的目标是使车中装载的物品价值最大。当然,所装货物不能超过车的容量,且同一种物品不得拿走多件。如何选择量度

11、标准才能找到最优解? 若N=2, w=100,10,10,p=20,15,15,C=105。利用价值贪心准则时所得结果是否是最优?,22,问题: 设一个由N个城市v1,v2,vn组成的网络, ci,j 为从vi 到vj的代价不妨设ci,j = cj,i ,且ci,i= .一推销员要从某城市出发经过每城市一次且仅一次后返回出发地问如何选择路线使代价最小。,抽象描述:将城市以及之间的道路抽象为一个无向图G, G中每边的权值表示这段线路的代价. 问题转化为求一条最佳周游路线:从一点出发,经过每点一次且仅一次并返回原点,且该路线的总代价最小.,C=,思考题-旅行商问题(Traveling Salesm

12、an Problem),费用矩阵,23,思考题-旅行商问题(货郎担问题),首先在图中选一条代价最小的边。为了选择下一条边,先要检查一下候选边与已选入的边之间是否满足以下两点:1)不会有三条边(候选边及已入选边)与同一顶点相关联。2)不会使入选边形成回路,除非入选边的个数已等于图中的顶点总数。 在满足以上两点的候选边中,挑选最短的边作为入选边。如此做下去,直到得到一个经过所有顶点的回路。,最后求得的回路是125341,代价是14。实际图11最小代价的回路是12543一1,代价是10。,24,输入:城市的数目n,代价矩阵c=c(1n,1n). 输出: 最小代价路线 1. tour:=0; / to

13、ur 纪录路线/ 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),*该算法不能求的最优解.,思考题-旅行商问题(货郎担问题),25,3.3 最优装载,有一批集装箱要装上一艘载重量为C的轮

14、船。其中集装箱i的重量为Wi。最优装载问题要求确定在装载体积不受限制的情况下,将尽可能多的集装箱装上轮船。 问题可形式化描述为 其中变量xi=0表示不装入集装箱i,xi=1表示装入集装箱i。,26,3.3 最优装载,例 设N=8,w1,w8=100, 200, 50, 90, 150, 50, 20, 80,C=400。 所考察货箱的次序为 t18=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,算法思路 将装船过程

15、划为多步选择,每步装一个货箱,每次从剩下的货箱中选择重量最轻的货箱.如此下去直到所有货箱均装上船或船上不能再容纳其他任何一个货箱。,27,3.3 最优装载算法描述,最优装载问题可用贪心算法求解。采用重量最轻者先装的贪心选择策略,可产生最优装载问题的最优解。 void Loading(int x, Type w, Type c, int n) int *t = new int n+1; Sort(w, t, n); /按货箱重量排序O(nlogn) for (int i = 1; i = n; i+) xi = 0; /O(n) for (int i = 1; i = n /调整剩余空间 ,28

16、,思考,设N=8,w1,w8=100, 200, 50, 90, 150, 50, 20, 80,C=400。 编程求t18.,29,3.4 哈夫曼编码,哈夫曼编码是广泛地用于数据文件压缩的十分有效的编码方法。 哈夫曼编码压缩率通常在20%90%之间。哈夫曼编码算法用字符在文件中出现的频率表来建立一个用0,1串表示各字符的最优表示方式。 给出现频率高的字符较短的编码,出现频率较低的字符以较长的编码,可以大大缩短总码长。,30,3.4 哈夫曼编码,例如一个包含100,000个字符的文件,各字符出现频率不同,如下表所示。定长编码需要300,000位,而按表中变长编码方案,文件的总码长为: (451

17、+133+123+163+94+54)1000=224,000。 比用定长码方案总码长较少约45%。,31,1.前缀码,对每一个字符规定一个0,1串作为其代码,并要求任一字符的代码都不是其它字符代码的前缀。这种编码称为前缀码。 编码的前缀性质可以使译码方法非常简单。 表示最优前缀码的二叉树总是一棵完全二叉树,即树中任一结点都有2个儿子结点。 平均码长定义为:,使平均码长达到最小的前缀码编码方案称为给定编码字符集C的最优前缀码。,32,2.构造哈夫曼编码,哈夫曼提出构造最优前缀码的贪心算法,由此产生的编码方案称为哈夫曼编码。 哈夫曼算法以自底向上的方式构造表示最优前缀码的二叉树T。 算法以|C|

18、个叶结点开始,执行|C|1次的“合并”运算后产生最终所要求的树T。,33,2.构造哈夫曼树,构造最优二叉树的算法是由哈夫曼提出的,所以称之为哈夫曼算法,具体叙述如下: 根据与n个权值w1,w2,.,wn对应的n个结点构成n棵二叉树的森林F=T1,T2,.,Tn,其中每棵二叉树Ti(1=i=n)都由一个权值为wi的根结点,其左右子树均为空; 在森林F中选出两棵根结点的权值最小的树作为一棵新树的左右子树,且置新树的附加根结点的权值为其左右子树上根结点的权值之和; 从F中删除这两棵树,同时把新树加入F中; 重复(2)和(3),直到F中只含有一棵树为止。此树便是哈夫曼树。,34,35,算法说明,在书上

19、给出的算法huffmanTree中,编码字符集中每一字符c的频率是f(c)。以f为键值的优先队列Q用在贪心选择时有效地确定算法当前要合并的2棵具有最小频率的树。一旦2棵具有最小频率的树合并后,产生一棵新的树,其频率为合并的2棵树的频率之和,并将新树插入优先队列Q。经过n1次的合并后,优先队列中只剩下一棵树,即所要求的树T。 算法huffmanTree用最小堆实现优先队列Q。初始化优先队列需要O(n)计算时间,由于最小堆的removeMin和put运算均需O(logn)时间,n1次的合并总共需要O(nlogn)计算时间。因此,关于n个字符的哈夫曼算法的计算时间为O(nlogn) 。,36,3.5

20、 单源最短路径,(Single-Source Shortest-Paths Problem) 给定带权有向图G =(V,E),其中每条边的权是非负实数。另外,还给定V中的一个顶点,称为源。 单源最短路径问题: 已知图G(V,E),找出从某给定的源结点SV到V中的每个结点的最短路径。,37,3.5.1 Dijkstra算法,Dijkstra算法是解单源最短路径问题的贪心算法。 基本思想:设置顶点集合S并不断地作贪心选择来扩充这个集合。一个顶点属于集合S当且仅当从源到该顶点的最短路径长度已知。 (1)初始时,S中仅含有源节点。 (2)设u是G的某一个顶点,把从源到u且中间只经过S中顶点的路称为从源

21、到u的特殊路径,用数组Di记录顶点i当前所对应的最短特殊路径长度。 (3)Dijkstra算法每次从V-S中取出具有最短特殊路长度的顶点u,将u添加到S中,同时对数组D作必要的修改。 (4)一旦S包含了所有V中顶点,dist就记录了从源到所有其它顶点之间的最短路径长度。,38,1、 Dijkstra算法的基本思想,设S为最短距离已确定的顶点集(红点集) V-S是最短距离尚未确定的顶点集(蓝点集)。 初始化 最初只有源点s的最短距离是已知的(D(s)=0),故红点集S=s 。 重复以下工作,按路径长度递增次序产生各顶点最短路径 在当前蓝点集中选择一个最短距离最小的蓝点来扩充红点集,以保证算法按路

22、径长度递增的次序产生各顶点的最短路径。 当蓝点集中仅剩下最短距离为的蓝点,或者所有蓝点已扩充到红点集时,s到所有顶点的最短路径就求出来了。,39,一个实例,Dijkstra(G,D,s) /Dijkstra 算法 O(V2) /初始化操作 S=s;Ds=0; /设置初始的红点集及最短距离 for( all i V-S ) Di=Gsi; /O(V) /扩充红点集for (i=1;iDk+Gkj) Dj=Dk+Gkj; ,#define VEX 5/定义结点的个数 #define maxpoint 100 double graphmaxpoint= 0 , 10 , -1 , 30 , 100

23、, -1 , 0 , 50 , -1 , -1 , -1 , -1 , 0 , -1 , 10 , -1 , -1 , 20 , 0 , 60 , -1 , -1 , -1 , -1 , 0 ; /邻接矩阵,-1代表节点间无边相连 int Rmaxpoint=0,Bmaxpoint; int DVEX,PVEX;/定义数组D用来存放结点特殊距离,P数组存放父亲结点,/初始时,红点集中仅有源结点0 R0=1; B0=0; for(int i=1;iVEX;i+) /初始化蓝点集节点 Bi=1;/对数组D、P进行初始化 for(i=0;iVEX;i+) Di=graph0i;if(Di!=-1)

24、Pi=0;else Pi=-1; ,for(int k=1;kDmin+graphminj|Dj=-1)Dj=Dmin+graphminj; /每次迭代求最小值,最后一次即为到源点的最短路径Pj=min; ,44,3.5.2 Dijkstra算法Relax描述,du:su的距离 pu:记录前一节点 Relax松弛算法 Init-single-source(G,s)for each vVGdodv= pv=NILds=0, ps=NIL,Relax(u,v,w)if dvdu+w(u,v) then dv=du+wu,vpv=u,45,算法描述,dijkstra(G,w,s) 1. Init-s

25、ingle-source(G,s) /O(v) 2. S=s 3. Q=VG-s 4.while Q do u=min(Q) /用数组O(V)S=Sufor each vadju & v Q /O(E)do Relax(u,v,w),46,算法基本思想,47,3.5.3 Bellman-Ford算法思想,dijkstra算法的前提是所有边是正的 Bellman-Ford算法允许负边 初始化:将除源点外的所有顶点的最短距离估计值 dv +, ds 0;迭代求解:反复对边集E中的每条边进行松弛操作,使得顶点集V中的每个顶点v的最短距离估计值逐步逼近其最短距离;(运行|v|-1次)检验负权回路:如果

26、存在负边,则算法返回false,表明问题无解;否则算法返回true,并且从源点可达的顶点v的最短距离保存在 dv中。,48,3.5.3 Bellman-Ford算法思想,dijkstra算法的前提是所有边是正的 Bellman-Ford算法允许负边Init-single-source(G,s) for i 1 to |VG| - 1 /O(V) 3. do for each edge (u, v) EG/O(E) 4. do RELAX(u, v, w) 5. for each edge (u, v) EG /O(E) 6. do if du + w(u, v) dv 7. then retu

27、rn FALSE /存在负环 8. return TRUE,存在负权回路的图是不能求两点间最短路径,因为只要在负权回路上不断兜圈子,所得的最短路长度可以任意小。,49,3.5.4 其他最短路径问题,单目标最短路径问题(Single-Destination Shortest-Paths Problem):找出图中每一顶点v到某指定顶点u的最短路径。只需将图中每条边反向,就可将这一问题变为单源最短路径问题,单目标u变为单源点u。 单顶点对间最短路径问题(Single-Pair Shortest-Paths Problem):对于某对顶点u和v,找出从u到v的一条最短路径。显然,若解决了以u为源点的

28、单源最短路径问题,则上述问题亦迎刃而解。而且从数量级来说,两问题的时间复杂度相同。 所有顶点对间最短路径问题(All-Pairs Shortest-Paths Problem):对图中每对顶点u和v,找出u到v的最短路径问题。这一问题可用每个顶点作为源点调用一次单源最短路径问题算法予以解决。,50,3.6 最小生成树,设G =(V,E)是无向连通带权图,即一个网络。E中每条边(v,w)的权为cvw。如果G的子图G是一棵包含G的所有顶点的树,则称G为G的生成树。 生成树上各边权的总和称为该生成树的耗费。 在G的所有生成树中,耗费最小的生成树称为G的最小生成树。 网络的最小生成树在实际中有广泛应用

29、。例如,在设计通信网络时,用图的顶点表示城市,用边(v,w)的权cvw表示建立城市v和城市w之间的通信线路所需的费用,则最小生成树就给出了建立通信网络的最经济的方案。,51,1、最小生成树性质,用贪心算法设计策略可以设计出构造最小生成树的有效算法。 Prim算法和Kruskal算法 2个算法都利用了最小生成树性质: 最小生成树性质:设G=(V,E)是一个连通网络,U是顶点集V的一个真子集。若(u,v)是G中所有的一个端点在U(uU)里、另一个端点不在U(即vV-U)里的边中,具有最小权值的一条边,则一定存在G的一棵最小生成树包括此边(u,v)。这个性质称为MST(Minimum Spannin

30、g Tree )性质。,52,1、最小生成树性质,MST性质的证明: 约定: 集合U中的顶点红色顶点 V-U中的顶点蓝色顶点 连接红点和蓝点的边紫色边 权最小的紫边称为轻边(即权重最“轻”的边)。 用反证法证明MST性质,53,1、最小生成树性质,假设G中任何一棵MST都不含轻边(u,v)。则若T是G的一棵MST,则它不含此轻边。 由于T是包含了G中所有顶点的连通图,所以T中必有一条从红点u到蓝点v的路径P,且P上必有一条紫边(u ,v )连接红点集和蓝点集,否则u和v不连通。当把轻边(u,v)加入树T时,该轻边和P必构成了一个回路。删去紫边(u ,v )后回路亦消除,由此可得另一生成树T 。

31、T 和T的差别仅在于T用轻边(u,v)取代了T中权重可能更大的紫边(u ,v )。因为w(u,v)w(u ,v ),所以 w(T)=w(T)+w(u,v)-w(u,v)w(T) 故T亦是G的MST,它包含边(u,v),这与假设矛盾。 所以,MST性质成立。,54,2、Prim(普里姆)算法,设G=(V,E)是连通带权图,V=1,2,n。 构造G的最小生成树的Prim算法的基本思想是:首先置U=1,然后,只要U是V的真子集,就作如下的贪心选择:选取满足条件iU,jV-U,且cij最小的边,将顶点j添加到U中。这个过程一直进行到U=V时为止。 在这个过程中选取到的所有边恰好构成G的一棵最小生成树。

32、 例如,对于右图中的带权图,按Prim算法选取边的过程如图所示。,55,2、Prim(普里姆)算法,PrimMST(G,T,r) /求图G的以r为根的MST,结果放在T中 T=;U=1;while(U!=V) /O(V) (i,j)=iU,jV-U,且cij最小的边/O(V) T=T (i,j) /轻边 (i,j) 加入TU=U j; / 节点j 加入U,变为红点 ,http:/ 若一个蓝点与多个红点有边相接,选权最小的边做紫边。 连通网的最小生成树不一定是惟一的,但它们的权相等。 用这个办法实现的Prim算法所需的计算时间为O(V2),与图中边数无关,该算法适合于稠密图。,57,2、Prim

33、(普里姆)算法,如何有效地找出满足条件iU, jV-U,且权cij最小的边(i,j)?较简单的办法是设置2个数组closest和lowcost。 在Prim算法执行过程中,先找出V-U中使lowcost值最小的顶点j,然后根据数组closest选取边(j,closestj),将j添加到U中,并对closest和lowcost作必要的修改。,58,3、Kruskal(克鲁斯卡尔)算法,Kruskal算法构造最小生成树的基本思想: (1)将G的n个顶点看成n个孤立的连通分支。 (2)将所有的边按权从小到大排序。 (3)从第一条边开始,依边权递增的顺序查看每一条边,并按下述方法连接2个不同的连通分支

34、:当查看到第k条边(v,w)时,如果端点v和w分别是当前2个不同的连通分支T1和T2中的顶点时,就用边(v,w)将T1和T2连接成一个连通分支,然后继续查看第k+1条边;如果端点v和w在当前的同一个连通分支中,就直接再查看第k+1条边。这个过程一直进行到只剩下一个连通分支时为止。 例如,对前面的连通带权图,按Kruskal算法顺序得到的最小生成树上的边如图所示。,59,3、Kruskal(克鲁斯卡尔)算法,(1)算法思想 T的初始状态 只有n个顶点而无边的森林T=(V, ) 按边长递增的顺序选择E中的n-1安全边(u,v)并加入T,生成MST,注意: 安全边指两个端点分别是森林T里两棵树中的顶

35、点的边。加入安全边,可将森林中的两棵树连接成一棵更大的树 因为每一次添加到T中的边均是当前权值最小的安全边,MST性质也能保证最终的T是一棵最小生成树,60,3、Kruskal(克鲁斯卡尔)算法,MST-Kruskal (G) /求连通网G的一棵MSTT=(V,); /初始化,T是只含n个顶点不包含边的森林 /依权值递增序对E(G)中的边排序,并设结果在E0e-1中 O(Elog(E) sort the edges of E by non-decreasing weight w for(i=0;ie;i+) /e为图中边总数,O(E) 取第i条边(u,v) if u和v分别属于T中两棵不同的树

36、 T=T(u,v);/(u,v)是安全边,将其加入T中 return T; ,61,说明,有关说明: 该算法的时间复杂度为O(ElogE)。 Kruskal算法的时间主要取决于边数。它较适合于稀疏图。,62,3.7 多机调度问题,设有 n 个独立的作业 1 , 2 , , n ,由 m 台相同的机器进行加工处理。作业 i 所需的处理时间为 ti。 约定:任何作业可以在任何一台机器上加工处理,但未完工前不允许中断处理。任何作业不能拆分成更小的作业。 多机调度问题要求给出一种作业调度方案,使所给的 n 个作业在尽可能短的时间内由 m 台机器加工处理完成。,63,3.7 多机调度问题,这个问题是NP

37、完全问题(Non-deterministic Polynomial Complete Problem) ,也即是多项式复杂程度的非确定性问题 ,到目前为止还没有有效的解法。 对于这一类问题,用贪心选择策略有时可以设计出较好的近似算法。 非确定性问题:无法按部就班直接地计算出来。比如,找大质数的问题。没有一个公式,一套公式,就可以一步步推算出来,下一个质数应该是多少呢?再比如,大的合数分解质因数的问题,有没有一个公式,把合数代进去,就直接可以算出,它的因子各自是多少?也没有这样的公式。,64,3.7 多机调度问题,采用最长处理时间作业优先的贪心选择策略可以设计出解多机调度问题的较好的近似算法。

38、按此策略,当nm时(作业数m时,首先将n个作业依其所需的处理时间从大到小排序。然后依此顺序将作业分配给空闲的处理机。算法所需的计算时间为O(nlogn)。,65,一个实例,例如,设7个独立作业1,2,3,4,5,6,7由3台机器M1,M2和M3加工处理。各作业所需的处理时间分别为2,14,4,16,6,5,3。按算法greedy产生的作业调度如下图所示,所需的总加工时间为17。,作业编号,数据输入: 首先输入 2 个正整数 n 和 m,分别表示有 n 个作业和 m 台相同的机器。 然后输入 n 个正整数,第 i 个数表示作业 i 所需的处理时间。,#define N 10 /作业数 #defi

39、ne M 3 /机器数 static int timeN=2,8,18,32,50,72,98,128,182,200; int sM=0,0,0; /S数组存储每台机器当前已分配任务总耗时 void main() sort(time,N); /将处理时间从大到小排序if(M=N) /作业数小于机器数coutset_work1(time,N)endl;else coutset_work2(time,N)endl; ,/用选择法将处理时间从大到小排序,O(n2) void sort(int t,int n) for(int k=0;ktj) j=i; int temp=tj;tj=tk;tk=t

40、emp; ,当然,最好选O(nlogn)或O(n)时间复杂度算法。,int set_work1(int t,int n) int m=0;for(int i=0;in;i+) /分派作业sm+=ti;m+;return max(s,N); int set_work2(int t,int n) for(int i=0;in;i+)smin(M)+=ti;return max(s,M); ,int min(int m)int min=0; /min记录目前处理作业时间和最小的机器号for(int i=1;isi) min=i;return min; int max(int t,int num) /

41、max函数求最长处理时间int max=t0;for(int i=1;inum;i+)if(maxti) max=ti;return max; ,70,练习,1、N个顾客等待同时等待一项服务,顾客i需要的服务时间是ti,如何安排使所有顾客总的等待时间最短? 若有S处提供同一服务,又该如何安排顾客服务次序?,71,练习,2、通过键盘输入一个高精度的正整数n (n的有效位数240),去掉其中任意s个数字后,剩下的数字按原左右次序将组成一个新的正整数。编程对给定的n 和s,寻找一种方案,使得剩下的数字组成的新数最小。 【样例输入】178543S=4 【样例输出】13,72,练习分析,贪心策略:每一步

42、总是选择一个使剩下的数最小的数字删去。 (1)按高位到低位的顺序搜索,删除首个上升子序列的末字符。 (2)回到串首,按上述规则再删除下一个数字。 (3)重复以上过程s次,剩下的数字串便是问题的解了。,【样例输入】178543S=4【过程】 178543 17543 1543 143 13,73,练习分析,贪心策略:每一步总是选择一个使剩下的数最小的数字删去。 (1)按高位到低位的顺序搜索,删除首个上升子序列的末字符。 (2)回到串首,按上述规则再删除下一个数字。 (3)重复以上过程s次,剩下的数字串便是问题的解了。,delete(n ,s) 输入s, n; while( s 0 ) i=1; /从串首开始找 while (i1) ,

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

当前位置:首页 > 实用文档 > 简明教程

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


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

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

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