求拓扑图关键路径

求解关键路径往往用于在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),如果有

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;
		}
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值