有向无环图及其应用

有向无环图及其应用

  • 1.有向无环图的用处
  • 2.AOV网络以及拓扑排序
    • 2.1. AOV网络
    • 2.2. 拓扑序列
  • 3.AOE网络及关键路径

1.有向无环图的用处

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

2.AOV网络以及拓扑排序

2.1. AOV网络

有向无环图及其应用_第1张图片

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

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)//处理弧,求弧头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)//处理弧,求弧尾的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条弧的ee(i)=ve(j),el(i)=vl(k)-weight()
	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
}

你可能感兴趣的:(数据结构,图)