【Algorithms 4】算法(第4版)学习笔记 19 - 6.0.4 网络流算法

news2024/12/23 16:36:05

文章目录

    • 前言
    • 参考目录
    • 学习笔记
      • 1:介绍
      • 1.1:最小切分问题
      • 1.2:最大流问题
      • 1.3:小结
      • 2:Ford-Fulkerson 算法(FF 算法)
      • 2.1:介绍
      • 2.2:问题
      • 3:最大流量 - 最小切分定理 maxflow-mincut theorem
      • 3.1:流和切分之间的关系
      • 3.2:定理以及证明
      • 3.3:计算最大流中的最小切分
      • 4:运行时间分析
      • 4.1:FF 算法问题
      • 4.2:整数容量 FF 算法
      • 4.3:FF 算法最坏情况
      • 4.4:增广路径的选择
      • 5:Java 实现
      • 5.1:流网络表示
      • 5.2:流量网络中的边的 API
      • 5.3:Java实现:流量边
      • 5.4:流量网络的 API
      • 5.5:Java 实现:流量网络
      • 5.6:流量网络:邻接列表表示
      • 5.7:寻找最短增广路径(BFS)
      • 5.8:Java 实现:FF 算法
      • 6:应用

前言

本篇是在书本第 4 章学习基础上进行拓展,主要内容包括:问题介绍Ford-Fulkerson 算法最大流量 - 最小切分定理运行分析算法 Java 实现

参考目录

  • B站 普林斯顿大学《Algorithms》视频课
    (请自行搜索。主要以该视频课顺序来进行笔记整理,课程讲述的教授本人是该书原版作者之一 Robert Sedgewick。)
  • 微信读书《算法(第4版)》
    (本文主要内容来自《6.0.4 网络流算法》)
  • 官方网站
    (有书本配套的内容以及代码)

学习笔记

注1:下面引用内容如无注明出处,均是书中摘录。
注2:所有 demo 演示均为视频 PPT demo 截图。
注3:如果 PPT 截图中没有翻译,会在下面进行汉化翻译,因为内容比较多,本文不再一一说明。

1:介绍

1.1:最小切分问题

![L16-64MaxFlow_02]

定义:

![L16-64MaxFlow_05]

定义: st 切分(st-cut)是一个顶点集合的划分,将其分为两个不相交的子集 A 和 B,其中源节点 s 属于集合 A,目标顶点(汇节点) t 属于集合 B。

定义: 这个切分的容量(Capacity)是从集合 A 到集合 B 的所有边的容量之和。

最小 st 切分问题: 找到具有最小容量的切分。

1.2:最大流问题

![L16-64MaxFlow_08]

定义:

![L16-64MaxFlow_11]

定义: st 流(简称流)是一种对边的赋值方案,需满足以下条件:

  • 容量约束:每条边的流量必须在0到该边的容量之间,即 0 ≤ 边的流量 ≤ 边的容量。
  • 局部平衡:除了源点s和汇点t外,每个顶点的流入流量等于流出流量。

定义: 流的值是指在汇点 t 处的流入流量。

最大 st 流(最大流)问题: 找到具有最大值的流。

1.3:小结

![L16-64MaxFlow_14]

值得注意的事实: 这两个问题是双重的!

2:Ford-Fulkerson 算法(FF 算法)

2.1:介绍

摘自书本《6.0.4.4 Ford-Fulkerson算法》:

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

初始化:

![L16-64MaxFlow_16]

初始流量为零。

想法:通过增加的路径增大流量

![image-20240317134724648]

增广路径: 寻找一条从源点 s 到汇点 t 的无向路径,且该路径需要满足以下条件:

  • 沿路径上的正向边(即从当前顶点指向路径下一个顶点的边)仍有增加流量的空间(未达到其容量上限);
  • 沿路径上的逆向边(即与正向边方向相反的边,在流网络中通常表示反向流动)存在非零流量(即并非为空,可以减少流量)。

第 1 次增广路径:

![image-20240317134940967]

第 2 次增广路径:

![image-20240317135008241]

第 3 次增广路径:

![image-20240317135413162]

第 4 次增广路径:

![image-20240317135719996]

没有更多的增广路径:

![image-20240317135931025]

2.2:问题

![L16-64MaxFlow_22]

Ford-Fulkerson 算法:

![image-20240317140418140]

问题:

  • 如何计算最小切分?
  • 如何寻找增广路径?
  • 如果 FF 算法终止,它是否总是计算出了最大流?
  • FF 算法是否总会终止?如果是,会在多少次增广之后终止?

3:最大流量 - 最小切分定理 maxflow-mincut theorem

