关键路径

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

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值