求AOE网络中的关键路径算法
基于邻接矩阵存储的AOE网的关键路径算法的实现
F福建电脑UJIAN COMPUTER福建电脑2017年第11期1引言有向无环图在工程和管理中的应用有两种:AOV 网和AOE 网,前者用顶点表示活动,有向弧表示活动间。
后者用顶点表示事件,弧表示活动,弧上的权值表示活动持续的时间。
AOE 网在工程计划和管理中用于解决两类问题,一类是求解影响工程进度的关键活动,另一类是求解完成整个工程所需要的最少时间。
在AOE 网中唯一一个入度为零的顶点称作源点;唯一一个出度为零的顶点称作汇点。
从源点到汇点的最长路径称作关键路径,关键路径的长度就是完成整个工程任务所需要的最短时间。
关键路径上的活动都是关键活动。
如果这些活动中的任意一项未能按期完成,则整个工程就要延期。
如果某个关键活动的进度能够提前,那么整个工程就可能提前完成。
2算法所用数据结构:设图G =(V ,VR )是一个具有n 个顶点的有向网,其中,V 为顶点集,VR 为两个顶点间的关系的集合。
G 的邻接矩阵定义为如下n 伊n 矩阵A :则定义如下数组和矩阵:top_sort [n ]:存放G 的一个拓扑序列ve [n ]:ve [i ]为事件vi 的最早发生时间vl [i ]:vl [i ]为事件vi 的最晚发生时间e [n ][n ]:e [i ][j ]为活动<vi ,vj>的最早开始时间l [n ][n ]:l [i ][j ]为活动<vi ,vj>的最晚开始时间3基于邻接矩阵的拓扑排序(Topological Sort)的实现在顶点集V 和弧集E 构成的有向图G=(V ,E)中,满足如下条件的顶点序列(v i1,v i2,v i3…,v in )称为拓扑序列:对于序列中的任意两个顶点v i 、v j ,如果在G 中存在一条从v i 到v j 的路径,那么在序列中v i 一定在v j 之前。
如图1所示有向网的一个拓扑序列为:v 0,v 1,v 2,v 3,v 4,v 5,v 6,v 7,v 8。
AOE网的关键路径求解算法改进及其应用
3 2 1 图的存储结构 .. 图的存储 结构 采 用十 字 链表形 式 ,在 十 字链 表 , 中, 对应有 向图 中每一条弧有一个结 点 , 对应于每个顶
L i = L k 一D ti ) () V ( ) u (, k 求 、 () V () , i和 L 1需分两步进行 : E ()从 V () 0开始 向前递推 1 E1 =
A pe ehi e应用技术 4 pldTcn u i q 7
维普资讯
计 算 机 系 统 应 用
20 年 第 9 期 06
果工序 a 由弧 (, ) i ik 表示 , 其持续 时 间记 为 D t i ) u (, , k 则有如下关系 :
点也有一个结点 。这些结点的结构 如下 :
弧结点
Tie I H a vx l Hl l Tn I Io avx ede lk lk n l n i f
、 () , i=Ma {E i D ti }其 中 ( E xV ()+ u( ) i )∈T2 ,
≤i , 是所有以 i ≤n T 为头的弧的集合 。
关键 词 : 关键 路 径 A E网 生产 工序 O
1 引言
在项 目管理 中 , 合理 估计 工期 , 找出影响工 程进度 的关键活 动 , 从而采取各种措施 缩短 工期 , 提高 效率是 生产 管理 者的一 项核 心 工作。 而 A E网 的关键 路径 O 算法正是 用来解决此问题的。在传统的讲解数 据结构
刘小晶 ( 嘉兴 学院信 息工程 学院 34 0 ) 1 1 0
摘要 : 在项 目企业生产管理 中, 舍理估计工期是一个 必不可 少的环 节。而 A E网的关键路径 算法是 用 于此环 节的 O
关于AOE网中关键路径求解算法的研究
l 相关概念
在 A E网 中有 些活 动可 以并行 地进 行 , 以完 O 所
第三步 , A E网所有活动的最早开始时间 e 求 O 。
如 果活 动 a 由 < , 表 示 , 用公 式 ( ) 解 : () k> 利 3求
e i =v() ( ) ej () 3
V() M x v() d ti ) , 中 2<= ej = a { i + u(, }其 e <
=n () 1
第 二 步 , A E 网所 有 时 间 的最 迟 发 生 时 间 求 O v。利用 公式 ( ) v( )= v( ) l 2 从 ln e n 开始 向后递推 V()= n{f()一dti ) , 中 1< =i 1i Mi e u(, }其 <
第六步 , 找出所有 z e 0的关键路径。 —=
作者简 介 : 常友渠( 99一) 讲师 , 士学位 , 17 , 硕 主要研究方 向: 计算机应用 。
3 8
重 庆 电 力 高 等 专 科 学 校 学 报
第1 5卷
22 基于 P 阵的求解方法 . 矩
基于 P 矩阵的求关键路径的算法 : 第 一 步 , 造 图 G 的 /阶 P邻 接 矩 阵 M。 构 7 , = ( , o) 其中, 如果 邻接 v, , ( )>, j口 =< L i j 否则 0= 0的值 ; , 其中 L i 的值为 到 边上的权 ; () j 第 二步 , 据 构 造 : 根 将 中所 有 路删 去
【 关键词】 O A E网; 关键路径; 算法 ; 广度优先搜索遍历(F ) B S 【 中图分类号]P 1.2 T 311 【 文献标识码】 A 【 文章编号】08 02 2l) 1 O7 10— 3 (000 _ 3 3 8 o
(整理)AOE关键路径.
显然,对于关键活动而言,e(i)= l(i)。对于非关键活动,l(i)-e(i)的值是该工程的期限余量,在此范围内的适度延误不会影响整个工程的工期。
一个活动ai的最晚开始时间l(i)和最早开始时间e(i)的差值l(i)-e(i)是该活动完成的时间余量。它是在不增加完成整个工程所需的总时间的情况下,活动ai可以拖延的时间。当一活动的时间余量为零时,说明该活动必须如期完成,否则就会拖延整个工程的进度。所以称l(i)-e(i)=0,即l(i)=e(i)时的ai是关键活动。
(4)根据各顶点的ve和vl值,求每条弧(活动)ai的最早开始时间e(i)和最迟开始时间l(i)。
(5)找出e(i)=l(i)的活动,则为关键活动。由关键活动形成的由源点到汇点的每一条路径就是关键路径,关键路径有可能不止一条。
三、关键路径算法的实现
由于每个事件的最早发生时间ve(i)和vl(i)要在拓扑序列的基础上进行计算,所以关键路径算法的实现要基于拓扑排序算法,我们仍采用邻接表做有向图的存储结构。
if(vl[k]<vl[j]-p->weight) vl[k]= vl[j]-p->weight;
(6)从源点开始,对于每个顶点i,用指针p依次指向i的每个邻接顶点,取得每个顶点的序号j=p->adjvex,分别计算活动<vi,vj>的最早发生时间和最迟发生时间e和l。
e=ve[i];l=vl[j]-p->weight;
图6.22一个AOE网
和AOV-网不同,对AOE-网有待研究的问题是:
(1)完成整项工程至少需要多少时间?
(2)哪些活动是影响工程进度的关键?
由于在AOE-网中有些活动可以并行地进行,所以完成工程的最短时间是从开始点到完成点的最长路径的长度(这里所说的路径长度是指路径上各活动持续时间之和,不是路径上弧的数目)。路径长度最长的路径叫做关键路径(Critical Path)。假设开始点是v0,从v0到vi的最长路径长度叫做事件vi的最早发生时间。这个时间决定了所有以vi为尾的弧所表示的活动的最早开始时间。我们用e(i)表示活动ai的最早开始时间。还可以定义一个活动的最迟开始时间l(i),这是在不推迟整个工程完成的前提下,活动ai最迟必须开始进行的时间。两者之差l(i)-e(i)意味着完成活动ai的时间余量。我们把l(i)=e(i)的活动叫做关键活动。显然,关键路径上的所有活动都是关键活动,因此提前完成非关键活动并不能加快工程的进度。因此,分析关键路径的目的是辨别哪些是关键活动,以便争取提高关键活动的工效,缩短整个工期。
数据结构程序设计实验~AOE图的关键路径
数据结构课程设计报告专业网络工程班级姓名学号指导老师评分计算AOE网的关键路径AOE网即边表示活动的网络。
通常,可用AOE网来估算工程计划的完成时间。
如下所示的AOE网包括11项活动,9个事件,每个事件都有所需的完成时间。
我们现在要解决的是:(1)完成整项工程至少需要多少时间(最短时间);(2)哪些活动是影响工程进度的关键(关键活动)。
用e(i)表示活动最早开始时间,l(i)表示活动的最迟开始时间,则l(i)-e(i)为完成该活动的时间余量。
对于本例列表如下:下图就是上述AOE网的关键路径:请编程完成下列工作:1、输入:(1)顶点的信息和入度;(2)AOE网的边(始点、终点和权值)。
2、输出:(1) AOE网的邻接表(按“顶点入度:—>顶点权值”的格式输出)如a 0:-->4 5-->3 4-->2 6(2)输出关键活动每行所显示的分别为开始事件、结束事件、最早开始时间、最迟开始时间和完成活动的时间余量:当l(i)-e(i)=0时,在该行注明为关键活动。
如:a b 0 0 0 关键活动源程序#include<stdio.h>#include<stdlib.h>#include<iomanip.h>#include <process.h>//#define PROJECTNUMBER 9//10//#define PLANNUMBER 11//13typedef struct node{int adjvex;int dut;struct node *next;}edgenode;typedef struct{int projectname;int id;edgenode *link;}vexnode;//vexnode Graphicmap[PROJECTNUMBER];void CreateGraphic(vexnode* Graphicmap,int projectnumber,int activenumber){int begin,end,duttem;edgenode *p;for(int i=0;i<projectnumber;i++){Graphicmap[i].projectname=i;Graphicmap[i].id =0;Graphicmap[i].link =NULL;}printf("某项目的开始到结束在图中的节点输入<vi,vj,dut>\n");printf("如:3,4,9 回车表示第三节点到第四节点之间的活动用了9个单位时间\n"); for(int k=0;k<activenumber;k++){scanf("%d,%d,%d",&begin,&end,&duttem);p=(edgenode*)malloc(sizeof(edgenode));p->adjvex =end-1;p->dut =duttem;Graphicmap[end-1].id ++;p->next =Graphicmap[begin-1].link ;Graphicmap[begin-1].link =p;}}int SearchMapPath(vexnode* Graphicmap,int projectnumber,int activenumber,int& totaltime){int i,j,k,m=0;int front=-1,rear=-1;int* topologystack=(int*)malloc(projectnumber*sizeof(int));//用来保存拓扑排列int* vl=(int*)malloc(projectnumber*sizeof(int));//用来表示在不推迟整个工程的前提下,VJ允许最迟发生的时间int* ve=(int*)malloc(projectnumber*sizeof(int));//用来表示Vj最早发生时间int* l=(int*)malloc(activenumber*sizeof(int));//用来表示活动Ai最迟完成开始时间 int* e=(int*)malloc(activenumber*sizeof(int));//表示活动最早开始时间edgenode *p;totaltime=0;for(i=0;i<projectnumber;i++) ve[i]=0;for(i=0;i<projectnumber;i++){if(Graphicmap[i].id==0){topologystack[++rear]=i;m++;}}while(front!=rear){front++;j=topologystack[front];m++;p=Graphicmap[j].link ;while(p){k=p->adjvex ;Graphicmap[k].id --;if(ve[j]+p->dut >ve[k])ve[k]=ve[j]+p->dut ;if(Graphicmap[k].id ==0)topologystack[++rear]=k;p=p->next ;}}if(m<projectnumber){printf("\n本程序所建立的图有回路不可计算出关键路径\n");printf("将退出本程序\n");return 0;}totaltime=ve[projectnumber-1];for(i=0;i<projectnumber;i++)vl[i]=totaltime;for(i=projectnumber-2;i>=0;i--){j=topologystack[i];p=Graphicmap[j].link ;while(p){k=p->adjvex ;if((vl[k]-p->dut )<vl[j])vl[j]=vl[k]-p->dut ;p=p->next ;}}i=0;printf("| 起点 | 终点 | 最早开始时间 | 最迟完成时间 | 差值 | 备注 |\n");for(j=0;j<projectnumber;j++){p=Graphicmap[j].link;while(p){k=p->adjvex ;e[++i]=ve[j];l[i]=vl[k]-p->dut;printf("| %4d | %4d | %4d | %4d | %4d |",Graphic map[j].projectname +1,Graphicmap[k].projectname +1,e[i],l[i],l[i]-e[i]);if(l[i]==e[i])printf(" 关键活动 |");printf("\n");p=p->next ;}}return 1;}void seekkeyroot(){int projectnumber,activenumber,totaltime=0;system("cls");printf("请输入这个工程的化成图形的节点数:");scanf("%d",&projectnumber);printf("请输入这个工程的活动个数:");scanf("%d",&activenumber);vexnode* Graphicmap=(vexnode*)malloc(projectnumber*sizeof(vexnode)); CreateGraphic(Graphicmap,projectnumber,activenumber);SearchMapPath(Graphicmap,projectnumber,activenumber,totaltime);printf("整个工程所用的最短时间为:%d个单位时间\n",totaltime);system("pause");}int main(){char ch;for(;;){do{system("cls");printf("| 欢迎进入求关键路径算法程序 |");for(int i=0;i<80;i++)printf("*");printf("%s","(S)tart开始输入工程的节点数据并求出关键路径\n"); printf("%s","(E)xit退出\n");printf("%s","请输入选择:");scanf("%c",&ch);ch=toupper(ch);}while(ch!='S'&&ch!='E');switch(ch){case'S':seekkeyroot(); break; case'E':return 1; }}}。
关键路径算法
(4)根据各顶点的ve和vl值,求每条弧s的最早开 始时间e(s)和最迟开始时间 l(s)。若某条弧满足条 件e(s)=l(s),则为关键活动。
先将拓扑排序算法7.12改写成算法7.13,则算法 7.14便为求关键路径的算法。
typedef float AdjType;
typedef struct ArcNode
{ int adjvex;
/* 相邻顶点字段 */
AdjType weight; struBiblioteka t ArcNode *nextarc;
/* 链字段 */
}ArcNode;
/* 边表中的结点 */
&top)
{ int k;
while(p)
/* 删除以该顶点为起点的边 */
{ k=p->adjvex;
indegree[k]--;
if(indegree[k]==0) /* 将新的入度为零的边 入栈 */
{ indegree[k]=top;
top=k;
}
p=p->nextarc;
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) vl[i]=ve[G.vexnum-1]; /*每个事件的最迟发生时间赋初值
关键路径AOE网及其如何求关键路径步骤
关键路径AOE网及其如何求关键路径步骤一、关键路径(一)AOE网在带权有向图中,以顶点表示事件,以有向边表示活动,以边上的权值表示完成该活动的开销(如完成活动所需的时间),称之为用边表示活动的网络,简称AOE网(Activity On Edge NetWork)AOE⽹具有以下两个性质:①只有在某顶点所代表的事件发生后,从该顶点出发的各有向边所代表的活动才能开始;②只有在进入某顶点的各有向边所代表的活动都已结束时,该顶点所代表的事件才能发生。
另外,有些活动是可以并行进行的在AOE网中仅有一个入度为0的顶点,称为开始顶点(源点),它表示整个工程的开始;也仅有一个出度为0的顶点,称为结束顶点(汇点),它表示整个工程的结束。
(二)关键路径从源点到汇点的有向路径可能有多条,所有路径中,具有最大路径长度的路径称为关键路径,⽽把关键路径上的活动称为关键活动完成整个工程的最短时间就是关键路径的长度,若关键活动不能按时完成,则整个工程的完成时间就会延迟。
活动ai的时间余量d(i)=l(i)-e(i),表⽰在不增加完成整个工程所需总时间的情况下,活动ai 可以拖延的时间若一个活动的时间余量为零,则说明该活动必须要如期完成,d(i)=0即l(i)=e(i)的活动ai是关键活动由关键活动组成的路径就是关键路径(三)求关键路径的步骤(四)求所有事件的最早发生时间1.求所有事件的最早发生时间ve()(五)求所有事件的最迟发生时间1.求所有事件的最迟发生时间vl()1.求所有活动的最早发生时间e()1.求所有活动的最迟发生时间l()(八)求所有活动的时间余量(九)关键活动、关键路径的特性若关键活动耗时增加,则整个工程的工期将增长缩短关键活动的时间,可以缩短整个工程的工期当缩短到一定程度时,关键活动可能会变成非关键活动可能有多条关键路径,只提高⼀条关键路径上的关键活动速度并不能缩短整个工程的工期,只有加快那些包括在所有关键路径上的关键活动才能达到缩短工期的目的。
AOE网中求取关键路径的一种新算法
图1
图2
结点
v1 v2 v3 v4 v5 v6 v7 v8 S
表1 从 v 到各结点最短路径的求解过程
0
i =1 3 7 5 ∪ { v1 }
得出源点到汇点的最短路径长度为 16, 通过回溯 前驱结点分别记录两条路径 v → v → v → v → v 和 此两条路径即为所有原 AOE v →v →v →v →v ; 网的关键路径, 如图 3, 每条路径都穿程 4 条边, 所以 关键路径长度为 e·W - D = 4·9 - 16 = 20 。这里特 别需要指出, 正常情况下, 汇点的最短路径一定是所 有算得结点最短路径长度中的极大值。如果汇点的 最短路径不是在最后一次循环计算得出或者不是所 有结点最短路径长度中的极大值的话, 则说明该 AOE 网存在异常, 并非一个合理工程施工的进度表述。
谢㊀ 科㊀ 丁皓明㊀
㊀ AOE
网中求取关键路径的一种新算法
AOE
网中求取关键路径的一种新算法
谢㊀ 科, 丁皓明
( 阿坝师范学院㊀ 数学与计算机科学学院,四川㊀ 汶川㊀
623002
)
摘要: 基于求解单源最短路径问题的 Dijkstra 算法, 提出在 AOE 网络中求取关键路径的一种新算法。该算法易 于理解, 适合在“数据结构与算法”课程教学改革中使用。 ㊀ ㊀ 关键词: AOE 网; 最短路径; 关键路径; 教学改革 ㊀ ㊀ 中图分类号: TP393㊀ ㊀ 文献标识码: A㊀ ㊀ 文章编号: 2096 - 1707 ( 2017 ) 03 - 0121 - 02
㊀ ㊀
S ∪ { vj } 3 V - S ( min D [ k ] D [ j ] + v j v k ) 4 2 3
关键路径的计算
关键路径的计算从源点到汇点路径长度最长的路径为该project的关键路径,即关键路径可以保证全部路径的活动都可以完毕。
ok,再次进⼊我们的作业题:例如以下图所看到的的AOE⽹(弧上权值代表活动的持续天数)1)完毕此project最少所须要多少天?2)哪些是关键活动,在图中表⽰出关键路径我们先计算最早发⽣时间ve和最迟发⽣时间vl:12345678910Ve05612151616192123Vl09612152116192123⾸先呢,编号1和编号10分别为该project的源点和汇点,我们规定最早发⽣时间ve(源点)=0,最迟发⽣时间vl(汇点)=ve(汇点)。
那么这两个量该怎样计算呢,看图:对于事件i来说,ve(i) = Max{ve(m) + dut(<m, i>)},vl(i) = Min{vl(j) – dut(<i, j>)};当中ve(m)代表i前⼀个事件的最早发⽣时间,dut(<m, i>)表⽰从m到i的持续时间,⼤家能够把它看成⼀个递归算法,⼀直调⽤ve(),直到ve(源点)为⽌,然后取其最⼤值,由于它要保证全部路径上的活动都能完毕;⽽最迟发⽣时间和前者⼀样,⼀直递归调⽤vl(),直到vl(汇点)为⽌,然后取其最⼩值就可以。
回到原题中对⽐例图能够⾮常快地得到表格所看到的内容。
我们再来看两个概念:e(i)和l(i),前者为活动ai 的最早可能開始时间,后者为活动ai的最迟同意開始时间。
差别于前边的ve和vl,e和l为标识的是某活动的时间,⽽前者是某事件的时间。
假如从事件m到事件i的活动为af,则有e(f)=ve(m), l(f)=vl(i)–dut(<m,i>) ,即活动af的最早可能開始时间为其弧尾事件最早可能发⽣时间;最迟同意開始时间为其弧尾事件最迟发⽣时间与两个事件的持续时间之差。
是不是感觉有点别扭,但仅仅要理解了这⼏个关键词也就⾮常easy看懂了。
关键路径算法
关键路径算法相关概念: (1)AOE (Activity On Edges)⽹络如果在⽆有向环的带权有向图中⽤有向边表⽰⼀个⼯程中的各项活动(Activity),⽤边上的权值表⽰活动的持续时间(Duration),⽤顶点表⽰事件(Event),则这样的有向图叫做⽤边表⽰活动的⽹络,简称AOE (Activity On Edges)⽹络。
AOE ⽹是⼀个带权的有向⽆环图。
AOE⽹络在某些⼯程估算⽅⾯⾮常有⽤。
例如,可以使⼈们了解: a、完成整个⼯程⾄少需要多少时间(假设⽹络中没有环)? b、为缩短完成⼯程所需的时间, 应当加快哪些活动? (2)关键路径(Critical Path) 在AOE⽹络中, 有些活动顺序进⾏,有些活动并⾏进⾏。
从源点到各个顶点,以⾄从源点到汇点的有向路径可能不⽌⼀条。
这些路径的长度也可能不同。
完成不同路径的活动所需的时间虽然不同,但只有各条路径上所有活动都完成了,整个⼯程才算完成。
因此,完成整个⼯程所需的时间取决于从源点到汇点的最长路径长度,即在这条路径上所有活动的持续时间之和。
这条路径长度最长的路径就叫做关键路径(Critical Path)。
(3)由于实际⼯程只有⼀个开始点和⼀个结束点,因此AOE⽹存在唯⼀的⼊度为0的开始点(⼜称源点)和唯⼀的出度为0的结束点(⼜称汇点)参数定义: (1)事件的最早发⽣时间 etv(earliest time of vertex):即顶点V k的最早发⽣时间。
(2)事件的最晚发⽣时间 ltv(latest time of vertex):即顶点V k的最晚发⽣时间,也就是每个顶点对应的事件最晚需要开始的时间,超出此事件将会延误整个⼯期。
(3)活动的最早开⼯时间 ete(earliest time of edge):即弧ak的最早发⽣时间。
(4)活动的最晚开⼯时间 lte(latest time of edge):即弧ak的最晚发⽣时间,也就是不推迟⼯期的最晚开⼯时间。
AOE网和关键路径试题实例解析
AOE网和关键路径AOE网(Activity On Edge Network)是一个带权的有向无环图。
其中用顶点表示事件,弧表示活动,权值表示两个活动持续的时间。
AOE网是以边表示活动的网。
关键路径:AOE网中从起点至终点最长的路径。
关键路径上的活动均为关键活动。
最早开始时间:在关键路径上,从开始到该任务的最早执行的时间,取最大值最晚开始时间:关键路径的总时间-反向得出该任务的时间注意:关键路径不一定只有一条松弛时间:不影响完工前提下可能被推迟完成的最大时间松弛时间=关键路径的总时间-包含该任务的关键路径花的时间松弛时间=最晚开始时间-最早开始时间计算完成项目的最少时间:计算关键路径试题:1、下图所示的AOE网表示一项包含8个活动的工程。
活动d的最早开始时间和最迟开始时间分别是()A、3和7B、12和12C、12和14D、15和15求AOE网的关键路径的步骤如下:解析:选C2、某软件项目的活动图如下图所示,其中顶点表示项目里程碑,链接顶点的边表示包含的活动,变色数字表示活动的持续时间(天)。
完成该项目的最少时间为(17)天。
由于某种原因,现在需要同一个开发人员完成BC和BD,则完成该项目的最少时间为(18)天。
(17) A.11 B.18 C.20 D.21(18) A.11 B.18 C.20 D.21【答案】B D【解析】关键路径为ABCEFJ 和ABDGFJ ,18天。
BC持续时间3天,BD持续时间2天,由一天完成,则可以把BC持续时间作为5天,BD持续时间也为5天,则关键路径为ABDGFJ,21天3、某软件项目的活动图如下图所示,其中顶点表示项目里程碑,连接顶点的边表示包含的活动,边上的数字表示活动的持续时间(天),则完成该项目的最少时间为(17)天。
活动BD 和HK 最早可以从第(18)天开始。
(活动AB、AE 和AC 最早从第1 天开始)(17) A.17 B.18 C.19 D.20(18) A.3 和10 B.4 和11 C.3 和9 D.4 和10【答案】D B【解析】因为网络图是从0开始算的,按题目要求活动AB从第1天开始的话,就是1、2、3,活动BD就是第4天开始,相应的活动HK就是第11天开始。
关键路径.
V4
V6 V5 V8 V7
13
20 17 22 19
Vl(i)
24
v9
24
3、据ve,vl的值求活动的e(s)、l (s),找e(s)=l(s)的活动
(1)可由公式 e(i)=ve(j) ai的 l(i)=vl(k)-dut(〈j,k〉) 求得 。 示意图: ai=? j k
2
7
v7 v8 v5 v6 v4 v2 v3 bottom v9 v1
经过拓扑排序(借助stack 1)得到如下拓扑 序列: v1,v3,v2,v4,v6,v5,v8,v7,v9
而拓扑逆序(借助stack 2)为: v9,v7,v8,v5,v6,v4,v2,v3,v1
2、按拓扑有序求其余各顶点的ve(i)
(3)关键活动:关键路径上的所有活动。 例如: 上述AOE网中,v1为源点,v9为汇点; 〈v1,v3,v4,v5,v7,v9〉为一条关键 路径(不唯一但长度一定); a1,a3,a4为关键活动。 (4)最早发生时间:AOE网中,从源点v1 到任意vi的最长路径长度,叫事件vi的最 早发生时间。由该时间决定了所有以vi为 尾的弧所表示的活动的最早开始时间。
^
1 2 3 4
1 2 3 4
2 4 4 5
3
^
stack top
1
2
5 6
^ 7 ^
5
6
5
6
7
9 ^
8
^
7
8
7
8
9
9
^
^
9
9
^
bottom
V1
其中stack 1用于拓扑排序,2用于拓扑逆序
1 2
关键路径的概念和算法
关键路径的概念和算法AOE⽹:在⼀个表⽰⼯程的带权有向图中,⽤顶点表⽰事件,⽤有向边表⽰活动,边上的权值表⽰活动的持续时间,称这样的有向图叫做边表⽰活动的⽹,简称AOE⽹。
AOE⽹中没有⼊边的顶点称为始点(或源点),没有出边的顶点称为终点(或汇点)。
AOE⽹的性质:⑴只有在某顶点所代表的事件发⽣后,从该顶点出发的各活动才能开始;⑵只有在进⼊某顶点的各活动都结束,该顶点所代表的事件才能发⽣。
关键路径:在AOE⽹中,从始点到终点具有最⼤路径长度(该路径上的各个活动所持续的时间之和)的路径称为关键路径。
关键活动:关键路径上的活动称为关键活动。
关键活动:e[i]=l[i]的活动 由于AOE⽹中的某些活动能够同时进⾏,故完成整个⼯程所必须花费的时间应该为始点到终点的最⼤路径长度。
关键路径长度是整个⼯程所需的最短⼯期。
与关键活动有关的量:⑴事件的最早发⽣时间ve[k] ve[k]是指从始点开始到顶点vk的最⼤路径长度。
这个长度决定了所有从顶点vk发出的活动能够开⼯的最早时间。
⑵事件的最迟发⽣时间vl[k] vl[k]是指在不推迟整个⼯期的前提下,事件vk允许的最晚发⽣时间。
⑶活动的最早开始时间e[i] 若活动ai是由弧<vk , vj>表⽰,则活动ai的最早开始时间应等于事件vk的最早发⽣时间。
因此,有:e[i]=ve[k]⑷活动的最晚开始时间l[i] 活动ai的最晚开始时间是指,在不推迟整个⼯期的前提下,ai必须开始的最晚时间。
若ai由弧<vk,vj>表⽰,则ai的最晚开始时间要保证事件vj的最迟发⽣时间不拖后。
因此,有:l[i]=vl[j]-len<vk,vj>⽰例:所以:代码实现:123456789101112131415161718192021222324252627282930313233Status TopologicalOrder(ALGraph G, Stack &T){// 有向⽹G 采⽤邻接表存储结构,求各顶点事件的最早发⽣时间ve(全局变量)。
AOE网与关键路径_数据结构与算法分析(C++语言版)_[共4页]
s.Push(k); } } } if(count<algraph.vexnum)//零入度顶点栈 s 已空,图 G 还有顶点未输出 { cout<<"此有向图有回路"<<endl; return false; } else { cout<<"为一个拓扑序列"<<endl; return true; } }
分析上述算法,对有 n 个顶点和 e 条弧的有向图而言,建立求各顶点入度的时间复杂度为 O(e); 建零入度顶点栈的时间复杂度为 O(n);在拓扑排序过程中,若有向图无环,则每个顶点进一次栈, 出一次栈,入度减 1 的操作在 while 语句中总共执行 e 次,所以总的时间复杂度为 O(n+e)。
当有向图无环时,也可利用深度优先遍历进行拓扑排序,因为图中无环,则由图中某顶点出 发进行深度优先搜索遍历时,最先退出 DFSTraverse 函数的顶点即为出度为 0 的顶点,是拓扑有 序序列中最后一个顶点。由此,按退出 DFSTraverse 函数的先后记录下来的顶点序列即为逆向的 拓扑有序序列。
数据结构与算法分析(C++语言版)
ArcNode *p; FindInDegree(indegree);//求顶点的入度 for(i = 0;i<algraph.vexnum;i++) {
if(!indegree[i])//若其入度为 0 {
s.Push(i); //将 i 入零入度顶点栈 s } } while(!s.StackEmpty())// 当零入度顶点栈 s 不空 { i=s.Pop(); //出栈 1 个零入度顶点的序号,并将其赋给 i cout<<algraph.vertices[i].data<<" "; //输出 i 号顶点 count++; //已输出顶点数+1 for(p=algraph.vertices[i].firstarc;p;p = p->nextarc)//对 i 号顶点的每个邻接顶点 {
数据结构与算法—关键路径
关键路径若在带权的有向图中,以顶点表示事件,以有向边表示活动,边上的权值表示活动的开销(如该活动持续时间),则此带权的有向图称为边表示活动的网(Activity on Edge Network) ,简称AOE 网。
【例】图7.21 是一个网。
其中有9 个事件v 1 , v 2 , … , v 9 ;11 项活动 a 1 , a 2 , … , a 11 。
每个事件表示在它之前的活动已经完成,在它之后的活动可以开始。
如v 1 表示整个工程开始,v 9 表示整个工程结束。
V 5 表示活动a 4 和a 5 已经完成,活动a 7 和a 8 可以开始。
与每个活动相联系的权表示完成该活动所需的时间。
如活动 a 1 需要 6 天时间可以完成。
(1)AOV 网具有的性质⒈只有在某顶点所代表的事件发生后,从该顶点出发的各有向边所代表的活动才能开始。
⒉只有在进入某一顶点的各有向边所代表的活动都已经结束,该顶点所代表的事件才能发生。
⒊表示实际工程计划的AOE 网应该是无环的,并且存在唯一的入度过为0 的开始顶点和唯一的出度为0 的完成顶点。
(2)由事件v j 的最早发生时间和最晚发生时间的定义, 可以采取如下步骤求得关键活动:1. 从开始顶点v 1 出发, 令ve(1)=0, 按拓扑有序序列求其余各顶点的可能最早发生时间。
Ve(k)=max{ve(j)+dut(<j,k>)} (7.1 )j ∈T其中T 是以顶点v k 为尾的所有弧的头顶点的集合(2 ≤ k ≤ n) 。
如果得到的拓朴有序序列中顶点的个数小于网中顶点个数n ,则说明网中有环,不能求出关键路径,算法结束。
2. 从完成顶点v n 出发,令vl(n)=ve(n) ,按逆拓朴有序求其余各顶点的允许的最晚发生时间: vl(j)=min{vl(k)-dut(<j,k>)}k ∈S其中S 是以顶点v j 是头的所有弧的尾顶点集合(1 ≤ j ≤ n-1) 。
用遗传算法求解AOE-网中的关键路径
第 3期
张国权 : 用遗传算 法求 解 A E一网中的关键路径 O
文 章 编 号 :09— 2 920 )3一 O9— 3 10 2 6 (0 60 OO 0
用 遗 传 算 法 求 解 A E一网 中的 关键 路径 O
张 国权 2 ,
(. 1兰州教 育学 院 , 甘肃 兰州 7 (2 ; . 3 ) 2 西北师范大学 数学与信息科学学院 , X0 甘肃 兰州 717 ) 300 3
求解问题无连续性和可微性的要求 , 只需知道 目标函数的信息 , 并且借鉴生物遗传学研究的成果 .A的寻 G
优过 程始终 保 持整个 种 群 的进 化 , 不是一 点而是 在种 群 中寻优 因此 , A为解 决许多 困难 问题 的全局 优化 G
问题开 辟 了新途 径
遗传 算 法 中的几 个基 本概 念 : 1 )染色 体 ( ho oo e : C r sm )在使 用遗 传算 法时 , m 需
生 的先 后 自然排 序 , 故此 染色体 中的基 因排 列顺 序 即为各 顶点 在此 条通路 中出现 的先 后顺序 , 色体 的长 染 度等 于 网中顶 点 的个 数 . 由于第 一个顶 点 ( 源点 ) 和最 后一 个顶 点 ( 汇点 ) 然在 关键路径 中 , 必 故在 可行解 中
要把 G A的搜 索空 间影 射 到 解 空 间 , 即把 问题 的解
编 码成 一个 合适 的代 码 串 , 种 具 有 固定 结 构 的代 这 码 串称 为染 色 体 . 码 串 的 每 一 位 代 表 一 个 基 因 . 代 代 码 串的总 长度 叫做 染 色 体 的长 度 . 个 染 色体 一 就 代表 问题 的一 个解 , 叫一个 个体 . 又 2 )种 群 (ou tn : 组 个 体 的 集 合 称 为 种 Ppli )一 ao
关键路径算法
关键路径算法
关键路径
定义:关键路径是包含AOE图中所有顶点(事件)的最⼤路径长度,其长度代表所有活动完成所需最短时间
涉及概念:AOE图,ve,vl,ee,el
AOE图:
activities on edges
边表⽰活动(具体的⼯程内容),边长度(权值)代表活动所花费的时间
顶点表⽰事件(事件不是⼯程内容,可以理解为⼀个状态,⽤以描述所有活动的完成情况)
ve,vl,ee,el分别代表事件最早开始时间、事件最晚开始时间、活动最早开始时间、活动最晚开始时间
注:AOE图之外还有AOV图,也即顶点表⽰活动,有向边仅代表活动先后顺序⽽没有权值,故AOV图不能⽤来求所有活动完成的最短时间(关键路径)
解释:⾄于为什么最⼤长度代表最短时间,主要是因为在AOE图中,当指向⼀个顶点的所有边所代表的活动都完成后这个事件才能发⽣。
⽽所有边代表的活动的完成才是整个⼯程的完成
注意:AOE⽹是有向⽆环的,也即不能存在事件之间的相互依赖
计算⽅法:
按ve,vl,ee,el的次序计算
ve,ee从起点到终点顺着边的⽅向进⾏计算,vl,el则从终点到起点逆着边的⽅向进⾏计算
ve[x]=max(ve[x1]+e1,ve[x2]+e2,...,ve[xn]+en)其中xi是有边指向x的顶点,ei是从xi指向x的边
vl[x]=min(vl[x1']-e1',vl[x2']-e2',...,vl[xn']-en')
ee[x]=ve[x]
el[x]=vl[xi']-ei'
所有ee[x]=el[x]的边x都是关键路径上的边,它们代表关键活动(关键路径可以不⽌⼀条)。
数据结构关键路径例题
数据结构关键路径例题10 题1. 有一个AOE 网,顶点表示事件,弧表示活动,弧上的权值表示活动的持续时间。
求该AOE 网的关键路径。
-首先计算每个事件的最早发生时间ve 和最晚发生时间vl,然后确定活动的最早开始时间e 和最晚开始时间l,e = ve(活动起点事件),l = vl(活动终点事件) -活动持续时间,当 e = l 时,该活动在关键路径上。
2. 给出一个复杂的AOE 网,其中包含多个并行的活动路径。
找出关键路径并分析其对项目进度的影响。
-同样按照计算事件时间和活动时间的方法确定关键路径,关键路径决定了项目的最短完成时间,任何关键活动的延迟都会导致整个项目的延迟。
3. 在一个AOE 网中,某些活动的持续时间可能会发生变化。
分析这种变化对关键路径的影响。
-当活动持续时间变化时,重新计算事件时间和活动时间,确定新的关键路径。
如果关键活动的持续时间增加,项目完成时间也会增加;如果非关键活动的持续时间增加,只要不超过其总时差,不会影响项目完成时间。
4. 有多个相互关联的AOE 网,代表不同的子项目。
求合并后的关键路径。
-将多个AOE 网合并为一个大的AOE 网,然后按照常规方法计算关键路径。
合并后的关键路径决定了整个项目组合的最短完成时间。
5. 给定一个AOE 网,其中某些活动有前置条件和后置条件。
求关键路径并考虑这些条件对项目进度的影响。
-在计算关键路径时,要考虑活动的先后顺序,确保前置活动完成后才能进行后置活动。
关键路径上的活动必须严格按照顺序执行,任何延误都会影响项目进度。
6. 在一个AOE 网中,增加一个新的活动。
求新的关键路径。
-将新活动加入到AOE 网中,重新计算事件时间和活动时间,确定新的关键路径。
新活动可能会改变关键路径,也可能不影响关键路径,具体取决于其在网中的位置和持续时间。
7. 已知一个AOE 网的关键路径长度,现在要缩短项目的完成时间。
确定哪些活动可以缩短以及缩短多少时间不会影响关键路径。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//求AOE网络中的关键路径算法
#include <cstdio>
#include <cstring>
#define MAXN 100 //顶点个数的最大值
#define MAXM 200 //边数的最大值
struct ArcNode
{
int to, dur, no; //边的另一个顶点,持续时间,活动序号
ArcNode *next;
};
int n, m; //顶点个数、边数
ArcNode* List1[MAXN]; //每个顶点的边链表表头指针(出边表) ArcNode* List2[MAXN]; //每个顶点的边链表表头指针(入边表) int count1[MAXN]; //各顶点的入度
int count2[MAXN]; //各顶点的出度
int Ee[MAXN]; //各事件的最早可能开始时间
int El[MAXN]; //各事件的最迟允许开始时间
int e[MAXM]; //各活动的最早可能开始时间
int L[MAXM]; //各活动的最迟允许开始时间
void CriticalPath( ) //求关键路径
{
//拓扑排序求Ee
int i, j, k;
int top1 = -1;
ArcNode* temp1;
memset( Ee, 0, sizeof(Ee) );
for( i=0; i<n; i++ )
{
if( count1[i]==0 )
count1[i] = top1, top1 = i;
}
for( i=0; i<n; i++ )
{
if( top1==-1 )
{
printf( "Network has a cycle!\n" ); return;
}
else
{
j = top1; top1 = count1[top1];
temp1 = List1[j];
while( temp1!=NULL )
{
k = temp1->to;
if( --count1[k]==0 )
count1[k] = top1, top1 = k;
if( Ee[j] + temp1->dur > Ee[k] ) //有向边<j,k> Ee[k] = Ee[j] + temp1->dur;
temp1 = temp1->next;
}//end of while
}//end of else
}//end of for
//逆拓扑排序求El
int top2 = -1;
ArcNode* temp2;
for( i=0; i<n; i++ )
{
El[i] = Ee[n-1];
if( count2[i]==0 )
count2[i] = top2, top2 = i;
}
for( i=0; i<n; i++ )
{
j = top2; top2 = count2[top2];
temp2 = List2[j];
while( temp2!=NULL )
{
k = temp2->to;
if( --count2[k]==0 )
count2[k] = top2, top2 = k;
if( El[j] - temp2->dur < El[k] ) //有向边<k,j> El[k] = El[j] - temp2->dur;
temp2 = temp2->next;
}//end of while
}//end of for
//求各活动的e[k]和L[k]
memset( e, 0, sizeof(e) ); memset( L, 0, sizeof(L) ); printf( "The critical activities are:\n" );
for( i=0; i<n; i++ ) //释放边链表上各边结点所占用的存储空间{
temp1 = List1[i];;
while( temp1!=NULL )
j = temp1->to; k=temp1->no; //有向边<i,j>
e[k] = Ee[i]; L[k] = El[j] - temp1->dur;
if( e[k]==L[k] )
printf( "A%d : %d->%d\n", k, i, j );
temp1 = temp1->next;
}
}
}
int main( )
{
int i, u, v, w; //循环变量、边的起点和终点
scanf( "%d%d", &n, &m ); //读入顶点个数n,边数
memset( List1, 0, sizeof(List1) ); memset( List2, 0, sizeof(List2) );
memset( count1, 0, sizeof(count1) ); memset( count2, 0, sizeof(count2) );
ArcNode *temp1, *temp2;
for( i=0; i<m; i++ )
{
scanf( "%d%d%d", &u, &v, &w ); //读入边的起点和终点
count1[v]++;
temp1 = new ArcNode; //构造邻接表
temp1->to = v; temp1->dur = w;
temp1->no = i+1; temp1->next = NULL;
if( List1[u]==NULL ) List1[u] = temp1;
else{ temp1->next = List1[u]; List1[u] = temp1; }
count2[u]++;
temp2 = new ArcNode; //构造邻接表
temp2->to = u; temp2->dur = w;
temp2->no = i+1; temp2->next = NULL;
if( List2[v]==NULL ) List2[v] = temp2;
else{ temp2->next = List2[v]; List2[v] = temp2; } }
CriticalPath( );
for( i=0; i<n; i++ ) //释放边链表上各边结点所占用的存储空间
{
temp1 = List1[i]; temp2 = List2[i];
while( temp1!=NULL )
{
List1[i] = temp1->next; delete temp1; temp1 = List1[i];
}
while( temp2!=NULL )
List2[i] = temp2->next; delete temp2; temp2 = List2[i];
}
}
return 0;
}
代码来自。