maxflow-mincut theorem 也被翻译成 最大流 - 最小割定理,本文采用书本的翻译。

3.1:流和切分之间的关系

![L16-64MaxFlow_26]

定义: 对于一个切分集 (A, B),其净流量是通过该割集中从集合 A 到集合 B 的所有边的流量之和减去从集合 B 到集合 A 的所有边的流量之和。

![L16-64MaxFlow_27]

流值引理: 设 f 为任意一个流,(A, B) 为任意一个切分集。则 (A, B) 之间的净流量等于流 f 的值。

直观理解: 这是基于流量守恒原则。

证明: 通过归纳法对集合 B 的大小进行论证。

  • 基础情况:当 B = {t} 时。
  • 归纳步骤:当将任何顶点从集合 A 移动至集合 B 时,由于局部平衡原理,上述结论依然成立。

推论: 源点 s 的流出流量等于汇点 t 的流入流量,两者都等于流的值。

对应书本命题 E:

![image-20240317142700938]

弱对偶性:

![L16-64MaxFlow_28]

弱对偶性: 设 f 为任意一个流,并设 (A, B) 为任意一个切分集。
那么,流 f 的值小于等于该切分集的容量。

证明: 流 f 的值 = 切分集 (A, B) 净流量 <= 切分集 (A, B) 总容量。
=:流值引理;<=:流量受容量限制)

3.2:定理以及证明

![image-20240317143815702]

对应书本命题 F:

![image-20240317144131259]

3.3:计算最大流中的最小切分

![L16-64MaxFlow_32]

计算由最大流 f 决定的最小切分 (A, B) 的方法:

  • 根据增广路径定理,针对当前最大流 f,不存在可以进一步增广的路径。
  • 计算集合 A:它是由所有通过一条不包含满容量正向边或空容量逆向边的无向路径与源点 s 相连的顶点组成的集合。

4:运行时间分析

4.1:FF 算法问题

![L16-64MaxFlow_34]

问题:

  • 如何计算最小切分? (Easy.)
  • 如何寻找增广路径? (BFS.)
  • 如果 FF 算法终止,它是否总是计算出了最大流? (Yes.)
  • FF 算法是否总会终止?如果是,会在多少次增广之后终止?
    (Yes,前提是边容量是整数 (或者仔细选择增强路径);需要巧妙分析)

4.2:整数容量 FF 算法

![L16-64MaxFlow_35]

关键特性: 边的容量为介于 1 和 U 之间的整数。

不变式: 在整个 FF 算法过程中,流的值均为整数值(每条边上的流量都是整数)。
证明(通过归纳法):

  • 找到的瓶颈容量为整数。
  • 对于每条边,其流量在增广过程中会按瓶颈容量整数单位增加或减少。

命题: 增广次数不超过最大流的值。
证明: 每次增广都会至少使流的值增加 1。

整数性定理(对于某些应用场景极为关键): 存在一个整数值的最大流。
证明: 由于 FF 算法最终会停止运行,并找到一个整数值的最大流。

对应书本推论:

![image-20240317150840710]

4.3:FF 算法最坏情况

![image-20240317151332473]

坏消息: 即使边的容量为整数,增广路径的数量也可能恰好等于所求最大流的值。

初始状态:

![image-20240317151511970]

第 1 次增广路径:

![image-20240317151624722]

第 2 次增广路径:

![image-20240317151648453]

第 3 次增广路径:

![image-20240317151744875]

第 4 次增广路径:

![image-20240317151754831]

……

第 199 次增广路径:

![image-20240317151822222]

第 200 次增广路径:

![image-20240317151841519]

结束。

![L16-64MaxFlow_44]

好消息: 这种情况很容易避免。[可以使用最短/最宽路径算法]

4.4:增广路径的选择

![L16-64MaxFlow_45]

在选择增广路径时要慎重考虑。

  • 某些选择会导致指数级时间复杂度的算法。
  • 明智的选择则会导向多项式时间复杂度的算法。

![L16-64MaxFlow_46]

选择增广路径算法:

  • 最短路径算法:边数量最小。
  • 最宽路径算法:最大瓶颈容量。

5:Java 实现

5.1:流网络表示

![L16-64MaxFlow_48]

流边数据类型: 为边 e = v → w 定义一个数据结构,其中包含流量属性 fe 和容量属性 ce

流网络数据类型: 必须能够处理边 e = v → w 两个方向的信息,即将 e 同时包含在顶点 v 和 w 的邻接表中。

剩余容量:

  • 正向边(从 v 到 w):剩余容量 = ce - fe
  • 反向边(从 w 到 v):剩余容量 = fe

