算法导论随笔(十一):最大流(Max-Flow)与Ford-Fulkerson算法(附Python实现源码)

前面的几篇文章中我们讨论了一些图的算法。其中大部分都是关于无向图的算法。这篇文章里我来说说有向图的算法。先说一说有向图的一个应用,也就是流网络(Flow Network)。

1. 流网络

先来看流网络的定义。对于流网络,《算法导论》第26章是这样定义的:

流网络 G = (V, E)是一个有向图,图中每一条边(u, v) ∈ E有一个非负的容量值c(u, v) >=0。而且,如果边集合E包含一条边(u, v),则图中不存在反方向的边(v, u)。如果(u, v) ∉ E,则为方便起见,定义c(u, v) = 0。并且在图中不允许自循环。在流网络的所有节点中,我们特别分辨出两个特殊节点:源节点s和汇点t。

下面我来用一个例子对这个定义进行解释。来看下面的这个有向图。图中的s为源节点(source),t为汇点(sink)。也就是说,对于顶点s,只能有以它为起点的边;而对于t,只能有以它为终点的边。图中每个边上面的数字就是这条边的容量值c。例如,c(s, v) = 6。图中没有(s, z)这条边,因此c(s, z) = 0。图中不能有自循环边,也就是(s, s)这样的边。我们用f(u, v)表示两个点之间的实际流量值。

算法导论随笔(十一):最大流(Max-Flow)与Ford-Fulkerson算法(附Python实现源码)_第1张图片
一个流网络有如下两个性质
容量限制:对于流网络中所有的节点u, v ∈ V,都有
0 ≤ f ( u , v ) ≤ c ( u , v ) 0 \le f(u, v) \le c(u, v) 0f(u,v)c(u,v)
也就是说,图中一条边的实际流量不能超过流量上限(即容量值c, 是capacity的缩写),也不能少于0。例如,我们把上图想象成一个水管网格。那么对于(s, w)这条水管来说,它里面流淌的水不能超过6个单位(也就是c(s, w)),也不能少于0个单位。

流量守恒: 对于流网络中除了s和t之外的其他节点 v∈ V - {s, t},都有
∑ v ∈ V f ( v , u ) = ∑ v ∈ V f ( u , v ) \sum\limits_{v \in V} f(v, u) = \sum\limits_{v \in V} f(u, v) vVf(v,u)=vVf(u,v)
这个看起来复杂的公式其实要表达的意思非常简单。以上面图中的点u来说,所有以它为终点的边的实际流量的和,必须等于所有以它为起点的边的实际流量的和

(注意:我们用x/y来表示一条边的实际流量和容量,例如下图中(s, v1)的11/16,表示实际流量为11,容量为16)

举一个例子说明这个性质。如下图。例如对于点v1来说,有两条边以它为终点:(s, v1)和(v2, v1)。我们来看着两条边的流,一个是f(s, v1) = 11,一个是f(v2, v1) = 1。因此,以v1为终点的边的实际流量之和为11 + 1 = 12。
而网络中以v1为起点的边只有一条,即(v1, v3)。而f(v1, v3) = 12。
算法导论随笔(十一):最大流(Max-Flow)与Ford-Fulkerson算法(附Python实现源码)_第2张图片
因此,对于点v1,我们有
f ( s , v 1 ) + f ( v 2 , v 1 ) = f ( v 1 , v 3 ) = 12 f(s, v_1) + f(v_2, v_1) = f(v_1, v_3) = 12 f(s,v1)+f(v2,v1)=

你可能感兴趣的:(算法,路径规划,算法,python)