本文参考Google OR-Tools官网文档介绍OR-Tools的使用方法。
1 网络流模型
网络流问题(Network Flows)是图论领域的一个经典问题,由多个节点和节点间的连接构成一个网络,在这个网络上需要考虑最大效率地传输。和其他图问题相比,网络流最关键的一个约束就是网络上的每条边都有固定的容量,在这条边上传输的最大量不能超过容量,拿现实中的例子来举例,比如一条网路上的数据上传有最大流量限制,一条交通要道上通过的车流量有上限。
数学上,将一个网络流定义为一个图 G = ( V , E ) G=(V,E) G=(V,E), V V V表示图上所有的节点集合, E E E表示图上所有的边集合,对于图 G G G,有:
- 每条边具有方向性,表示这上面的流的可流动方向
- 每条边 e ∈ E e \in E e∈E,都有一个非负数的容量 c e c_e ce,例如下面示意图中A和B间的容量为4
- 有一个源节点 s ∈ V s \in V s∈V,源节点只有流出,没有流入
- 有一个终结点 t ∈ V t \in V t∈V,终结点只有流入,没有流出
在图 G G G上,定义函数 f ( e ) f(e) f(e)表示边 e e e上的流的大小,对于 f ( e ) f(e) f(e)有着基本约束 0 ≤ f ( e ) ≤ c ( e ) 0\leq f(e)\leq c(e) 0≤f(e)≤c(e)
2 最大流问题 Maximum Flows
2.1 线性规划建模
在基本的流模型上,加上一个流平衡约束,对于一个除了 s s s和 t t t的节点 v v v,有
∑ e i n t o v f ( e ) = ∑ e l e a v i n g v f ( e ) \begin{aligned} \sum_{e\ into\ v} f(e)=\sum_{e\ leaving\ v} f(e)\\ \end{aligned} e into v∑f(e)=e leaving v∑f(e)
这个约束表示对于节点 v v v,流入的量等于流出的量
然后我们定义函数 v ( f ) v(f) v(f)表示网络流上流的总量值:
v ( f ) = ∑ e o u t o f s f ( e ) \begin{aligned} v(f)=\sum_{e\ out\ of\ s}f(e)\\ \end{aligned} v(f)=e out of s∑f(e)
即从 s s s节点流出的总量。有了这些信息,我们就可以把最大流问题定义为,对于一个网络流 G G G,找到它的最大的 v ( f ) v(f) v(f),也就是可以从节点 s s s流出的最大流量
最大流问题显然是一个线性规划问题。我们以上面的网络流示例图为例,要求的变量就是每条边上的流量大小 f ( e ) f(e) f(e),如下图中的 f S A f_{SA} fSA, f S C f_{SC} fSC, . . . ... ...
需要满足容量约束
f S A ≤ 4 f S C ≤ 3 f A B ≤ 4 . . . \begin{aligned} f_{SA}\leq 4 \\ f_{SC}\leq 3 \\ f_{AB}\leq 4 \\ ... \end{aligned} fSA≤4