网络流探索:解决网络最大流问题的算法集锦

1.初识网络流

网络流一直是初学者心中很难过去的一道坎,很多人说它是一个不像DFS/BFS那么直观的算法,同时网上也有各种参差不齐的材料,让人感到一知半解。
如果你也有这样的感觉,那么不要灰心,坚持住,因为网络流是组合优化理论的明珠,是你走向计算机理论深邃奥秘的第一步。
路径这个概念虽然非常基础,但是有着很多的应用,例如,可以把交通网络看成一个图,那么图上的路径就是一个合法的交通路线,我们可以通过最短路径算法求出最佳的路径。同样我们可以把社会网络,也就是人和人的关系看成一个网络,我们可以用路径来分析社会网络的各种性质关系;甚至我们可以把编写的程序看成一个图,可以通过路径建模程序当中的性质,例如,可以证明程序当中犯的某一些错误是否会发生,这些都是在图论的基础上建立的各种各样有趣的应用。

2.最大流问题的定义与基础

最大流问题属于图论的范畴,这里的图是有向有权图,边都有方向和权重,图中有很多节点,其中一个节点是起点,记作s,还有一个节点是终点,记作t。
可以这样理解最大流问题:我们希望把水从节点s送到终点t,水要通过管道来输送,这些管道就是图中的边,边都有权重,权重可以理解为管道的容量,否则可能会导致压力过大导致管道爆裂,那么,给定管道的限制,那么最大流是多少?
第一步创建residual graph,它的权重等于水管的空闲量,初始时没有水流,所以空闲量等于容量;
在这里插入图片描述
最直观的简单算法为:
第二步是在residual graph找到augumenting path,augumenting path是指从起点s到终点t的简单路径,寻找路径上最小的权重,假设最小权重为x,那么该路径下最多只能传输x单位的水流,再多的话,最弱的水管会爆裂。此外,我们让x单位的水流过这条路径,那么这条路径下所有边的空闲量都要减去x,不断重复第二步的过程,直到找不到起点到终点的路径,这就说明没有办法把更多的水从起点送到终点,这时候就应该终止循环!
在这里插入图片描述
**简单算法有时候会失败!**这种算法只能找到blocking flow阻塞流,阻塞流意思是把网络给阻塞了,没办法传输更多的水流,阻塞流未必是最大流。具体示例如下所示:
在这里插入图片描述
这说明简单算法不能保证结果是最大流,后序介绍的算法可以保证求出的结果一定是最大流

3.Ford–Fulkerson algorithm

前面说简单算法不一定找到最大流,究其原因主要是简单算法不会反悔,不能纠正错误,一旦坏的路径被选中,算法就无法找到最大流。
但是Ford–Fulkerson algorithm一定可以找到最大流,因为它可以把不好的路径给撤销掉
Ford–Fulkerson algorithm与简单算法相比,唯一的区别是添加一条反向的路径,这样一来,就算之前选择的路径不好,也可以原路撤销返回。
在这里插入图片描述
Ford-Fulkerson算法是一种用于解决网络最大流问题的经典算法。它基于寻找增广路径的思想,通过不断寻找增广路径来增加流量,直到无法找到增广路径为止。
该算法的步骤如下:

  1. 创建一个residual graph并初始化所有边的流量为0。
  2. 当存在从源节点到汇节点的增广路径时:
    • 使用深度优先搜索或广度优先搜索来寻找一条增广路径。增广路径是指路径上的每条边的剩余容量大于0。
    • 在找到增广路径后,通过更新路径上的边的剩余容量来增加流量。
    • 更新路径上的边的剩余容量,即减少正向边的剩余容量,增加反向边的剩余容量
  3. 当无法找到增广路径时,算法终止。此时,得到的流就是最大流。
    在这里插入图片描述
    需要注意的是,Ford-Fulkerson算法的时间复杂度很慢,并且会在某些情况下陷入无限循环,因此为了保证算法的终止和收敛性,通常需要采用其他技术,如Edmonds-Karp算法中使用的最短增广路径策略。
    总之,Ford-Fulkerson算法是一种通过不断寻找增广路径来逐步增加流量的经典算法,用于解决网络最大流问题。

