of {$slidecount} ½ {$title} ATZJG.NET {$author}

首页






图论算法
若干定义
拓扑排序
最短路径算法
网络流问题
最小生成树
深度优先搜索的应用
NP完全性介绍


Haifeng Xu


(hfxu@yzu.edu.cn)

This slide is based on the book of Mark Allen Weiss
Data Structures and Algorithm Analysis in C++
张怀勇等译.

And the bool of Sartaj Sahni
Data Structures, Algorithms, and Applications in C++
王立柱、刘志红 译

目录

基本概念

基本概念

图(graph) $G$ 由顶点(vertex)集合 $V$ 和边(edge)的集合 $E$ 所组成, 一般记作 $G=(V,E)$. 这里 $V=\{v_i\mid i=1,2,\ldots,n\}$.(我们一般考虑有限集.) $E$ 是 $V$ 的二元无序(或有序)配对集的子集, 即

\[ E\subset\{[v_i, v_j]\ :\ v_i, v_j\in V\} \]

有时边也记作 $(v,w)$, 其中 $v,w\in V$. 边也称为弧(arc).

无序配对指 $[v_i, v_j]=[v_j, v_i]$. 此时图 $G$ 称为无向图.

如果 $[v_i,v_j]$ 中 $v_i$ 是起点或源点, $v_j$ 是终点, 则称 $[v_i,v_j]$ 是有向边, 图 $G$ 是有向图(digraph).

顶点 $v$ 和 $w$ 邻接(adjacent)当且仅当 $[v,w]\in E$. 在无向图中, 若 $v$ 与 $w$ 邻接, 显然, $w$ 与 $v$ 也邻接, 此时邻接是对称关系.

有时边还具有第三种成分, 称作权(weight)或值(cost).

图中的一条路径(path)是指一个顶点序列 $w_1,w_2,w_3,\ldots,w_n$, 其中 $(w_i,w_{i+1})\in E$, $1\leq i < n$. 这条路径的长为该路径上的边数, $n-1$.

每一条边也可以有自己的长度, 如果 $(w_i,w_{i+1})$ 的长度是 $\ell_i$, 那么这条路径的长度是 $\sum_{i=1}^{n-1}\ell_i$.

设 $w_1,w_2,w_3,\ldots,w_n$ 是图中一条路径, 若除第一和最后一个点外, 其余所有顶点均不同, 则称之为简单路径(simple path).

起始点和终点相同的简单路径被称为环路(cycle).

设 $G=(V,E)$ 是一个无向图. 若 $G$ 中任两个顶点都存在一条路径连接, 则称 $G$ 是(道路)连通的(connected).

没有环路的连通无向图称为树(tree).

基本概念

生成树(spanning tree)

子图

如果图 $H=(V_H, E_H)$ 的顶点集合和边的集合都是图 $G=(V,E)$ 的子集, 即 $V_H\subset V$, $E_H\subset E$, 则称 $H$ 是 $G$ 的一个子图.

生成树

$G$ 的一个子图, 如果包含 $G$ 的所有顶点, 且是一棵树, 则称为 $G$ 的生成树(spanning tree).

假设 $G$ 是一个带权的图, 生成树的成本是所有链路成本之和.

一个具有 $n$ 个顶点的连通无向图至少有 $n-1$ 条边. 因此, 当连通网络的每条链路的建造成本都相同时, 即每条边的权都相同时, 任意一棵生成树的建设成本都可以将网络建设成本减至最小, 并保证网络的连通性.

如果不同的链路具有不同的建造成本, 即不同的边具有不同的权, 那么需要在一棵成本最小的生成树上建设链路.

基本概念

二部图(bipartite graph)

图 $G=(V,E)$ 的顶点集 $V$ 分为两个互不相交的子集的并, 即 $V=V_1\cup V_2$, 且 $E$ 仅由 $(v_{1i}, v_{2j})$ 组成, 这里 $v_{1i}\in V_1$, $v_{2j}\in V_2$, 则称 $G$ 是一个二部图(bipartite graph) 或二分图.

应用

假设你正在策划一次国际会议, 所有发言人都只说英语. 我们假设英语母语的听众不需要翻译. 每一个(非英语为母语的)与会人员所能听懂的语言是 $\{L_1,L_2,\ldots, L_n\}$ 中的一种. 翻译小组可以在英语和其他语言之间互译. 现在的任务是如何使得翻译小组的人数最少.

这样, 图 $G=(V,E)$ 构成一个二部图.

基本概念

度(degree)

