“抽象”《大话数据结构》第七章——关键路径

关键路径介绍

AOE网:在一个表示工程的带权有向图中,用顶点表示事件(比如:发动机造好啦),用有向边表示活动(比如:我正在造发动机),用边上的权值表示活动的持续时间(比如:造发动机需要3天),这种有向图的边表示的活动的往,就是AOE网。
这个网有一个源点和一个汇点,源点到汇点的最长路径称作关键路径,关键路径上的活动称为关键活动。

关键路径算法原理

首先需要对拓扑排序进行改进,用于求出etv[]数组。

int *etv;
int top2;
int *stack2;
int TopologicalSortloth(GraphVerter G)
{
	EdgeNode *e;
	int i;
	int top = 0;
	int gettop;
	int count = 0;
	int *stack;
	stack = (int *)malloc(G.numvertexes * sizeof(int));
	for(i = 0; i < G.numvertexes; i++)
	{
		if(G.verter[i]->in == 0)
			stack[++top] = i;
	}
	top2 = 0;
	etv = (int *)malloc(G.numvertexes * sizeof(int));
	for(i = 0; i < G.numvertexes; i++)
		etv[i] = 0;
	stack2 = (int *)malloc(G.numvertexes * sizeof(int));

	while(top != 0)
	{
		gettop = stack[top--];
		printf("%d",G.verter[gettop]->data);
		count++;
		stack2[++top2] = gettop;
		for(e = G.verter[gettop]->firstedge; e ; e = e->next)
		{
			G.verter[e->adjvex]->in--;
			if(G.verter[e->adjvex]->in == 0)
				stack[++top] = e->adjvex;
			if((etv[gettop]+e->weight) > etv[e->adjvex])
				etv[e->adjvex] = etv[gettop]+e->weight;
		}
	}
	if(count < G.numvertexes)
		return 0;
	else
		return 1;
}

关键路径算法:
1 首先调用TopologicalSortloth(GraphVerter G)函数,得到etv[]数组,以及stack2栈。
2 初始化ltv[]数组,全部赋值为最后一个顶点的最早发生时间。
3 在top2不为0的情况下开始循环,后一个活动最晚开始时间减去它的权值weight,得到前一个活动的最晚开始时间(注意最后一个顶点是一定在关键路径上的,所以最早开始时间和最晚开始时间是必然相等的),都存在ltv[]数组里面。
4 开始对每一个顶点的邻接表进行访问,顶点表是邻接表的前继顶点所在地,前继顶点发生的时间在etv,后接顶点发生的时间点在ltv,后接顶点减去weight,可能会等于etv,如果相等,则这条边在关键路径上。
代码如下

void CriticalPath(GraphVerter G)
{
	EdgeNode *e;
	int i,gettop,k,j;
	int ete,lte;
	TopologicalSortloth(G);
	ltv = (int *)malloc(G.numvertexes * sizeof(int));
	for(i = 0; i < G.numvertexes; i++)
	{
		ltv[i] = etv[G.numvertexes - 1];
	}
	while(top2 != 0)
	{
		gettop = stack2[top2--];
		for(e = G.verter[gettop]->firstedge; e ; e = e->next)
		{
			k = e->adjvex;
			if(ltv[k] - e->weight < ltv[gettop])
				ltv[gettop] = ltv[k] - e->weight;
		}

	}
	for(j = 0; j < G.numvertexes; j++)
	{
		for(e = G.verter[j]->firstedge; e ; e = e->next)
		{
			k = e->adjvex;
			ete = etv[j];
			lte = ltv[k] - e->weight;
			if(ete == lte)
				printf("<%d,%d> length : %d",G.verter[j]->data,G.verter[k]->data,e->weight);
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值