4.Edmonds-Karp Algorithm

Edmonds-Karp论文发表在1972年,比Ford–Fulkerson algorithm晚了12年,Edmonds-Karp算法不是新的算法,而是Ford–Fulkerson algorithm算法的特例,Edmonds和Karp的贡献在于他们证明了更好的时间复杂度,时间复杂度不依赖于最大流的大小。Edmonds-Karp Algorithm与Edmonds-Karp Algorithm几乎完全一样,唯一的区别在于Edmonds-Karp Algorithm寻找路径的时候要用最短路径算法

Edmonds-Karp算法是Ford-Fulkerson算法的一种改进版本,用于求解网络最大流问题。它通过使用广度优先搜索来选择最短增广路径,从而提高算法的效率和收敛速度。
以下是Edmonds-Karp算法的详细步骤:

  1. 初始化所有边的流量为0。
  2. While 存在从源节点到汇节点的增广路径:
    • 使用广度优先搜索来找到一条最短增广路径。最短增广路径是指路径上的边数最少,即最短距离最短。
    • 在找到最短增广路径后,计算路径上的最小剩余容量。最小剩余容量是指路径上所有边的剩余容量的最小值。
    • 通过更新路径上的边的流量来增加流量,即在正向边上增加流量,或在反向边上减少流量。
    • 更新路径上的边的剩余容量,即减少正向边的剩余容量,增加反向边的剩余容量。
  3. 当不存在从源节点到汇节点的增广路径时,算法终止。此时,得到的流就是最大流。
    Edmonds-Karp算法通过使用广度优先搜索来选择最短增广路径,相比于Ford-Fulkerson算法的深度优先搜索,它能够更快地找到增广路径。这是因为广度优先搜索以层次化的方式逐层遍历网络,从而找到最短距离的路径。这种选择最短增广路径的策略确保了算法的收敛性和终止性。
    总结来说,Edmonds-Karp算法是一种基于广度优先搜索的改进Ford-Fulkerson算法,用于求解网络最大流问题。它通过选择最短增广路径来提高算法的效率和收敛速度。
    在这里插入图片描述
    从图中可以看出,这个时间复杂度比Ford-Fulkerson算法要好的多,因为它不依赖于网络流的大小。Edmonds和Karp两个人更好的贡献是证明了更好的时间复杂度,下面会简单分析一下Edmonds-Karp算法的时间复杂度。
    主要意思就是:假设residual graph有m条边,n个点,算法的每一轮循环都要在residual graph中寻找无权的最短路,所以需要O(m)的时间复杂度,原因是,如果原图中有m条边,那么residual graph中最多有m条反向边,所以residual graph一共有不超过2m条边,如果一个无权图有2m条边,那么寻找最短路就需要O(m)的时间。此外,Edmonds和Karp两个人证明了算法最多循环mn轮,即,算法每一轮需要O(m)的时间,最多循环mn轮,所以最坏时间复杂度是 O ( m 2 n ) O(m^2n) O(m2n),这个时间复杂度与最大流无关,最大流可以是几百几千万,都不会影响时间复杂度的大小。
    在这里插入图片描述

5.Dinic’s Algorithm

