关键路径算法

上传人:博****1 文档编号:568784052 上传时间:2024-07-26 格式:PPT 页数:26 大小:112.50KB
返回 下载 相关 举报
关键路径算法_第1页
第1页 / 共26页
关键路径算法_第2页
第2页 / 共26页
关键路径算法_第3页
第3页 / 共26页
关键路径算法_第4页
第4页 / 共26页
关键路径算法_第5页
第5页 / 共26页
点击查看更多>>
资源描述

《关键路径算法》由会员分享,可在线阅读,更多相关《关键路径算法(26页珍藏版)》请在金锄头文库上搜索。

1、1l与AOV-网相对应的是AOE-网(Activity On Edge)即边表示活动的网。AOE-网是一个带权的有向无环图,其中,顶点表示事件(Event),弧表示活动,权表示活动持续的时间。通常,AOE-网可用来估算工程的完成时间。l例如,图7.29是一个假想的有11项活动的AOE-网。其中有9个事件v1,v2,v3,v9,每个事件表示在它之前的活动已经完成,在它之后的活动可以开始。如v1表示整个工程开始,v9表示整个工程结束,v5表示a4和a5已经完成,a7和a8可以开始。与每个活动相联系的数是执行该活动所需的时间。比如,活动a1需要6天, a2需要4天等。23l和AOV-网不同,对AOE

2、-网有待研究的问题是:l (1)完成整项工程至少需要多少时间?l (2)哪些活动是影响工程进度的关键?l 由于在AOE-网中有些活动可以并行地进行,所以完成工程的最短时间是从开始点到完成点的最长路径的长度(这里所说的路径长度是指路径上各活动持续时间之和,不是路径上弧的数目)。路径长度最长的路径叫做关键路径(Critical Path)。假设开始点是v1,从v1到vi的最长路径长度叫做事件vi的最早发生时间。这个时间决定了所有以vi为尾的弧所表示的活动的最早开始时间。我们用e(i)表示活动ai的最早开始时间。还可以定义一个活动的最迟开始时间l(i),这是在不推迟整个工程完成的前提下,活动ai最迟

3、必须开始进行的时间。两者之差l(i)-e(i)意味着完成活动ai的时间余量。我们把l(i)=e(i)的活动叫做关键活动。显然,关键路径上的所有活动都是关键活动,因此提前完成非关键活动并不能加快工程的进度。因此,分析关键路径的目的是辨别哪些是关键活动,以便争取提高关键活动的工效,缩短整个工期。4l由上分析可知,辨别关键活动就是要找e(i)=l(i)的活动。为了求得AOE-网中活动的e(i)和l(i), 首先求事件的最早发生时间ve(j)和最迟发生时间vl(j)。如果活动ai由弧表示,其持续时间记为dut(),则有如下关系:l e(i ) = ve(j) (7-1)l l (i) = vl(k)-

4、dut() l 求ve(j)和vl(j)需分两步进行:l (1)从ve(0)开始向前递推l ve(j) = Maxve(i)+dut()lil T, j=1,2,3,n-1 (7-2)l 其中,T是所有以第j个顶点为尾的弧的结合。l(2)从vl(n-1)=ve(n-1)起向后递推l vl(i) = Min vl (j) dut() l jl S , i=n-2,0 (7-3)5l 其中,S是所有以第i个顶点为头的弧的集合。l 这两个递推公式的计算必须分别在拓扑有序和逆拓扑有序的前提下进行。也就是说ve(j-1)必须在vj的所有前驱的最早发生时间求得之后才能确定,而vl(j-1)则必须在vj的所

