目录
十二、图与网络
图是用以理解元组(tuple)最好的知识;
元组就是数学模型;
12.1 有向图
Definition 12.1 A directed graph is a tuple G = ( V , E ) \mathrm{G} = (\mathbf{V},\mathbf{E}) G=(V,E), where V \mathbf{V} V is the set of nodes, E ⊆ V × V \mathbf{E} \subseteq \mathbf{V} \times \mathbf{V} E⊆V×V is the set of arcs.
- 节点集合 V = { v 1 , … , v n } \mathbf{V} = \{ v_{1}, \dots, v_{n} \} V={ v1,…,vn};
- 弧(有向边)的集合 E \mathbf{E} E 本质上是 V \mathbf{V} V 上的关系。因此,节点比边更本质;
- 弧记为 ⟨ v i , v j ⟩ \langle v_i, v_j \rangle ⟨vi,vj⟩,有角度的括号表示有向;
- 元组(tuple)可以把不同类型的数据融合到一起,对应与Java程序设计中的对象;
12.2 元组与对象
图的Java代码如下:
public class Graph{
/**
* 节点数. 表示节点 v_0 至 v_{n-1}.
*/
int n;
/**
* 相应弧是否存在. 1 表示是,0 表示否. 最多有 n*n 条弧.
*/
int[][] arcs;
/**
* 构造一个包括 n 个节点的图,没有边.
*/
public Graph(int paraN) {
n = paraN;
arcs = new int[n][n];
}// Of the constructor
/**
* 设置边,paraValue = 1 表示添加, 0 表示删除.
*/
public void setArc(int paraI, int paraJ, int paraValue) {
arcs[paraI][paraJ] = paraValue;
}// Of setArc
}// Of Graph
- 元组为对象的成员变量部分.
- 邻接矩阵表示:
E = [ 0 1 1 0 0 0 0 0 0 1 0 0 1 0 1 0 ] \mathbf{E} = \left[ \begin{matrix} 0&1&1&0 \\ 0&0&0&0 \\ 0&1&0&0 \\ 1&0&1&0 \end{matrix} \right] E= 0001101010010000
源码展示:\mathbf{E} = \left[ \begin{matrix} 0&1&1&0 \ 0&0&0&0 \ 0&1&0&0 \ 1&0&1&0 \end{matrix} \right]
12.3 二元关系与有向图
- 有向图的边集合可以看做一个关系.
- 课堂练习:
- 根据二元关系的知识,计算 E 2 = E ∘ E , E 3 = E 2 ∘ E \mathbf{E}^{2}=\mathbf{E} \circ \mathbf{E}, \mathbf{E}^{3}=\mathbf{E}^{2} \circ \mathbf{E} E2=E∘E,E3=E2∘E 与 E 0 \mathbf{E}^{0} E0,源码为\mathbf{E}^{2}=\mathbf{E} \circ \mathbf{E}, \mathbf{E}{3}=\mathbf{E}{2} \circ \mathbf{E}:.
- 根据矩阵知识,计算 E 2 , E 3 , E 0 \mathbf{E}^{2}, \mathbf{E}^{3}, \mathbf{E}^{0} E2,E3,E0.
- 对照分析.
- 回到图上,分析可行性.
- 不但表达了可达性,而且表达了路径数量.
12.4 无向图
Defination 12.2 An undirected graph is a tuple G = ( V , E ) \mathrm{G}=(\mathbf{V},\mathbf{E}) G=(V,E), where V \mathbf{V} V is the set of nodes, E ⊆ V × V \mathbf{E} \subseteq \mathbf{V} \times \mathbf{V} E⊆V×V where ( v i , v j ) ∈ E ⇔ ( v j , v i ) ∈ E ( v_{i}, v_{j}) \in \mathbf{E} \Leftrightarrow ( v_{j}, v_{i}) \in \mathbf{E} (vi,vj)∈E⇔(vj,vi)∈E is the set of edges.
源码为:( v_{i}, v_{j}) \in \mathbf{E} \Leftrightarrow ( v_{j}, v_{i}) \in \mathbf{E}
- 无向边用小括号, ( v i , v j ) (v_i,v_j) (vi,vj).
- 问题:有向图和无向图,哪个更特殊?
在无向图中,边没有方向,常用于表达节点之间无特殊方向性关系的场景,如地图上城市与城市的连接。在有向图中,边是有方向的,常用于表达具有明确方向性关系的场景,如食物链中的捕食关系。因此,我认为有向图更特殊一些,它引入了方向性这一特点,使有向图在表达复杂关系时更具体。 - 练习:写出该无向图的邻接矩阵.
邻接矩阵表示如下:
E = [ 0 1 1 1 1 0 1 0 1 1 0 1 1 0 1 0 ] \mathbf{E} = \left[ \begin{matrix} 0&1&1&1 \\ 1&0&1&0 \\ 1&1&0&1 \\ 1&0&1&0 \end{matrix} \right] E= 0111101011011010
12.5 有向网络
有向网络的Java代码如下:
public class Net{
/**
* 节点数. 表示节点 v_0 至 v_{n-1}.
*/
int n;
/**
* 权重.
*/
double[][] weights;
/**
* 构造一个包括 n 个节点的网,权值均为0.
*/
public Net(int paraN) {
n = paraN;
weights = new double[n][n];
}// Of the constructor
/**
* 设置边权重.
*/
public void setWeight(int paraI, int paraJ, double paraWeight