Dinic’s Algorithm它是寻找网络最大流的算法,它的时间复杂度比Edmonds-Karp Algorithm更低,先简单比较一下两种算法的时间复杂度,具体如下所示:
在这里插入图片描述
从图中可以看出,若边的数量为m,点的数量为n,则Edmonds-Karp Algorithm的时间复杂度为O( m 2 n m^2n m2n),而Dinic’s Algorithm的时间复杂度为O( m n 2 mn^2 mn2),但是一般边的个数m会远大于点的个数n,因此Dinic’s Algorithm的时间复杂度会更低。
Dinic’s Algorithm要用到Blocking Flow(阻塞流),阻塞流意思是拥有这些流量,就不能增加更多流量,也就是这些流量阻塞了管道。
最大流一定是阻塞流,但是阻塞流未必是最大流。 前面介绍的简单算法一定能找到阻塞流,但是未必能找到最大流。
此外,Dinic’s Algorithm还会用到Level Graph ,下面简单介绍一下Level Graph。
给定右边的原图,下面一步步构造Level Graph,从起点S开始,走一步能达到 v 1 , v 2 v_{1},v_{2} v1,v2这两个节点,把 v 1 , v 2 v_{1},v_{2} v1,v2加入左边的Level Graph,同时把 v 1 , v 2 v_{1},v_{2} v1,v2记作第一层,意思是从起点出发走一步能达到,保留从起点S到第一层的边。再看右边的原图,从第一层的 v 1 , v 2 v_{1},v_{2} v1,v2出发,走一步能达到 v 3 , v 4 v_{3},v_{4} v3,v4两个节点,把 v 3 , v 4 v_{3},v_{4} v3,v4加入左边的Level Graph,同时把 v 3 , v 4 v_{3},v_{4} v3,v4记作第二层,意思是从起点出发走两步能达到,保留从第一层到第二层的三条边。再看右边的原图,从第二层的节点 v 3 , v 4 v_{3},v_{4} v3,v4出发。走一步可以达到终点t,把终点t加入左边的Level Graph,同时把终点t记作第三层,意思是从起点出发走三步能达到,并保留第二层到第三层的边,Level Graph的边指的是从上一层到下一层。,下图右侧两条紫色的边分别是从第一层到第一层,第二层到第二层,因此不能加入Level Graph中。
在这里插入图片描述
掌握了与预备知识,那么下面进入正题!
Dinic’s算法是一种高效的解决最大流问题的算法,它基于增广路径和分层图的概念。以下是Dinic’s算法的步骤总结:

  1. 构建初始残余网络(residual graph):将所有边的流量初始化为0,并根据网络中的边构建初始的残余网络(residual graph)。
  2. 构建分层图(Level Graph):使用广度优先搜索(BFS)构建分层图。分层图是在残余网络中,将每个节点按照其到源节点的最短距离分层的图。
  3. 寻找增广路径:在分层图中,从源节点到汇节点寻找增广路径。增广路径是指路径上所有边的剩余容量大于0。
  4. 更新阻塞流和反向边:如果找到增广路径,则将对应residual graph路径上的最小剩余容量作为阻塞流,增加流量,并更新路径上的边的剩余容量。同时,对于路径上的每条边,增加反向边的剩余容量。
  5. 重复迭代:重复步骤2到步骤4,直到无法再找到增广路径为止。每次迭代中,分层图(Level Graph)会更新,从而更好地指导下一次增广路径的寻找。
  6. 终止条件:当无法再找到增广路径时,算法终止。此时,得到的流就是最大流。
    Dinic’s算法通过构建分层图(Level Graph)来指导增广路径的寻找,从而减少了无效的搜索,提高了算法的效率。在寻找增广路径时,除了更新阻塞流和路径上的边的剩余容量外,还需要增加反向边的剩余容量,以确保反向流的正确性。
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/e82e433f7a91418d891a1c6d62c1f6fe.png

6.Minimum Cut Problem

Minimum Cut Problem翻译为最小割问题,最小割与最大流是等价的。
可以这样理解最小割问题,Cut的意思是割断一些管道,让水不能从起点s流向终点t,Min-Cut最小割的目标是让割断的水管总容量最小,也就是说,我尽量割断细的管道,而不是粗的管道,我用最小的力气就能截断水流。
对于同一张图,有不同的切断方式,左边的割量为3,是最小割,而右边的割为6,它不是最小割!此外,还需要注意,最小割的并不唯一!
在这里插入图片描述

