文章目录

  • 最大流问题
    • 福特-富尔克森算法
    • 最大流最小割定理

最大流问题

在给定弧赋权的有向图D=(V, A)中有两个特殊的点,一个是源点s,一个是汇点t。
我们可以将弧e上的权值理解为管道的容量,这时,从s往t的最大流量为多少的问题称为最大流问题

最大流问题的数学定义如下。作为问题的输入,我们需要给出上述有向图D=(V, A)、顶点s与t,以及各弧的容量w(e)。
定义一个函数f,为每条弧指定一个实数值,若函数满足以下条件,则称之为

容量限制原则:
∀弧e,f(e)≦w(e)\forall 弧e,f(e) \leqq w(e)∀弧e,f(e)≦w(e)
流量守恒原则:
对于s、t之外的任意顶点v,下式都成立
∑指向v的弧ef(e)=∑从v引出的弧ef(e)\sum_{指向v的弧e} f(e) = \sum_{从v引出的弧e} f(e)指向v的弧e∑​f(e)=从v引出的弧e∑​f(e)

流f的流量定义为从s流出的流量总和
∑从s引出的弧ef(e)\sum_{从s引出的弧e} f(e)从s引出的弧e∑​f(e)
根据流量守恒原则,f的流量也等于流入t的流量总和
∑指向t的弧ef(e)\sum_{指向t的弧e} f(e)指向t的弧e∑​f(e)
流量最大的流被称为最大流,最大流问题就是求解最大流的问题

福特-富尔克森算法

该算法最初随意选择某个流作为基础,判断是否可以增加流量。
若可以,则增加流量,并重复执行以上过程以得到最大的流。若不可以,则输出当前的流作为结果。
判断是否可以增加流量,需要引入残留网络的概念。
残留网络是为当前流f定义的一个赋权有向图(记为R)。
其顶点的集合与输入的图G相同,其弧的集合由与D中的弧方向相同和相反的两种弧构成。
设D中有弧e=(u, v),则R中有相应的两条弧(u, v)权值为w(e)-f(e),(v, u)权值为f(e)。这代表从u到v可以增加w(e)-f(e)的流量,从v到u可以增加f(e)的流量。
在残留网络中,从s到t的路称为增广路(augmenting path),增广路P上权值最小的弧的权重称为该增广路的容量,记为c§。
换句话说,流f沿着增广路P,从s到t可以增加c§的流量。

福特-富尔克森算法的基本步骤如下

  1. 求出初始流f(对于所有的弧e,f(e)=0)
  2. 求出流f的残留网络R
  3. 在R中寻找增广路。找到后,则按照增广路修改流f与残留网络R;如果没找到则进入下一步
  4. 输出流f

福特-富尔克森算法的有效性等同于下面这个命题

流f为最大流的充分必要条件是,流f的残留网络中没有增广路

必要性是显然的, 下面用证明充分性

假设残留网络R中不存在增广路。将R中s出发可以到达的顶点的集合记为X(包含s本身),显然t不在X中。
首先,在输入的图D中,存在一条弧(u, v),使得u∈Xu \in Xu∈X且v∉Xv \notin Xv∈/X,即从X内的点指向X外的点。根据X的定义,R中不存在弧(u, v),因此弧(u, v)的容量被全部用完了。
其次,在输入的图D中,存在一条弧(u, v),使得u∉Xu \notin Xu∈/X且v∈Xv \in Xv∈X,即从X外的点指向X内的点。根据X的定义,R中不存在弧(v, u),因此弧(u, v)的容量完全没有被使用。
因此从X输出的流量到了最大值,因此,f就是s到t的最大流。

下面给出python实现,存储在我的github公共库中

from copy import deepcopydef dfs_audmenting_path(residual_net, s, t):# 使用深度优先搜索寻找增广路stack = [s]visited = []path = dict()found = Falsewhile stack and not found:point = stack.pop()visited.append(point)for vertex in residual_net.ad_list(point):if vertex not in visited:if vertex not in stack:stack.append(vertex)path[vertex] = pointif vertex == t:path[t] = pointfound = Trueif found:road = []point = troad.append(t)while point != s:point = path[point]road.append(point)return road[::-1]return Falsedef update(road, residual_net, max_flow, flow_capacity):bound = len(road) - 1min_weight = min(residual_net.get_weight((road[i], road[i + 1])) for i in range(bound))  # 找到增广路上的最小容量,这是要增加的容量flow_capacity += min_weightfor i in range(bound):# 修改残留网络与最大流草图edge = (road[i], road[i + 1])reversed_edge = (road[i + 1], road[i])weight = residual_net.get_weight(edge)if weight == min_weight:# 在残留网络中,如果权在修改后为零,则删除此弧residual_net.remove_edge(edge)else:residual_net.weights[edge] -= min_weightif reversed_edge in residual_net.edges:# 修改反向的弧residual_net.weights[reversed_edge] += min_weightelse:residual_net.add_edge(reversed_edge)residual_net.add_weight({reversed_edge: min_weight})if edge in max_flow.edges:# 修改最大流草图max_flow.weights[edge] += min_weightelse:max_flow.weights[edge] -= min_weightdef ford_fulkerson(G, s, t):"""输入:G,有向正权图;s,源点;t,汇点输出:max_flow,有向正权图,最大流"""max_flow = deepcopy(G)  # 最大流草图flow_capacity = 0for edge in max_flow.edges:# 目前的最大流为零max_flow.weights[edge] = 0residual_net = deepcopy(G)  # 残留网络road = dfs_audmenting_path(residual_net, s, t)  # 寻找增广路while road:# 寻找增广路,并修改残留网络与最大流草图,直到找不到位置update(road, residual_net, max_flow, flow_capacity)road = dfs_audmenting_path(residual_net, s, t)return max_flow, flow_capacity

