/** * Computes topological order and event earliest times. * * Args: * graph: AOE network stored by adjacency list. * topoOrder: Output topological sequence. * ve: Output earliest occurrence time of each event. * * Returns: * true if the network is acyclic. * false if a directed cycle exists. */ boolTopologicalOrderAndVe(const ALGraph *graph, int topoOrder[], int ve[]) { int inDegree[MAX_VERTEX_NUM] = {0}; Queue queue; int count = 0;
InitQueue(&queue);
for (int v = 0; v < graph->vexNum; ++v) { ve[v] = 0; }
for (int i = 0; i < graph->edgeNum; ++i) { ++inDegree[graph->edges[i].to]; }
for (int v = 0; v < graph->vexNum; ++v) { if (inDegree[v] == 0) { EnQueue(&queue, v); } }
while (!IsEmpty(&queue)) { int current = DeQueue(&queue); topoOrder[count++] = current;
for (int edgeIndex = graph->head[current]; edgeIndex != -1; edgeIndex = graph->edges[edgeIndex].next) { int next = graph->edges[edgeIndex].to; int weight = graph->edges[edgeIndex].weight;
/** * Computes latest occurrence times and prints critical activities. * * Args: * graph: AOE network. * topoOrder: Topological sequence. * ve: Earliest occurrence time of each event. * vl: Output latest occurrence time of each event. */ voidCriticalPath(const ALGraph *graph, constint topoOrder[], constint ve[], int vl[]) { int sink = topoOrder[graph->vexNum - 1];
for (int v = 0; v < graph->vexNum; ++v) { vl[v] = ve[sink]; }
for (int i = graph->vexNum - 1; i >= 0; --i) { int current = topoOrder[i];
for (int edgeIndex = graph->head[current]; edgeIndex != -1; edgeIndex = graph->edges[edgeIndex].next) { int next = graph->edges[edgeIndex].to; int weight = graph->edges[edgeIndex].weight;
for (int i = 0; i < graph->edgeNum; ++i) { int from = graph->edges[i].from; int to = graph->edges[i].to; int weight = graph->edges[i].weight; int earliest = ve[from]; int latest = vl[to] - weight; int slack = latest - earliest;
if (slack == 0) { printf("critical activity: V%d -> V%d, weight=%d\n", from, to, weight); } } }