【转载】网络流和最小费用流

这段时间复习了下网络流模型,感觉比以前的理解有了长足进展,虽然我知道这东西难就难在建模上,而它的算法本身其实难度不大,但我还是决定说一些我的理解,毕竟理解了本质的东西运用起来才会更灵活。

最大流的求解一般有两类算法(用费用流附带求出的不列入考虑范围),就是增广路(FF)系列和预流推进(PF)系列。在很多地方都看到推荐使用后者,因为效率更高,但其实不然,今天我这篇文章就是要重点介绍前者,相信大家看了过后也会喜欢它的。

首先,那些一大堆的关于网络的定义我就不说了,不明白的就先去看看书好了,我们约定S是源,T是汇,G表示残余图。增广路算法其实相当好理解,因为只要在G中存在一条从ST的通路,那沿这条路走,流量一定还可以增加,所以当求得最大流的时候一定不存在S-T通路。 那反过来成立么?显然,因为我们有最小割最大流定理,所以由此就得到了FF算法的基本方法:

不断的在G中找一条S-T通路,然后沿其增广,直到无法找到。

至于用什么方法去找一条路,那就随便了,BFSDFS,甚至A*,你可以把你能想到的方法试个遍,看看哪个合胃口就用哪个吧。

注意那个用BFS的方法,它的官方名字叫Edmonds-KarpEK,它和我们后面要说的费用流有很大的关系,这里先简单提示一下。

那这方法的复杂度呢?如果是整数流(事实上分数流的话可以构造数据让FF无法停止,这时候必须用到PF的方法),显然每次至少增广1的流量,每次查找O(E)条边,增广要O(V)的时间,因此复杂度为O((m+n)*U)U是最大流。

听上去很恐怖,其实EK算法的一个稍微精确的上界是O(VE^2),还是很夸张。

那么,怎样才能跑得更快呢?想想,每次用BFS求出的Shortest Path TreeSPT),我们只关心了S-T最短路,其实还有很多信息没有利用到,那么如果求一次SPT,我们可以增广多次的话,是不是会好些??

于是,引入层次图的概念,说通俗点,就是求GSPT,把G中每个顶点的距离S的标号d给求出来,保留所有的s->td[s]+1=d[t]的边(注意可以不是SPT中的边),最后再在层次图中用多次BFS把所有的增广路求出来增广。

这样看似更快了,其实没有,因为分析复杂度依然是O(VE^2),没有改进,而且我们还要写更多的代码。那瓶颈在哪里呢?对了,就是那步在层次图中用BFS来找增广路。其实更好的方法是用DFS,一次就可以把所有的增广路求出来,具体做法如下:

S开始做DFS,一旦发现一条增广路,于是就沿其增广,然后DFS回退到离S最近的一条满流的边的起点处,并在图中删除该边的终点,继续搜索。

上面的算法就是著名的Dinic算法,它的复杂度为O(EV^2)(注意,看清楚2的位置),对于密图有不小的改进。

事实上,我非常推荐在各类比赛中用Dinic算法,因为它实现简单,而且实际运行速度快,比起PF算法好写太多了!!

那单纯的说好还是不行,要拿出依据来。关于PF算法的理论在本文中就不详细叙述了,可能以后我会专门介绍它。一般的PF实现是O(V^4)的,而Relable-To-FrontO(V^3),高标推进据称是O(V^2*sqrt(E)),虽然它实际中确实比较快,但是PF的算法都有一个缺点,就是必须加启发优化,至少是Gap优化,否则实际中会比较慢。因此,写一个PF的代码自然就比较多了。

上面基本上把最大流的算法盘点了一下,下面还是说一下最小费用流问题。

如果一个网络的边不仅有容量,还有单位流量费用的话,那我们自然想在求得最大流的同时,使总费用更低。因此,最小费用流实际上是一个更通用的模型,因而其应用也更广。

