AOE网:在一个表示工程的带权有向图中,用顶点表示事件,用有向边表示活动,用边上的权值表示活动的持续时间,这种有向图的边表示活动的网,我们称之为AOE网。
把路径上各个活动所持续的时间之和称为路径长度,从源点到汇点具有最大长度的路径称为关键路径,在关键路径上的活动叫关键活动。
关键路径算法:
我们需要定义如下几个参数:
1、事件的最早发生时间etv:即顶点v的最早发生时间。
2、事件的最晚发生时间ltv:即顶点v的最晚发生时间。也就是每个顶点对应的事件的最晚需要开始的时间,超出此时间将会延误整个工期。
3、活动的最早开工时间ete:即弧a的最早发生时间。
4、活动的最晚开工时间lte:即弧的最晚发生时间,也就是不推迟工期的最晚开工时间。
有1和2可以求得3和4,然后再根据ete[k]是否与lte[k]相等来判断a是否是关键活动。
求etv的过程,就是从头到尾找拓扑序列的过程。求ltv就是把拓扑序列倒过来的过程。
此算法的时间复杂度是O(n+e)。
typedef struct EdgeNode
{
int adjvex;
int weight;
struct EdgeNode *next;
} EdgeNode;
typedef struct VertexNode
{
int in;
int data;
EdgeNode *firstedge;
} VertexNode, AdjList[MAXVEX];
typedef struct
{
AdjList adjList;
int numVertexes, numEdges;
} graphAdjList, *GraphAdjList;
int *etv, *ltv;
int *stack2;
int top2;
Status TopologicalSort(GraphAdjList GL)
{
int i, k, gettop;
int count = 0;
int *stack;
int top = 0;
EdgeNode *e;
stack = (int *)malloc(GL->numVertexes * sizeof(int));
for (i = 0; i < GL->numVertexes; i++)
if (GL->adjList[i].in == 0)
stack[++top] = i;
stack2 = (int *)malloc(GL->numVertexes * sizeof(int));
etv = (int *)malloc(GL->numVertexes * sizeof(int));
top2 = 0;
for (i = 0; i < GL->numVertexes; i++)
etv[i] = 0;
while (top != 0)
{
gettop = stack[top--];
count++;
stack2[++top2] = gettop;
for (e=GL->adjList[gettop].firstedge; e; e = e->next)
{
k = e->adjvex;
if (!(--GL->adjList[k].in))
stack[++top] = k;
if (e[k] < e[gettop] + e->weight)
e[k] = e[gettop] + e->weight;
}
}
if (count < GL->numVertexes)
return ERROR;
else
return OK;
}
void CriticalPath(GraphAdjList GL)
{
int i, j, k, gettop, ete, lte;
EdgeNode *e;
TopologicalSort(GL);
ltv = (int *)malloc(GL->numVertexes * sizeof(int));
for (i = 0; i < GL->numVertexes; i++)
ltv[i] = etv[GL->numVertexes - 1];
while (top2 != 0)
{
gettop = stack2[top2--];
for (e = GL->adjList[gettop].firstedge; e; e = e->next)
{
k = e->adjvex;
if (ltv[gettop] > ltv[k] - e->weight)
ltv[gettop] = ltv[k] - e->weight;
}
}
for (j = 0; j < GL->numVertexes; j++)
for (e = GL->adjList[j].firstedge; e; e = e->next)
{
k = e->adjvex;
ete = etv[j];
lte = ltv[k] - e->weight;
if (ete == lte)
printf("<v%d v%d> length %d", GL->adjList[j].data, GL->adjList[k].data, e->weight);
}
}