【图与网络数学模型】3.Ford-Fulkerson算法求解网络最大流问题

在这里插入图片描述

【图与网络数学模型】3.Ford-Fulkerson算法求解网络最大流问题

  • 一、网络流模型
    • 1. 概述
    • 2. 可行流
    • 3. 增广链
  • 二、示例
    • 1. 最大流问题
    • 2. Alternate Formulation:最小截量问题
  • 三、Ford-Fulkerson 算法
    • 1. 导入库
    • 2. 初始化残差图
    • 3. 定义查找增广路径
    • 4. 定义循环
    • 5. 程序运行
  • 四、其它发现
  • 参考文献


一、网络流模型

1. 概述

许多系统中包含了流量问题,例如,公路系统中有车辆流,控制系统中有信息流,供水系统中有水流,金融系统中有现金流等。

在生物安全领域和医疗系统中,也包括就诊、挂号、检查、治疗、转院等过程涉及的患者流,医疗设备、药品、医用材料等的采购、配送、使用等过程涉及的医疗资源流,以及医疗质量控制流和医保支付流等等。

对于这样一些包含了流量问题的系统,我们往往要求出其系统的最大流量。给一个带收发点的网络,每条弧的赋权称为容量,在不超过每条弧的容量的前提下,确定每条弧的流量,求出从发点到收点的最大流量,这类问题通常称为最大流问题

