拓扑排序

一、拓扑排序

设G=(V,E)是一个具有n个顶点的有向图,V中顶点序列v1,v2,…,vn称为一个拓扑序列

当且仅当该顶点序列满足下列条件:

若<i,j>是图中的边(即从顶点i到j有一条路径),则在拓扑序列中顶点i必须排在顶点j之前。

在一个有向图中找一个拓扑序列的过程称为拓扑排序。        


例如,计算机专业的学生必须完成一系列规定的基础课和专业课才能毕业,假设这些课程的名称与相应代号有如下关系:


课程之间的先后关系可用有向图表示:



对这个有向图进行拓扑排序可得到一个拓扑序列:C1-C3-C2-C4-C7-C6-C5。

也可得到另一个拓扑序列:C2-C7-C1-C3-C4-C5-C6,还可以得到其他的拓扑序列。

学生按照任何一个拓扑序列都可以顺序地进行课程学习。


拓扑排序步骤:

(1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它。

(2)从网中删去该顶点,并且删去从该顶点发出的全部有向边。

(3)重复上述两步,直到剩余的网中不再存在没有前驱的顶点为止。


为了实现拓扑排序的算法,对于给定的有向图,采用邻接表作为存储结构,为每个顶点设立一个链表,每个链表有一个表头节点,这些表头节点构成一个数组,表头节点中增加一个存放顶点入度的域count

即将邻接表定义中的VNode类型修改如下: 

     typedef struct          //表头节点类型
  {   eertex data;         //顶点信息
      int count;           //存放顶点入度
      ArcNode *firstarc;   //指向第一条弧

   } VNode;

void  TopSort(VNode adj[],int n)
{  int i,j;int St[MAXV],top=-1;  //栈St的指针为top
   ArcNode *p;
   for (i=0;i<n;i++)
     if (adj[i].count==0)    //入度为0的顶点入栈
     { top++; St[top]=i; }
     while (top>-1)      //栈不为空时循环
     {  i=St[top];top--; //出栈
        printf("%d ",i); p=adj[i].firstarc;
        while (p!=NULL) 
        {  j=p->adjvex; adj[j].count--; 
           if (adj[j].count==0) 
     {   top++;  St[top]=j;  }
           p=p->nextarc;     //找下一个相邻顶点
        }
     }


二、AOE网与关键路径

若用前面介绍过的带权有向图(DAG)描述工程的预计进度以顶点表示事件,有向边表示活动,边e的权c(e)表示完成活动e所需的时间(比如天数),或者说活动e持续时间。

图中入度为0的顶点表示工程的开始事件(如开工仪式),出度为0的顶点表示工程结束事件。则称这样的有向图为AOE网(Activity On Edge)。 

整个工程完成的时间为:从有向图的源点到汇点的最长路径,具有最大长度的路径叫关键路径。

“关键活动”指的是:该边上的权值增加,将使有向图上的最长路径的长度增加。

注意:在一个AOE网中,可以有不止一条的关键路径。 


计算各事件的ee(v)如下:
ee(A)=0

ee(B)=ee(A)+c(a1)=6

ee(C)=ee(A)+c(a2)=4

ee(D)=ee(A)+c(a3)=5

ee(E)=MAX(ee(B)+c(a4),ee(C)+c(a5)}=MAX{7,5}=7

ee(F)=ee(E)+c(a7)=16

ee(G)=ee(E)+c(a8)=14

ee(H)=ee(D)+c(a6)=7

ee(I)=MAX{ee(F)+c(a10),ee(G)+c(a11),ee(H)+c(a9)}=MAX(18,18,11}=18

由此可知,关键活动有a11、a10、a8、a7、a4、a1,因此关键路径有两条:A-B-E-F-I和A-B-E-G-I。 


(1)事件v的最早开始时间:规定源点事件的最早开始时间为0。定义图中任一事件v的最早开始时间(early event) ee(v)等于x、y、z到v所有路径长度的最大值

(2)事件v的最迟开始时间:定义在不影响整个工程进度的前提下,事件v必须发生的时间称为v的最迟开始时间(late event) ,记作le(v)。le(v)应等于ee(y)与v到汇点的最长路径长度之差

(3)活动a的最早开始时间e(a)指该活动起点x事件的最早开始时间,即:e(a)=ee(x)

(4)活动a的最迟开始时间l(a) 指该活动终点y事件的最迟开始时间与该活动所需时间之差 ,即:l(a)=le(y)-c

(5)关键活动:对于每个活动a,求出d(a)=l(a)-e(a),若d(a)为0,则称活动a为关键活动。 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值