在一个无向图中, 与顶点 $v_i$ 相关联的边的总数称为该顶点的度(degree), 记作 $d_i$, 或 $d_{v_i}$ 或 $\deg(v_i)$.

性质. 设 $G=(V,E)$ 是一个无向图. 令 $n=|V|$, $e=|E|$, 则

证明. 在无向图中, 每一条边都与两个顶点关联, 因此顶点的度之和等于边数的两倍. 第二个结论显然.

一个具有 $n$ 个顶点和 $\frac{n(n-1)}{2}$ 条边的无向图称为完全图(complete graph). 也即每一对顶点都有边相连. 用 $K_n$ 表示 $n$ 阶完全图.

入度(indegree)

设 $G$ 是有向图, 顶点 $v_i$ 的入度(in-degree)被定义为连接到(指向) $v_i$ 的边的数目, 即作 $d_i^{\mathrm{in}}$ 或 $d_{v_i}^{\mathrm{in}}$, 或 $\mathrm{indegree}(v_i)$ 即 \[ \mathrm{indegree}(v_i):=\#\{(u,v_i)\in E\} \]

顶点 $v_i$ 的出度(out-degree)被定义为关联于 $v_i$(即从 $v_i$ 出发) 的边的数目, 即作 $d_i^{\mathrm{out}}$ 或 $d_{v_i}^{\mathrm{out}}$, 或 $\mathrm{outdegree}(v_i)$ 即 \[ \mathrm{outdegree}(v_i):=\#\{(v_i,u)\in E\} \]

性质. 设 $G=(V,E)$ 是一个有向图. 令 $n=|V|$, $e=|E|$, 则

如果入度用正数表示, 出度用负数表示, 则 \[ \sum_{i=1}^{n}d_i^{\mathrm{in}}+\sum_{i=1}^{n}d_i^{\mathrm{out}}=0. \]

证明. 对于有向图中每条边 $(v_i, v_j)$, 它贡献了一个出度给 $v_i$, 贡献了一个入度给 $v_j$. 因此若采用上面的出度为负, 入度为正的写法, 则在计算所有顶点的出度和入度总和时, 结果总时 0.

记号的含义

记号的含义

记号 含义 英文
$V(G)$ 图 $G$ 的顶点集  
$E(G)$ 图 $G$ 的边的集合  
$|V|$ 集合 $V$ 中元素个数, 即顶点个数  
$|E|$ 集合 $E$ 中元素个数, 即边的条数  
$|G|$ 定义为 $|V(G)|$, 即图 $G$ 中顶点个数, 称为图 $G$ 的阶. order of $G$
$e(G)$ 图 $G$ 中边的条数, 即 $|E(G)|$. size of $G$
$x\in G$ 如果 $x$ 是 $G$ 的一个顶点, 即 $x\in V(G)$, 通常简写为 $x\in G$.  
$xy$ 边 $xy$  
$G^n$ 阶为 $n$ 的图 $G$.  
$G'\subset G$ 图 $G'=(V',E')$ 是图 $G=(V,E)$ 的子图, 即要求 $V'\subset V$ 且 $E'\subset E$. subgraph
$G\cong H$ 两个图同构, 可以简写为 $G=H$.  $G$ is isomorphic to $H$
$\Gamma(x)$ 与顶点 $x$ 关联的点之集. set of adjacent points of vertex $x$.
$d(x)$ 顶点 $x$ 的度, 即定义为 $d(x)=|\Gamma(x)|$. degree of vertex $x$
$d^{+}(x)$ $x$ 的出度, 即 $d^{+}(x)=|\{y\in\Gamma(x)\mid \overrightarrow{xy}\in E\}|$  
$d^{-}(x)$ $x$ 的入度, 即 $d^{-}(x)=|\{y\in\Gamma(x)\mid \overrightarrow{yx}\in E\}|$  
$\delta(G)$ $G$ 的最小度. minimal degree
$\Delta(G)$ $G$ 的最大度. maximum degree

通常我们考虑有限图, 即 $|V(G)|$ 和 $|E(G)|$ 均有限的图.

基本概念

Def. (同构) 图 $G=(V,E)$ 与 $G'=(V',E')$ 同构是指存在一个双射 $\phi: V\rightarrow V'$, 使得 $xy\in E$ 当且仅当 $\phi(x)\phi(y)\in E$.

显然, 同构的图拥有相同的阶和大小. 通常我们不区分两个同构的图, 除非图中有特定的标记的情况下.

Def. 度为 0 的点称为孤立点(isolated vertex).

Def. ($k$-正规图) 若 $\delta(G)=\Delta(G)=k$, 也即 $G$ 中每个顶点的度为 $k$, 则称图 $G$ 是 $k$-正规图($k$-regular graph), 或度为 $k$ 的正规图.

一个 $3$-正规图被称为立方图(cubic graph).

基本性质

Claim 1. $n$ 阶图 $G$ 的大小(size) 在 $0$ 和 $C_n^2=\frac{n(n-1)}{2}$ 之间.

Def. 大小为 $C_{n}^{2}$ 的图称为 $n$ 阶完全图(complete $n$-graph), 记作 $K^n$.

$n$ 阶空图指仅有 $n$ 个顶点, 边数为 0 的图, 记为 $E^n$.

Prop. 设 $G$ 是 $k$-正规图, 若 $k$ 是奇数, 则 $|G|$ 必是偶数.

Pf. 记 $m=|G|$, 则 $|E(G)|=\frac{m\cdot k}{2}$, 而 $k$ 是奇数, 故 $m$ 是偶数.


References

基本性质

基本性质

性质. 无向图 $G$ 中度为奇数的顶点个数是偶数. 即 $\#\{v_i\in V\mid \deg(v_i)\equiv 1\pmod 2\}$ 是偶数.

证明. (反证法) 假设度为奇数的顶点数目是奇数, 则这些度为奇数的顶点的度之和仍是奇数. 剩下的是度为偶数的顶点, 自然它们的度之和为偶数. 因此总的度之和是奇数, 这与 $\sum_{i=1}^{n}d_i=2e$ 矛盾.

强连通图

强连通

一个有向图是强连通(strongly connected)的, 当且仅当对于每一对不同的顶点 $v_i$ 和 $v_j$, 从 $v_i$ 到 $v_j$ 和从 $v_j$ 到 $v_i$ 都有一条有向路径.

性质. 对每个 $n$ ($n >= 2$), 都存在一个恰有 $n$ 条边的强连通有向图.

证明. 取顶点集 $V=\{v_1,v_2,\ldots,v_n\}$, 令 \[ E=\{(v_1,v_2),(v_2,v_3),\ldots,(v_{n-1},v_n),(v_n,v_1)\} \] 这样的有向图 $G=(V,E)$ 即符合要求.

性质. 每一个具有 $n$ ($n >= 2$) 个顶点的强连通有向图至少包含 $n$ 条边.

证明. (反证法) 设 $G=(V,E)$ 是具有 $n$ ($n >= 2$) 个顶点的强连通有向图, 这里 $V=\{v_1,v_2,\ldots,v_n\}$. 假若 $e=|E| < n$, 那么至多有 $n-1$ 条边关联这 $n$ 个顶点. 对于有向图, 做不到强连通. 这是因为强连通意味着每个顶点的出度和入度都至少是 1. 因此所有度之和至少是 $2n$. 而 $\sum_{i=1}^{n}d_i^{\mathrm{in}}+\sum_{i=1}^{n}d_i^{\mathrm{out}}=2e$, 故 $e >= n$.

无权图的描述

无权图的描述

对无向图最常用的描述方法都是基于邻接的方式: 邻接矩阵(adjacent matrix)邻接链表邻接数组.

邻接矩阵

一个 $n$ 顶点图 $G=(V,E)$ 的邻接矩阵(adjacent matrix)是一个 $n\times n$ 的矩阵, 假设是 $A$. 其每个元素是 $0$ 或 $1$. 设 $V=\{1,2,3,\ldots,n\}$. 对于无向图, $A$ 中的元素定义为: \[ A_{ij}=A(i,j)=\begin{cases} 1, & \text{若}\ (i,j)\in E\ \text{或}\ (j,i)\in E,\\ 0, & \text{否则}. \end{cases} \]

对于有向图, $A$ 中的元素定义为: \[ A_{ij}=A(i,j)=\begin{cases} 1, & \text{若}\ (i,j)\in E,\\ 0, & \text{否则}. \end{cases} \]

对于无向图, 有如下基本结论.

对于有向图,

邻接矩阵映射到数组

在用数组表示邻接矩阵时, 需要考虑访问的便捷性、准确性, 以及存储的问题.

图 $G=(V,E)$ 的顶点集 $V$ 一般

由于无权图的邻接矩阵元素是 $1$ 或 $0$. 故 在矩阵阶数并不大时, 不妨利用 $A(i,j)$ 的指标 $(i,j)$ 与二维数组中元素 $A[i][j]$ 的对应性, 使用 $(n+1)\times(n+1)$ 的数组来存储邻接矩阵.

对于无向图的邻接矩阵, 此时所浪费的空间是 \[ (n+1)^2-\frac{n(n-1)}{2} \]

对于大型的无向图, 其邻接矩阵是 $n$ 阶对称矩阵, 可以视为上三角或下三角矩阵. 应使用一个大小为 $\frac{n(n+1)}{2}$ 的一维数组来表示.

邻接链表

邻接链表

一个顶点 $i$ 的邻接表(adjacency list)是一个线性表, 它包含所有邻接于顶点 $i$ 的顶点.

在一个图的邻接表描述中, 图的每个顶点都有一个邻接表. 当邻接表用链表来表示时, 就称之为邻接链表(linked-adjacency-list).

邻接链表的存储空间估计

可以用存储类型为链表的数组(或向量, 比如 vector<List>) 来存储所有邻接链表.

假定这个数组名为 aList, 我们仍采用顶点 $i$ 对应到 aList[i] 的做法, 因此需要预留 $n+1$ 个存储空间. 每个一个指针和一个整数各需要 $4$ 个字节的存储空间. 因此用邻接链表描述一个 $n$ 顶点图时需要 $8(n+1)$ 个字节存储 $n+1$ 个 firstNode 指针和该数组.

每个链表节点的两个域(next和element)各需要 $4$ 个字节, 如果有 $m$ 个节点, 则需要 $4*2*m$ 个字节存储这些节点. 对于无向图, $m=2e$; 对于有向图, $m=e$. 这里 $e=|E|$ 为边数.

当 $e$ 远小于 $n^2$ 时, 邻接链表比邻接矩阵省空间. 例如, 一个 $e=n$ 的有向图, 用邻接链表描述需要 $16n+8$ 个字节,

邻接数组

邻接数组

在邻接数组中, 每一个邻接表用一个数组线性表而非链表来描述.

邻接数组比邻接链表少用 $4m$ 字节, 因为不需要 next 指针域(这样的指针域有 $m$ 个).

大部分的图操作, 无论是用邻接链表, 还是邻接数组, 其渐近复杂度是相同的.

根据实验, 对大部分的图操作, 邻接数组的用时要少于邻接链表.

加权图

加权图的描述

将无权图的描述进行简单扩充就可得到加权图的描述. 用成本邻接矩阵(cost-adjacency-matrix)$C$ 描述加权图.

如果 $C(i,j)$ 表示边 $(i,j)$ 的权, 那么它的使用方法和邻接矩阵的使用方法一样. 在这种描述方法中, 需要给不存在的边指定一个值, 通常是一个很大的值.

拓扑排序

拓扑排序

拓扑排序(topological sort)是对有向无圈图的顶点集的一种排序. 它使得若存在一条从 $v_i$ 到 $v_j$ 的路径, 则将 $v_j$ 排在 $v_i$ 的后面. 若 $v_i$ 和 $v_j$ 之间没有道路相连, 则此两个顶点的先后顺序可以任意.

显然, 如果图含有圈, 则无法进行拓扑排序.

拓扑排序的确切定义

设 $G(V,E)$ 是一个有向无圈图, $V=\{v_1,v_2,\ldots,v_n\}$. 序列 $v_{i_1}v_{i_2}\cdots v_{i_n}$ 是 $G$ 的所有顶点的一个排列(此时 $i_1,i_2,\ldots,i_n$ 是 $1,2,\ldots,n$ 的一个排列). 若对于 $G$ 中的任意一条有向边 $v_{j}\rightarrow v_{k}$, 在拓扑排列中 $v_{j}$ 出现在 $v_{k}$ 之前, 即 $j=i_a$, $k=i_b$, 且 $a < b$, 则称此排列为 $G$ 的一个拓扑排序.

注意: 拓扑排序不一定惟一.

最短路径算法

最短路径算法

无权最短路径

无权最短路径

Dijkstra 算法

Dijkstra 算法

具有负边值的图

具有负边值的图

无环图

无环图

所有顶点对的最短路径

所有顶点对的最短路径

最短路径举例

最短路径举例

网络流问题

最小生成树

最小生成树

Prim 算法

Prim 算法

Kruskal 算法

Kruskal 算法

深度优先搜索的应用

深度优先搜索的应用

无向图

无向图

双连通性

双连通性

欧拉回路

欧拉回路

有向图

有向图

查找强分支

查找强分支

NP 完全性介绍

NP 完全性介绍

难与易

难与易

NP 类

NP 类

NP 完全性问题

NP 完全性问题

End






Thanks very much!

This slide is based on Jeffrey D. Ullman's work, which can be download from his website.