拓扑与最短路径
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
7.5.1 拓扑排序 数学基础: 什么是拓扑排序 (Topological Sort)? 简单地说,由 某个集合上的一个偏序得到该集合上的一个全序,这个 操作称之为拓扑排序。 回顾离散数学中关于偏序和全序的定义: 若集合X上的关系R是自反的、反对称的和传递的, 则称只是集合X上的偏序关系。 设 R 是集合 X 上的偏序 (Partial Order) ,如果对每个 x,y∈X必有xRy或yRx,则称 R是集合X上的全序关系。
例如,一个软件专业的学生必须学习一系列基本课 程,其中有些课程是基础课,它独立于其它课程,如 《高等数学》;而另一些课程必须在学完作为它的基础 的先修课程才能开始。如在《程序设计基础》和《离散 数学》学完之前就不能开始学习《数据结构》。这些先 决条件定义了课程之间的领先( 优先 ) 关系。这个关系可 以用有向图更清楚地表示。图中顶点表示课程,有向边 (弧)表示先决条件。若课程i是课程j的先决条件,则图中 有弧<i,j>。
v2
v1
v3
v4
v1
v2
v3
v4
(a)表示偏序 (b)表示全序 图1 表示偏序和全序的有向图
实际问题: 一个表示偏序的பைடு நூலகம்向图可用来表示一个流程图。它 或者是一个施工流程图,或者是一个产品生产的流程图, 再或是一个数据流图( 每个顶点表示一个过程) 。图中每 一条有向边表示两个子工程之间的次序关系 ( 领先关系 ) 。
printf(i,G.vertices[i].data); ++count; //输出i号顶点并计数 for(p=G.vertices[i].firstarc;p; p=p->nextarc) { k=p->adivex; //对i号顶点的每个邻接点的入度减1 if(!(--indegree[k])) Push(S,k);//若入度减为0,则入栈 }//for }//while if(count<G.vexnum) return ERROR;//该有向图有回路 else return OK; }//TopologicalSort
直观地看,偏序指集合中仅有部分成员之间可比 较,而全序指集合中全体成员之间均可比较。例如, 图所示的两个有向图,图中弧(x,y)表示x≤y,则(a)表示 偏序,(b)表示全序。若在(a)的有向图上人为地加一个 表示v2≤v3的弧(符号“≤”表示v2领先于v3),则(a) 表 示的亦为全序,且这个全序称为拓扑有序(Topological Order) ,而由偏序定义得到拓扑有序的操作便是拓扑 排序。
Prerequisites None None C1, C2 None C4 C5 C3, C6 C3 C7, C8 C7 C10 C7 C7 C13 C6
建立模型: 用顶点表示活动,用弧表示活动间的优先关系的 有向图称为顶点表示活动的网 (Activity On Vertex Network) ,简称 AOV- 网。在网中,若从顶点 i 到顶点 j 有一条有向路径,则i是j的前驱;j是i的后继。若<i,j> 是网中一条弧,则i是j的直接前驱;j是i的直接后继。
v1 v4 v2 v3 v1 v4 (b) v2 v3 v5 (c) v4 v2 v3 v5 v2 v3 v5 (d) v5 (e) v5 (f) v2
v6 v5 (a)
图7.28 AOV-网及其拓扑有序序列产生的过程
如何在计算机中实现?
针对上述两步操作,我们可采用邻接表作有向图 的存储结构,且在头结点中增加一个存放顶点入度的 数组(indegree)。入度为零的顶点即为没有前驱的顶点, 删除顶点及以它为尾的弧的操作,则可换以弧头顶点 的入度减1来实现。 为了避免重复检测入度为零的顶点,可另设一栈 暂存所有入度为零的顶点,由此可得拓扑排序的算法。
注意: 在AOV-网中不应该出现有向环,因为存在环意味着某项活动 应以自己为先决条件。若设计出这样的流程图,工程便无法进行。 而对程序的数据流图来说,则表明存在一个死循环。因此,对给 定的 AOV-网应首先判定网中是否存在环。检测的办法是对有向 图构造其顶点的拓扑有序序列,若网中所有顶点都在它的拓扑有 序序列中,则该AOV-网中必定不存在环。
以图7.28(a)中的有向图为例,图中v1,和v6没有 前驱,则可任选一个。假设先输出 v6, 在删除 v6 及弧 <v6,v4>,<v6,v5>之后,只有顶点v1没有前驱,则 输出v1且删去v1及弧<v1,v2>、<v1,v3>和<v1, v4>, 之后v3和 v4都没有前驱。依次类推,可从中任选一个 继续进行。 最后得到该有向图的拓扑有序序列为: v6 - v1 - v4 - v3 - v2 - v5
Status Topological Sort(ALGraph G){
//有向图G采用邻接表存储结构。若G无回路,则输出 //G的顶点的1个拓扑序列并返回OK,否则ERROR。
FindInDegree(G,indegree); //对各顶点求入度indegree[0..vernum-1] InitStack(S); for(i=0;i<G.vexnum; ++i) if(!indegree[i]) Push(S,i) //建零入度顶点栈,s入度为0者进栈 count=0; //对输出顶点计数 while (!StackEmpty(S)) { Pop(S,i);
Course number C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15
Course name Programming I Discrete Mathematics Data Structure Calculus I Calculus II Linear Algebra Analysis of Algorithms Assembly Language Operating Systems Programming Languages Compiler Design Artificial Intelligence Computational Theory Parallel Algorithms Numerical Analysis
例如,一个软件专业的学生必须学习一系列基本课 程,其中有些课程是基础课,它独立于其它课程,如 《高等数学》;而另一些课程必须在学完作为它的基础 的先修课程才能开始。如在《程序设计基础》和《离散 数学》学完之前就不能开始学习《数据结构》。这些先 决条件定义了课程之间的领先( 优先 ) 关系。这个关系可 以用有向图更清楚地表示。图中顶点表示课程,有向边 (弧)表示先决条件。若课程i是课程j的先决条件,则图中 有弧<i,j>。
v2
v1
v3
v4
v1
v2
v3
v4
(a)表示偏序 (b)表示全序 图1 表示偏序和全序的有向图
实际问题: 一个表示偏序的பைடு நூலகம்向图可用来表示一个流程图。它 或者是一个施工流程图,或者是一个产品生产的流程图, 再或是一个数据流图( 每个顶点表示一个过程) 。图中每 一条有向边表示两个子工程之间的次序关系 ( 领先关系 ) 。
printf(i,G.vertices[i].data); ++count; //输出i号顶点并计数 for(p=G.vertices[i].firstarc;p; p=p->nextarc) { k=p->adivex; //对i号顶点的每个邻接点的入度减1 if(!(--indegree[k])) Push(S,k);//若入度减为0,则入栈 }//for }//while if(count<G.vexnum) return ERROR;//该有向图有回路 else return OK; }//TopologicalSort
直观地看,偏序指集合中仅有部分成员之间可比 较,而全序指集合中全体成员之间均可比较。例如, 图所示的两个有向图,图中弧(x,y)表示x≤y,则(a)表示 偏序,(b)表示全序。若在(a)的有向图上人为地加一个 表示v2≤v3的弧(符号“≤”表示v2领先于v3),则(a) 表 示的亦为全序,且这个全序称为拓扑有序(Topological Order) ,而由偏序定义得到拓扑有序的操作便是拓扑 排序。
Prerequisites None None C1, C2 None C4 C5 C3, C6 C3 C7, C8 C7 C10 C7 C7 C13 C6
建立模型: 用顶点表示活动,用弧表示活动间的优先关系的 有向图称为顶点表示活动的网 (Activity On Vertex Network) ,简称 AOV- 网。在网中,若从顶点 i 到顶点 j 有一条有向路径,则i是j的前驱;j是i的后继。若<i,j> 是网中一条弧,则i是j的直接前驱;j是i的直接后继。
v1 v4 v2 v3 v1 v4 (b) v2 v3 v5 (c) v4 v2 v3 v5 v2 v3 v5 (d) v5 (e) v5 (f) v2
v6 v5 (a)
图7.28 AOV-网及其拓扑有序序列产生的过程
如何在计算机中实现?
针对上述两步操作,我们可采用邻接表作有向图 的存储结构,且在头结点中增加一个存放顶点入度的 数组(indegree)。入度为零的顶点即为没有前驱的顶点, 删除顶点及以它为尾的弧的操作,则可换以弧头顶点 的入度减1来实现。 为了避免重复检测入度为零的顶点,可另设一栈 暂存所有入度为零的顶点,由此可得拓扑排序的算法。
注意: 在AOV-网中不应该出现有向环,因为存在环意味着某项活动 应以自己为先决条件。若设计出这样的流程图,工程便无法进行。 而对程序的数据流图来说,则表明存在一个死循环。因此,对给 定的 AOV-网应首先判定网中是否存在环。检测的办法是对有向 图构造其顶点的拓扑有序序列,若网中所有顶点都在它的拓扑有 序序列中,则该AOV-网中必定不存在环。
以图7.28(a)中的有向图为例,图中v1,和v6没有 前驱,则可任选一个。假设先输出 v6, 在删除 v6 及弧 <v6,v4>,<v6,v5>之后,只有顶点v1没有前驱,则 输出v1且删去v1及弧<v1,v2>、<v1,v3>和<v1, v4>, 之后v3和 v4都没有前驱。依次类推,可从中任选一个 继续进行。 最后得到该有向图的拓扑有序序列为: v6 - v1 - v4 - v3 - v2 - v5
Status Topological Sort(ALGraph G){
//有向图G采用邻接表存储结构。若G无回路,则输出 //G的顶点的1个拓扑序列并返回OK,否则ERROR。
FindInDegree(G,indegree); //对各顶点求入度indegree[0..vernum-1] InitStack(S); for(i=0;i<G.vexnum; ++i) if(!indegree[i]) Push(S,i) //建零入度顶点栈,s入度为0者进栈 count=0; //对输出顶点计数 while (!StackEmpty(S)) { Pop(S,i);
Course number C1 C2 C3 C4 C5 C6 C7 C8 C9 C10 C11 C12 C13 C14 C15
Course name Programming I Discrete Mathematics Data Structure Calculus I Calculus II Linear Algebra Analysis of Algorithms Assembly Language Operating Systems Programming Languages Compiler Design Artificial Intelligence Computational Theory Parallel Algorithms Numerical Analysis