增广流量:

  • 正向边(从 v 到 w):增加流量值 ∆。
  • 反向边(从 w 到 v):减少流量值 ∆。

![L16-64MaxFlow_49]

剩余网络: 这是一种流网络的有效视角。(包含了所有具有正剩余容量的边)

关键要点: 在原网络中的增广路径与剩余网络中的有向路径一一对应。

对应书本中的说明:

![image-20240317154439026]

5.2:流量网络中的边的 API

![image-20240317154551633]

5.3:Java实现:流量边

edu.princeton.cs.algs4.FlowEdge

![image-20240317155204793]

edu.princeton.cs.algs4.FlowEdge#residualCapacityTo

![image-20240317155319042]

edu.princeton.cs.algs4.FlowEdge#addResidualFlowTo

![image-20240317155335791]

5.4:流量网络的 API

![image-20240317155438184]

5.5:Java 实现:流量网络

edu.princeton.cs.algs4.FlowNetwork

![image-20240317155552347]

![image-20240317155640306]

5.6:流量网络:邻接列表表示

![image-20240317160412457]

5.7:寻找最短增广路径(BFS)

edu.princeton.cs.algs4.FordFulkerson#hasAugmentingPath

![image-20240317160831992]

5.8:Java 实现:FF 算法

edu.princeton.cs.algs4.FordFulkerson

![image-20240317161052673]

![image-20240317161118916]

6:应用

![L16-64MaxFlow_59]

最大流量/最小切分问题是广泛应用于多种问题解决模型的一种方法。

  • 数据挖掘
  • 露天采矿规划
  • 二分匹配
  • 网络可靠性分析
  • 棒球联赛淘汰赛制分析
  • 图像分割技术
  • 网络连通性研究
  • 分布式计算问题
  • 统计数据安全保护
  • 平等稳定婚姻匹配问题
  • 多摄像机场景重建
  • 国土安全传感器布局设计
  • ……

(完)

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

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

相关文章

QT----基于QT的人脸考勤系统

目录 1 编译opencv库1.1 下载源代码1.2 qt编译opencv1.3 执行Cmake一直卡着data: Download: face_landmark_model.dat 2 编译SeetaFace2代码2.1 遇到报错By not providing "FindOpenCV.cmake" in CMAKE_MODULE_PATH this project has2.2遇到报错Model missing 3 测试…

python爬虫-AES.CBS加密案例(mmz批量爬取)

下载mmz本页数据 批量下载请看主页&#xff01;&#xff01;&#xff01; 代码&#xff1a; import requests from Crypto.Cipher import AES import base64cookies {PHPSESSID: 48nu182kdlsmgfo2g7hl6eufsa,Hm_lvt_6cd598ca665714ffcd8aca3aafc5e0dc: 1710568549,SECKEY_A…

唯一约束

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 唯一约束 唯一约束的特点是在某一个列上的内容不允许出现重复。 例如&#xff0c;现在要收集用户的信息&#xff0c;假设包含编号&#xff08;mid&#xff09;、姓名&…

SpringBoot(文件上传功能,阿里云OSS存储,几种配置文件用法)【详解】

目录 一、新增员工 二、文件上传-技术点 1. 文件上传功能 1.客户端上传文件三要素 2 服务端接收文件 Controller接收文件示例 修改允许上传的文件大小 2. 本地存储文件 3. 阿里云OSS存储&#xff08;这里只写一种&#xff0c;可以用其它的&#xff09; 1.介绍 2.开通…

第 126 场 LeetCode 双周赛题解

A 求出加密整数的和 模拟 class Solution { public:int sumOfEncryptedInt(vector<int> &nums) {int res 0;for (auto x: nums) {string s to_string(x);char ch *max_element(s.begin(), s.end());for (auto &c: s)c ch;res stoi(s);}return res;} };B 执行…

QT网络编程之实现UDP广播发送和接收

推荐一个不错的人工智能学习网站&#xff0c;通俗易懂&#xff0c;内容全面&#xff0c;作为入门科普和学习提升都不错&#xff0c;分享一下给大家&#xff1a;前言https://www.captainbed.cn/ai 一.UDP通信 1.QT中实现UDP通信主要用到了以下类&#xff1a;QUdpSocket、QHost…

Type-C接口介绍

1、USB介绍 &#xff08;1&#xff09;标准USB A型连接器&#xff08;左&#xff09;及B型连接器&#xff08;右&#xff09; 引脚1 VCC&#xff08;5V&#xff09; 引脚2 Data- 引脚3 Data 引脚4 接地 &#xff08;2&#xff09;Micro USB 引脚定义及OTG (USB-HOST) …

如何使用GIT

