网络最大流问题之Ford-Fulkerson算法原理详解
前言
最大流问题是网络优化中典型的问题,用形象的语言来描述就是在满足容量约束的前提下将尽可能多的流从源节点(始点)到汇节点(终点)。解决此问题的经典方法很多,本文介绍广为人熟知的Ford-Fulkerson算法,来解决最大流问题。尽管网上关于此问题的文章多如牛毛,但笔者希望结合自己学习过程中对算法的理解,给予算法最清晰的介绍,希望对大家有帮助。(笔者曾尝试使用java来实现,但最终因用java实现和使用图太麻烦了,又不想重新用python来实现,故放弃,以后的实现估计会采用python而不是java,java毕竟不适合写图相关算法)。
一、知识准备
学习此算法前建议读者学习网络流相关知识和基本概念,一些需要了解的概念和知识先罗列如下
1、可增广路
2、最大流最小割定理
3、图的割集
4、饱和割集
5、可行流向量
6、节点的散度
7、前向后向边
二、可增广路搜索算法
对于k=0,1,..., 给定Tk, 若Tk为空集或者t∈Tk则算法终止。否则,令
Tk+1 = { Tk | 存在节点m∈Tk, 以及边(m, n) 满足xmn < cmn, 或者边(n, m) 满足 bnm<xnm},
(其中节点数为n,bnm和cnm为边mn容量的最小和最大值,xmn为边的流量, Tk+1集合的节点不能属于T其他集合节点)
上式的含义即为Tk+1为在集合Tk中所有节点满足可增广路条件的相邻的节点组成的集合,当然,这些节点不能包括已经存在其他T集合中的节点。
当算法终止时,最后一个集合Tk有两种情况(假设s为起点, t为终点):
(1) 最后一个集合Tk包含t,此时从t向前标记即可构造从s到t的简单可增广路。即从T1,T2,T3,....,Tk中每个取一个节点的路
(2)最后一个集合Tk为空集,此时得到一个分离s和t的饱和割集
现举例说明,如下图(容量下限(最小值),流量,容量上限(最大值))标在每条边旁
1为源点,6为汇点。开始T0只有1个节点,就是节点1。接下来从和T0中节点,也就是节点1相邻的节点2和3开始。边12,流量为0,为前向边,满足流量小于容量上限;边13也为前向边,满足流量小于上限(0 < 1)。所以节点2和节点3组成T1。然后考虑以节点2和节点3来寻找T2,原理和前面一致,其中边35,为后向边,流量为2,大于容量下限1,所以节点5添加到T2,。到最后T3,集合包含6,终止。此时增广路为(1,3,5,6)。
现在看另一图,只是把边56的流量改为了0,此时后向边56不满足流量大于下限,所以T3为空集。此时存在饱和割集{S, N-S}分离1和6,其中S = {1,2,3,4,5},是所有集合Tk的并集
三、Ford-Fulkerson算法
在了解了可增广路搜索算法后,现在正式进入本文的主题,Ford-Fulkerson算法。该算法在每次迭代中改进原费用(s的散度),因此是原费用改进型算法。算法思想是,给定可行流向量x(即满足容量可行且除了s和t之外节点的散度为零,即节点流入和流出相等,的流向量),以及对于x可增广的从s到t的路P,就可以增进P的前向边(i,j)的流量并减小P的后向边(i,j)的流量。流量增量的最大值为
δ = min{ {cij - xij | (i, j) ∈ P+}, {xij - bij | (i, j) ∈ P-} }, 其中P+是P的前向边的集合, P-是P的后向边的集合。
由此得到的流向量y由
yij = :xij + δ 如果(i, j) ∈ P+,
xij - δ 如果(i,j) ∈P-,
算法的迭代步骤
使用可增广路搜索算法实现下述两种情况之一:
(1)、得到将s和t分离的饱和割集
(2)、得到从s到t的x的可增广路P。
在情况1下,算法终止;此时的流向量即为所求。在情况2下,沿着P进行增广,并进行下一次迭代。每次增广时,算法通过增广增量δ改进原费用(s的散度)。现在以例子说明
初始图,如图1。搜索到增广路(1, 2, 5),路12和路25为正向边,求δ=min{ c12- x12, c25- x25}为1。如图2
图1
图2
对增广路中的所有边x12和x25使用δ改进费用,因为均为正向边,有新的流量为x12=0 + 1 = 1, x25= 0 + 1 = 1。费用改进后如图3。费用改进后继续寻找增广路,如图4。
图3
图4
迭代
图5
图6
迭代
图7
图8
在最后一次费用改进后,已找不到增广路。其中T0包含节点1,T1包含节点2,T3包含节点3,因此饱和割集为[{1, 2, 3}, {4, 5}]。割集容量即为最大容量,即5=c24 + c34 + c25 = 5
图9
四、
在学习此算法时,笔者已经尽力描述算法的主要内容了。由于需要有一些图论的知识作为辅助,加上算法有些复杂,所以结合文中例子效果会更好。
五、知识相关
网络最大流问题之Ford-Fulkerson算法原理详解的更多相关文章
- CRF(条件随机场)与Viterbi(维特比)算法原理详解
摘自:https://mp.weixin.qq.com/s/GXbFxlExDtjtQe-OPwfokA https://www.cnblogs.com/zhibei/p/9391014.html C ...
- 2. EM算法-原理详解
1. EM算法-数学基础 2. EM算法-原理详解 3. EM算法-高斯混合模型GMM 4. EM算法-高斯混合模型GMM详细代码实现 5. EM算法-高斯混合模型GMM+Lasso 1. 前言 概率 ...
- [置顶]
Isolation Forest算法原理详解
本文只介绍原论文中的 Isolation Forest 孤立点检测算法的原理,实际的代码实现详解请参照我的另一篇博客:Isolation Forest算法实现详解. 或者读者可以到我的GitHub上去 ...
- DQN算法原理详解
一. 概述 强化学习算法可以分为三大类:value based, policy based 和 actor critic. 常见的是以DQN为代表的value based算法,这种算法中只有一个值函数 ...
- hash算法原理详解
转载出处http://blog.csdn.net/tanggao1314/article/details/51457585 一.概念 哈希表就是一种以 键-值(key-indexed) 存储数据的结构 ...
- AAC解码算法原理详解
”
- EM算法原理详解
1.引言 以前我们讨论的概率模型都是只含观测变量(observable variable), 即这些变量都是可以观测出来的,那么给定数据,可以直接使用极大似然估计的方法或者贝叶斯估计的方法:但是当模型 ...
- [置顶]
Isolation Forest算法实现详解
本文算法完整实现源码已开源至本人的GitHub(如果对你有帮助,请给一个 star ),参看其中的 iforest 包下的 IForest 和 ITree 两个类: https://github.co ...
- Isolation Forest算法实现详解
本文介绍的 Isolation Forest 算法原理请参看我的博客:Isolation Forest异常检测算法原理详解,本文中我们只介绍详细的代码实现过程. 1.ITree的设计与实现 首先,我们 ...
随机推荐
- windows 注册表编程
例子:将本地计算机的Monitor ID写入到注册表中 (1)获取MonitorID BOOLEAN DeviceMonitorService::EnumClassDevice(const GUID ...
- Android中ListView 控件与 Adapter 适配器如何使用?
一个android应用的成功与否,其界面设计至关重要.为了更好的进行android ui设计,我们常常需要借助一些控件和适配器.今天小编在android培训网站上搜罗了一些有关ListView 控件与 ...
- Xcode模拟器和真机生成的日志查看(转载)
在进行实际代码开发的过程中,我们会生成一些plist文件,但是如何在调试过程中查看这些plist文件是否被成功生成以及生成的内容是否正确? 如果查看模拟器生成的日志和真机生成的日志到底如何查看? DE ...
- 关于nginx的限速模块
nginx 使用 ngx_http_limit_req_module和ngx_http_limit_conn_module 来限制对资源的请求 这种方法,对于CC攻击(Challenge Collap ...
- C++基础——子类转父类转子类 (派生类转基类转派生类)
==================================声明================================== 本文原创,转载在正文中显要的注明作者和出处,并保证文章的完 ...
- 烂泥:虚拟化KVM安装与配置
本文由秀依林枫提供友情赞助,首发于烂泥行天下. 最近打算把公司的服务器全部做成虚拟化,一是跟有效的利用了服务器,二也是对自己是一个学习的机会. KVM的安装与配置步骤如下: 1. 查看是否支持虚拟化 ...
- 利用Keydown事件阻止用户输入
先了解下各事件的区别 keydown:在控件有焦点的情况下按下键时发生 keypress:在控件有焦点的情况下按下键时发生 keyup: 在控件有焦点的情况下释放键时发生 意义 keypress主 ...
- linux搭建一个配置简单的nginx反向代理服务器 2个tomcat
1.我们只要实现访问nginx服务器能跳转到不同的服务器即可,我本地测试是这样的, 在nginx服务器里面搭建了2个tomcat,2个tomcat端口分别是8080和8081,当我输入我nginx服务 ...
- linux下对2个连通的串口读写遇到的问题
想要分析下zmodem协议,搜索发现linux下的工具lrzsz是一个包含x,y,z modem传输的工具,下载其源码,下载.它可以借助各种串行的接口进行数据传输,比如串口,socket也可以,这点描 ...
- linux sed命令
一.初识sed 在部署openstack的过程中,会接触到大量的sed命令,比如 # Bind MySQL service to all network interfaces. sed -i 's/1 ...