求解关键路径往往用于在AOE网图中从起始点到结束点做完所有事所需要的最小时间
求解关键路径的具体算法如下:
(1)从开始顶点v0出发,假设开始顶点最早开始时间ve(0) = 0,然后按照拓扑有序求出其它各顶点i的最早开始时间ve(i),
如果得到的拓扑序列中顶点书目小于图中的顶点数,则表示图中存在回路,算法结束,否则继续执行
(2)初始化最晚发生时间vl(i)为结束顶点最早发生时间,从结束顶点vn出发,假设结束顶点最晚开始时间vl(n - 1) = ve(n - 1)
(结束顶点最晚开始时间等于结束顶点最早开始时间,最早开始时间在(1)已求),然后按拓扑有序求出其它各顶点i的最晚发生时间vl(i)
(3)根据各顶点最早开始时间ve(i)和最晚开始时间vl(i)依次求出每条狐的最开始时间e(k)和最晚发生时间l(k),如果有
求解关键路径的具体算法如下:
(1)从开始顶点v0出发,假设开始顶点最早开始时间ve(0) = 0,然后按照拓扑有序求出其它各顶点i的最早开始时间ve(i),
如果得到的拓扑序列中顶点书目小于图中的顶点数,则表示图中存在回路,算法结束,否则继续执行
(2)初始化最晚发生时间vl(i)为结束顶点最早发生时间,从结束顶点vn出发,假设结束顶点最晚开始时间vl(n - 1) = ve(n - 1)
(结束顶点最晚开始时间等于结束顶点最早开始时间,最早开始时间在(1)已求),然后按拓扑有序求出其它各顶点i的最晚发生时间vl(i)
(3)根据各顶点最早开始时间ve(i)和最晚开始时间vl(i)依次求出每条狐的最开始时间e(k)和最晚发生时间l(k),如果有
e(k) = l(k),则为关键活动。关键活动组成的路径则为关键路径
typedef struct
{
int adjVex;
int weight;
edgeNode * next;
}edgeNode;
typedef struct
{
edgeNode *firstEdge;
char data;
}node;
typedef struct
{
node vertex[1000];
int numVertex;
}graph;
//计算图g中每个节点的入度,保存到inDegree中
void findIndegree(graph &g, vector<int>&inDegree)
{
inDegree.assign(g.numVertex, 0);
for(int i = 0; i < g.numVertex; i++)
{
for(edgeNode *e = g.vertex[i].firstEdge; e; e = e->next)
inDegree[e->adjVex]++;
}
}
// 求时间最早发生时间和拓扑排序,最早发生时间保存到etv中,将排序结果依次保存到栈s中
bool topoLogicalSort(graph &g, vector<int> & etv, stack<int> &s)
{
vector<int> indegree;
stack<int> t;
etv.assign(g.numVertex, INT_MIN);
findIndegree(g, indegree);
for(int i = 0; i < g.numVertex; i++)
{
if(indegree[i] == 0)
t.push(i), etv[i] = 0;
}
int count = 0;
while(!t.empty())
{
int k = t.top();
s.push(k);
count++;
t.pop();
for(edgeNode *e = g.vertex[k].firstEdge; e; e = e->next)
{
int x = e->adjVex;
if((--indegree[x]) == 0)
{
t.push(x);
etv[x] = max(etv[x], etv[t] + e->weight);
}
}
}
if(count < g.numVertex)
return false;
else return true;
}
void criticalPath(graph &g)
{
vector<int> etv, ltv;//时间最早发生时间和最晚发生时间数组
stack<int> s;
//拓扑排序与求最早发生时间,拓扑排序保存在栈s中
topoLogicalSort(g, etv, s);
ltv.assign(g.numVertex, INT_MAX);
ltv[g.numVertex - 1] = etv[g.numVertex - 1];
//求最晚发时间
while(!s.empty())
{
int k = s.top();
s.pop();
for(edgeNode *e = g.vertex[k].firstEdge; e; e = e->next)
{
ltv[e->adjVex] = min(ltv[k] - e->weight, ltv[e->adjVex]);
}
}
//输出最早发生时间==最晚发生时间的事件,即关键路径
for(int i = 0; i < g.numVertex; i++)
{
for(edgeNode *e = g.vertex[i].firstEdge; e; e = e->next)
{
int ete, lte;//事件最早发生时间和最晚发生时间
int k = e->adjVex;
ete = etv[i];
lte = ltv[k] - e->weight;
if(ete == lte)
cout << "<V" << g.vertex[i].data << "->V" << g.vertex[k].data << "):" << e->weight << endl;
}
}
}