AOE关键路径知识讲解

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

• for(k=0;k<G.vexnum;k++) /* 求事件vj可能的最早发 生时间ee(j) */
• { i=topo[k];
//k仅起控制作用

p=G.vertices[i].firstarc;
• while(p!=NULL)
• { j=p->adjvex;
• if(ve[i]+p->weight>ve[j]) ve[j]=ve[i]+p->weight;
• typedef float AdjType;
• typedef struct ArcNode
• { int adjvex;
/* 相邻顶点字段 */
• AdjType weight;
• struct ArcNode *nextarc;
/* 链字段 */
• }ArcNode;
/* 边表中的结点 */
• while(p!=NULL)
• { j=p->adjvex;
• if(vl[j]-p->weight<vl[i]) vl[i]=vl[j]-p->weight;
• p=p->nextarc;
•}
•}
•}
百度文库
• void counte_l(ALGraph G,AdjType *ve,AdjType *vl,AdjType *ee,AdjType *el)
7.5.2 关键路径
• 与AOV-网相对应的是AOE-网(Activity On Edge) 即边表示活动的网。AOE-网是一个带权的有向无 环图,其中,顶点表示事件(Event),弧表示活动, 权表示活动持续的时间。通常,AOE-网可用来估 算工程的完成时间。
• 例如,图7.29是一个假想的有11项活动的AOE-网。 其中有9个事件v1,v2,v3,…,v9,每个事件 表示在它之前的活动已经完成,在它之后的活动 可以开始。如v1表示整个工程开始,v9表示整个 工程结束,v5表示a4和a5已经完成,a7和a8可以 开始。与每个活动相联系的数是执行该活动所需 的时间。比如,活动a1需要6天, a2需要4天等。
• 由此得到求关键路径的算法:
• (1)输入e条弧<j,k>,建立AOE-网的存储结构;
• (2)从源点v0出发,令ve[0]=0,按拓扑有序求 其余各顶点的最早发生时间ve[i] (1≤i≤n-1)。如果 得到的拓扑有序序列中顶点个数小于网中顶点数n, 则说明网中存在环,不能求关键路径,算法终止; 否则执行步骤(3)。
• (3)从汇点vn出发,令vl[n-1]=ve[n-1],按逆拓 扑有序求其余各顶点的最迟发生时间vl[i](n— 2≥i≥2);
• (4)根据各顶点的ve和vl值,求每条弧s的最早开 始时间e(s)和最迟开始时间 l(s)。若某条弧满足条 件e(s)=l(s),则为关键活动。
• 先将拓扑排序算法7.12改写成算法7.13,则算法 7.14便为求关键路径的算法。
最后一个顶点止顺序编号。
• p=p->nextarc; • }}}
• int CriticalPath(ALGraph G) /*关键路径算法*/
• { AdjType
ve[MAXVEX],vl[MAXVEX],ee[MAXEDGE],el[MAXEDGE];
• int topo[MAXVEX];
• if(topoSort(G,topo)==FALSE) /*求AOE网的一个拓扑序列*/
• return FALSE;
/*若有环则返回FALSE*/
• vl[i]=ve[G.vexnum-1]; /*每个事件的最迟发生时间赋初值 为最生事件的最早发生时间(本例均为18)*/
• for(k=G.vexnum-2;k>=0;k--) /*下标从0开始,最后一个顶点 无后继,所以减2*/
• { i=topo[k];

p=G.vertices[i].firstarc;
• 由上分析可知,辨别关键活动就是要找e(i)=l(i)的活动。为 了求得AOE-网中活动的e(i)和l(i), 首先求事件的最早发 生时间ve(j)和最迟发生时间vl(j)。如果活动ai由弧<j,k>表 示,其持续时间记为dut(<j,k>),则有如下关系:

e(i ) = ve(j)
(7-1)
• p=p->nextarc;
•}
•}
•}
• void countvl(ALGraph G,int *topo,AdjType *ve, AdjType *vl) /* 计算各事件的最迟发生时间*/
• { int i,j,k; ArcNode *p;
• for(i=0;i<G.vexnum;i++) //求事件vi允许的最迟发生时间vl(i)
/* 取出当前栈顶元素 */
• topo[count++]=j;
/*ptopo数组存放拓扑序列*/
• p=G.vertices[j].firstarc;
• //取该元素边表中的第一个边结点,删除该结点,构造新的AOV网
• makeNewAOV(p,indegree,top); //对indegree数组进行修改

vl(i) = Min{ vl (j) – dut(<i,j>) }

j

<i,j> ∈S , i=n-2,…,0 (7-3)
• 其中,S是所有以第i个顶点为头的弧的集 合。
• 这两个递推公式的计算必须分别在拓扑 有序和逆拓扑有序的前提下进行。也就是 说ve(j-1)必须在vj的所有前驱的最早发生时 间求得之后才能确定,而vl(j-1)则必须在vj 的所有后继的最迟发生时间求得之后才能 确定。因此,可以在拓扑排序的基础上计 算ve(j-1)和vl(j-1)。
•}
•}
• int topoSort(ALGraph G,int *topo) /*拓扑排序算 法*/
• { ArcNode *p; • int i,j,count=0,top=-1; • int indegree[MAXVEX]; • FindInDegree(G,indegree); /* 求出图中所有顶
•}
• if(count<G.vexnum) /* AOV网中存在回路 */
• { printf("The aov network has a cycle\n");
• return FALSE;
•}
• printf("拓扑序列为: "); //输出拓扑序列
• for(i=0;i<G.vexnum;i++)
• /*图的关键路径问题的算法AOE.C*/
• #include <stdio.h>
• #include <stdlib.h>
• #define MAXVEX 100
• #define TRUE 1
• #define FALSE 0
• typedef char VertexType[MAXVEX]; /*存放顶点信息的字符串*/
• typedef struct VNode
• { VertexType data;
/* 顶点信息 */
• ArcNode *firstarc;
/* 边表头指针 */
• }VNode,AdjList[MAXVEX]; /* 顶点表中的结点 */
• typedef struct
• { AdjList vertices;
• { int k;
• while(p)
/* 删除以该顶点为起点的边 */
• { k=p->adjvex;
• indegree[k]--;
• if(indegree[k]==0) /* 将新的入度为零的边 入栈 */
• { indegree[k]=top;
• top=k;
•}
• p=p->nextarc;
• void makeList(ALGraph &G) /*邻接表的构造*/ • { int i; • G.vexnum=9; • for(i=0;i<G.vexnum;i++) //给顶点指针域赋初值 • G.vertices[i].firstarc=NULL; • insert(G,0,1,6); insert(G,0,2,4); insert(G,0,3,5); • insert(G,1,4,1); insert(G,2,4,1); insert(G,3,5,2); • insert(G,4,6,9); insert(G,4,7,7); insert(G,5,7,4); • insert(G,6,8,2); insert(G,7,8,4); •}
• #define MAXEDGE 100 /*MAXEDEG为边的最大数目*/
• void countve(ALGraph G,int *topo,AdjType *ve) /* 计算 各事件的最早发生时间*/
• { int i,j,k;
• ArcNode *p;
• for(i=0;i<G.vexnum;i++) ve[i]=0; /*ee数组赋初值*/
• int vexnum,arcnum;
/* 图的顶点个数 */
• }ALGraph;
• /* 求出图中所有顶点的入度,方法是搜索整个邻接表 */ • void FindInDegree(ALGraph G,int inDegree[]) • { int i; • ArcNode *p; • for(i=0;i<G.vexnum;i++) inDegree[i]=0; /*顶点入度
• /*计算各活动的最早发生时间和最迟发生时间,并输出关 键路径*/
• { int i=0,j,k; ArcNode *p; • printf("关键路径是: "); • for(j=0;j<G.vexnum;j++) /*求活动ai的最早开始时间ee(i)
及最晚开始时间el(i) */ • { p=G.vertices[j].firstarc; • while(p!=NULL) • { k=p->adjvex; • ee[i]=ve[j]; • el[i]=vl[k]-p->weight; • if(ee[i]==el[i]) printf("<v%1d, v%1d>, ",j+1,k+1); • i++; //i表示弧的序号。弧的序号自第一个顶点开始到
printf("V%1d ",topo[i]+1);
printf("\n");
• return TRUE;
•}
• void insert(ALGraph &G,int a,int b,float weight) • /*在表尾插入表结点*/ • { ArcNode *p,*temp; • temp=(ArcNode *)malloc(sizeof(ArcNode)); • temp->adjvex=b; • temp->nextarc=NULL; • temp->weight=weight; • p=G.vertices[a].firstarc; • if(p==NULL) • G.vertices[a].firstarc=temp; • else • { while(p->nextarc!=NULL) p=p->nextarc; /*找表尾*/ • p->nextarc=temp; •} •}
点的入度 */ • for(i=0;i<G.vexnum;i++) • if(indegree[i]==0) / / 将入度为零的顶点入栈 • { indegree[i]=top; • top=i; •}
• while(top!=-1)
/* 栈不为空 */
• { j=top;
• top=indegree[top];

l (i) = vl(k)-dut(<j,k>)
• 求ve(j)和vl(j)需分两步进行:
• (1)从ve(0)开始向前递推

ve(j) = Max{ve(i)+dut(<i,j>)}
•i

<i,j> ∈T, j=1,2,3,…,n-1
(7-2)
• 其中,T是所有以第j个顶点为尾的弧的结合。
• (2)从vl(n-1)=ve(n-1)起向后递推
数组赋初值*/ • for(i=0;i<G.vexnum;i++) • { p=G.vertices[i].firstarc; • while(p) • { inDegree[p->adjvex]++; • p=p->nextarc; •} •} •}
• void makeNewAOV(ArcNode *p,int *indegree, int &top)
相关文档
最新文档