跳转至

最小费用流:建模,拓展⚓︎

约 2539 个字 预计阅读时间 8 分钟

最小费用流问题(Minimal Cost Flow Problem)在网络最优化问题中占有核心地位。可以表述如下:

给定图 G(V,E)G(V,E),对每个节点 viv_i 均给定实数 bib_i, 如果 bi>0b_i > 0,那么称 bib_i 为发点,可以供给资源,bib_i 的值为该点的供给量。如果 bi<0b_i < 0,那么称 bib_i 为收点,需要接收资源, bi-b_i 为该点的需求量。若 bi=0b_i = 0,那么称 bib_i 为转运点。

对于每条边 eje_j,给定实数 cjc_j,它是在边 eje_j 上每单位流量的费用,称为费用系数。再给定正数 uju_j,它是边 eje_j 上流量的上界。

最小费用流的问题就是要确定每个边上的流量 xjx_j,使得不超过上界限制,并满足各个节点的供需要求,同时又使得总费用最小。对于网络,我们引入一个 m×nm \times n 的矩阵 AA。其中每个元素按照如下标准取值:

aij={1,if ejstarts fromvi1,if ejends atvi0,Otherwise\begin{aligned}\begin{equation*}
a_{ij} = \begin{cases}
1, \hspace{10pt} \text{if } e_j \quad \text{starts from} \quad v_i \\
-1, \hspace{10pt} \text{if } e_j \quad \text{ends at} \quad v_i \\
0, \hspace{10pt} \text{Otherwise}
\end{cases}
\end{equation*}\end{aligned}

写成矩阵形式,如下:

[1100010010110000011010100001100100000111]\begin{bmatrix} 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 \\ -1 & 0 & 1 & 1 & 0 &  0 & 0 & 0 \\  0 & -1 & -1 & 0 & 1 & 0 & -1 & 0 \\ 0 & 0 & 0 & -1 & -1 & 0 & 0 & -1 \\ 0 & 0 & 0 & 0 & 0 & -1 & 1 & 1 \end{bmatrix}

即可表示如图的网络。

在前面介绍最短路问题的时候,我们也出现了这个矩阵,一般称之为节点-边关联矩阵(Node-edge incidence matrix)。

事实上,最小费用流模型可以视为一种基于边的建模方式。由于上述矩阵的列数 = 边数,所以假设我们的决策变量是针对每一条边而言的,那么关联矩阵乘决策向量,正好构成了约束条件的左端项,同时约束条件的个数也就对应了节点个数,可以用此刻画节点中的流量关系。以矩阵乘法形式给出就是:

[1100010010110000011010100001100100000111][x1x2x3x4x5x6x7x8]=[b1b2b3b4b5]\begin{bmatrix} 1 & 1 & 0 & 0 & 0 & 1 & 0 & 0 \\ -1 & 0 & 1 & 1 & 0 &  0 & 0 & 0 \\  0 & -1 & -1 & 0 & 1 & 0 & -1 & 0 \\ 0 & 0 & 0 & -1 & -1 & 0 & 0 & -1 \\ 0 & 0 & 0 & 0 & 0 & -1 & 1 & 1 \end{bmatrix} \begin{bmatrix} x_1 \\ x_2 \\ x_3 \\ x_4 \\ x_5 \\ x_6 \\ x_7 \\ x_8 \end{bmatrix}= \begin{bmatrix} b_1 \\ b_2 \\ b_3 \\ b_4 \\ b_5 \end{bmatrix}

节点-边关系矩阵

m×nm \times n 的矩阵,行表示节点,列表示边。

对每一列而言,有且仅有一个1和一个-1,1表示从该节点出发,-1表示到该节点。0表示与该节点无关。

对每一行而言,可能有多个1和多个-1,因为一个节点可能有多条边出发/到达,1的个数,表示从该节点出发的边数(出度);-1的个数,表示到达该节点的边数(入度)。

于是,我们给出最小费用流的数学模型:

mincx\min \mathbf{cx}
{Ax=b0xu\begin{aligned}
\begin{cases}
\begin{align}
\mathbf{Ax} = \mathbf{b} \quad\\
\mathbf{0} \leq \mathbf{x} \leq \mathbf{u} \quad
\end{align}
\end{cases}
\end{aligned}

其中,A\mathbf{A} 就是节点-边关系矩阵,x\mathbf{x} 是边的流量向量,长度等于边的数量; b\mathbf{b} 是每个节点的供求向量,长度等于节点的数量。u\mathbf{u} 是边的流量限制向量,限制每条边的流量大小。

对于约束 (1) 中的每一个约束,可以表示为:

jEaijxj=bi,iV\sum \limits_{j \in E} a_{ij} x_j = b_i , \forall i \in V

实际上,左边就是:

jEaijxj=aij=1xjaij=1xj,iV\sum \limits_{j \in E} a_{ij} x_j = \sum \limits_{a_{ij} = 1} x_{j} - \sum \limits_{a_{ij} = -1} x_j  , \forall i \in V

(因为如果 aij=0a_{ij} = 0,就不会出现 xjx_j )。

等式右边的第一个和式,对应的是所有从 vjv_j 离开的流量;第二个和式,对应所有汇入 vjv_j 的流量。

不失一般性,我们可以假设供求总是平衡的,也就是 iVbi=0\sum_{i \in V} b_i = 0,对于供大于求的图 (iVbi>0\sum_{i \in V} b_i > 0),可以设置一个虚拟节点,吸收全部的过剩供给量,从每个发点添加一个虚拟边到这个虚拟节点,这个虚拟边的费用是0。这样就转化为一个供求平衡的最小费用流问题。

最小费用流问题是网络流问题的重要基础,事实上,许多问题均可以被转化为这类问题,或者是最小费用流问题的一个特例。下面展开几个例子。




从最小费用流到运输问题⚓︎

运输问题,具体的问题描述同样可以参考第三章。这里简要复习一下。

运输问题

给定一张图G(V,E)G(V,E),所有节点分为供给节点和需求节点两类。各个供给节点之间没有边相连,各个需求节点之间也没有边相连,但是供给和需求节点之间可以相互抵达。以图论的概念表示,网络图就是一个Bipartite Graph(二分图,概念的具体解释见本笔记最后)。

  • 问题:我们需要在事先给定运费和供给量的情况下,规划从不同供给节点到不同需求节点运送的货物量,使得总运输成本最小,同时还能满足所有需求节点的需求。

第三章,我们已经给出了运输问题在供需平衡下的建模, 由于我们考虑的是不带转运的运输问题,因此建模如下:

minz=i=1mj=1ncijxij\mathop{\min} \hspace{4pt} z = \sum \limits^{m}_{i = 1} \sum \limits^{n}_{j = 1} c_{ij}x_{ij}
s.t{j=1nxij=ai,i=1,2,..,mi=1nxij=bj,j=1,2,..,nxij0,i=1,2,...m,j=1,2...ns.t \hspace{4pt} \left\{ \begin{aligned} \sum \limits^{n}_{j=1} x_{ij} = a_i , i = 1,2,..,m \\ \sum \limits^{n}_{i=1} x_{ij} = b_j , j = 1,2,..,n   \\  x_{ij} \geq 0, i = 1,2,...m, j = 1,2...n  \end{aligned}  \right.

这里的决策变量 xijx_{ij} 是基于节点的,表示从 ii 地到 jj 地的流量。我们同样可以基于最小费用流模型框架给出模型,差异在于,基于最小费用流模型的决策变量是基于边的。 yijy_{ij} 表示边 (i,j)E(i,j) \in Eii 流到 jj的流量。我们保持节点-边关系矩阵 (incidence-matrices)不变,作为系数矩阵, cijc_{ij} 表示边 (i,j)(i,j) 上的运输成本。所以可以给出等价模型:

minz=(i,j)Ecijyij\mathop{\min} \hspace{4pt} z = \sum \limits_{(i,j) \in E} c_{ij} y_{ij} 
{(i,j)Eyij(j,i)Eyji=di,iVyij0,(i,j)E\begin{aligned}
\begin{cases}
\begin{align}
\sum \limits_{ (i, j) \in E} y_{ij} - \sum \limits_{(j, i) \in E} y_{ji} = d_i, \quad \forall i \in V \\
y_{ij} \geq 0, \quad \forall (i,j) \in E
\end{align}
\end{cases}
\end{aligned}

这里的右端项 did_i 表示:运输问题下,节点 ii 的需求情况。由于节点区分供给点和需求点,因此,有如下情形:

  1. 如果 ii 是供给点,记该点的供给量为 aia_i,则 di=aid_i = a_i
  2. 如果 ii 是需求点,记该点的需求量为 bib_i,则 di=bid_i = -b_i

事实上,基于此,我们也可以很容易地写出基于边的建模框架下,带转运的运输问题的模型。

解答

实际上,你只需要更改一下 did_i 的定义即可,除了收地、发地外,还要考虑中转地,中转地不存储货物,因此中转点的 di=0d_i = 0,也就是流平衡约束。

从最小费用流到指派问题⚓︎

指派问题可以视为运输问题的一个特例,实际背景是把 n 个活分配给 n 个人去做,每个人做不同工作有不同的时间,每个人都做一个工作,使得总时间最少。

上面已经写了最小费用流 -> 运输问题,只需要稍微修改就可以得到分配问题的建模。

限制每个节点的供给/需求量都是1,每个边上的流量只能为0或者1.




从最小费用流到最短路问题⚓︎

从最小费用流模型也可以推导出最短路问题的建模。一句话概括一下最短路:

已知一个网络上各边长度,要求出从图上给定的节点 vsv_s 到 节点 vtv_t 的最短路径。

事实上,只需要把最小费用流的系数 cijc_{ij} 换成边 (i,j)(i,j) 的长度。令右端项中 bs=1,bt=1b_s = 1, b_t = -1,其他 bi=0b_i = 0,就得到了最短路问题的模型。这其实就是限制了除了起点和终点外其他节点都视为转运点。各个边上的流量上界 uiju_{ij} 取 1。这样就得到了最短路问题的建模。这个建模可以参考第七章:最短路问题 .




⚓︎

从最小费用流到最大流问题⚓︎

从最小费用流模型也可以推导出最大流问题的建模。一句话概括一下最大流:

已知一个网络上各边的流量上界,每个边的流量不得超过这个界限。要求出从图上给定的节点 vsv_s 到 节点 vtv_t 的最大流量。

看起来不怎么相关的问题,也可以转化为最小费用流进行计算。

我们先令原来网络中所有边的费用系数向量 c=0\mathbf{c} = \mathbf{0},令供求向量 b=0\mathbf{b} = \mathbf{0}。此时,我们添加一条虚拟边 en+1e_{n+1},从终止节点 vtv_t 通往 vsv_s。这条边上的流量没有上界限制,其费用系数为负数,设为 1-1

此时,求解包括这个虚拟边的新图的最小费用流问题。因为虚拟弧的边权(费用系数)是负数,所以当目标函数最小的时候,这条边上的流量也就达到最大了。同时,由于 b=0\mathbf{b} = \mathbf{0},意味着所有节点的流入和流出的流量是相等的(包括起点和终点,与之不同的,最小费用流问题的起终点的流量不为0)。

上述建模方式,实际上是,虚拟边流入节点 vsv_s 的流量就要在原来的网络上以零费用返回节点 vtv_t,也就是说只要不超过各边的流通能力,从 vsv_svtv_t 的流量越大。