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.到这里就求出 ...
随机推荐
- 解决AndroidStudio导入项目在 Building gradle project info 一直卡住
Android Studio导入项目的时候,一直卡在Building gradle project info这一步,主要原因还是因为被墙的结果.gradle官网虽然可以访问,但是速度连蜗牛都赶不上.. ...
- 在Linux上部署DotNet Core项目的时候发现Apache无法转发Kestrel的5000端口的问题
CentOS服务器上使用Apache托管Dotnet Core2,服务启动了,端口也打开了.在本地使用curl命令可以访问5000端口的网页内容,但是访问Apache的端口却无法获取到网页的内容.想起 ...
- 21天学通C++_Day2
继续学习,今天满课,相对学习内容较少,下面罗列内容: 0.常量 ▪字面常量: ▪使用关键字const声明的常量,const double Pi = 22.0/7; //后面有分号,跟定义变量一样 ▪使 ...
- mybatis 联表查询
一.一对一关联 1.1.提出需求 根据班级id查询班级信息(带老师的信息) 1.2.创建表和数据 创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关 ...
- 5,基于关系和超链接的 API
Tutorial 5: Relationships & Hyperlinked APIs At the moment relationships within our API are repr ...
- LibreOJ β Round #2 题解
LibreOJ β Round #2 题解 模拟只会猜题意 题目: 给定一个长为 \(n\) 的序列,有 \(m\) 次询问,每次问所有长度大于 \(x\) 的区间的元素和的最大值. \(1 \leq ...
- Vue.js devtool插件下载安装及后续问题解决
在中国,你是无法使用谷歌应用商店,所以你下载插件,要使用一些别的手段,一种是下载源码编译,另一种是通过第三方网站.第一种不适合小白,所以现在介绍第二组. 下载插件网站 国外网站:https://www ...
- 支付宝RSA签名
1.参考网上相关文章,开放php中的openssl,但使用网上例子调用openssl_pkey_new,一直报100013错误.后改用用支付宝提供的SDKdemo程序 发现使用提供的privkye,可 ...
- mysql 统计sql
1.按照月份统计数据 SELECT DATE_FORMAT(d.create_time,'%Y-%m') months,COUNT(id) AS scannum FROM detail d GROUP ...
- 1118 Birds in Forest
题意: 思路:并查集模板题. 代码: #include <cstdio> #include <algorithm> using namespace std; ; int fat ...