令 人惊奇的是,解决该问题可以不需要先求出最大流来(当然也有方法需要),所以如果你不想记那么多算法的话只知道该算法也没问题。因为费用流的算法如果说复 杂的话可以把线性规划扯近来,所以先罗列下几个基本方法,然后介绍最简单的一种,其它的如果你有兴趣可以自己找文章来看:

1 连续最短路算法(Successive Shortest Path);

2 消圈算法(Cycle Canceling);

3 原始对偶算法(Primal Dual);

4 网络单纯形(Network Simplex)。

后面的两个分别是前面两个的高级优化版本,其基本的优化思路就是和我们上面论述的优化增广类似,就是希望每次都能做几次运算,不要一次用了就丢弃了。最好用的就是第一个方法,方法二在Algorithm in C图论部分有详细论述,我就不说了。

还记得刚才我说的EK么?其实如果我们用DijkstraG中找S-T最短路,而不是BFS的话,是不是就解决问题了呢?是的,完全正确,我把证明留给大家想,其实很简单。

但是,有个问题,在G中存在负权的边,用Dijkstra是不是不行了呢?非要用Bellman-Ford么?其实不然,只要原图中没有负环存在(有的话不存在最小费用),那么我们可以利用Johnson算法的重赋权技术把所有的边先变成正权,然后以后每次增广后再维护一下不就可以用高效的Dijkstra了?算法如下:

Bellman-Ford求各点到S的高度标号d[]

以后每求一次最短路,设标号为pi[],那么执行:

For i=1 to v do

d[v]+=pi[v]

这样一来,标号就一直合法了(具体证明还是留给大家吧)。

好了,说这么多理论,下篇文章将会说几个具体的题目,加深对算法的理解。

 

转载于:https://www.cnblogs.com/zen_chou/archive/2009/07/16/1525185.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/264260.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实验1.1

转载于:https://www.cnblogs.com/P201821430028/p/10689308.html

札记__ADT:URL,Lua:strlen方法

2019独角兽企业重金招聘Python工程师标准>>> 01,Android ADT 在线更新的URL: https://dl-ssl.google.com/android/eclipse/ 02,Lua中字符串长度的判断可以使用 # local str "abcabc" print(#str) --6 print(#"a…

vue路由添加.html,怎么使用VueRouter的addRoutes方法实现动态添加用户的权限路由

怎么使用VueRouter的addRoutes方法实现动态添加用户的权限路由发布时间:2021-04-26 13:34:44来源:亿速云阅读:76作者:小新小编给大家分享一下怎么使用VueRouter的addRoutes方法实现动态添加用户的权限路由,希望大家阅读…

vue中的适配:px2rem

这应该是vue项目在适配移动端时候,最简单的方法之一下面是基本步骤(使用cnpm)1.下载并引入lib-flexible cnpm install --save lib-flexible 在main.js中 :import ‘lib-flexible/flexible’2.引入px2rem-loader cnpm install --sa…

SQL Server 2005参考:Apply运算符

SQL Server 2005参考:Apply运算符 使用 APPLY 运算符可以为实现查询操作的外部表表达式返回的每个行调用表值函数。表值函数作为右输入,外部表表达式作为左输入。通过对右输入求值来获得左输入每一行的计算结果,生成的行被组合起来作为最终输…

Java高级篇 -- List选择及优化

为什么80%的码农都做不了架构师?>>> 在java编程中,我们常常使用到java自带的集合类List 以下为几点简单的优化建议: 1.Vector还是ArrayList Vector有其特有有点,其每个方法都为同步方法【synchronized】&#xff0c…

韶关无线电厂台式计算机,中国芯片30年的历史 它背后有哪些不为人知的故事?...

1972年,自主研制的大规模1973年,北京大学、北京有线电厂等单位联合研制150计算机,该机字长数48位,运算能力达每秒100万次,主要用于石油、地质、气象和军事部门。1973年,韶关市无线电厂研制成功晶体管161型“…

