05. 图与网络
基本概念
无向图:一个非空有限集合
和 中的某些元素的无序对集合 构成的二元组,记 其中 称顶点集或结点集, 称边集, 中的每个元素 为 中某两个元素 的无序对,记 称从 到 的边; - 有限图:结点集和边集都有限的图;
- 简单图:没有环也没有两条边连接同一对结点。
有向图:一个有向图
由一个非空有限集合 和 中的某些元素的有序对集合 构成二元组,记 其中 称顶点集或结点集, 称弧集, 中的每个元素 为 中某两个元素的有序对,记 称从 到 的弧; 完全图:每一对不同的顶点都有一条边相连的简单图;
子图:如果
,称 是 的子图, 是 的母图; 结点的度:设
, 中与 关联的边数称 的度,记 。
问题求解
最短路
对于给定的赋权图
固定起点 Dijkstra 算法
Dijkstra 的步骤:
为每个结点维护:
: 表示起点到结点 的长度; : 表示结点 的父结点。
令
,对 ,令 对每个
,令 若此次迭代利用结点 修改了 ,则 ,否则不变; 将结点
加入 ,构成新的集合; 若
或 进入 ,算法终止;否则转步骤 3。
每对结点 Floyd 算法
Floyd 算法:
对于赋权图
如果要求得最短路径,还需引入路由矩阵
初始时
迭代公式为
其中
最小生成树
在赋权图
Kruskal 算法
步骤:
- 初始化
; - 每次从
中选取一条边,加入 ,要求使得 不构成圈的边中权值最小; - 直到选取
个边为止 。为 结 点 个 数
Prime 算法
步骤:
初始化
;每次找最短边
,其中 ,使直到
中包含所有结点。
最大流
给定有向图
满足下列条件的流
容量限制:对每一弧
, ;平衡:
即,发点的流出为 ,收点的流入为 ,其余点流出量=流入量。
根据上述条件,可以构造线性规划模型
不过对于图论模型,有效率更高的解决方法。
Ford-Fulkerson 算法
步骤:
初始化一个残差网络,与原网络相同,为每条弧
初始化空闲流量 (即未使用的流量) ,其中 为容量;找到一个从发点到收点的路径,记经过的弧集
取空闲流量最小值作为路径的流量,对每条弧更新空闲流量对找到的路径生成反向路径,记经过的弧集
其中 即为 的反向弧,每条弧的空闲流量即为之前的正向路径扣除的流量合并相同方向的弧,使它们的空闲流量相加;
直到找不到发点到收点的路径,迭代结束,否则转步骤 2;
令初始网络的每条弧的容量
与迭代后的残差网络对应的弧的闲流量 相减,即为该条弧的流量
Networkx 包
networkx 是一个用 Python 开发的图论与复杂网络建模工具,内置常用的图与复杂网络的分析算法。
常用函数如下:
Graph()
: 创建无向图;DiGraph()
: 创建有向图;add_edge()
:加边;add_edge_from()
:加多条边;add_node()
:加结点;add_node_from()
:加多个结点;dijkstra_path()
:求最短路径;dijkstra_path_length()
:求最短距离。
画图
对于邻接矩阵表示的无向图:
1 | # %% |
输出如下:
求最短路
对下图:
graph LR v1 v2 v3 v4 v5 v6 v7 v1 --3--> v2 v1 --2--> v3 v2 --4--> v4 v2 --6--> v5 v2 --2--> v6 v3 --8--> v2 v3 --1--> v4 v3 --3--> v6 v4 --2--> v5 v6 --5--> v5 v5 --7--> v7 v6 --3--> v7
固定起点
求解
1 | # %% |
输出如下:
1 | (['v1', 'v3', 'v6', 'v7'], 8) |
于是有,最短路径为
每对结点
对于上述问题,求解任意每对结点间的最短距离和路径,代码如下:
1 | # %% |
输出如下:
1 | ({'v1': {'v1': ['v1'], |
可以发现,如
求最小生成树
对画图示例的邻接矩阵求最小生成树,代码如下:
1 | # %% |
输出如下:
求最大流
对于求最短路的示例,将权值看作容量,求
1 | # %% |
输出如下:
1 | (5, |
最大流为 5,并给出具体流向和流量。 e, flow_dic
%%
dic = {} for s in flow_dic: for t in flow_dic[s]: dic[(s,t)] = flow_dic[s][t]
pos = nx.spring_layout(G) nx.draw_networkx(G, pos=pos)
nx.draw_networkx_edge_labels(T,pos=pos, edge_labels=dic)
1
2
3
4
5
6
7
8
9
10
11
12
输出如下:
```python
(5,
{'v1': {'v2': 3, 'v3': 2},
'v2': {'v4': 0, 'v5': 3, 'v6': 0},
'v3': {'v2': 0, 'v4': 0, 'v6': 2},
'v4': {'v5': 0},
'v5': {'v7': 3},
'v6': {'v5': 0, 'v7': 2},
'v7': {}})
[外链图片转存中...(img-CFykI3AE-1627132572853)]
最大流为 5,并给出具体流向和流量。