ISAP网络流算法
ISAP全称Improved Shortest Augmenting Path,意指在SAP算法进行优化。SAP即Edmonds-Karp算法,其具体思路是通过不断向残存网络推送流量来计算整个网络的最大流。阅读本文要求掌握网络流的基础概念,不懂的出门左拐算法导论。ISAP的时间复杂度与EK算法一致,而EK算法的时间复杂度为min(O(E|f|),O(VE^2)),其中O(E|f|)部分是因为其是在FORD-FULKERSON算法上的改进。EK算法在FF算法的基础上将随意取增广路径替换为取最短增广路径,而ISAP在EK算法的基础上剔除了除了第一次外的后续广度优先搜索寻找最短路径的部分。下面对ISAP算法进行说明。
先说明一些名词,称残存网络中容量非0的边为有效边。
我们首先在EK算法的基础上,为每个顶点添加新的属性d,表示其到汇点t的最短路径(路径只能包含有效边),这个最短路径是基于残存网络的,而非原图,因此d属性会随着流的推送导致残存网络的变更而变更。显然要维护这样一个属性d,每次在推送流后,都需要基于新形成的残存网络重新执行广度优先搜索算法,以计算每个顶点正确的d属性,这样不就与EK算法完全一样了吗?是的,因此为了避免每次流推送都必须重新计算最短路径,我们需要修改d的定义,d表示顶点到t的距离的某个下界。为了说明这样定义之后就不用再每次重新执行广度优先搜索算法计算d,只需要说明每次向残存网络推送流,只会导致每个顶点到t的距离非严格递增:
证明:假设我们向图G沿最短路径推送流,并形成新图G'。我们记R(a,b)表示原图中从点a到点b的最短距离,记R'(a,b)表示在新图(残存网络)中a到b的最短距离。我们所要证明的就是对于任意点x都有R(x,t)<=R'(x,t)。假设存在点x,满足R(x,t)>R'(x,t),显然x到t的最短路径之中必然包含由于流推送而新增的边,假设(v,u)是图G'中x到t中距离点x最近的新增边,而(u,v)是处于G中最短增广路径上。这样我们就可以把G'中的x到t的最短路径写作x,...,v,u,...,t,显然R'(x,v)=R(x,v),因为其中不含新增边和删除边(即与G上的最短增广路径无交集)。由于R'(x,t)<R(x,t)可得R'(v,t)<R(v,t),从而有R'(u,t)<R(u,t),因此由前面的说明可知存在增广路径的边(q,w),使得(w,q)存在于R'(u,t)代表的最短路径中。利用同样的思路证明下去我们可以得到无穷多的增广路径上的边出现在了R'(x,t)对应的路径之中,而由于一条最短路径是不可能包含重复边,且所有不同边的总数最多只有2*|E|条(正向边以及逆向边),因此这与R'(x,t)是最短路径这一性质相悖,故假设不成立,因此R'(x,t)>=R(x,t)。
继续说明流程的执行。由于d是描述一个顶点距离t的下界,因此当一个顶点的属性d超过|V|时,这个顶点将永远无法推送流到t(最短路径不含相同顶点的简单应用)。而我们可以以源点s的属性d是否超过|V|来作为结束推送的条件。具体流程是我们循环推送,每次都从s开始向其余所有与s相邻且d属性为s.d-1的顶点推送无穷的流。我们期望这样的流推送成功当且仅当增广路径上的顶点序列的d属性为s.d,s.d-1,...,1,0,否则推送就不应该成功。显然在推送成功的情况下,由于d是距离下界,因此推送路径一定是最短的增广路径。而所谓的推送失败是指抵达一个顶点x(非t),所有邻接的可抵达顶点(指存在有效边连接)的距离都不等于x-1,这意味着附近的所有顶点到t的距离都由于前面对流的推送而增大了,因此我们也应该对x的距离进行增大(因为一个顶点距离t的最短距离应该是其与可以通过有效边连接的所有顶点到t的最短距离的最小值+1),由于周边的所有顶点的d属性均>=x.d,因此我们将x.d赋值为x.d+1也是合适的,不会违背我们对d的定义,在我们修改了d的值之后,显然这与我们期望的可推送的增广路径已经不相符了,因为d属性为x.d+1的顶点出现了两次,因此我们宣告失败回到之前的顶点。而当我们推送成功且x是方才推送的增广路径上的某个顶点,且此时从前面顶点传来的流还足够支持下次推送,那么我们可以继续寻找其满足d属性为x.d-1的后继顶点,继续推送(这也是ISAP的优化之一)。
先说明程序会正确停止。由于推送成功就意味着存在增广路径(而且是符合严苛条件的最短增广路径),此时显然还可以继续通过向增广路径推送流来获得最大流。当我们发现不存在增广路径时,即s向周边推送失败,我们会不断增大s.d属性,而当s.d>|V|时,我们就结束推送,此时程序正确结束。
时间复杂度与EK基本一致,只是将其中原本每次成功推送后执行广度优先搜索去掉,取而代之的是增加了推送失败情况下对顶点d属性的增大。由于一个顶点d属性不会超过|V|,因此我们可以保证每个顶点d属性最多增大|V|次,而总共有|V|个顶点,因此失败处理次数不会超过|V|^2。同时由于我们每次推送成功时也会遍历大量的不同边和不同顶点,这个流程在最糟糕的情况下的时间复杂度为O(|V|+|E|),与广度优先搜索算法一致,因此算法上界应该为O(VE^2+V^2)=O(VE^2),与EK算法一致。
ISAP有一个通用的GAP优化就是我们将拥有不同d属性值的顶点进行分组,以d属性值作为编号。当我们修正一个顶点p的d属性值(推送失败时),我们可以通过判断p.d这一组元素是否只有一个,当只有一个时,意味着我们再修改p.d为p.d+1后,p.d这一组将会为空,这是一个好消息,因为后面所有从s发出的推送请求都会由于没有p.d组的顶点可以接受请求而失败,因此我们可以断定此时残存网络中的流即是最大流,我们可以通过提前将s.d修改为|V|来跳过后面一系列的失败处理,从而优化性能。
下面给出代码:
bfs(t) //从t开始进行广度优先搜索,如果顶点v到t无路径,则v.d=-1
for v in V
v.d=-1
t.d =
que = empty-queue
que.enque(t)
while(!que.isEmpty())
head = que.deque()
group[head.d]+=
for edge in head.edgeList
if(edge.isNegative)//只允许沿着有效边的反向边移动
if(edge.dst.d == -)
edge.dst.d = head.d +
que.enque(edge.dst) sendFlow(node, flowLimit) //通过顶点node向周围最多推送flowLimit单位的流,如果推送量为0,则表示推送失败
total =
for edge in node.edgeList
if(edge.capacity > edge.flow && edge.dst.d == node.d - ) //发现符合条件的有效边
actually = sendFlow(edge.dst, min(flowLimit, edge.capacity - edge.flow)
flowLimit -= actually
edge.sendFlow(actually);
total += actually
if(flowLimit == 0)
break
if(total == ) //如果发送失败
group[node.d]-=
if(group[node.d] == ) //发现断层
s.d = |V|
node.d+=
group[node.d]+=
return total isap(s, t)
bfs(t)
if(s.d == -)//如果从s到t不存在路径
return
sum =
while(s.d < |V|)
sum += sendFlow(s, INF)
return sum
ISAP网络流算法的更多相关文章
- [转] 网络流算法--Ford-Fulkerson方法及其多种实现
网络流 转载自:http://www.cnblogs.com/luweiseu/archive/2012/07/14/2591573.html 在上一章中我们讨论的主题是图中顶点之间的最短路径,例如公 ...
- 网络流最经典的入门题 各种网络流算法都能AC。 poj 1273 Drainage Ditches
Drainage Ditches 题目抽象:给你m条边u,v,c. n个定点,源点1,汇点n.求最大流. 最好的入门题,各种算法都可以拿来练习 (1): 一般增广路算法 ford() #in ...
- ACM - 图论- 网络流 - 算法模板
\(EK\) 算法模板 #include <iostream> #include <queue> #include<string.h> using namespac ...
- 最大流算法-ISAP
引入 最大流算法分为两类,一种是增广路算法,一种是预留推进算法.增广路算法包括时间复杂度\(O(nm^2)\)的EK算法,上界为\(O(n^2m)\)的Dinic算法,以及一些其他的算法.EK算法直接 ...
- 【2018.2.8-】网络流学习笔记(含ISAP!)
网络流的基础内容就不详细发了,网上到处都是,可自学. 总版点这里 ps:以下有些链接是hihocoder的题目(题面有详细讲解),请确保先登录hihocoder,再点击进入相应题目网页. 最大流 基础 ...
- ISAP 算法的学习
http://www.renfei.org/blog/isap.html 算法与数学 网络流-最大流问题 ISAP 算法解释 2013-08-07Renfei Song 2 条评论 内容提要 [隐藏] ...
- 网络流最大流——dinic算法
前言 网络流问题是一个很深奥的问题,对应也有许多很优秀的算法.但是本文只会讲述dinic算法 最近写了好多网络流的题目,想想看还是写一篇来总结一下网络流和dinic算法以免以后自己忘了... 网络流问 ...
- 图论4——探索网络流的足迹:Dinic算法
1. 网络流:定义与简析 1.1 网络流是什么? 网络流是一种"类比水流的解决问题方法,与线性规划密切相关"(语出百度百科). 其实,在信息学竞赛中,简单的网络流并不需要太高深的数 ...
- HDOJ-3416(最大流+最短路+ISAP算法+向前星dijikstra算法+如何判断一条边是否在最短路中)
Marriage Match IV HDOJ-3416 这题的题意就是要找两点之间最短路的路径个数,而且边不能重复. 最大流和最短路的结合.首先正向和反向建图,再跑两遍dijikstra.到这里就求出 ...
随机推荐
- (三)canvas绘制样式
beginPath() 对画线点的一个开始限制 moveTo() 画线的起点,只在开头使用 参数两个x轴,y轴 lineTo() 后续连线 两个参数x轴,y轴 stroke() 连线无填充 fill( ...
- 如果有人问你ZooKeeper是什么,就把这篇文章发给他。
前言 提到ZooKeeper,相信大家都不会陌生.Dubbo,Kafka,Hadoop等等项目里都能看到它的影子.但是你真的了解 ZooKeeper 吗?如果面试官让你给他讲讲 ZooKeeper 是 ...
- 【java规则引擎】基本语法和相关属性介绍
一个规则的语法信息 [1]条件部分(LSH部分)===>规则pattern之间的连接条件符号: (1)LHS 部分是由一个或多个条件组成,条件又称之为 pattern(匹配模式),多个 pa ...
- Tornado输出和响应头
1.输出 再来看看输出`write`,实际上,`write`并没有直接把数据返回给前端,而是先写到缓存区,函数结束之后才会返回到前端,我们验证如下 class FlushHandler(tornado ...
- C#动态执行代码
在开始之前,先熟悉几个类及部分属性.方法:CSharpCodeProvider.ICodeCompiler.CompilerParameters.CompilerResults.Assem ...
- Windows下查看什么进程占用文件
任务管理器→性能Tab→资源管理器→CPU→关联的句柄后面的检索框中录入文件名(关键文件夹即可). 比如我的是在删除tomcat下面的WEB-INF文件出现问题:就输入WEB-INF:mygod,发现 ...
- BZOJ4755:[JSOI2016]扭动的回文串
浅谈\(Manacher\):https://www.cnblogs.com/AKMer/p/10431603.html 题目传送门:https://lydsy.com/JudgeOnline/pro ...
- 使用Log4j将程序日志实时写入Kafka
第一部分 搭建Kafka环境 安装Kafka 下载:http://kafka.apache.org/downloads.html tar zxf kafka-<VERSION>.tgz c ...
- 根据wsdl文件生成WebService客户端代码
有时候在项目中,一个项目可能有好几个公司在做.系统之间难免会出现互相调用接口的现象,这时候有一种办法就是使用webService.本篇文章将介绍如何将对接系统提供的WebService接口,根据对方提 ...
- 监控mysql 脚本
监控mysql脚本 http://oldboy.blog.51cto.com/2561410/986905