7.Max-Flow Min-Cut Theorem

最大流最小割定理(Max-Flow Min-Cut Theorem)说明了最大流问题和最小割问题的等价性!
对于一个网络流问题,最大流的流量等于最小割的容量,也就是说,你求出了最大流问题,就相当于求出了最小割问题。这个定理是Ford和Fulkerson两个人在1962年提出来的。
在这里插入图片描述
接下来介绍一种寻找最小割问题!
这种方法把最小割问题等价转换为最大流问题,只要我们找到最大流,我们就能找到最小割。
简单来说就是:
1.使用Edmonds-Karp Algorithm找到最终的residual graph;
2.然后在最终的residual graph去掉所有的反向边;
3.在去掉所有反向边的residual graph后,从该图中找到从s出发能到达的所有顶点,让其作为集合的一部分,剩下的作为集合的剩余部分;
4.最后根据划分好的两部分集合找到最小割。
在这里插入图片描述

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

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

相关文章

linux音频-IIS音频接口

IIS 总线 IIS(Integrate Interface of Sound)即集成音频接口,在上个世纪 80 年代首先被 Philips 公司用于消费产品的音频设备, I2S规范 I2S总线只能用来处理audio data,而别的信号比如控制信号,编码信号则交给别的模块处理。为了…

【攻克】抓包工具:中文版Fiddler使用 教程-攻克获取微信账单

Fiddler是一款免费网络代理调试工具。 Fiddler是一个蛮好用的抓包工具,可以将网络传输发送与接受的数据包进行截获、重发、编辑、转存等操作。也可以用来检测网络安全。反正好处多多,举之不尽呀! 当年学习的时候也蛮费劲,一些蛮…

数据清洗与规范化详解

数据处理流程,也称数据处理管道,是将原始数据转化为有意义的信息和知识的一系列操作步骤。它包括数据采集、清洗、转换、分析和可视化等环节,旨在提供有用的见解和决策支持。在数据可视化中数据处理是可视化展示前非常重要的一步,…

信息科技如何做好风险管理

文章目录 前言介绍亮点结构读者对象 前言 信息科技对金融业务发展所起的作用是举足轻重的。 近年来,金融机构在战略规划中相继引入科技引领的概念。作为金融机构信息科技从业人员,我们笃信信息科技是一个非常有用的工具,一个兼具产品思维和管…

Mysql在ubuntu22.04上安装配置

更新并下载Mysql sudo apt update sudo apt install mysql-server启动Mysql服务 sudo systemctl start mysql安全配置 包括设置密码、删除匿名用户、禁止远程root登录等,按提示进行即可。 sudo mysql_secure_installation是否设置密码:是 三种强度密…

DBeaver连接数据库报错:Public Key Retrieval is not allowed 的解决方案

写在前面: DBeaver是一款免费的数据库管理工具,安装也是傻瓜式一键安装,比较推荐。 DBeaver官网(加载有点慢,耐心等待):DBeaver Community | Free Universal Database Tool 报错详情&#xff…

ARM,汇编指令

一、汇编指令 1、搬移指令 mov r0 ,#3 mov r1,r0 msr cpsr,r0 mrs r0,cpsr 2、条件执行及标志位 cmp moveq movgt 3、机器码 1)、立即数合法性 2)、立即数不合法 ldr r0,0x12345678 伪指令解决不合法的问题 前4位表示16个数,一个数移动2次。 …

疯狂java 三-六章

第三章 数据类型和运算符 Java语言是强类型语言,意思是每个变量和每个表达式都有一个在编译时就确定的类型,所有的变量都必须显式声明类型 标识符就是类,变量、方法命名的符号 标识符不能包含空格 标识符只能包含美元符($),不…

UG\NX二次开发 连接曲线、连结曲线 UF_CURVE_auto_join_curves