2. 可行流

  • 网络流一般在有向图上讨论
  • 定义网络上支路的容量为其最大通过能力,记为 c i j c_{ij} cij,支路上的实际流量记为 f i j f_{ij} fij
  • 图中规定一个发点s,一个收点t
  • 节点没有容量限制,流在节点不会存储
  • 容量限制条件:0 ≤ f i j f_{ij} fij c i j c_{ij} cij
  • 平衡条件:
    ∑ v j ∈ A ( v i ) f i j − ∑ v j ∈ B ( v i ) f j i = { v ( f ) i = s 0 i ≠ s , t − v ( f ) i = t \sum_{v_j \in A\left(v_i\right)} f_{i j}-\sum_{v_j \in B\left(v_i\right)} f_{j i}=\left\{\begin{array}{cc} v(f) & i=s \\ 0 & i \neq s, t \\ -v(f) & i=t \end{array}\right. vjA(vi)fijvjB(vi)fji= v(f)0v(f)i=si=s,ti=t

满足上述条件的网络流称为可行流,总存在最大可行流。

当支路上 f i j = c i j f_{ij}=c_{ij} fij=cij ,称为饱和弧;v( f )为可行流的流量。

最大流问题也是一个线性规划问题。

3. 增广链

设 f 是一个可行流, μ \mu μ v s v_s vs v t v_t vt 到的一条链,若 μ \mu μ 满足下列条件,则 μ \mu μ 是可行流的一条增广链

  1. ( v i , v j ) ∈ μ + \left(v_i, v_j\right) \in \mu^{+} (vi,vj)μ+上, 0 ≤ f i j < c i j 0\leq{f}_{i_j}<c_{i j} 0fij<cij,即 μ + \mu^{+} μ+ 中每一条弧是非饱和弧;
  2. ( v i , v j ) ∈ μ − \left(v_i, v_j\right) \in \mu^{-} (vi,vj)μ上, 0 < f i j ≤ c i j 0<f_{i j} \leq c_{i j} 0<fijcij,即 μ − \mu^{-} μ中每一条弧是非零流孤。

二、示例

1. 最大流问题

给定一个图,该图表示每个边都有一个容量的流网络。此外,给定图中的两个顶点源 ‘s’ 和接收器 ‘t’,使用以下约束找到从 s 到 t 的最大可能流量:

在这里插入图片描述

该问题的最大流量为23:

在这里插入图片描述

2. Alternate Formulation:最小截量问题

  • 把网络分割为两个成分的弧的最小集合,其中一个成分包含 s s s 点,另一个包含 t t t
  • 一般包含 s s s 点的成分中的节点集合用 V V V 表示,包含 t t t 点的成分中的节点集合用 V ˉ \bar{V} Vˉ 表示
  • 截量集容量是指截量集中前向弧的容量之和:
    C ( V , V ˉ ) = ∑ i ∈ V j ∈ V ˉ c i j C(V, \bar{V})=\sum_{\substack{i \in V \\ j \in \bar{V}}} c_{i j} C(V,Vˉ)=iVjVˉcij

福特-富克森定理:网络的最大流等于最小截量集容量。

从原始图中“减去”最大流路径,得到下图:

在这里插入图片描述

标记从 s 到达的所有节点——调用可到达节点集 A:

在这里插入图片描述
将这些节点和其他节点分开:

在这里插入图片描述

从图中删除红色的边,使得删除这些边后,没有从 s 到 t 的路径:

在这里插入图片描述

相应的最大流量路径为:
− s → a → b → t : 11 − s → c → a → b → t : 1 − s → c → d → b → t : 7 − s → c → d → t : 4 \begin{aligned} & -s \rightarrow a \rightarrow b \rightarrow t: 11 \\ & -s \rightarrow c \rightarrow a \rightarrow b \rightarrow t: 1 \\ & -s \rightarrow c \rightarrow d \rightarrow b \rightarrow t: 7 \\ & -s \rightarrow c \rightarrow d \rightarrow t: 4 \end{aligned} sabt:11scabt:1scdbt:7scdt:4

三、Ford-Fulkerson 算法

在1962年,L.R.Ford和D.R.Fulkerson发明了一种解决最大流量问题的有效方法。它是一种沿着由起点到终点的路径逐步增加流量的通用方法,因此它也是同类算法的基础。在经典文献中它被称为Ford-Fulkerson算法,但它也被称为增广路径算法。

Ford-Fulkerson最大流量算法: 网络中的初始流量为零,沿着任意从起点到终点(且不含有饱和的正向边或是空逆向边)的增广路径增大流量,直到网络中不存在这样的路径为止。

1. 导入库

from collections import defaultdict

2. 初始化残差图

初始化残差图(residual graph)以及行数 ROW。

	def __init__(self, graph):self.graph = graph # 残差图self. ROW = len(graph)# self.COL = len(gr[0])

3. 定义查找增广路径

使用广度优先搜索来找到从源点 s 到汇点 t 的一条增广路径,同时更新父节点数组 parent。

	def BFS(self, s, t, parent):visited = [False]*(self.ROW)queue = []queue.append(s)visited[s] = Truewhile queue:u = queue.pop(0)for ind, val in enumerate(self.graph[u]):if visited[ind] == False and val > 0:queue.append(ind)visited[ind] = Trueparent[ind] = uif ind == t:return Truereturn False

4. 定义循环

在 FordFulkerson 方法中,使用 while 循环来不断寻找增广路径,并更新残差图直到没有增广路径为止。

	def FordFulkerson(self, source, sink):parent = [-1]*(self.ROW)max_flow = 0 while self.BFS(source, sink, parent) :path_flow = float("Inf")s = sinkwhile(s != source):path_flow = min (path_flow, self.graph[parent[s]][s])s = parent[s]max_flow += path_flowv = sinkwhile(v != source):u = parent[v]self.graph[u][v] -= path_flowself.graph[v][u] += path_flowv = parent[v]return max_flow

5. 程序运行

from collections import defaultdictclass Graph:def __init__(self, graph):self.graph = graphself. ROW = len(graph)def BFS(self, s, t, parent):visited = [False]*(self.ROW)queue = []queue.append(s)visited[s] = Truewhile queue:u = queue.pop(0)for ind, val in enumerate(self.graph[u]):if visited[ind] == False and val > 0:queue.append(ind)visited[ind] = Trueparent[ind] = uif ind == t:return Truereturn Falsedef FordFulkerson(self, source, sink):parent = [-1]*(self.ROW)max_flow = 0 while self.BFS(source, sink, parent) :path_flow = float("Inf")s = sinkwhile(s != source):path_flow = min (path_flow, self.graph[parent[s]][s])s = parent[s]max_flow += path_flowv = sinkwhile(v != source):u = parent[v]self.graph[u][v] -= path_flowself.graph[v][u] += path_flowv = parent[v]return max_flowgraph = [[0, 16, 13, 0, 0, 0],[0, 0, 10, 12, 0, 0],[0, 4, 0, 0, 14, 0],[0, 0, 9, 0, 0, 20],[0, 0, 0, 7, 0, 4],[0, 0, 0, 0, 0, 0]]g = Graph(graph)source = 0; sink = 5print ("The maximum possible flow is %d " % g.FordFulkerson(source, sink))

运行结果为:

The maximum possible flow is 23

四、其它发现

Edmonds和Karp发明的另一种Ford-Fulkerson算法的实现是优先处理能够将流量增大最多的增广路径。对于这种(以及其他一些)方法,可以通过稍加修改Dijkstra的最短路径算法、由优先队列得到剩余容量最大的正向边或是流量最大的逆向边来实现。或者也可以寻找最长增广路径,或是随机选择增广路径。

各种最大流量算法的分析仍然是一个有趣而活跃的研究领域。从理论角度来说,我们已经得到了各种最大流量算法在最坏情况下的上界,但这些上界大多远远高于实际应用中所观察到的真实成本,而且也比较小的下界(线性级别)高出许多。

“最大流量算法的实际应用仍然既是一门艺术也是一门科学。它的艺术之处在于为特定的应用场景选择最有效的策略;它的科学之处在于对问题本质的理解。”

参考文献

  1. Derigs U, Meier W. Implementing Goldberg’s max-flow-algorithm—A computational investigation[J]. Zeitschrift für Operations Research, 1989, 33(6): 383-403.
  2. Ahuja R K, Kodialam M, Mishra A K, et al. Computational investigations of maximum flow algorithms[J]. European Journal of Operational Research, 1997, 97(3): 509-542.
  3. Cherkassky B V, Goldberg A V. On implementing push-relabel method for the maximum flow problem[C]//International Conference on Integer Programming and Combinatorial Optimization. Springer, Berlin, Heidelberg, 1995: 157-171.
  4. Thomas H. Cormen,Charles E. Leiserson,Ronald L. Rivest,Clifford Stein.算法导论. 美国.麻省理工学院出版社.2009

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

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

相关文章

ubuntu22.04@Jetson Orin Nano之OpenCV安装

ubuntu22.04Jetson Orin Nano之OpenCV安装 1. 源由2. 分析3. 证实3.1 jtop安装3.2 jtop指令3.3 GPU支持情况 4. 安装OpenCV4.1 修改内容4.2 Python2环境【不需要】4.3 ubuntu22.04环境4.4 国内/本地环境问题4.5 cudnn版本问题 5. 总结6. 参考资料 1. 源由 昨天用Jetson跑demo程…

《英伟达-本地AI》--NVIDIA Chat with RTX-本机部署

阿丹&#xff1a; 突然发现公司给配置的电脑是NVIDIA RTX 4060的显卡&#xff0c;这不搞一搞本地部署的大模型玩一玩&#xff1f;&#xff1f;&#xff1f; 从0-》1记录一下本地部署的全过程。 本地模型下载地址&#xff1a; Build a Custom LLM with Chat With RTX | NVIDIA…

虚拟机安装Centos7迷你版

虚拟机安装Centos7迷你版 迷你版较常规版精简了很多功能&#xff0c;所以体积也小了很多&#xff0c;喜欢自定义安装的可以选择迷你版 参考文章&#xff1a; VirtualBox虚拟机安装Centos7详细教程图解 网卡配置参考文章 下载Centos迷你版镜像 安装镜像 下载镜像 阿里云Cen…

理论学习-ARM-内核

ARM内核 函数的调用加载、存储计算中断异常线程的切换 为了提高学习效率&#xff0c;我们要提前想好学习策略。 首先&#xff0c;使用频率越高的知识点&#xff0c;越要首先学习。假使&#xff0c;我们学习了一个知识点&#xff0c;能覆盖工作中80%的工作量&#xff0c;那是不是…

机器学习基础(四)非监督学习的进阶探索

导语&#xff1a;上一节我们详细探索监督学习的进阶应用&#xff0c;详情可见&#xff1a; 机器学习基础&#xff08;三&#xff09;监督学习的进阶探索-CSDN博客文章浏览阅读296次&#xff0c;点赞13次&#xff0c;收藏11次。监督学习作为机器学习的一个主要分支&#xff0c;…

【C++】vector模拟实现+迭代器失效

vector模拟实现 成员变量定义默认成员函数构造函数 迭代器范围for、对象类型匹配原则 容量操作sizeemptycapacityreserve成员变量未更新memcpy值拷贝 resize内置类型的构造函数 数据访问frontbackoperator[ ] 数据修改操作push_backpop_backswapclearinsertpos位置未更新无返回…

【Linux】Linux调试器-gdb使用

1. 背景 程序的发布方式有两种&#xff0c;debug模式和release模式 Linux gcc/g出来的二进制程序&#xff0c;默认是release模式 要使用gdb调试&#xff0c;必须在源代码生成二进制程序的时候, 加上 -g 选项 2. 开始使用 gdb binFile 退出&#xff1a; ctrl d 或 quit 调…

Java 学习和实践笔记(15):面向过程和面象对象其实很简单!

学完这一节&#xff0c;才真正明白了什么叫面向对象和面向过程&#xff0c;其实很简单~ 第一个例子&#xff1a;怎样把大象装进冰箱 这个很清楚很容易地可以列出第一步。 第二个例子&#xff1a;怎样制造一台汽车 这个就很难确定哪一步做第一步。 面向过程和面向对象的区别 …

笔记:torch.roll

最近在准备写 swin transformer 的文章&#xff0c;记录下 torch.roll 的用法&#xff1a; >>> x torch.tensor([1, 2, 3, 4, 5, 6, 7, 8]).view(4, 2) >>> x tensor([[1, 2],[3, 4],[5, 6],[7, 8]]) 第0维度向下移1位&#xff0c;多出的[7,8]补充到顶部 &g…

【移动开发】iOS平台 Java编译器 Jedona Compiler 评测

上期编译器评测链接&#xff1a; Java Compiler IDE评测 一、使用平台 该编译器&#xff08;Jedona Compiler&#xff09;在苹果应用市场App Store中下载&#xff0c;笔者使用iPad进行Java代码编写。 应用市场界面&#xff1a; 二、开发界面介绍 开发界面比较简洁&#xf…

python 与 neo4j 交互(py2neo 使用)

参考自&#xff1a;neo4j的python.py2neo操作入门 官方文档&#xff1a;The Py2neo Handbook — py2neo 2021.1 安装&#xff1a;pip install py2neo -i https://pypi.tuna.tsinghua.edu.cn/simple 1 节点 / 关系 / 属性 / 路径 节点(Node)和关系(relationship)是构成图的基础…

重磅!移远通信正式发布一站式XR产品解决方案,助力探索数字世界新纪元

伴随着以5G、大数据、云计算等现代化信息科技的发展&#xff0c;人类对数字世界、智慧地球的探索更加深入。尤其是以XR&#xff08;扩展现实&#xff09;为代表的技术崛起&#xff0c;更让物理世界与虚拟世界中的连接愈发紧密&#xff0c;千行百业也亟待新探索。 近日&#xff…

计算机组成原理(4)-----Cache的原理及相关知识点

目录 1.Cache的原理 2.Cache的性能 3.Cache和主存的映射方式 &#xff08;1&#xff09;全相联映射 &#xff08;2&#xff09;直接映射 &#xff08;3&#xff09;组相联映射 4.替换算法 (1)随机算法(RAND) (2)先进先出算法(FIFO) (3)近期最少使用(LRU) (4)最近不经…

论文阅读:How Do Neural Networks See Depth in Single Images?

是由Technische Universiteit Delft(代尔夫特理工大学)发表于ICCV,2019。这篇文章的研究内容很有趣,没有关注如何提升深度网络的性能&#xff0c;而是关注单目深度估计的工作机理。 What they find&#xff1f; 所有的网络都忽略了物体的实际大小&#xff0c;而关注他们的垂直…

WEB APIs (4)

日期对象 实例化 代码中出现new关键字&#xff0c;创建时间对象 得到当前时间&#xff1a; const date new Date&#xff08;&#xff09; 获得指定时间&#xff1a; const date new Date&#xff08;‘2022-5-1’&#xff09; 方法作用说明getFullYear()获取年份获取…

搜索专项---DFS之连通性模型

文章目录 迷宫红与黑 一、迷宫OJ链接 本题思路:DFS直接搜即可。 #include <iostream> #include <cstring> #include <algorithm>constexpr int N110;int n; char g[N][N]; bool st[N][N]; int x1, y1, x2, y2;int dx[4] {-1, 0, 1, 0}, dy[4] {0, 1, 0, …

2024 高级前端面试题之 计算机通识(基础) 「精选篇」

该内容主要整理关于 计算机通识&#xff08;基础&#xff09; 的相关面试题&#xff0c;其他内容面试题请移步至 「最新最全的前端面试题集锦」 查看。 计算机基础精选篇 一、网络1.1 UDP1.2 TCP1.3 HTTP1.4 DNS 二、数据结构2.1 栈2.2 队列2.3 链表2.4 树2.5 堆 三、算法3.1 时…

使用 Nuxt 构建简单后端接口及数据库数据请求

写在前面 本文主要为大家介绍&#xff0c;如何使用 Nuxt 框架实现一个简单的后端接口&#xff0c;并且从数据库中请求数据返回给前端。 实现 创建 serverMiddleware 文件夹 首先我们新建一个名字为 serverMiddleware 文件夹用来存储接口相关信息 目录结构如下&#xff1a;…

汽车电子论文学习--电动汽车电机驱动系统动力学特性分析

关键重点&#xff1a; 1. 汽车的低速转矩存在最大限制&#xff0c;受附着力限制&#xff0c;因路面不同而变化。 2. 起步加速至规定转速的时间可以计算得到&#xff1a; 3. 电机额定功率的计算方式&#xff1a; 可以采取最高设计车速90%或120km/h匀速行驶的功率作为电机额定功…

如何区分期权,很简单WeTrade众汇教你两招

二元期权有许多变体&#xff0c;很多投资者难以区分外汇和二元期权&#xff0c;很简单WeTrade众汇教你两招1秒快速区分&#xff0c;我们可以根据这两个最重要的参数进行区分: 1)合同类型的范围 只有一种外汇合约。当然&#xff0c;你可以交易货币对、差价合约、商品或证券&am…