7.5 拓扑排序及关键路径
title: 数据结构 | 图-5 | 拓扑排序
date: 2019-11-27 17:14:58
tags: 数据结构
拓扑排序、关键路径
拓扑排序
背景
- 顶点——表示课程
- 有向弧——表示先决条件,若课程i是课程j的先决条件,则图中有弧<i,j>
- 拓扑排序
学生应按怎样的顺序学习这些课程,才能无矛盾、顺利地完成学业
定义
AOV网
用顶点表示活动,用弧表示活动间优先关系的有向图称为顶点表示活动的网(Activity On Vertex network),简称AOV网。
若<vi,vj>是图中有向边,则vi是vj的直接前驱,vj是vi的直接后继;
AOV网中不允许有回路,这意味着某项活动以自己为先决条件;
拓扑排序的定义
把AOV网络中各顶点按照它们相互之间的优先关系排列成一个线性序列的过程叫拓扑排序
-拓扑排序应用
检测AOV网中是否存在环:
对有向图构造其顶点的拓扑有序序列,若网中所有顶点都在它的拓扑序列,则该AOV网必定无环
方法
- 在有向图中选一个没有前驱的顶点且输出之;
- 从图中删除该顶点和所有以它为尾的弧;
- 重复上述两步,直至全部顶点均已输出,或图中不存在无前驱的顶点。
算法实现
以邻接表作存储结构,
- 把邻接表中所有入度为0的顶点进栈;
- 栈非空时,输出栈顶元素Vj并退栈;
- 在邻接表中查找Vj的直接后继Vk,把Vk的入度减1;若Vk的入度为0则进栈;
- 重复上述操作直至栈空为止。
若栈空时输出的顶点个数不是n,则有向图有环;否则,拓扑排序完毕
Status TopologicalSort(ALGraph G) {
for(i = 0;i <G.vexnum; ++ i ) //查找入度为为零的顶点
if(! Indegree[i]) //把入度为零的顶点进栈
push (S,i );
count = 0; //计数器置0
while (! StackEmpty(s)) {
pop(s, i);
printf(i,Gvextices[i].data);
++count;//输出顶点、计数
for(p=G.vextices[i].firstarc; p ; p = p->nextarc) {
k = p->adjvex; //得到与输出顶点相邻接的顶点下标
if(! (--indegree[k]))
push( S,k);
//将邻接点的入度减1,将为零的入栈
}//for
}//while
if (count<G.vexnum)
return ERROR;//该图有回路
else return OK;
}//TopologicalSort
关键路径
背景
- 把工程计划表示为有向图,用顶点表示事件,弧表示活动;
每个事件表示在它之前的活动已完成,在它之后的活动可以开始;
事件 V1——表示整个工程开始
事件 V9——表示整个工程结束
其中,T为所有以第j个顶点为头的弧的集合。
定义
AOE网(Activity On Edge)
边表示活动的网。AOE网是一个带权的有向无环图,其中顶点表示事件,弧表示活动,权表示活动持续时间
路径长度
路径上各活动持续时间之和。
关键路径
路径长度最长的路径叫关键路径。
Ve——事件Vj的最早发生时间Ve(j)
- 源点的最早发生时间为0,其余任一顶点Vj的最早发生时间,等于从源点出发沿着各条路径达到Vj时每条路径上权的累加和的最大值。计算公式为:
Ve(j)=Max{ve(i) + dut(<i ,j>)}
<i,j>∈T, j = 1,2,3…n-1
Vl—事件的最迟发生时间Vl(j)
- 汇点的最迟发生时间Vl[n]等于汇点的最早发生时间Ve[n]。
其余任一顶点Vi的最迟发生时间等于从汇点的最迟发生时间中减去从顶点Vi出发沿着各条路径达到汇点时,每条路径上权的累加和的最大值。
最迟发生时间一般用下列公式计算:
Vl(i)=Min{vl(j)-dut(<i ,j>)}
<i,j> ∈S, i = n -2,..,0
其中, S为所有以第i个顶点为尾的弧的集合。
e(i)——表示活动ai的最早开始时间
l(i)——表示活动ai的最迟开始时间
设活动ai用弧<j,k>表示,
其持续时间记为:dut(<j,k>)
则有:(1)e(i)=Ve(j) //最早开始时间是弧尾事件的最早发生时间
(2)l(i)=Vl(k)-dut(<j,k>)//最迟开始时间是弧头事件的最晚发生时间减去活动的持续时间,即弧的权值
- l(i)-e(i)——表示完成活动ai的时间余量
- 关键活动——关键路径上的活动叫关键活动,即l(i)=e(i)的活动
算法实现
描述
- 输入顶点和弧信息,建立其邻接表
- 计算每个顶点的入度
- 对其进行拓扑排序
- 排序过程中求顶点的Ve[i]
- 将得到的拓扑序列进栈
- 按逆拓扑序列求顶点的Vl[i]
- 计算每条弧的e[i]和l[i],找出e[i]=l[i]的关键活动
……没看,待更新