文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C++-CSDN博客 简介 UG\NX二次开发 连接曲线、连结曲线 UF_CURVE_auto_join_curves 效果 代码 #include "me.hpp" extern DllExport void ufusr(char* param, int* returnC…

白嫖在线云服务器,免费在 linux 服务器使用 docker 。 附视频+附文档

白嫖在线云服务器,免费在 linux 服务器使用 docker 。 附视频附文档 文章目录 前言启动 Nginx 案例最后 视频:https://www.bilibili.com/video/BV1WN411W79V/ 国内互联网经过多年发展,单体应用已经无法支持我们的互联网业务,分布…

“第五十一天”

无符号整数: 计算机硬件在进行无符号整数的加法时,从最低位开始,按位相加,并往更高位进位。 当进行减法时,被减数不变,减数全部按位取反,末位加一(将一个正数变负,或者…

使用element-UI Cascader组件,实现第一级单选选,第二级,第三级,子级可以多选

最近开发过程中,遇到需求测一个需求,就是级联选择器,需要多选;但是第一级是单选; 既要单选又要复选。参照网上内容,自己整理了一下功能实现; 如下图: 思路:1.把第一层的…

卡巴斯基2009杀毒软件

下载地址:https://user.qzone.qq.com/512526231/main https://user.qzone.qq.com/3503787372/main

ROS学习记录2018.7.10

ROS学习记录2018.7.10 1.ROS基础了解 开源机器人操作系统ROS(robot operation system) 分级: 1.计算图集(一种网络结构) 1.节点:执行运算的进程(做基础处理的单元)2.消息&#x…

输入/输出应用程序接口和设备驱动程序接口

文章目录 1.输入/输出应用程序接口1.字符设备接口2.块设备接口3.网络设备接口1.网络设备套接字通信 4.阻塞/非阻塞I/O 2.设备驱动程序接口1.统一标准的设备驱动程序接口 1.输入/输出应用程序接口 1.字符设备接口 get/put系统调用:向字符设备读/写一个字符 2.块设备接口 read/wr…

Ubuntu环境下DOSBOX的配置

【步骤一】 先打开命令行,进入root模式,输入如下语句: sudo apt-get install dosbox 该语句的作用主要是安装dosbox 【步骤二】 安装完成之后,命令行输入dosbox 会进入dosbox页面: 【步骤三】 在你的主机中&…

淘宝app商品详情源数据API接口(解决滑块问题)可高并发采集

通过API接口采集淘宝商品列表和app商品详情遇到滑块验证码的解决方法(带SKU和商品描述,支持高并发),主要是解决了高频情况下的阿里系滑块和必须要N多小号才能解决的反扒问题,以后都可以使用本方法: 大家都…

统计数(C++)

系列文章目录 进阶的卡莎C++_睡觉觉觉得的博客-CSDN博客数1的个数_睡觉觉觉得的博客-CSDN博客双精度浮点数的输入输出_睡觉觉觉得的博客-CSDN博客足球联赛积分_睡觉觉觉得的博客-CSDN博客大减价(一级)_睡觉觉觉得的博客-CSDN博客小写字母的判断_睡觉觉觉得的博客-CSDN博客纸币(…

Ubuntu22.04 交叉编译阿里oss c-sdk

一、交叉编译openssl Ubuntu20.04 交叉编译openssl 1.0.1f_编译前去除 makefile 中所有的"-m64"字段_qq76211822的博客-CSDN博客文章浏览阅读319次。Ubuntu20.04 交叉编译openssl_编译前去除 makefile 中所有的"-m64"字段https://blog.csdn.net/sz7621182…

力扣刷题 day56:10-26

1.解码异或后的数组 未知 整数数组 arr 由 n 个非负整数组成。 经编码后变为长度为 n - 1 的另一个整数数组 encoded ,其中 encoded[i] arr[i] XOR arr[i 1] 。例如,arr [1,0,2,1] 经编码后得到 encoded [1,2,3] 。 给你编码后的数组 encoded 和原…