网络流算法学习笔记——Dinic有效算法

屈婉玲《算法设计与分析》第2版第7章网络流算法学习笔记。

概述

Dinic有效算法同样用来求最大流,相当于FF算法的改进。

FF算法参考:网络流算法学习笔记——最大流问题基本概念和Ford-Fulkerson方法(标号法C++实现)

改进之处有:

  1. FF算法每次只找1条s-t增广链,而Dinic算法每次能找很多条
  2. Dinic算法每次都找最短的(边数最少的)s-t增广链(why?)

第1点显然能提高效率,但第2点为什么要找最短路径呢?看《算法导论》的一个FF算法的例子。

初始为0流的网络,找到一条增广路径:
在这里插入图片描述
更新残留网络,再找增广路径:
在这里插入图片描述
更新残留网络:
在这里插入图片描述
在这种情况下,每次仅增加1个单位的总流量,共要执行2,000,000次运算。

dinic算法能确保不发生这种情况。

概念

初始网络N,及当前可行流f:
在这里插入图片描述
辅助网络、辅助容量:N(f)、ac
设容量网络N,f是一个可行流,记其辅助网络为N(f);屈婉玲版《算法设计与分析》对残留网络的别称。

辅助容量是辅助网络中重新定义的容量 :

  • ac(i, j) = c(i, j) - f(i, j),当<i, j>是前向边,且f(i, j) < c(i, j)时
  • ac(j, i) = f(i, j),当<i, j>是前向边,且f(i, j) > 0时

即前向边还能压入多少流量,后向边还能退回多少流量。

分层辅助网络:AN(f)
删除辅助网络中部分非最短路径的辅助网络。用广度优先搜索N(f),标记每个节点的层号(图b方框里标注),把从高层到低层的边,及层数大于等于t的顶点删掉。

在这里插入图片描述
在这里插入图片描述
流通量:th(i)
AN(f)中所有以顶点i为终点的边的容量和,与所有以i为始点的容量和中的最小者。即顶点i所能承载的最大流量。规定以s为终点和以t为始点的边的容量为+∞。

算法步骤

1. 构造AN(f)

接下来,循环执行下面的步骤2、3。

2. 删去流通量0的顶点和边

流通量为0的顶点及关联的边都可以删去,出现新的流通量0的顶点继续删:
在这里插入图片描述
至此,网络简化了不少,准备工作完成了。

3. 安排流量

构造好AN(f)后,尽可能多的找出s到t的最短路径并分配流量:

  1. 找出流通量最小的顶点:1,6,10,流通量均为3;
  2. 从顶点1向后看,发出3单位的流量,尽可能多的分配给每个后面的边(比如从顶点4分配2个单位的流量时,不能给顶点6一个、给顶点8一个),全部送到t为止;
  3. 从顶点1向前看,从s获得3单位的流量。

在这里插入图片描述

安排完毕后,重复步骤2,AN(f)变成了下图;重复步骤3安排流量:
在这里插入图片描述
再重复步骤2,发现此时s、t的流通量都变为了0(下图所有顶点流通量都是0),跳出循环:
在这里插入图片描述
至此,把以上找到的流叠加起来,就找到了AN(f)的一个极大流g1,如下:
在这里插入图片描述
将极大流叠加到原来的流f上,得到新的N和f2:
在这里插入图片描述


至此第一个过程结束。回到步骤1,重复执行上述过程,构造AN(f)并寻找其极大流:
在这里插入图片描述
在这里插入图片描述

下一组,构造AN(f)时发现没有从s到t的通路,计算结束:
在这里插入图片描述

代码实现

伪码

屈婉玲《算法设计与分析》第2版中的伪代码如下:

1. f ← 0  //取零流作为初始可行流
2. 构造AN(f)
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值