如何使用GIT https://www.runoob.com/w3cnote/git-five-minutes-tutorial.html 欢迎使用Markdown编辑器 你好&#xff01; 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章&#xff0c;了解一下Markdown的基本语…

Vue | 使用 ECharts 绘制折线图

目录 一、安装和引入 ECharts 二、使用 ECharts 2.1 新增 div 盒子 2.2 编写画图函数 2.3 完整代码结构 三、各种小问题 3.1 函数调用问题 3.2 数据格式问题 3.3 坐标轴标签问题 3.4 间隔显示标签 参考博客&#xff1a;Vue —— ECharts实现折线图 本文是在上…

【Linux】Shell编程【一】

shell是一个用 C 语言编写的程序&#xff0c;它是用户使用 Linux 的桥梁。Shell 既是一种命令语言&#xff0c;又是一种程序设计语言。 Shell 是指一种应用程序&#xff0c;这个应用程序提供了一个界面&#xff0c;用户通过这个界面访问操作系统内核的服务。 Shell属于内置的…

JAVA学习9

目录 一.继承 1.继承的原理&#xff1a; 2.继承的细节&#xff1a; 3.继承的本质&#xff1a; 二.super的使用&#xff1a; 1.基本介绍&#xff1a; 2.注意事项与使用细节&#xff1a;&#xff08;1&#xff09;访问父类的属性super.属性名&#xff0c;但不能访问父类的p…

快速从0-1完成聊天室开发——环信ChatroomUIKit功能详解

聊天室是当下泛娱乐社交应用中最经典的玩法&#xff0c;通过调用环信的 IM SDK 接口&#xff0c;可以快速创建聊天室。如果想根据自己业务需求对聊天室应用的 UI界面、弹幕消息、礼物打赏系统等进行自定义设计&#xff0c;最高效的方式则是使用环信的 ChatroomUIKit 。 文档地址…

个税计算器(Python)

任务描述 目前我国个人所得税计算公式如下&#xff1a; 应纳个人所得税税额 (工资薪金所得 -五险一金 - 个税免征额)适用税率-速算扣除数 个税免征额为5000元/月&#xff0c;2018年10月1日起调整后&#xff0c;也就是2018年实行的7级超额累进个人所得税税率表如下&#xff1…

【组合回溯】Leetcode 131. 分割回文串

【组合回溯】Leetcode 131. 分割回文串 解法 切割组合回溯 ---------------&#x1f388;&#x1f388;131. 分割回文串 题目链接&#x1f388;&#x1f388;------------------- 解法 切割组合回溯 全局变量&#xff1a;result存储所有path的集合&#xff0c;path用来记录切…

新!PCA+DBO+K-means聚类,蜣螂优化算法DBO优化K-means,适合学习,也适合发paper。

PCADBOK-means聚类&#xff0c;蜣螂优化算法DBO优化K-means&#xff0c;适合学习&#xff0c;也适合发paper。 一、 蜣螂优化算法 摘要&#xff1a;受蜣螂滚球、跳舞、觅食、偷窃和繁殖等行为的启发&#xff0c;提出了一种新的基于种群的优化算法(Dung Beetle Optimizer, DBO…

拜占庭将军问题相关问题

1、拜占庭将军问题基本描述 问题 当我们讨论区块链共识时&#xff0c;为什么会讨论拜占庭将军问题&#xff1f; 区块链网络的本质是一个分布式系统&#xff0c;在存在恶意节点的情况下&#xff0c;希望 整个系统当中的善良节点能够对于重要的信息达成一致&#xff0c;这个机…

8.6 Springboot项目实战 Spring Cache注解方式使用Redis

文章目录 前言一、配置Spring Cache1. @EnableCaching2. 配置CacheManager3. application.properties配置二、使用注解缓存数据1. 使用**@Cacheable** 改造查询代码2. 使用**@CacheEvict** 改造更新代码前言 在上文中我们使用Redis缓存热点数据时,使用的是手写代码的方式,这…

每日学习笔记:C++ STL 的forward_list

定义 特点 操作函数 元素查找、移除或安插 forward_list::emplace_after arg...指的是元素构造函数的参数&#xff08;0~N个&#xff09; #include <iostream> #include <memory> #include <list> #include <forward_list> using namespace std;class…

【数据结构】深入理解AVL树:实现和应用

AVL树是一种自平衡的二叉搜索树&#xff0c;它能够保持良好的平衡性质&#xff0c;使得在最坏情况下的时间复杂度也能保持在对数级别。本文将深入介绍AVL树的原理、实现和应用&#xff0c;并通过示例代码演示其基本操作。 文章目录 什么是AVL树&#xff1f;AVL树的实现在AVL树…