在一个表示工程的有向图中,用顶点表示活动,用弧表示活动之间的优先关系,这样的有向图为顶点表示活动的网,我们称之为AOV网 ( Activity On Vertex Network )。在AOV网(拓扑排序)的基础上,AOE网(关键路径算法+拓扑排序)为一个全新的概念。
在一个表示工程的带权有向图中,用顶点表示事件,用有向边表示活动,用边上的权值表示活动的持续时间,这种有向图的边表示活动的网,便被称之为AOE网 ( Activity On Edge Network )。
AOE网是要建立在活动之间的制约关系没有矛盾的基础之上,再来分析完成整个工程至少需要多少时间,或者为缩短完成工程所需时间应当加快哪些活动等问题的。
我们把路径上各个活动所持续的时间之和称为关键路径,从源点到汇点具有的最大长度的路径称为关键路径,在关键路径上的活动称为关键活动。
关键路径算法原理
假设一个学生放学回家之后,到睡觉前只有4个小时的空闲·,而完成家庭作业需要两小时。
此例的详解见下图(引用自《大话数据结构》)。
也就是说,我们只需要找到所有活动的最早开始时间和最晚开始时间,并且比较它们,如果相当就意味着此活动是关键活动,活动间的路径为关键路径。如果不等,则就不是。
为此,我们需要定义如下参数:
1.事件的最早发生时间etv:顶点vk的最早发生时间。
2.事件的最晚发生时间ltv:顶点vk的最晚发生时间。
3.活动的最早开工时间ete:弧ak的最早发生时间。
4.活动的最晚开工时间lte:弧ak的最晚发生时间。
由1和2可以求得3和4,然后再根据ete[k]
是否与lte[k]
相等来判断ak是否是关键活动。
关键路径算法
所用的数据结构仍为邻接表(拓扑排序所用的数据结构也为邻接表,但增加了一个入度域,此处仍保留入度域),这里的邻接表增加了weight域,用来存储弧的权值。
(邻接表复习:邻接表上的边表结点与adjvex结点是由同一条弧相连的,即通俗来讲,顶点表上每一个结点,后面跟着的所有边表结点,与该顶点皆为邻点。)
求事件的最早发生时间etv的过程,就是从头至尾拓扑排序的过程,因此,求关键路径之前,需要先调用一次拓扑排序计算etv和拓扑排序列表(存储在一个栈中)。
为此,程序开始处先声明几个全局变量的伪代码。
int *etv,*ltv;//存储事件最早发生时间与最迟发生时间的数组
int *stack2;//用于存储拓扑序列的栈
int top2;//用于stack2的指针
//注:述皆为伪代码
存储图的数据结构~邻接表代码:
#include <iostream>
using namespace std;
typedef int VertexType;
typedef int EdgeType;
const int MAXVEX = 105;
struct EdgeNode{
//定义边表结构
int adjvex;
EdgeNode *next;
EdgeType weight;//存储边的权值
};
typedef struct//定义顶点表(一维数组实现)结构
{
int in;
VertexType data;
EdgeNode *Fi