1、数据结构,第7章 图 - 2,第7章 图,7.1 图的定义和术语7.2 图的存储结构7.3 图的遍历7.4 图的连通性问题7.5 有向无环图及其应用7.6 最短路经,7.4 图的连通性问题,7.4.1 无向图的连同分量和生成树 7.4.2 有向图的强连同分量 7.4.3 最小生成树 7.4.4 关节点和重连同分量,7.4.1 无向图的连同分量和生成树,A,B,C,D,E,F,G,I,J,L,H,M,K,A,B,C,D,E,H,M,F,G,I,J,L,K,无向图G的三个连通分量,无向图G,连通:顶点v至v 之间有路径存在 连通图:无向图图 G 的任意两点之间都是连通的,则称 G 是连通图。 连通
2、分量:极大连通子图,7.4.1 无向图的连同分量和生成树,生成树:极小连通子图。包含图的所有 n 个结点,但只含图的 n-1 条边。在生成树中添 加一条边之后,必定会形成回路或环。因为在生成树的任意两点之间,本来就 是连通的,添加一条变之后,形成了这两点之间的第二条通路。,A,B,C,D,E,H,M,A,B,C,D,E,H,M,无向图G,无向图G的生成树,生成方法:进行深度为主的遍历或广度为主的遍历,得到深度优先生成树或广度优先生成树。,生成森林:在进行深度为主的遍历或广度为主的遍历时,对于非连通图,将得到多棵深度优先生成树或广度优先生成树。称之为生成森林。,7.4.1 无向图的连同分量和生成
3、树,生成森林:在进行深度为主的遍历或广度为主的遍历时,对于非连通图,将得到多棵深度优先生成树或广度优先生成树。称之为生成森林。,A,B,C,D,E,F,G,I,J,L,H,M,K,A,B,C,D,E,H,M,F,G,I,J,L,K,无向图G的生成森林,无向图G,7.4.2 有向图的强连同分量,深度优先搜索是求有向图的强连同分量的一个有效方法。,7.4.3 最小生成树,最小代价生成树(简称:最小生成树) Minimum Cost Spanning Tree,定义:生成树中边的权值(代价)之和最小的树。 实例:,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,1,2,4,3,5,6
4、,1,5,3,4,2,左图的最小代价生成树,MST 性质:假设 G = V, E 是一个连通图,U 是结点集合 V 的一个非空子集。若 ( u, v ) 是一条代价最小的边,且 u 属于 U , v 属于 V - U,则必存在一棵包括边 ( u, v ) 在内的最小代价生成树。,7.4.3 最小生成树,证明:假定存在一棵不包括边 ( u, v ) 在内的最小代价生成树,设其为 T。将边( u, v ) 添加到树 T ,则形成一条包含 ( u, v ) 的回路。因此,必定存在另一条边 ( u ,v ) ,且 u 属于 U , v 属于 V - U。删去边 ( u ,v ) ,得到另一棵生成树 T
5、 ; 因为边 ( u, v ) 的代价小于边 ( u ,v ) 的代价,所以新的生成树T 将是代价最小的树。和原假设矛盾。 新的生成树T 是树的理由:连通且无回路。,u,v,u,v,T,7.4.3 最小生成树,Kruscal 算法,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,最小代价生成树,1,2,4,3,5,6,1,5,3,4,2,5,5,7.4.3 最小生成树,Kruscal 算法的实现,数据结构:用邻接表标识该图,用堆实现挑选代价最小的边。时间复杂性级别:O(eloge),用于稀疏图。,Kruscal 算法的基本描述设 U:set of vertex, G: Grap
6、h, T: mininum cost spanning tree ;u, v : vertex; V: set of vertex; E:set of edges /初始时,V 包含所有结点 T V , ; / T 初始时具有 n 个不同的连通分量,每个分量只有一个结点。T 的边数 n - 1 吗?等则结束在 E 中选择代价最小的边,令为 ( u,v ) 。并置 E E ( u,v )。如果 ( u,v ) 不和 T 中已有的边构成回路,则 T T ( u,v ),否则放弃。转回 ,7.4.3 最小生成树,克鲁斯卡尔(Kruskal)算法 typedef struct VertexType v
7、ex1;VertexType vex2;VRType weight; EdgeType;typedef ElemType EdgeType;typedef struct / 有向网的定义VertexType vexsMAX_VERTEX_NUM; / 顶点信息EdgeType edgeMAX_EDGE_NUM; / 边的信息int vexnum,arcnum; / 图中顶点的数目和边的数目 ELGraph;,7.4.3 最小生成树,克鲁斯卡尔(Kruskal)算法(续) void MiniSpanTree_Kruskal(ELGraph G, SqList / MiniSpanTree_Kru
8、skal,7.4.3 最小生成树,Prim 算法,Prim 算法的基本描述设 U:set of vertex, G: Graph, T: set of edges(mininum cost spanning tree;u, v : vertex; V: set of vertex; /初始时,V 包含所有结点 T ;U 1 ;由于 1 在 U 中,其余各结点都在 VU 中,可用一数组记录 VU中的结点至 1 的路径。因为它们构成了当前横跨 U 和 VU 两个集合的所有的边。while ( U != V ) 设 ( u,v ) 是一条代价最小的边,并且 u 在 U 中,v 在 V - U中。T
9、= T ( u,v );U = U v ;由于 u 已在 U 中,查找 由 u 至它的仍在 VU中的邻接结点的路径,若 小于原来相应的数组元素记录的最小值,则用该值数组元素之值。,时间代价分析:邻接矩阵:时间复杂性 O(n2),和边数无关。用于稠密图。邻接表且使用最小化堆:时间复杂性 O(n+e)logn)。,7.4.3 最小生成树,Prim 算法的实例,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,最小代价生成树的生成过程,U,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,7.4.3 最小生成树,Prim 算法的实例,1,2,4,3,5,6,6,1,6,5
10、,5,5,6,3,4,2,最小代价生成树的生成过程,U,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,6,1,5,7.4.3 最小生成树,Prim 算法的实例,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,最小代价生成树的生成过程,U,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,6,1,5,7.4.3 最小生成树,Prim 算法的实例,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,最小代价生成树的生成过程,U,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,5,1,5,6,4,7.4.3 最小生成树,Pr
11、im 算法的实例,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,最小代价生成树的生成过程,U,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,5,1,5,6,4,7.4.3 最小生成树,Prim 算法的实例,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,最小代价生成树的生成过程,U,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,5,1,2,6,4,7.4.3 最小生成树,Prim 算法的实例,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,最小代价生成树的生成过程,U,1,2,4,3,5,6,6,1,6,5,
12、5,5,6,3,4,2,5,1,2,6,4,7.4.3 最小生成树,Prim 算法的实例,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,最小代价生成树的生成过程,U,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,5,1,2,6,4,7.4.3 最小生成树,Prim 算法的实例,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,最小代价生成树的生成过程,U,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,5,1,2,3,4,7.4.3 最小生成树,Prim 算法的实例,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2
13、,最小代价生成树的生成过程,U,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,5,1,2,3,4,7.4.3 最小生成树,Prim 算法的实例,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,最小代价生成树的生成过程,U,1,2,4,3,5,6,1,5,3,4,2,要点:每当新的结点并入 U 之后,则调整仍在 V - U 集合中的结点至 U 中结点的最小距离。,7.4.3 最小生成树,1、最小代价生成树(简称:最小生成树),Prim 算法数据结构:,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,图G,1,2,4,3,5,6,6,1,6,5,5
14、,5,6,3,4,2,图G,1,2,4,3,5,6,6,1,6,5,5,5,6,3,4,2,图G,U,U,0,6,1,5,0 1 2 3 4 5,0,0,0,0,0,lowcost nearvex,注意:lowcost j 表示在 VU中的结点 j 到 U 中的结点的最短距离。nearvex j : if 值为 -1, 表 示相应结点 j 已在 U 之中。否则,表示结点 j 和 U 中的结点 k = nearvex j 距离是最短的, 且为 Lowcost j 。 因结点j到U中结点路径有多条,-1,0,5,1,5,6,4,0 1 2 3 4 5,2,-1,0,2,2,lowcost near
15、vex,-1,值为1,2,3,4,5,6de 结点,用下标0,1,2,3,4,5标识。,7.4.4 关节点和重连同分量,V2,V4,V3,V1,V6,V5,V4,V6,V5,V2,V3,V1,T 树边:(v1,v2)、 (v1,v5)、 (v2,v3)、 (v2,v4)、 (v5,v6),B 后向边:(v3,v1) 、(v4,v1)、 (v6,v1),注意:子图 (V,T) 是一个无向森林,称为关于 G 的先深生成森林。如仅一棵树的情况下, (V,T) 称为先深生成树。 如 G 是连通的,则这个先深生成森林将是一棵树。,7.4.4 关节点和重连同分量,A,L,M,C,E,D,G,H,K,F,J
16、,I,无向图G,关节点:设 G(V,E)是一个连通无向图。一个结点 a 若说是 G 的一个关节点。则 存在和 a 不同的结点 v、w, v、w 之间的每一条路径都包含结点 a。或者换句话 说,a 是 G 的一个关节点,如果移去 a 就把 G 分裂成两个或两个以上的部分。 重连通图:图 G 是重连通的,如对于互不相同的结点 v、w、a 的每个三元组都存在 一条由 v 到 w 的不含 a 的路径。即一个无向图是重连通的,当且仅当它 没有关节点。,B,关节点:A、B、D、G,7.4.4 关节点和重连同分量,重连通分量的求法。,边的相关关系:两条边 e1 、 e2是相关的:如果e1 e2 或者有一个既
17、包含 e1 又包含 e2 的回路,则说 e1 和 e2 是相关的。,相关关系是等价关系:它把 G 的边划分成等价类:E1 、E2 、E3 Ek; 使得两条不同 的边在同一类,当且仅当它们位于同一回路内。,重连通分量:对于 1 = i = k 设 Vi 是 Ei 中的结点集,每个图 Gi = (Vi , Ei) 称为一个重 连通分量。,V1,V7,V8,V2,V4,V3,V6,V5,V9,V1,V2,V3,V2,V4,V5,V4,V6,重连通分量: (v4,v6) ,V7,V8,V6,V9,重连通分量: (v6,v7) 、(v7,v8)、 (v8,v9)、(v9,v6)、 (v6,v8) ,每个
18、等价类中的边产生一个重连通分量,各等价类的边不相交。最多只有一个结点(即关节点)为两个重连通分量的结点集的交。,重连通分量: (v1,v2) 、(v1,v3)、 (v2,v3) ,重连通分量: (v2,v4) 、(v2,v4)、 (v2,v5),7.4.4 关节点和重连同分量,引理: 对于 1 = i = k 设 Gi = (Vi , Ei) 是一个连通无向图 G = (V , E) 的一个重连通分量。 则:1、对于每一个 i ( 1 = i = k ) , Gi 是重连通的。 2、 对于所有的 i != j , Vi Vj 最多包含一个结点。,证明:1、(反证法) 假设 Gi = (Vi ,
19、 Ei) 中的 Vi 有三个不同的结点v、w、a,使得v、w、之间 的所有路径都经过 a。注意:根据该假设边(v,w)不存在。但根据等价关系及等价 类的定义, v、w 之间必须存在回路包含它们。但这样一来,从 v 到 w 将不经 过 a。请参照右图。和原假设矛盾。因此,象 a 这样的关节点是不存在的。故图 Gi =(Vi , Ei) 是重连通的。,2、(反证法) 设两个不同的结点 v、 w 在 Vi Vj 之中。 v 和 w 之间有路径(有一条以上的边组成)存在。这样, 在 Ei 中的边形成的回路之中,包含该路径。同样,在 Ej 中 也如此。这是不可能的。,7.4.4 关节点和重连同分量,引理
20、:设 Gi = (Vi , Ei)是一个连通无向图,并设 S = (V , T)是G 的一棵先深生成树。 结点 a 是 G 的一个关节点,当且仅当:或者1、a 是根且 a 的儿子多于一个。或者,2、a 不是根。但对于 a 的某个儿子 s,在 s 的任一子孙 (包括 s 本身) 和 a 的一个真正祖先之间没有后向边。,证明: 1、a 是根且 a 的儿子多于一个。那么,儿子同儿子之间的所有的路径都必 须经过根结点作为唯一的路径。,2、参见右图。设 f 是 a 的父亲结点。 s是a 的某个儿子 结 点。设 v 是 s 的一个真正的子孙。并且 v 有 后向边进到 v的一个祖先,但和 a 的一个真正祖先
21、之间,无后 向边。考察 s 和 f 之间的所有路径,可知必须经过结点 a 。因此,a 是一个 关节点。,a,f,v,s,f 是a 的父亲,s是a 的某个儿子,后向边进到v的一个祖先,但和a的一个真正祖先之间,无后向边。,重连通分量:利用无向图的先深生成树寻找关节点。,如何判断是否有后向边,利用下面介绍的 LOW 值。,7.4.4 关节点和重连同分量,x,v,w,a,f,v,s,v,y,x,v 是关节点,LOW(x) = v ?,根据引理:v 是关节点,必须:对于 v 的某个儿子 x,在 x 的任一子孙 (包括 x 本身) 和 v 的一个真正祖先之间没有后向边。 参见上张引理,第 2 点。非根情
22、况。,LOW 值的定义解释:设 T 和 B 是连通无向图 G = (V,E) 的先深搜索产生的树边和后向边的集合。 使用经过后向边与 v 邻接的结点和 LOW 在 v 的各个儿子结点 w 的最小值加以定义。LOW(v) = MIN( v LOW(s) | s 是 v 的儿子 w | (v,w) B ),7.4.4 关节点和重连同分量,a,f,v,s,v,y,s,v 是关节点,LOW(s) = v,x,v,w,LOW值的定义解释:设 T 和 B 是连通无向图 G = (V,E) 的先深搜索产生的树边和后向边的集合。 使用经过后向边与 v 邻接的结点和 LOW 在 v 的各个儿子结点 w 的最小值
23、加以定义。目的是简化计算。LOW(v) = MIN( v LOW(s) | s 是 v 的儿子 w | (v,w) B ),7.4.4 关节点和重连同分量,LOW值的定义解释:设 T 和 B 是连通无向图 G = (V,E) 的先深搜索产生的树边和后向边的集合。 使用经过后向边与 v 邻接的结点和 LOW 在 v 的各个儿子结点 w 的最小值加以定义。目的是简化计算。LOW(v) = MIN( v LOW(s) | s 是 v 的儿子 w | (v,w) B ),a,f,v,s,v,y,s,v 是关节点,LOW(s) v,x,v,w,7.4.4 关节点和重连同分量,LOW值的定义解释:设 T
24、和 B 是连通无向图 G = (V,E) 的先深搜索产生的树边和后向边的集合。 使用经过后向边与 v 邻接的结点和 LOW 在 v 的各个儿子结点 w 的最小值加以定义。目的是简化计算。LOW(v) = MIN( v LOW(s) | s 是 v 的儿子 w | (v,w) B ),a,f,s,v,s,P,G,W,7.4.4 关节点和重连同分量,实例:,V2,V3,V9,V1,V6,V8,V4,V7,V5,V2,V3,V9,V1,V6,V8,V4,V7,V5,该图的一棵先深生成树,相应的带有 LOW 值的先深生成树,LOW 1,LOW 2,LOW 1,LOW 1,LOW 4,LOW 4,LOW
25、 4,LOW 4,LOW 2,1,8,7,2,3,4,5,9,6,V2,V3,V7,V1,V6,V9,V4,V8,V5,无向连通图,先深搜索序号,先深搜索起始结点,7.4.4 关节点和重连同分量,实例:,V1,V2,V2,V4,V4,V6,V6,V8,V8,V9,V9,V6,V8,V7,V7,V6,由V6是关节点得到的第一个重连通分量的边。,V2,V3,V9,V1,V6,V8,V4,V7,V5,LOW 1,LOW 2,LOW 1,LOW 1,LOW 4,LOW 4,LOW 4,LOW 4,LOW 2,1,8,7,2,3,4,5,9,6,先深搜索序号,相应的带有 LOW 值的先深生成树,7.5
26、有向无环图及其应用,何为有向无环图(DAG 图) Directed Acyclic Graph,B,E,F,G,L,F,G,B,E,F,G,L,F,G,B,E,F,G,L,F,G,有向树,DAG图,有向图(含环),7.5 有向无环图及其应用,用途:描述工程项目或系统进行的工具,AOV 网络:(Activity On Vertex)定义结点为活动,有向边的指向表示活动执行的次序。AOE网络:(Activity On Edge)定义结点为事件,有向边的指向表示事件的执行次序。单位是时间(时刻)。有向边定义为活动,它的权值定义为活动进行所需要的时间。,A,B,A,B,10,7.5.1拓扑排序,拓扑排
27、序(Topological Sort) 由某个集合上的一个偏序得到该集合上的一个全序。 偏序(Partial Order):若集合 X 上的关系 R 是传递的、自反的、反对称的,则称 R 是集合 X 上的偏序关系。 全序(Total Order):若关系 R 是集合 X 上的偏序关系,如果对于每个 x, y 属于 X,必有 x R y 或 y R x ,则称 R 是集合 X 上的全序关系。,7.5.1拓扑排序,拓扑排序:由某个集合上的一个偏序关系通过人为地加上一些关系得到该集合上的一个全序。 用途:描述工程项目或系统进行的次序 AOV 网络:定义结点为活动,有向边的指向表示活动执行的次序。,7
28、.5.1拓扑排序,实例:下述集合 M 代表课程的集合,其中,1代表数学, 2代表程序设计,3代表离散数学,4代表汇编程序设计,5代表数据结构,6代表结构程序设计, 7代表编译原理。 关系 R 课程学习的先后关系,如数学必须在离散数学之前学习。要求排一张学习的先后次序表。,1,3,2,7,5,6,4,数学,程序设计,离散数学,汇编程序设计,数据结构,结构程序设计,编译原理,序列:1、3、2、4、6、5、7 合乎拓扑排序的要求,序列:3、1、2、4、6、5、7 不合乎拓扑排序的要求,7.5.1拓扑排序,那么如何进行拓扑排序?步骤如下: (1) 在AOV网中选择一个没有前驱的顶点并输出; (2) 从
29、AOV网中删除该顶点以及从它出发的弧; 重复以上两步直至AOV网变空(即已输出所有顶点)或者剩余子图中不存在没有前驱的顶点。后一种情况则说明该AOV网中含有向环。,7.5.1拓扑排序,实例:课程学习先后关系的排序。,1,3,2,7,5,6,4,数学,程序设计,离散数学,汇编程序设计,数据结构,结构程序设计,编译原理,1,3,2,7,5,6,4,1,3,2,4,6,5,7,7.5.1拓扑排序,算法(使用邻接表),算法的执行步骤: 1、用一个数组记录每个结点的入度。将入度为零的结点进栈。 2、将栈中入度为零的结点V输出。 3、根据邻接表找到结点V的所有的邻接结点,并将这些邻接结点的入度减一。如果某
30、一结点的入度变为零,则进栈。 4、反复执行 2、3;直至栈空为止。 次序执行结束,如果输出结点数等于图的结点总数,则有向图无环,否则有向图有环,1,3,2,7,5,6,4,数学,程序设计,离散数学,数据结构,结构程序设计,编译原理,汇编程序设计,1,2,1,2,01234 56,null,3,4,4,6,3,4,5,5,null,null,null,6,7,6,3,null,null,null,注意: 0,1,2,3,4,5,6 分别标识结点 1,2,3,4,5,6,7,0,1,0123456,1,1,2,1,3,0,栈,indegree,7.5.1拓扑排序,算法(使用邻接矩阵),0 1 1
31、0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0,1 2 3 4 5 6 7,1 2 3 4 5 6 7,算法的执行步骤: 1、找到全为零的第 j 列,输出 j 2、将第 j 行的全部元素置为零 3、找到全为零的第 k 列,输出 k 4、将第 k 行的全部元素置为零 反复执行 3、4;直至所有元素输出完毕。,0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0
32、0 0 1 0 0 0 0 0 0 0,1,3,2,7,5,6,4,数学,程序设计,离散数学,数据结构,结构程序设计,编译原理,汇编程序设计,7.5.1拓扑排序,算法描述如下(使用邻接矩阵)建有向图的邻接表并统计各顶点的入度;InitStack(S); / 初始化S为空栈将当前所有入度为零的顶点入栈;m=0; / 以 m 记输出的顶点个数while (!StackEmpty(S) / 尚有入度为零的顶点存在Pop(S,v);输出 v ; +m; / 输出入度为零的顶点,并计数w = FirstAdj(G,v); / w 为 v 的邻接点while (w0) / 将v 的所有邻接点的入度减1in
33、Degreew-; / w 的入度减一if( 0=inDegreew) Push(S,w);w = nextAdj(G,v,w); / 取 v 的下一个邻接点 / while w / while Sif (mn) printf(“图中有回路”); / 输出的顶点数不足图中顶点数DestroyStack(S);,7.5.2 关键路径,关键路径: AOE 网络的应用 用途:估算工程项目完成时间 AOE网络:定义结点为事件,有向边的指向表示事件的执行次序。单位是时间(时刻)。有向边定义为活动,它的权值定义为活动进行所需要的时间。 术语: 源点:表示整个工程的开始点,也称起点。 收点:表示整个工程的结
34、束点,也称汇点。 事件结点:单位时间,表示的是时刻。 活动(有向边):它的权值定义为活动进行所需要的时间。方向表示起始结点事件先发生,然后终止结点事件才能发生。,7.5.2 关键路径,一个实例: 源点:v1 收点:v6待解决的问题 完成整项工程至少需要多少时间? 哪些活动是影响工程进度的关键?,V1,V3,V2,V5,V6,V4,135,11,2 2,2,2,1,7.5.2 关键路径,术语: 事件的最早发生时间(Ve(j)):从起点到本结点的最长的路径。意味着事件最早能够发生的时刻。 事件的最迟发生时间(V l (j)):不影响工程的如期完工(汇点的最早完成时间),本结点事件必须发发生的时刻。
35、 活动的最早开始时间:e(ai ) = Ve( j ) 活动的最迟开始时间: l (ai ) = V l( k ) - dut( j , k ) 关键活动:最早开始时间 最迟开始时间的活动 关键路径:从源点到收点的最长的一条路径,或者全部由关键活动构成的路径。,V1,VJ,1 5 1288,Ve(Vj) = 88 取 1、5、12、88的最大值 88,起点: 0,Vj,Vn,Vl(Vj) = 取 10-2、10-4、10-3、10-7的最小值 3;或 10 - 最长路径 7,2 4 3 7,1010,收点,k,j,dut(j,k),ai,7.5.2 关键路径,Ve(j) 的求法:,VJ,3 5
36、 12 88,Ve(Vj) = 3、5、12、88的最大值 88,起点:0,V1,VJ,Ve(Vj) = Vj 的起始结点的最早发生时间 + 各自的边的权值中的和的最大值 88,Vu,Vv,Vw,Vx,2,3,9,82,1,2,3,6,由源点至收点,注意:本图说明由已知的所有的起始结点的 Ve ,可得知终止结点的 Ve 。 如:从Ve(Vu) 、Ve (Vv) 、 Ve (Vw) 、 Ve (Vx) 可知Ve(Vj),注意:开始时只有源点的 Ve 0 已知,利用拓扑排序的序列可得到每一个结点的 Ve 。且结点的 Ve 确定次序和拓扑排序的序列相同。,V1,7.5.2 关键路径,求事件的最早发生
37、时间的实例,V1,V3,V2,V5,V6,V4,1 3 5,11,0,2 2,V1,V3,V2,V5,V6,V4,1,1,2,1,2,2,2,2,1,1,3、,5、,3、,3,5、,5,6,7、,8,V1,V2,V3,V4,V5,V6,正向拓扑排序:,0,0,0,0,0,0,1,3,5,2,利用拓扑排序算法求事件结点的最早发生时间的执行步骤: 1、设每个结点的最早发生时间为0,将入度为零的结点进栈。 2、将栈中入度为零的结点V取出,并压入另一栈,用于形成逆向拓扑排序的序列。 3、根据邻接表找到结点V的所有的邻接结点,将结点V的最早发生时间 + 活动的权值 得到的和同邻接结点的原最早发生时间进行
38、比较;如果该值大,则用该值取代原最早发生时间。另外,将这些邻接结点的入度减一。如果某一结点的入度变为零,则进栈。 4、反复执行 2、3;直至栈空为止。,7.5.2 关键路径,Vl(j) 的求法:,Vj,Vn,Vl(Vj) = 取 10-2、10-4、10-3、10-7的最小值 3,2 4 3 7,1010,收点,Vj,Vn,Vl(Vj) = 取终止结点的最迟发生时间 - 各自的边的权值的差的最小值 3,1010,收点,Vu,Vv,Vw,Vx,8,8,5,1,2,1,2,9,由收点至源点,注意:本图说明由已知的所有的终止结点的 Vl ,可得知起始结点的 Vl 。 如:从Vl(Vu) 、Vl (V
39、v) 、 Vl (Vw) 、 Vl (Vx) 可知 Vl(Vj),注意:开始时只有收点的 Vl Ve(Vn) 已知,利用逆拓扑排序的序列可得到每一个结点的 Vl 。且结点的 Vl 确定次序和逆拓扑排序的序列相同。,7.5.2 关键路径,实例:求事件结点的最迟发生时间,V1,V3,V2,V5,V6,V4,1 3 5,11,2 2,2,2,1,6、,5,6,8,V1,V2,V3,V4,V5,V6,逆向拓扑排序:,逆向拓扑排序同每个结点的 VL 发生时间的确定次序是一致的。 证;最末一个结点的 VL 最先确定。它确定之后,就可推出对相应的起始结点的影响,如上图的 V5 V4 V3 结点的 VL 当前
40、值,或者可以形象地认为结点V5 V4 V3的出度相应的减少了 1。第二个可以确定 VL 的结点是正向拓扑排序中的倒数第二个结点,如V5 。理由:此时它已相当于出度为零的结点。即在它之前已确定 VL 的结点,对它发生的影响已全部产生(反证:如果没有全部产生,就意味着V5 V6之间还有一个结点 如Vx还对它产生影响, 边V5 Vx存在。但这样一来,它将不会是正向拓扑排序中的倒数第二个结点。证毕。) 其余依次类推。,8,8,8,8,8,8,V1,V3,V2,V5,V6,V4,1,1,2,2,2,1,6、,4、,4,0、,0、,0,3,V1,V2,V3,V4,V5,V6,正向拓扑排序:,2,1,3,5
41、,7.5.2 关键路径,实例:求事件结点的最迟发生时间,V1,V3,V2,V5,V6,V4,1 3 5,11,2 2,2,2,1,6、,5,6,8,V1,V2,V3,V4,V5,V6,逆向拓扑排序:,8,8,8,8,8,8,V1,V3,V2,V5,V6,V4,1,1,2,2,2,1,6、,4、,4,0、,0、,0,3,V1,V2,V3,V4,V5,V6,正向拓扑排序:,2,1,3,5,利用逆向拓扑排序算法求事件结点的最迟发生时间的执行步骤: 1、设每个结点的最迟发生时间为收点的最早发生时间。 2、将栈中的结点V取出。 3、根据逆邻接表找到结点V的所有的起始结点,将结点V的最迟发生时间 - 活动
42、的权值得到的差同起始结点的原最迟发生时间进行比较;如果该值小,则用该值取代原最迟发生时间。 4、反复执行 2、3;直至栈空为止。,7.5.2 关键路径,V1,V3,V2,V5,V6,V4,实例的事件结点的最迟发生时间,1 3 5,11,2 2,2,2,1,3,0,4,5,6,8,V1,V3,V2,V5,V6,V4,实例的事件结点的最早发生时间,1 3 5,11,0,2 2,2,2,1,1,3,5,6,8,V1,V2,V1,V3,V1,V4,V2,V3,V3,V4,V3,V6,V4,V5,V4,V6,V5,V6,V2,V5,边,最早发生时间,最迟发生时间,关键活动,关键活动,关键活动,0 0 0
43、 1 1 3 3 5 5 6,2 1 0 3 4 4 6 5 6 6,7.5.2 关键路径,3,0,4,5,6,8,V1,V3,V2,V5,V6,V4,实例的关键路径(粗箭头所示),1 3 5,11,0,22,2,2,1,1,3,5,6,8,注意:关键路径可有多条缩短工期必须缩短关键活动所需的时间 反过来不一定成立。,时间代价:图中的结点和边都要访问到,故:O(e+n)。,课后习题,Project ID: 10 设数学院开设如下课程(下页或文件): 请根据你的理解,添加课程之间的依赖关系,编写程序给出所有可能的拓扑排序。提示: 如果你添加的课程依赖太少,拓扑排序的数量可能会太多,以至无法处理,
44、请添加足够的依赖。 如果必要,去掉一些完全没有前后依赖的课程 必修课程是毕业必要条件 可以只考虑你自己的专业,0362,JAVA 0364,复变函数 0365,差分方法 0366,常微分方程 0370,抽象函数与巴拿赫代数 0371,抽样技术 0375,概率论 0376,高等代数与解析几何2-1 0384,计算机辅助几何设计 0385,计算机集合论与逻辑 0386,金融工程学 0387,近代密码学 0388,李代数 0389,时间序列分析 0391,试验设计 0392,数理统计 0394,数学分析3-1 0397,数学软件 0399,数学实验 0400,数值代数 0401,随机过程 0402,
45、图象处理 0405,拓扑学,0406,小波 0407,信号处理技术与应用 0409,信息论 0410,有限群表示论 0412,运筹学 0415,抽象代数 0416,应用随机过程 0417,数值方法 0420,网络程序设计 0421,常微分方程数值解 0427,数学分析3-3 0431,金融市场学 0432,偏微分方程 0433,控制论基础 0434,Fortran语言 0435,高等代数与解析几何2-2 0436,毕业论文 0437,操作系统与网络 0441,代数与编码 0443,多元统计分析 0444,泛函分析 0450,科学计算实验 0452,偏微分方程数值解,0453,实变函数 0456,数据结构 0457,数理方程 0460,数值逼近 0462,图论 0463,微分几何 0464,信号与系统 0465,应用回归分析 0467,应用统计专题 0468,有限元方法 0469,组合论 0470,最优化方法 0473,数据库 0476,宏微观经济学 0477,数论 0478,风险理论基础 0483,数学分析3-2 0484,并行计算数值方法 0486,统计计算与统计软件包 0487,数学建模 0714,面向对象程序设计2-1 0759,面向对象程序设计2-2,