Java————迷宫问题

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。 package algorithm_java;import java.util.Scanner; import java.util.Stack;/*** 路径…

PB中函数测试遇到的问题

在PB中写了一个函数,需要连接两个数据库 tr_1,tr_2,测试时报错(无法连接到第二个数据库),再确定该函数代码没有其它问题后,选中该函数,右键Regenerate后,测试成功.转载于:https://ww…

每一件事情的开始总是很困难的!

每一件事情的开始总是很困难的!我今天花了一下午的时间终于把开头做完了,希望底下的事情,顺顺当当的!转载于:https://blog.51cto.com/7305256/1564904

html双翼布局,第19题 CSS如何实现双飞翼布局?

双飞翼布局如下图所示:有了圣杯布局的铺垫,双飞翼布局也就问题不大啦。这里采用经典的float布局来完成。HTML代码:双飞翼布局码云笔记mybj123.comCSS代码:*{margin: 0;padding: 0;}.container {min-width: 600px;}.left {float: l…

使用IE WebControls中的TabStrip控件和MultiPage控件实现选项卡式风格页面(转载)

第一步: 首先必须安装Internet Explorer WebControls.原始安装下载地址是:http://asp.net/IEWebControls/Download.aspx 下载后可以按照说明进行安装。 也可以下载下面这个我做的简易安装包,下载地址是:http://files.cnblogs.com/…

【原】关于AdaBoost的一些再思考

一、Decision Stumps: Decision Stumps称为单层分类器,主要用作Ensemble Method的组件(弱分类器)。一般只进行一次判定,可以包含两个或者多个叶结点。对于离散数据,可以选取该属性的任意一个数据作为判定的…

计算机系统时间无法更改,电脑时间不能修改|系统时间改不了 四个处理办法

电脑时间不能修改|系统时间改不了 四个处理办法?电脑时间不但可以让网友准确的查看时间,还对软件的运行、工作等方面至关重要,有时大家看电脑时间不准确想要修改,确发现改不了系统时间。碰到该故障的朋友不要惊慌,下面…

PHP常用字符串函数小结

最近面试被这个面到吐血,特地来fork一些。 来源:https://www.jb51.net/article/145084.htm 一、判断类型的函数 is_bool() //判断是否为布尔型 is_float() //判断是否为浮点型 is_real() //同上 is_int() //判断是否为整型 is_integer() //同…

醒来。。

很久没更新我的博客,缘由有二:其一,博客没人看,没有写下去的动力。其二:真的没啥东西可以写。。。 今天,一如既往地沉睡三小时后,醒了,还是带着无限的忧郁和惆怅,这次唯一…

斐波那契数列(fabnacci)java实现

斐波那契数列定义:From Wikipedia, the free encyclopedia http://en.wikipedia.org/wiki/Fibonacci_number In mathematics, the Fibonacci numbers or Fibonacci sequence are the numbers in the following integer sequence:[2][3] or (often, in modern usage)…

计算机二级offic考试题库2017,2017年9月计算机二级MSOffice考试题「带答案」

2017年9月计算机二级MSOffice考试题「带答案」一、单选题1). 存储一个3232点的汉字字形码需用的字节数是( )。A.256B.128C.72D.16正确答案:B2). 无符号二进制整数101001转换成十进制整数等于( )。A.41B.43C.45D.39正确答案:A3). 一个教师讲授多门课程&am…

LiveQing直播点播存储流媒体服务-服务器并发性能及消耗带宽计算参考

LiveQing云端直播点播流媒体软件: 提供设备接入; RTMP推流服务、RTMP分发、HLS分发、HTTP-FLV分发; 云端录像、云端录像检索、云端录像点播、云端录像下载; RTMP转推、推流鉴权验证、推流信息统计、播放信息统计; 直播…

思考设计模式在自助终端软件上的应用 ——Observer(观察着)模式

主要思想:将各硬件模块作为观察者加入观察者队列,当机器状态改变时Notify所有观察者,各观察者根据消息类型做不同反应或不作反应。 下面贴出代码简单实现,希望引起圈内朋友的关注,起到抛砖引玉的效果。 下面两个类是两个基类.…