最小费用流算法详解

文章目录

  • 1.前言
  • 2.问题
  • 3.可以写成如下规划
  • 4.上述规划问题的对偶问题
  • 5.互补松紧条件
  • 6.最小费用流算法

1.前言

  • 在学习最小费用流算法时,对其算法的设计,条件的设计,算法的流程有很大的疑惑,遂花时间来理解
  • 本文仅个人理解,仅供参考
  • 阅读本文前,最好已经了解过最大流算法,知道如何寻找增广路
  • 博主目前无法证明最小费用流算法的正确定,这里只介绍其原理及流程
  • 后续可能会添加实例,或者介绍最大流算法

2.问题

最小费用流算法详解_第1张图片

给定流值v,找到从 s->t 流值为 v 的流中,花费最小的那个流

3.可以写成如下规划

最小费用流算法详解_第2张图片

我们在图中,会用一对数表示一条边的信息,(a, b)

  • 其中 a 代表边的长度,也就是单位花费

  • b 代表边的容量,也就是允许通过的最大流值
    最小费用流算法详解_第3张图片

4.上述规划问题的对偶问题

将原问题的 x i j ≤ c i j x_{ij} \le c_{ij} xijcij 写成 − x i j − 新 变 量 = − c i j -x_{ij}-新变量 = -c_{ij} xij=cij 就很容易写成下面的形式

最小费用流算法详解_第4张图片

  • 每个变量没有很直观的物理意义,我们构造出来只是为了解决原始问题,但是在后面的分析中,我们能够很直观地看出每个变量的作用

5.互补松紧条件

若原问题的可行解 { x i j } \{x_{ij}\} {xij},对偶问题的可行解 { p i , r i j } \{p_i, r_{ij}\} {pi,rij}分别是原问题和对偶问题的最优解,则其充要条件是互补松紧条件,如下所示:

注意:必须要先是可行解,满足互补松紧条件之后,才能是最优解

最小费用流算法详解_第5张图片

我们进一步观察,可以通过上述两个等式,推导出下面两个条件

最小费用流算法详解_第6张图片

本算法的妙处之一:构造 r i j = m a x ( 0 , p j − p i − w i j ) r_{ij} = max(0, p_j -p_i-w_{ij}) rij=max(0,pjpiwij) ,这使得 r i j ≥ p j − p i − w i j r_{ij} \ge p_j-p_i-w_{ij} rijpjpiwij 恒成立,且 r i j ≥ 0 r_{ij} \ge 0 rij0恒成立使得 任意的 p i p_i pi 与构造出的 r i j r_{ij} rij 组成的解,都是对偶问题的可行解

  • 我们观察对偶问题,可以看到只有两个约束条件

    • 对于第一个条件,因为 r i j ≥ p j − p i − w i j r_{ij} \ge p_j-p_i-w_{ij} rijpjpiwij 恒成立,所以第一个条件满足

在这里插入图片描述

  • 对于第二个条件,因为 r i j ≥ 0 r_{ij} \ge 0 rij0 恒成立,所以满足

在这里插入图片描述

  • p i p_i pi 是无限制的

  • 所以,我们只要取 r i j = m a x ( 0 , p j − p i − w i j ) r_{ij} = max(0, p_j -p_i-w_{ij}) rij=max(0,pjpiwij),其与任意的 p i p_i pi 构成的解,都是对偶问题的可行解。这就是我们构造 r i j r_{ij} rij 的目的,保证取到的值是对偶问题的可行解

现在,我们通过使用构造的 r i j r_{ij} rij 来重新看待刚刚得到的两个条件,可以证明

在这里插入图片描述

  • 在这里插入图片描述

  • 第二个式子很好看出来,我们下面给出第一个式子的证明

最小费用流算法详解_第7张图片

还记得刚刚的互补松紧条件吗?就是下面这个

最小费用流算法详解_第8张图片

我们使用上面通过构造的 r i j r_{ij} rij 得到的两个条件,可以将互补松紧条件等价为

最小费用流算法详解_第9张图片

也就是说,只要我们找到了原问题的可行解 { x i j } \{x_{ij}\} {xij},对偶问题的可行解 { p i , r i j } \{p_i, r_{ij}\} {pi,rij}恒可行),他们满足上面这两个条件,则这两个解分别是原问题和对偶问题的最优解。

