系列文章
【管理运筹学】第 7 章 | 图与网络分析(1,图论背景以及基本概念、术语、矩阵表示)
【管理运筹学】第 7 章 | 图与网络分析(2,最小支撑树问题)
【管理运筹学】第 7 章 | 图与网络分析(3,最短路问题)
【管理运筹学】第 7 章 | 图与网络分析(4,最大流问题)
文章目录
- 系列文章
- 引言
- 五、最小费用流问题
- 5.1 基本概念及定理
- 5.2 最小费用流算法
- 六、最小费用最大流问题
- 写在最后
引言
上一篇文章,我们讨论了网络最大流的问题,但是没有考虑运送这些流量所需要产生的费用,因此,本文来对流的费用问题进行探讨。
五、最小费用流问题
5.1 基本概念及定理
相关概念可以套用上一节的内容来定义,上一节中的网络,有流量 f i j , c i j f_{ij},c_{ij} fij,cij 两个属性,考虑费用时,我们需要再添加一个 w i j w_{ij} wij ,表示弧 a i j a_{ij} aij 的单位流费用。那么一条流的费用即为各段弧的费用之和,所有流中,费用最小的流称为最小费用流。
对于一条增广链 μ \mu μ ,所有前向弧的费用减去所有后向弧的费用即为链 μ \mu μ 的费用。所有增广链中费用最小的链,称为最小费用增广链,用 μ ∗ \mu^* μ∗ 表示。
定理 1 —— 若 f f f 为流量为 V ( f ) V(f) V(f) 的最小费用流, μ \mu μ 是关于 f f f 的从起点到终点的一条最小费用增广链,则 f f f 经过 μ \mu μ 调整流量后得到新的可行流 f ′ f' f′ , f ′ f' f′ 一定是流量为 V ( f ) + θ V(f)+\theta V(f)+θ 的可行流中的最小费用流。
5.2 最小费用流算法
定理 1 实际上为我们提供了一种求解最小费用流问题的思路,也就是为了求流量目标为 V m V_{m} Vm 的最小费用流,可以先从一个初始的最小费用可行流(一般采用零流,肯定能保证是最小费用)开始,根据上一节最大流算法的思想,不断调整这个初始的最小费用流,直至流量满足目标。
根据定理 1 ,初始的最小费用流增广链每一次调整后仍然是最小费用流,因此当流量达到目标后,即找到了 V m V_m Vm 的最小费用流。
每次调整流量后,都会得到一个新的流量网络,如何在新的流量网络中寻找到最小费用增广链是我们主要解决的问题。
如果把每条弧的费用看成是弧的权重,其实最小费用流问题可以近似看成一个最短路问题,而我们前面就学过最短路问题的解法。但由于每次调增流量后,网络中还存在着每条弧容量的限制,对于已经满容量的弧,其应只能减少流量,所以需要对网络进行一定处理。
因此,我们每次调整流量后,需要构造一个新的赋权有向网络 L ( f ) L(f) L(f) ,在这样的网络中,求最小费用增广链即为求起点到终点的最短路问题。
L ( f ) L(f) L(f) 的构造方法如下: L ( f ) L(f) L(f) 的顶点是原网络 G = ( V , A , C , W ) G=(V,A,C,W) G=(V,A,C,W) 中的点,而把 G G G 中的每一条弧 ( v i , v j ) (v_i,v_j) (vi,vj) 变成两个方向相反的弧 ( v i , v j ) (v_i,v_j) (vi,vj) 和 ( v j , v i ) (v_j,v_i) (vj,vi) 。定义这两条弧的权重 l i j l_{ij} lij 和 l j i l_{ji} lji 为 l i j = { w i j , f i j < c i j + ∞ , f i j < c i j , l j i = { − w i j , f i j > 0 + ∞ , f i j = 0 . l_{ij} = \begin{cases} w_{ij}, & f_{ij}<c_{ij} \\ +\infty, & f_{ij}<c_{ij} \\ \end{cases}, l_{ji} = \begin{cases} -w_{ij}, & f_{ij}>0 \\ +\infty, & f_{ij}=0 \\ \end{cases}. lij={wij,+∞,fij<cijfij<cij,lji={−wij,+∞,fij>0fij=0. 为简化网络,权重为 + ∞ +\infty +∞ 的弧可以省去。
如下图所示,括号里第一个数字为费用,第二个数字为容量,第三个数字为流量。对于未满容量的弧,构造的有向网络为双向弧,而对于已经满容量的弧,构造后只能为单向的弧(无穷省略了)。
综上所述,流量目标为 V m V_m Vm 的最小费用流算法步骤如下:
- k = 0 k=0 k=0 ,从一流量为 V ( f 0 ) V(f^0) V(f0) 的最小费用初始可行流 f 0 f^0 f0(一般取零流)开始。
- 构造 L ( f k ) L(f^k) L(fk) ,在 L ( f k ) L(f^k) L(fk) 中求从起点到终点的最短路,若 L ( f k ) L(f^k) L(fk) 中找不到最短路,则 f k f^k fk 为最大流,若 V ( f k ) < V m V(f^k)<V_m V(fk)<Vm ,表明不存在流量为 V m V_m Vm 的最小费用流,算法结束;否则转下一步。
- 在原网络中找到与 L ( f k ) L(f^k) L(fk) 中最短路对应的增广链 μ k \mu_k μk ,计算调整量 θ k = m i n { m i n μ k + { ( c i j − f i j k } , m i n μ k − f i j k } \theta_k=min\{min_{\mu_k^+}\{(c_{ij}-f_{ij}^k\},min_{\mu_k^-}f^k_{ij}\} θk=min{minμk+{(cij−fijk},minμk−fijk} 。若 θ k ≤ V m − V ( f k ) \theta_k \leq V_m-V(f^k) θk≤Vm−V(fk) ,则在链 μ k \mu_k μk 上按最大流算法中的调整方案调整,得到新流 f ′ f' f′ ,令 k = k + 1 k=k+1 k=k+1 ,赋新流为 f k f^k fk ,转第二步;否则,当 θ k > V m − V ( f k ) \theta_k > V_m-V(f^k) θk>Vm−V(fk) 时,在链 μ k \mu_k μk 上按最大流算法中的调整方案调整,调整量为 V m − V ( f k ) V_m-V(f^k) Vm−V(fk) ,得到新流 f ′ f' f′ , f ′ f' f′ 即为所求最小费用流,算法结束。
如果网络中节点个数较少,在求最短路时,可以不采用 Dijkstra 算法(无负权时)或逐次逼近法(出现负权时),而采用枚举法,加快求解速度。
六、最小费用最大流问题
所谓最小费用最大流,指的是对于最小费用可行流 f f f 没有目标流量的要求,但要求为最大。
有了最小费用流算法的铺垫,最小费用最大流算法就更好理解多了。后者的算法也前者几乎相同,只是后者算法结束不是找到 V ( f ) = V m V(f)=V_m V(f)=Vm 为止,而是在构造的有向网络中找不到最短路为止,其算法步骤如下:
- k = 0 k=0 k=0 ,从一流量为 V ( f 0 ) V(f^0) V(f0) 的最小费用初始可行流 f 0 f^0 f0(一般取零流)开始。
- 构造 L ( f k ) L(f^k) L(fk) ,在 L ( f k ) L(f^k) L(fk) 中求从起点到终点的最短路,若 L ( f k ) L(f^k) L(fk) 中找不到最短路,则 f k f^k fk 为最小费用最大流(转第四步);若存在最短路,进入第三步,调整。
- 在原网络中找到与 L ( f k ) L(f^k) L(fk) 中最短路对应的增广链 μ k \mu_k μk ,计算调整量 θ k = m i n { m i n μ k + { ( c i j − f i j k } , m i n μ k − f i j k } \theta_k=min\{min_{\mu_k^+}\{(c_{ij}-f_{ij}^k\},min_{\mu_k^-}f^k_{ij}\} θk=min{minμk+{(cij−fijk},minμk−fijk} 。在链 μ k \mu_k μk 上按最大流算法中的调整方案调整,得到新流 f ′ f' f′ ,令 k = k + 1 k=k+1 k=k+1 ,赋新流为 f k f^k fk ,转第二步。
- 停止运算,输出当前最小费用最大流,作为 G G G 的最小费用最大流。
写在最后
图论总算是完结了,攻坚战,但是还需要大量的训练加以巩固训练,有机会把这些算法用编程实现一下。