, j# M5 K' C! `+ ]$ G1 w一个图称为有限图,如果它的顶点集和边集都有限。图G 的顶点数用符号|V | 或 ν (G) 表示,边数用| E |或ε (G)表示。 : E! K1 T B) m# g) b$ f% i, _4 C; d5 g2 s X; L( t
当讨论的图只有一个时,总是用G 来表示这个图。从而在图论符号中我们常略去 字母G ,例如,分别用V,E,ν 和ε 代替V (G),E(G),ν (G) 和ε (G)。# W1 G& o C" v# B' F
0 N7 X+ I7 b$ K' F4 M端点重合为一点的边称为环(loop)。 一个图称为简单图(simple graph),如果它既没有环也没有两条边连接同一对顶点。 + V$ M5 K. M0 L/ i$ [6 J & a4 e2 w8 x1 u$ i2.2 有向图 " }4 C G8 x6 G1 [- y0 ^ . \5 C# F% \3 h0 P% t' s 9 } d' i; O) K. H5 N: G" B对应于每个有向图 D ,可以在相同顶点集上作一个图G ,使得对于 D 的每条弧, G 有一条有相同端点的边与之相对应。这个图称为 D 的基础图。反之,给定任意图G , 对于它的每个边,给其端点指定一个顺序,从而确定一条弧,由此得到一个有向图,这 样的有向图称为G 的一个定向图。 以下若未指明“有向图”三字,“图”字皆指无向图。 ' J I0 \0 v% Y; e# a. }. B , O# l4 [2 ^6 E4 c5 s- v3 i2.3 完全图、二分图 * i7 v2 h [6 V每一对不同的顶点都有一条边相连的简单图称为完全图(complete graph)。n 个顶点 的完全图记为 。* \ b6 I8 Y& s
+ k0 i& ~! ^2 U/ j4 c |% U/ [* k& [: p' J& V' t! P( o4 p8 P. s, T
2.4 子图5 g. j) i& X8 Q
图 H 叫做图 G 的子图(subgraph),记作 H ⊂ G ,如果 V (H ) ⊂V (G) , E(H) ⊂ E(G) 。若 H 是G 的子图,则G 称为 H 的母图。 G 的支撑子图(spanning subgraph,生成子图)是指满足V(H) =V(G) 的子 图 H 。, g5 J: [$ W8 E: e# ~) D! Z: E
1 j7 b g% J' x( n+ a3 Z% d2.5 顶点的度 ! S- T M5 B, \8 m设v ∈V (G) ,G 中与v 关联的边数(每个环算作两条边)称为v 的度(degree),记 作d(v)。若d(v)是奇数,称v 是奇顶点(odd point);d(v)是偶数,称v 是偶顶点(even point)。& `, @. N/ z$ A! c
) U" Q* [2 v( ]/ V: D
关于顶点的度,我们有如下结果: 3 l1 ^; ~! `4 [& S5 J) P/ v+ C4 X6 c f9 V) ?/ R- G
(i) $ {% }! n8 D/ q: L8 u, ^. o! f+ _ / x4 V9 w" M* T" G: w(ii) 任意一个图的奇顶点的个数是偶数。 # O3 M W7 H- V) A/ p) P" @8 ?* L" ^: I
2.6 图与网络的数据结构 5 }& S/ Z+ g9 ?/ S1 C5 q! P网络优化研究的是网络上的各种优化模型与算法。为了在计算机上实现网络优化的 算法,首先我们必须有一种方法(即数据结构)在计算机上来描述图与网络。一般来说, 算法的好坏与网络的具体表示方法,以及中间结果的操作方案是有关系的。这里我们介 绍计算机上用来描述图与网络的 5 种常用表示方法:邻接矩阵表示法、关联矩阵表示法、 弧表表示法、邻接表表示法和星形表示法。4 I' L* V3 c) ]9 K% p1 C" Y5 Y( K
3 ^9 `7 N5 {0 W
在下面数据结构的讨论中,我们首先假设 G = (V, A)是一个简单有向图,|V |= n,| A |= m ,并假设V 中的顶点用自然数1,2,....,n 表示或编号, A 中的弧用自然数1,2,...,m 表示或编号。对于有多重边或无向网络的情 况,我们只是在讨论完简单有向图的表示方法之后,给出一些说明。 6 Q8 D5 W: w+ Q1 F6 K, @$ ] [ - P7 p& J/ C. ]: F(i)邻接矩阵表示法2 t. k0 D$ Z: Q8 ^# p' F; m1 t( n
邻接矩阵表示法是将图以邻接矩阵(adjacency matrix)的形式存储在计算机中。图 G = (V, A)的邻接矩阵是如下定义的:C 是一个n × n 的0 −1矩阵,即 - C# L1 Z0 v5 E" h( r" K$ f / a8 L4 A, ~3 \$ P0 j ) ~8 {6 K, M( c$ S# B$ e2 c1 l0 [$ s ' A u) I9 s1 |1 L; @也就是说,如果两节点之间有一条弧,则邻接矩阵中对应的元素为 1;否则为 0。 可以看出,这种表示法非常简单、直接。但是,在邻接矩阵的所有 个元素中,只有m 个为非零元。如果网络比较稀疏,这种表示法浪费大量的存储空间,从而增加了在网络 中查找弧的时间。; f- w/ r, J+ l9 ~, D# E
0 e4 j- Q& Q" [2 I+ D例7 对于图 2 所示的有向图,可以用邻接矩阵表示为. o: l0 M6 | J- } O. f : o' [* Z M- l
& z. ?9 v1 c( J1 a% D" l5 p H ! ^8 `( ]3 b+ p同样,对于网络中的权,也可以用类似邻接矩阵的n × n 矩阵表示。只是此时一条 弧所对应的元素不再是 1,而是相应的权而已。如果网络中每条弧赋有多种权,则可以 用多个矩阵表示这些权。# e; g+ q+ s6 U! b/ }2 k, z
) q8 {* q' ~3 j6 S(ii)关联矩阵表示法0 B. N+ K9 C% M1 m& F
关联矩阵表示法是将图以关联矩阵(incidence matrix)的形式存储在计算机中.图 G = (V, A)的关联矩阵 B 是如下定义的: B 是一个n × m 的矩阵,即 1 g* n- i3 d: X- r$ a; ? e0 |0 P4 x. a3 ? n( |4 a
% V8 { {& x, K+ P# }6 P$ C8 Y# J' b' V1 W u
% a8 z8 V* G2 |; F+ R
- p# i/ |$ o$ ?, t5 @+ r5 J3 C也就是说,在关联矩阵中,每行对应于图的一个节点,每列对应于图的一条弧。如 果一个节点是一条弧的起点,则关联矩阵中对应的元素为 1;如果一个节点是一条弧的 终点,则关联矩阵中对应的元素为 −1;如果一个节点与一条弧不关联,则关联矩阵中 对应的元素为 0。 ! o7 u7 [0 e5 h. {' h ' T! o; k1 ?4 M7 l对于简单图,关联矩阵每列只含有两个非零元(一个 +1,一个 −1)。 可以看出,这种表示法也非常简单、直接。但是,在关联矩阵的所有nm 个元素中,只 有2m 个为非零元。如果网络比较稀疏,这种表示法也会浪费大量的存储空间。但由于 关联矩阵有许多特别重要的理论性质,因此它在网络优化中是非常重要的概念。" s4 C. E, \. b' N( z/ Y& m
7 K! w2 B9 @3 T- J. Q例 8 对于例 7 所示的图,如果关联矩阵中每列对应弧的顺序为(1,2),(1,3),(2,4), (3,2),(4,3),(4,5),(5,3)和(5,4),则关联矩阵表示为 0 C' O9 P: L, h' X$ d9 S% U! L: d, ~% _3 H# k - L+ E0 u+ D5 `; ~: D0 I
9 n# T' p- U. b同样,对于网络中的权,也可以通过对关联矩阵的扩展来表示。例如,如果网络中 每条弧有一个权,我们可以把关联矩阵增加一行,把每一条弧所对应的权存储在增加的 行中。如果网络中每条弧赋有多个权,我们可以把关联矩阵增加相应的行数,把每一条 弧所对应的权存储在增加的行中。 8 y- p9 x0 J7 A2 F- P$ ^ ; U/ p0 ^ Y5 i3 E5 z(iii)弧表表示法) S/ V* |, ^" A+ e3 f! T, m
弧表表示法将图以弧表(arc list)的形式存储在计算机中。所谓图的弧表,也就是 图的弧集合中的所有有序对。弧表表示法直接列出所有弧的起点和终点,共需2m 个存 储单元,因此当网络比较稀疏时比较方便。此外,对于网络图中每条弧上的权,也要对 应地用额外的存储单元表示。 5 W/ z8 s' g; R: p3 a) J/ ~! L! [4 |- }$ m; a( M2 O
例如,例 7 所示的图,假设弧(1,2),(1,3),(2,4),(3,2), (4,3),(4,5),(5,3)和(5,4)上的权分别为 8,9,6,4,0,3,6 和 7,则弧表表示如表 1 所示。 Z* T7 m# f% E; |% C R u4 g7 ]/ k! r
* [7 {/ t+ o& S1 p! J1 P. H/ M! ]) V * B4 l4 i) w& ?为了便于检索,一般按照起点、终点的字典序顺序存储弧表,如上面的弧表就是按 照这样的顺序存储的。 / R0 ]0 t- Q" Q: O4 Q9 D s' g& d( J J/ c( R- _7 q2 r(iv)邻接表表示法 ( r) \% f) I8 l9 `- @9 Y6 B+ i邻接表表示法将图以邻接表(adjacency lists)的形式存储在计算机中。所谓图的 邻接表,也就是图的所有节点的邻接表的集合;而对每个节点,它的邻接表就是它的所 有出弧。邻接表表示法就是对图的每个节点,用一个单向链表列出从该节点出发的所有 弧,链表中每个单元对应于一条出弧。为了记录弧上的权,链表中每个单元除列出弧的 另一个端点外,还可以包含弧上的权等作为数据域。图的整个邻接表可以用一个指针数 组表示。( \ P) Q- ~6 U: a( n! m7 W
( v' T. N3 W+ C f" @# Y F
例如,例 7 所示的图,邻接表表示为 j. q: i L ~! I* E 1 x( N" v5 p2 |9 I. V2 Z+ t) M $ y7 i6 d1 C+ S* z3 r, l% b# G$ k: }9 A, z
这是一个 5 维指针数组,每一维(上面表示法中的每一行)对应于一个节点的邻接 表,如第 1 行对应于第 1 个节点的邻接表(即第 1 个节点的所有出弧)。每个指针单元 的第 1 个数据域表示弧的另一个端点(弧的头),后面的数据域表示对应弧上的权。如 第 1 行中的“2”表示弧的另一个端点为 2(即弧为(1,2)),“8”表示对应弧(1,2)上的 权为 8;“3”表示弧的另一个端点为 3(即弧为(1,3)),“9”表示对应弧(1,3)上的权 为 9。又如,第 5 行说明节点 5 出发的弧有(5,3)、(5,4),他们对应的权分别为 6 和 7。; o- N4 u. ?, @7 ]
9 n0 c5 ?! Q2 d0 f& d% G
对于有向图G = (V, A),一般用 A(i) 表示节点i 的邻接表,即节点i 的所有出弧构 成的集合或链表(实际上只需要列出弧的另一个端点,即弧的头)。例如上面例子, A(1) = {2,3}, A(5) = {3,4}等。3 t1 F" B: e' f+ Y+ k8 _# P# P A3 B/ P S
; f y3 ]9 R- H w, x
(v)星形表示法7 l% M- y/ k( C0 e b0 R, c
星形(star)表示法的思想与邻接表表示法的思想有一定的相似之处。对每个节点, 它也是记录从该节点出发的所有弧,但它不是采用单向链表而是采用一个单一的数组表 示。也就是说,在该数组中首先存放从节点 1 出发的所有弧,然后接着存放从节点 2 出发的所有孤,依此类推,最后存放从节点n 出发的所有孤。对每条弧,要依次存放其 起点、终点、权的数值等有关信息。这实际上相当于对所有弧给出了一个顺序和编号, 只是从同一节点出发的弧的顺序可以任意排列。此外,为了能够快速检索从每个节点出 发的所有弧,我们一般还用一个数组记录每个节点出发的弧的起始地址(即弧的编号)。 在这种表示法中,可以快速检索从每个节点出发的所有弧,这种星形表示法称为前向星 形(forward star)表示法。( l2 I; _- A) w2 @" e$ ^1 Z6 C
- u* X: O, x" `" r$ U
例如,在例 7 所示的图中,仍然假设弧(1,2),(l,3),(2,4),(3,2),(4,3),(4,5), (5,3)和(5,4)上的权分别为 8,9,6,4,0,3,6 和 7。此时该网络图可以用前向 星形表示法表示为表 2 和表 3 。 / T0 A" U& M! m4 q2 X( ~' t6 E6 N) r4 Y