5、有后继的最迟发生时间求得之后才能确定。因此,可以在拓扑排序的基础上计算ve(j-1)和vl(j-1)。6l由此得到求关键路径的算法:l(1)输入e条弧,建立AOE-网的存储结构;l (2)从源点v0出发,令ve0=0,按拓扑有序求其余各顶点的最早发生时间vei (1in-1)。如果得到的拓扑有序序列中顶点个数小于网中顶点数n,则说明网中存在环,不能求关键路径,算法终止;否则执行步骤(3)。l (3)从汇点vn出发,令vln-1=ven-1,按逆拓扑有序求其余各顶点的最迟发生时间vli(n2i2);l (4)根据各顶点的ve和vl值,求每条弧s的最早开始时间e(s)和最迟开始时间 l(s)。若某

6、条弧满足条件e(s)=l(s),则为关键活动。l先将拓扑排序算法7.12改写成算法7.13,则算法7.14便为求关键路径的算法。 7l/*图的关键路径问题的算法AOE.C*/l#include l#include l#define MAXVEX 100l#define TRUE 1l#define FALSE 0ltypedef char VertexTypeMAXVEX; /*存放顶点信息的字符串*/ltypedef float AdjType;ltypedef struct ArcNodel int adjvex; /* 相邻顶点字段 */l AdjType weight;l struct