最大流最小割定理

将图D=(V, A)作为最大流问题的输入。为将包含s但不包含t的顶点的子集,即满足Y⊂V,s∈Y,t∉YY \subset V, s \in Y, t \notin YY⊂V,s∈Y,t∈/Y的集合Y称为D的
若弧(u,v)∈A(u, v) \in A(u,v)∈A满足u∈Yu \in Yu∈Y及v∈V−Yv \in V-Yv∈V−Y,则称为Y的割边。
割Y的容量是指Y的割边的权值总和。

最大流最小个定理即

对于任意的图都有最大流的流量等于最小割容量对于任意的图都有最大流的流量等于最小割容量对于任意的图都有最大流的流量等于最小割容量

最大流问题与福特-富尔克森算法相关推荐

  1. 了解福特-福克森算法

    文章目录 使用的术语 Ford-Fulkerson算法如何工作? Ford-Fulkerson 示例 C示例 Ford-Fulkerson 应用 参考文档     在本教程中,您将学习什么是Ford- ...

  2. 《算法图解》学习笔记(七):狄克斯特拉算法(附代码)

    欢迎关注WX公众号:[程序员管小亮] python学习之路 - 从入门到精通到大师 文章目录 欢迎关注WX公众号:[程序员管小亮] [python学习之路 - 从入门到精通到大师](https://b ...

  3. 算法图解part7:狄克斯特拉算法

    算法图解part7:狄克斯特拉(Dijkstra)算法 1.狄克斯特拉算法(Dijkstra's algorithm) 2.术语 3.负权边 4.实现狄克斯特拉算法 4.1 最短路径思路 4.2 py ...

  4. 第7章——狄克特斯拉算法

    算法比较 相比于第6章的广度优先算法计算的是无权图中的最短路径,狄克特斯拉算法计算的是加权图中的最短路径 算法流程 找出最便宜的节点,即可在最短时间内前往的节点. 对于该节点的邻居,检查是否有前往它们 ...

  5. 狄克斯特拉算法(入门)

    狄克斯特拉算法可以找出加权图中前往X的最短路径. 注意: - 其只适用于有向无环图 - 适用于正权边,负权边的将出错(贝尔曼-福德算法适用于负权边) 步骤: 找出当前最"便宜"的节 ...

  6. 小白的算法初识课堂(part7)--狄克斯特拉算法

    学习笔记 学习书目:<算法图解>- Aditya Bhargava 文章目录 狄克斯特拉算法 具体步骤实现 术语 跳蚤市场 具体步骤实现 负权边 python实现 狄克斯特拉算法 在上一个 ...

  7. 07-狄克斯特拉算法

    数据结构和算法 基于<算法图解>-Aditya Bhargava 和<数据结构>-严蔚敏 第7章 狄克斯特拉算法 上一章的广度优先搜索,找出的是段数最少的路径: 本章狄克斯特拉 ...

  8. 图解算法学习笔记(七):狄克斯特拉算法

    目录 1)使用狄克斯特拉算法 2)术语 3)实现 4)小结 本章内容; 介绍加权图,提高或降低某些边的权重: 介绍狄克斯特拉算法,找出加权图中前往X的最短路径: 介绍图中的环,它导致狄克斯特拉算法不管 ...

  9. 算法(四):图解狄克斯特拉算法

    算法简介 狄克斯特拉算法(Dijkstra )用于计算出不存在非负权重的情况下,起点到各个节点的最短距离 可用于解决2类问题: 从A出发是否存在到达B的路径: 从A出发到达B的最短路径(时间最少.或者 ...

最新文章

  1. Spring Batch在大型企业中的最佳实践
  2. jenkins 启动_CentOS 7 安装 Jenkins
  3. Spark内存管理(2)—— 统一内存管理
  4. 仿某某网站模板thinkphp_西安网站建设到底是什么?
  5. html基本标签与属性
  6. 两个多项式相乘求解系数数组算法
  7. 水滴石穿C语言之编译器引出的问题
  8. Java基础篇(03):流程控制语句,和算法应用
  9. 第一单元总结(汇编初探)
  10. Cinemachine教程 | Unity中如何快速制作相机切换动画?
  11. 多个 小程序_最简单的小程序制作方法,不会代码也能撸一个
  12. 推动隐私计算技术,360数科提出分割式神经网络框架
  13. java循环速度比较_List的二种循环速度比较
  14. 计算机装调与维护报告,Vmware workstation在计算机装调与维护实训中的应用
  15. 《激荡三十年》十九、脚下的路——对中国经济未来的猜想
  16. 计算机英语单词练习一
  17. 绿色计算产业峰会,易捷行云新一代ARM云平台推动绿色计算产业发展
  18. [学习笔记]UnityShader入门精要_第12章_屏幕后处理效果
  19. python在windows和linux系统下批量读取grib2数据
  20. 怎么让c语言程序右边对齐,c语言中的对齐方式

热门文章

  1. 如何下载生物数据(四):SRA数据下载
  2. 中国各省人力资本测算就业人员受教育程度构成(2000-2021年)
  3. Stlink固件更新问题“ST-Link is not in the dfu mode Please restart it“的解决方法
  4. 利用Linux宝塔界面搭建个不限速的网盘
  5. jupyter notebook 用PPT展示代码 +插入图片
  6. php判断单选框是否被选中,JQuery form验证单选框是否选中经验总结
  7. 以爱情规律为例,浅谈三段式描述状态机
  8. 魔兽世界模拟器技术之mangos gm命令分类别分组最详细攻略
  9. C语言 火车票信息管理系统
  10. 如何实现产销平衡_六个动作实现制造企业产销协调管理