数据结构 - 拓扑排序

应用背景

学生选修课程问题

顶点——表示课程

有向弧——表示先决条件,若课程i是课程j的先决条件,则图中有弧(i,j)

学生应按怎样的顺序学习这些课程,才能无矛盾、顺利地完成学业——拓扑排序

     拓扑序列是有向无环图中各顶点构成的有序序列。该序列满足如下条件:如果图中一顶点vi到另一顶点vj存在一条路径,那么vj在此图的拓扑排序序列中位于vi之后。

有向无环图(DAG)和 AOV网

有向无环图”(Directed Acyclic Graph,简称DAG

AOV网 (Activity On Vertex network): 一个“可行的” AOV 网络必须是DAG。否则图中有回路,从而就不能确定回路中的活动究竟哪个先实施。

顶点表示活动,

弧表示活动间的优先关系,

注意:

AOV网中的弧表示活动之间存在某种制约关系:若

void ToplogicalSort ( Graph G, int TopNum[ ] )
{
    int Counter;    /* 拓扑序号,用以标识每个顶点输出的次序*/
    int v, w;
    int *InDegree = (int *)malloc( G.n * sizeof(int) );
    GetInDegree(G, InDegree);   /* 计算图G中各顶点的入度 */
    for( Counter = 0; Counter < G.n; Counter++ ) {
        v = FindNewVertexOfDegreeZero( );
        /* 查找入度为0的顶点,若找到,则返回顶点在顶点数组的下标。若找不到入度为0的顶点,返回-1 */
        if ( v == -1 ) {
             printf( “图存在环路”);
             break;
        }
        TopNum[v] = Counter;
        for( G中关于v 的每个邻接点w )
           Indegree[w]--;  /* 与顶点v相连的各顶点的入度减1 */
    }
}
void ToplogicalSort ( GraphAdjList GL, int * TopNum )
{
    Queue queue;    EdgeNode *p;     int Counter = 0;    int v, w;
     //int *InDegree = (int *)malloc( G.n * sizeof(int) );
   //  GetInDegree(G, InDegree);   /* 计算图G中各顶点的入度 */
     queue = InitQueue( GL->numVertexes ); /* 创建空队列 */
     for( v = 0; v <GL->numVertexes; v++ )
          if( GL->adjList[v].in==0 )        EnQueue( &queue, v );
     while( ! QueueEmpty(queue) ) {
           v = DeQueue( &queue);
           TopNum[v] = ++Counter;      /* 赋顶点拓扑排序序号 */
           for( p=GL->adjList[v].firstedge;p!=NULL;p=p->next)
              if( --GL->adjList[p->adjvex].in == 0 )
                  EnQueue( &queue, p->adjvex );
      }
      if( Counter != GL->numVertexes )
          printf( "图存在环路\n" );
      DisposeQueue(&queue);    /* 释放队列空间*/
      //free(InDegree);
}

关键路径

    与AOV网相对应的是AOE(Activity On Edge) ,是边表示活动的有向无环图。
    顶点表示事件(Event),每个事件表示在它之前的活动已完成,在它之后的活动可以开始;
    弧表示活动,弧上的权值表示相应活动所需的时间或费用

AOV网与AOE网

拓扑排序主要是为解决一个工程能否顺利进行的问题。

关键路径是解决工程完成需要的最短时间问题。

AOV网与AOE网的区别:

AOV网,顶点表示活动,边描述活动之间的制约关系

AOE网,边上的权值表示活动持续的时间,

建立在活动之间制约关系没有矛盾的基础上,

讨论完成整个工程至少需要多少时间;或者为缩短完成工程所需时间,应当加快哪些活动等问题。

路径长度—路径上各活动持续时间之和

关键路径—从源点到汇点具有最大路径长度的路径

关键活动—关键路径上的活动。关键活动是影响整个工程的关键,延迟就会影响整个工期的活动。

最早发生时间—设v0是起点,从v0到vi的最长路径长度称为事件vi的最早发生时间,即是以vi为尾的所有活动的最早发生时间。

求AOE中关键路径和关键活动

⑴ 算法思想

① 利用拓扑排序求出AOE网的一个拓扑序列;

② 从拓扑排序的序列的第一个顶点(源点)开始,按拓扑顺序依次计算每个事件的最早发生时间ve(i) ;

从拓扑排序的序列的最后一个顶点(汇点)开始,按逆拓扑顺序依次计算每个事件的最晚发生时间vl(i) ;

求出各活动的最早发生时间e(i)和最晚发生时间l(e),同时求出ai的时间余量,时间余量=0的那些活动就是关键活动。

最短路径

用带权的有向图表示一个交通运输网,图中:

顶点:城市

边:城市间的交通联系

权:此线路的长度或沿此线路运输所花的时间或费用等

问题:

两地之间是否有通路?

在有多条通路的情况下,哪条最短?

将一条路径的起始顶点称为源点,最后一个顶点称为终点。

单源点最短路径

对于给定的有向图G=(V,E)及单个源点V0,求V0到G的其余各顶点的最短路径。
针对单源点的最短路径问题,Dijkstra提出了一种按路径长度递增次序产生最短路径的算法,即迪杰斯特拉(Dijkstra)算法。

求最短路径步骤

初使时令 S={V0},T={其余顶点},T中顶点对应的距离值

若存在 V0,Vi,为V0,Vi弧上的权值

若不存在 V0, Vi,为?

从T中选取一个其距离值为最小的顶点W,加入S

对T中顶点的距离值进行修改:若加进W作中间顶点,从V0到Vi的距离值比不加W的路径要短,则修改此距离值

重复上述步骤,直到S中包含所有顶点,即S=V为止

算法实现

图用带权邻接矩阵存储

数组dist[ ]存放当前找到的从源点V0到每个终点的最短路径长度(这些路径中间只经过集合S中的顶点),其初态为图中直接路径权值

数组pre[ ]表示从V0到各终点的最短路径上,此顶点的前一顶点的序号;若从V0到某终点无路径,则用0作为其前一顶点的序号

时间: 2024-08-23 17:26:05

数据结构 - 拓扑排序的相关文章

7-9-有向图无环拓扑排序-图-第7章-《数据结构》课本源码-严蔚敏吴伟民版

课本源码部分 第7章  图 - 有向无环图拓扑排序 ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接??? <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明        课本源码合辑  链接??? <数据结构>课本源码合辑        习题集全解析  链接??? <数据结构题集>习题解析合辑        本源码引入的文件  链接? Status.h.SequenceStack.c.ALGraph.c    

数据结构课程笔记_拓扑排序

何谓拓扑排序? 由某个集合上的一个偏序得到该集合上的一个全序,这个操作叫做拓扑排序. 如何得到一个有向图的拓扑排序? 按照有向图给出的次序关系,将图中顶点排成一个线性序列,对于有向图中没有限定次序关系的顶点,则可以人为加上任意的次序关系,由此所得顶点的线性序列称之为拓扑有序序列. 如何进行拓扑排序? 1.从有向图中选取一个没有前驱的顶点: 2.从有向图中删去此顶点以及所有以它为尾的弧: 重复上述两步直至图空,或者图中找不到无前驱的顶点为止,后一种情况说明图中有环. 算法中需要用定量描述代替定性概

数据结构:图--拓扑排序

拓扑排序 拓扑排序 在实际应用中,有向图的边可以看做是顶点之间制约关系的描述.把顶点看作是一个个任务,则对于有向边<Vi,Vj>表明任务Vj的完成需等到任务Vi完成之后,也就是说任务Vi先于任务Vj完成.对于一个有向图,找出一个顶点序列,且序列满足:若顶点Vi和Vj之间有一条边<Vi,Vj>,则在此序列中顶点Vi必在顶点Vj之前.这样的一个序列就称为有向图的拓扑序列(topological order). 步骤 从有向图中选取一个没有前驱(入度为0)的顶点输出. 删除图中所有以它为

数据结构:拓扑排序之 确定比赛名词

[BestCoder Round #3 来了!]8月3号19:00~21:00(赛前30分钟停止注册比赛) 确定比赛名次 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 11642    Accepted Submission(s): 4634 Problem Description 有 N个比赛队(1<=N<=500),编号依次为1,

算法与数据结构基础10:C++实现——拓扑排序

一 定义 拓扑排序是对有向无环图(Directed Acyclic Graph简称DAG)顶点的一种排序, 它使得如果存在一条从顶点A到顶点B的路径,那么在排序中B出现在A的后面. 二 先决条件 能够进行拓扑排序图有两个先决条件:有向.无环,即有向无环图. 三 偏序全序 连通图:任意两点之间都存在至少一条边 偏序:非连通图(有向无环图满足偏序关系) 全序:单连通图 四 结果唯一性 对于仅满足偏序关系的有向无环图中,因为有两个点之间的关系是不确定的,所以导致排序的结果是不唯一的. 满足全序关系的有

数据结构:图论:拓扑排序! 两种方法!

拓扑排序:(1)由偏序变成全序的过程!直观的说,偏序指集合中仅有部分成员之间可比较!而全序指集合中全体成员之间均可比较! (2)将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若边(u,v)∈E(G),则u在线性序列中出现在v之前. 数据结构中进行拓扑排序的方法: 方法一: (1)在有向图中选一个没有前驱的顶点且输出之! (2)从图中删除该顶点和所有以它为尾的弧. (3)重复上述两部,直至全部顶点均已输出,或者当前图中不存在无前驱的顶点为止.后一种情况说明有向图中存在环! 代码: #

ACM/ICPC 之 数据结构-邻接表+DP+队列+拓扑排序(TshingHua OJ-旅行商TSP)

做这道题感觉异常激动,因为在下第一次接触拓扑排序啊= =,而且看了看解释,猛然发现此题可以用DP优化,然后一次A掉所有样例,整个人激动坏了,哇咔咔咔咔咔咔咔~ 咔咔~哎呀,笑岔了- -|| 旅行商(TSP) Description Shrek is a postman working in the mountain, whose routine work is sending mail to n villages. Unfortunately, road between villages is

【数据结构】拓扑排序算法

对AOV网进行拓扑排序的基本思路是: 从AOV网中选择一个入度为0的顶点输出,然后删去此顶点,并删除以此顶点为尾的弧,继续重复此步骤,直到输出全部顶点或者AOV网中不存在入度为0的顶点为止. AOV网及邻接表数据结构: 代码: #include "stdio.h" #include "stdlib.h" #include "io.h" #include "math.h" #include "time.h"

数据结构和算法17 之拓扑排序

本文为博主原创文章,转载请注明出处:http://blog.csdn.net/eson_15/article/details/51194219 这一节我们学习一个新的排序算法,准确的来说,应该叫"有向图的拓扑排序".所谓有向图,就是A->B,但是B不能到A.与无向图的区别是,它的边在邻接矩阵里只有一项(友情提示:如果对图这种数据结构部不太了解的话,可以先看一下这篇博文:数据结构和算法之 无向图.因为拓扑排序是基于图这种数据结构的). 有向图的邻接矩阵如下表所示: A B C A