7、 ArcNode *nextarc; /* 链字段 */lArcNode; /* 边表中的结点 */ltypedef struct VNodel VertexType data; /* 顶点信息 */l ArcNode *firstarc;/* 边表头指针 */lVNode,AdjListMAXVEX;/* 顶点表中的结点 */ltypedef structl AdjList vertices;l int vexnum,arcnum;/* 图的顶点个数 */lALGraph;8l/* 求出图中所有顶点的入度,方法是搜索整个邻接表 */lvoid FindInDegree(ALGraph G,i

8、nt inDegree)l int i;l ArcNode *p;l for(i=0;iG.vexnum;i+) inDegreei=0; /*顶点入度数组赋初值*/l for(i=0;iadjvex+;l p=p-nextarc;l l l9lvoid makeNewAOV(ArcNode *p,int *indegree, int &top)l int k;l while(p) /* 删除以该顶点为起点的边 */l k=p-adjvex;l indegreek-;l if(indegreek=0) /* 将新的入度为零的边入栈 */l indegreek=top;l top=k;l l p

9、=p-nextarc;l l10lint topoSort(ALGraph G,int *topo) /*拓扑排序算法*/l ArcNode *p;l int i,j,count=0,top=-1;l int indegreeMAXVEX;l FindInDegree(G,indegree); /* 求出图中所有顶点的入度 */l for(i=0;iG.vexnum;i+)l if(indegreei=0) / / 将入度为零的顶点入栈l indegreei=top;l top=i;l 11l while(top!=-1) /* 栈不为空 */l j=top;l top=indegreetop

10、; /* 取出当前栈顶元素 */l topocount+=j; /*ptopo数组存放拓扑序列*/l p=G.verticesj.firstarc;l/取该元素边表中的第一个边结点,删除该结点,构造新的AOV网l makeNewAOV(p,indegree,top); /对indegree数组进行修改l l if(countG.vexnum) /* AOV网中存在回路 */l printf(The aov network has a cyclen);l return FALSE;l l printf(拓扑序列为: ); /输出拓扑序列l for(i=0;iadjvex=b;l temp-nex

11、tarc=NULL;l temp-weight=weight;l p=G.verticesa.firstarc;l if(p=NULL)l G.verticesa.firstarc=temp;l elsel while(p-nextarc!=NULL) p=p-nextarc; /*找表尾*/l p-nextarc=temp;l l13lvoid makeList(ALGraph &G) /*邻接表的构造*/l int i;l G.vexnum=9;l for(i=0;iG.vexnum;i+) /给顶点指针域赋初值l G.verticesi.firstarc=NULL;l insert(G,

12、0,1,6); insert(G,0,2,4); insert(G,0,3,5);l insert(G,1,4,1); insert(G,2,4,1); insert(G,3,5,2);l insert(G,4,6,9); insert(G,4,7,7); insert(G,5,7,4);l insert(G,6,8,2); insert(G,7,8,4);l14l#define MAXEDGE 100 /*MAXEDEG为边的最大数目*/lvoid countve(ALGraph G,int *topo,AdjType *ve) /* 计算各事件的最早发生时间*/l int i,j,k;l

13、ArcNode *p;l for(i=0;iG.vexnum;i+) vei=0; /*ee数组赋初值*/l for(k=0;kadjvex;l if(vei+p-weightvej) vej=vei+p-weight;l p=p-nextarc;l l l15lvoid countvl(ALGraph G,int *topo,AdjType *ve, AdjType *vl) /*计算各事件的最迟发生时间*/l int i,j,k; ArcNode *p;l for(i=0;i=0;k-) /*下标从0开始,最后一个顶点无后继,所以减2*/l i=topok;lp=G.verticesi.f

14、irstarc;l while(p!=NULL)l j=p-adjvex;l if(vlj-p-weightweight;l p=p-nextarc;l l l16lvoid counte_l(ALGraph G,AdjType *ve,AdjType *vl,AdjType *ee,AdjType *el)l/*计算各活动的最早发生时间和最迟发生时间,并输出关键路径*/l int i=0,j,k; ArcNode *p;l printf(关键路径是: );l for(j=0;jadjvex;l eei=vej;l eli=vlk-p-weight;l if(eei=eli) printf(,

15、 ,j+1,k+1);l i+; /i表示弧的序号。弧的序号自第一个顶点开始到最后一个顶点止顺序编号。l p=p-nextarc;l 17lint CriticalPath(ALGraph G) /*关键路径算法*/l AdjType veMAXVEX,vlMAXVEX,eeMAXEDGE,elMAXEDGE;l int topoMAXVEX;l if(topoSort(G,topo)=FALSE) /*求AOE网的一个拓扑序列*/l return FALSE; /*若有环则返回FALSE*/l countve(G,topo,ve); /*计算数组ve,ve存放事件可能的最早发生时间*/l c

16、ountvl(G,topo,ve,vl); /*计算数组vl,vl存放事件可能的最迟发生时间*/l counte_l(G,ve,vl,ee,el); /*计算数组ee,el并输出结果*/l printf(n); /*数组ee存放活动的最早开始时间,数组el存放活动的最晚开始时间*/l return TRUE;l18lvoid main() /*主程序*/l ALGraph G;l makeList(G);l if(CriticalPath(G)=FALSE)l printf(There is no critical path!n);l192021各事件的最早发生时间数组ve变化情况k01234

17、5678i=topok023514768V100000000000V210666666666V320444444444V430555555555V540055577777V650007777777V7600000016161616V870000111114141414V98000000018181822各事件的最迟发生时间数组vl变化情况 k76543210i=topok67415320V1018181818181818180V211818181866666V321818181818181866V43181818181818788V54181818777777V6518181818181010

18、1010V76181616161616161616V87181814141414141414V9818181818181818181823各事件和各活动的最早与最迟开始时间24l输出:l拓扑序列为:v1 v3 v4 v6 v2 v5 v8 v7 v9l关键路径是:,l即有两条关键路径:(v1,v2,v5,v7,v9)和(v1,v2,v5,v8,v9) 25l实践已经证明:用AOE-网来估算某些工程完成的时间是非常有用的。实际上,求关键路径的方法本身最初就是与维修和建造工程一起发展的。但是,由于网中各项活动是互相牵涉的,因此,影响关键活动的因素亦是多方面的,任何一项活动持续时间的改变都会影响关键路径的改变。由此可见,关键活动的速度提高是有限度的。只有在不改变网的关键路径的情况下,提高关键活动的速度才有效。l 另一方面,若网中有几条关键路径,那么,单是提高一条关键路径上的关键活动的速度,还不能导致整个工程缩短工期,而必须提高同时在几条关键路径上的活动的速度。 26

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 施工组织

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号