有向无环图及其应用

1.有向无环图的用处

  1. 有向无环图是描述含有公共子式的表达式的有效工具
  2. 有向图是描述一项工程或系统过程控制的有效工具

2.AOV网络以及拓扑排序

2.1. AOV网络

在这里插入图片描述

顶点是活动,弧表示优先关系。

2.2. 拓扑序列

将弧尾的结点拍在弧头的前面,没有优先关系的都无所谓。计算机是从小到大。
【算法实现】

//AOV网图及拓扑排序
int top_sort(ALGraph G)
{
	Stack S; StackInit(&S);//初始化顺序栈
	int m = 0;
	for (int i = 0; i < G.arcNum; i++)
		if (G.adjlist[i].id == 0)StackPush(&S, i);
	while (!StackEmpty(&S))
	{
		int v = StackTop(&S); StackPop(&S);
		m++;
		ArcNode* p = G.adjlist[v].firstArc;
		while (p != NULL)
		{
			int w = p->adjvex; G.adjlist[w].id--;
			if (G.adjlist[w].id == 0)StackPush(&S, w);
			p = p->nextArc;
		}
	}
	if (m < G.vexNum)
	{
		StackDestroy(&S);
		return 0;
	}
	return 0;
	StackDestroy(&S);
}

3.AOE网络及关键路径

在这里插入图片描述
【算法实现】

//求关键路径的算法
void critical_patch( ALGraph G)
{
	//为求ve[i],用栈s1存放入度为0的顶点序号
	//为求vl[i],用栈s2存放拓扑序列的顶点序号
	Stack s1, s2; StackInit(&s1); StackInit(&s2);
	int i = 0, j = 0, k = 0, ve[20] = { 0 }, vl[20] = { 0 }, ee = 0, el = 0;
	ArcNode* p = NULL;
	char tag = 0;
	findiInDegree(G);//求各个顶点的入度
	for (i = 0; i < G.vexNum; i++)//入度为0的顶点序号进栈
		if (G.adjlist[i].id == 0)StackPush(&s1, i);
	for (i = 0; i < G.vexNum; i++)ve[i] = 0;//ve初始化
	//按拓扑序列求各顶点的ve值,对每一条弧求弧头的ve,弧头取最大值
	while (!StackEmpty(&s1))//在拓扑排序的过程中求ve
	{
		j = StackTop(&s1); StackPop(&s1);//取拓扑序列顶点序号
		StackPush(&s2, j);//存拓扑序列顶点序号
		p = G.adjlist[j].firstArc;
		while (p != NULL)//处理弧<j,k>,求弧头k的ve
		{
			k = p->adjvex;
			G.adjlist[k].id--;
			if (G.adjlist[k].id == 0)StackPush(&s1, k);
			if (ve[j] + p->weight > ve[k])ve[k] = ve[j] + p->weight;
			p = p->nextArc;
		}//end_while(p!=NULL)
	}//end_while (!StackEmpty(&s1)),求ve[j]完成
	//用ve(汇点)对vl进行初始化
	for (i = 0; i < G.vexNum; i++)vl[i] = ve[s2._top];
	//按逆拓扑序列求各顶点的vl值,对每一个条弧求弧尾的vl,弧尾相同的取最小值
	while (!StackEmpty(&s2))
	{
		j = StackTop(&s2); StackPop(&s2);
		p = G.adjlist[j].firstArc;
		while (p != NULL)//处理弧<j,k>,求弧尾的vl
		{
			k = p->adjvex;
			if (vl[k] - p->weight < vl[j])vl[j] = vl[k] - p->weight;
			p = p->nextArc;
		}//end_while (p != NULL)
	}//end_while (!StackEmpty(&s2)),求vl[j]完成
	//已知ve[i]、vl[i],求ee和el
	//第i条弧<j,k>的ee(i)=ve(j),el(i)=vl(k)-weight(<j,k>)
	for (j = 0; j < G.vexNum; j++)
	{
		p = G.adjlist[j].firstArc;
		while (p != NULL)
		{
			k = p->adjvex;
			ee = ve[j]; el = vl[k] - p->weight;
			if (ee == el)tag = 'y';//标记关键活动
			else tag = 'n';
			printf("活动:%c->%c  ee=%-4d el=%-4d %c\n", G.adjlist[j].vertex, G.adjlist[k].vertex, ee, el, tag);
			p = p->nextArc;
		}//end_while
	}//end_for
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杰深入学习计算机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值