这有什么用呢?

  • 用处:我们在保证互补松紧条件始终成立的情况下找到原问题的一个可行解,则这个解就是原问题的最优解(就是找到一条路,如果其流值为 a a a,这条路就是流值为 a a a 的路中,费用最小的)
  • 这可以将寻找最小费用流问题转换为:
    • 在满足互补松紧条件的情况下,找原问题的可行解
      • 原问题中,任意一个 s-t 流都是原问题的可行解。因为我们满足从 s 点流出的流量等于流入 t 点的流量,中间节点流入流量等于流出流量(原问题的约束)
    • 假如一条 s-t 流的流量是 v 1 v_1 v1,因为满足互补松紧条件,这个流就是流量是 v 1 v_1 v1 的流中费用最小的,也就是 v 1 v_1 v1 对应的最小费用流
    • 如果 v 1 < v v_1 \lt v v1<v,我们就尝试通过寻找增广路,来增加流值,直到找到了流值为 v v v 的解。同样,这个解自然成为流值为 v v v 的时候,费用最小的。
    • 通过这种方式,我们可以找到给定流值 v v v 的最小费用流

总的来说,互补松紧条件的作用就是:使得我们在找到原问题的可行解的时候(任意一个 s-t 流),如果其满足互补松紧条件,则这个流就是当前流值对应的最小费用流

因为互补松紧条件有这样好的性质,所以下面我们寻找增广路时,要保证不破坏互补松紧条件

6.最小费用流算法

核心思想:总是在费用最小的增广路上增加流值,直到流值达到 v v v

我们从 { p i = 0 } \{p_i=0\} {pi=0}(是对偶问题的可行解), { x i j = 0 } \{x_{ij} = 0\} {xij=0}(原始问题不可行)开始

  • 通过 r i j = m a x ( 0 , p j − p i − w i j ) r_{ij} = max(0, p_j -p_i-w_{ij}) rij=max(0,pjpiwij),计算出 r i j r_{ij} rij
  • 当前 { p i , r i j } \{p_i, r_{ij}\} {pi,rij} 是对偶规划的可行解(前面说过,只要 r i j r_{ij} rij 是这样定义出来的,任意 { p i , r i j } \{p_i, r_{ij}\} {pi,rij} 都是对偶问题的可行解)

我们通过增广路,来增大流值,这时的流值变成 v 1 v_1 v1。注意:寻找增广路的时候,不能违背互补松紧条件,否则我们找到一条流,没法说明其是最小费用流。

最小费用流算法详解_第10张图片

  • 我们看到,互补松紧条件其实定义了边上的流的大小,在 p j − p i ≠ w i j p_j-p_i \ne w_{ij} pjpi=wij 时,我们是不能通过寻找增广路来增加流值的,因为这些边上的流,要么等于 0,要么等于其容量。如果对这些边进行增广路算法,将破坏互补松紧条件

  • 那我们寻找增广路时,只能在 p i − p h = w i j p_i - p_h = w_{ij} piph=wij 上的边中,寻找增广路,来增加流值。

    • 如果是前向弧,还需要满足 x i j < c i j x_{ij} \lt c_{ij} xij<cij。(容量没满才能继续增加流量)

    • 如果是后向弧,还需要满足 x i j > 0 x_{ij} \gt 0 xij>0。(边上有流量,才有机会退回流量)

    • 于是,我们定义可以运行增广路算法的弧,我们称其为允许弧,定义如下

      最小费用流算法详解_第11张图片

    • 我们为了不违反互补松紧条件,只能在允许弧上,搜索增广路。

  • 我们不断寻找增广路,增加流值,直到找到的流的流值等于 v v v

算法如下:

最小费用流算法详解_第12张图片

最小费用流算法详解_第13张图片

这个算法很容易理解,就是迭代增加流值

  • 每次迭代时,先确定可行弧

  • 然后再可行弧上寻找增广路

    • 如果能找到 s-t 增广路,则增加流量

    • 如果找不到

      • 将寻找增广路时,未获得标号的点的 p i p_i pi 值都 + 1

        • 这会导致,在标号的点 i i i 和没有标号的点 j j j 之间的 p i − p j p_i - p_j pipj 产生差值(因为只有未标号的点的 p i p_i pi 增加了)

        • 差值会导致什么呢?

        • 差值会导致,我们能够在有标号的点和未标号的点之间的边上,构造出 p i − p j = w i j p_i - p_j = w_{ij} pipj=wij 的条件,从而将这条边加入到允许弧的集合中

        • 如果 i i i 有两条邻接边,一条费用是3, 一条费用是 10,则费用是 3 的边会先加到允许弧中。因为找不到增路时,每次都是未标号的点 p j + 1 p_j + 1 pj+1,加到第三次时,费用为3的边就会被加入允许弧了。这同时保证了,我们优先走费用小的弧

        • 总的来说,这个操作的意义就是:

          最小费用流算法详解_第14张图片

  • 直到流量增加到 v v v,然后返回这个流(就是返回解)

这么看来,最小费用流算法,其实就是在互补松紧条件限制下的最大流算法

你可能感兴趣的:(组合优化,算法,贪心算法,动态规划)