数据结构与算法学习笔记15:最大流问题 / 二分图 / 有权无权二分图的匹配 / 匈牙利算法 / 银行家算法 / 稳定婚配
数据结构与算法学习笔记15:最大流问题 / 二分图 / 有权无权二分图的匹配 / 匈牙利算法 / 银行家算法 / 稳定婚配
- 引入小题:最短路径
- 最大流问题(maximum flow problem)
- 简单算法(可能会失败)
- 福特-富尔克森算法(Ford-Fulkerson)
- 时间复杂度
- Edmonds–Karp算法
- 时间复杂度
- Dinic Algorithm/又称Dinitz算法
- 层次图概念
- 过程分析
- 时间复杂度
- 二分图 / 二部图(Bipartite Graph)
- 二分图的判定
- 匹配概念
- 无权二部图中的最大匹配问题
- 有权二部图中的最大匹配问题
- 核心方法
- 匈牙利算法(找最小匹配)
- 稳定婚配
- Gale-Shapley 算法
- 银行家算法
- Bitmap算法
引入小题:最短路径
无权图中,如何找到图中点与点之间的最短路径?
- BFS 广度优先遍历
最大流问题(maximum flow problem)
(前提:有边 有权重)
最大流问题是一种组合最优化问题,指的是如何充分利用装置的能力,使得运输的流量最大以取得最好的效果。
简单算法(可能会失败)
1、构建残量图
2、找一条简单路径,找到路径上的瓶颈值(当前路径所允许流过的最大流量),更新残量图路径权值,并将瓶颈值所在边擦除,重复该操作,直到无简单路径。
- 但实际上,该算法并不一定能够求出最大流,上述图解我们可以看出最大流是2+3=5,但从其他简单路径s→v1→v4→t入手,求解得到的最大流为1+3=4,s→v1→v4→t(不能有更多的水从s流向t,称为阻塞流)。
- 最大流是阻塞流,但阻塞流不一定是最大流,上述的4就是该题的一种阻塞流。
福特-富尔克森算法(Ford-Fulkerson)
1、构建残量图
2、找一条简单路径,找到路径上的瓶颈值(当前路径所允许流过的最大流量),更新残量图路径权值,并将瓶颈值所在边擦除。
3、添加反向路径
时间复杂度
上例左图为原图,根据原图可容易看出最大流为走s→V1→t和s→V2→t的100+100=200,但在福特-富尔克森算法中,简单路径选择是随意的,如果选择了s→V1→V2→t,则会出现右边的残量图分析过程,后续步骤雷同,共需要200轮才能完成得到最终流量图。若fff表示轮,mmm表示边,则其最坏时间复杂度O(f∗m)O(f * m)O(f∗m),依赖于流量的时间复杂度,在流量大的时候很致命,这就是福特-富尔克森算法的弊端。
Edmonds–Karp算法
该算法与福特-富尔克森算法(Ford-Fulkerson)相同,只是定义了找到增广路径时的搜索顺序。找到的路径必须是具有可用容量的最短路径(这可以通过BFS广度优先搜索找到)。
时间复杂度
轮数为m*n,其中m为边数,n为顶点个数,其算法时间复杂度为O(m2∗n)O(m^2 * n)O(m2∗n),相较于前面福特-富尔克森算法最坏时间复杂度O(f∗m)O(f * m)O(f∗m)已有很大提升,但实际上,m边数比n顶点个数肯定要大,因此Dinic算法比Edmonds–Karp算法又好一些。
Dinic Algorithm/又称Dinitz算法
层次图概念
层次图,只有上一层到下一层的边,没有同层的边(同层会增加路径的长度),实际上是帮助求最短路径。
过程分析
1、残量图初始化
2、根据残量图绘制层次图,并根据简单算法寻找阻塞流
3、将阻塞流汇入残量图
4、根据新的残量图更新新的层次图,重复2-4步骤。
时间复杂度
共需要n-1轮,每轮消耗为m * n,即(n-1)(m * n)
因此其时间复杂度为O(m∗n2)O(m * n^2)O(m∗n2),远小于上个Edmonds–Karp算法的O(m2∗n)O(m^2 * n)O(m2∗n)
二分图 / 二部图(Bipartite Graph)
顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属于这两个互不相交的子集,两个子集内的顶点不相邻。即G=(u,v,e)G=(u,v,e)G=(u,v,e),其中u和v内部不可以有边。
二分图的判定
图上随便找一个点开始遍历,相邻的点为两个部分,全部遍历完看看是否有冲突。
步骤:1、任选一个点,颜色标记,入队;2、队首元素拿出,找到相关顶点,如未处理过则标记其他颜色,入队,如处理过则看颜色是否冲突,冲突则over。
如果是非连通图,那就结束后再选一个点进行标记,重复上述步骤,直到再也找不到未被标记的点为止。
实际就是BFS的操作~
匹配概念
匹配指的就是边的集合,但注意其限制,集合内的边顶点是不可以相同的。
如下图中男1女1,男2女3,男3女1(此时女1就相同重复),因此这一组就不是匹配。
最大匹配的概念就是所有匹配中边的数量最大。
无权二部图中的最大匹配问题
MCBM: 无权二部图中的最大匹配问题 Maximum-Cardinality Bipartite Matching (MCBM)
- 实际上该类题用最大流就可解决,前后分别加S和T,所有权值均赋值为1,使用前文算法最终即可得到匹配方案。但注意,最大流的方法只适用于无权图的最大匹配求解,有权图是不可用这个来求最大匹配的。
有权二部图中的最大匹配问题
核心方法
1、将权重符号取反
2、找最小匹配(实际上就是所求的最大匹配)
匈牙利算法(找最小匹配)
要求uv中顶点个数相同,如果不相同可以补全(把边的权值设置为无穷大),时间复杂度为O(n3)O(n^3)O(n3)
步骤分析:
1、根据关系图绘制邻接矩阵;
2、找到每行内的min,然后该行所有元素减去min值;
3、找到每列内的min,然后该列所有元素减去min值;
4、画线;
以最少线覆盖0;(只能画横线or竖线,不能斜!)
判断操作是否结束(若线的条数 = 顶点个数 则结束,否则继续);
没结束则找到未被线覆盖区域的min,然后未覆盖区域的所有元素减去min值;
线覆盖的交叉点位置加上min值,重复第4步操作……直到线的条数 = 顶点个数 结束。
5、最小匹配;
将所有0对应的边重新构建关系图画出
找到一行中只有一个0的点,以其为基础,将冲突的点进行删除,直到匹配关系成立(无重复顶点)。
6、权值累加计算。
稳定婚配
没有人可以找到比当前更好的配偶
Gale-Shapley 算法
时间复杂度为O(n2)O(n^2)O(n2)
流程分析:
所有人向第一顺位喜欢的人求婚
- 此时被求婚的人如果未婚,且仅有一人向其求婚,则牵手成功
- 此时被求婚的人如果未婚,且有多人向其求婚,则根据自己的排名进行顺位,选追求者中最喜欢的结婚
- 此时被求婚的人如果已婚,看追求者和现配偶间更喜欢谁,相应完成拒绝追求者或与配偶离婚的操作
银行家算法
一种最有代表性的避免死锁的算法
应用前提条件
1、固定数量的进程共享固定数量的资源;
2、每个进程要预先指定完成工作所需的最大资源数量;
3、每个进程不能申请比系统可用资源总数还多的资源;
4、每个进程等待资源的时间是有限的;
5、如果系统满足了进程对资源的最大需求,那么进程应该在有限时间内使用资源然后归还给系统。
算法分析
1、需要存储可分配的资源数量AAA
2、需要知道当前进程已得到的资源BBB
3、需要知道当前进程所需的最大资源数量CCC
4、需要知道进程还需要的资源DDD
5、需要知道每一次的需求EEE
当某一个进程提出资源申请时(E):
1、E≤DE≤DE≤D,否则直接报错
2、E≤AE≤AE≤A,否则需要等待
3、满足2的条件(系统给了),更新系统各个部分的资源:A=A−E;B=B+E;D=D−EA=A-E;B=B+E;D=D-EA=A−E;B=B+E;D=D−E
检测系统安全性:① 看标记(是否被检查过);② 如果没被检查,则检查,看是否满足D<FD<FD<F,满足的话则进行分配,更新FFF,然后进行标记(已检查),如果不满足,那么需要把状态恢复(把前面步骤中:A=A−EA=A-EA=A−E;B=B+EB=B+EB=B+E;D=D−ED=D-ED=D−E全部恢复成更新前的样子,然后进行下一次重新分配)。(FFF为目前可用资源数量,其实和上述的AAA差不多,但AAA和FFF也有一些区别,FFF是检查的时候用的,各个进程都需要进行安全性检查,给一号进程检查完检查二号的时候,FFF就不是一号的FFF了,是被更新过减去一号分配后的…以此类推。)
Bitmap算法
Bitmap算法是用bit数组来记录0-1两种状态,然后再将具体数据映射到这个比特数组的具体位置,这个比特位设置成0表示数据不存在,设置成1表示数据存在。Bitmap算法和布隆过滤器主要解决大数据去重的问题。用于对大量整型数据做去重和查询。
学习链接:数据结构与算法必知— Bitmap位图与布隆过滤器 - 简书 (jianshu.com)
数据结构与算法学习笔记15:最大流问题 / 二分图 / 有权无权二分图的匹配 / 匈牙利算法 / 银行家算法 / 稳定婚配相关推荐
- Bellman-Ford算法学习笔记【最短路径(负权边)】
通过对于Djkstra的学习,大致了解了最短路径问题,但是Djsktra算法由于其操作过程上的不足,不能处理带有负权边的情况,这个算法,Bellman-Ford[这些名字应该怎么记..]则可以处理带有 ...
- 数据结构与算法 学习笔记(5):字符串
数据结构与算法 学习笔记(5)- 字符串 本次笔记记录了LeetCode中关于字符串的一些问题,并给出了相应的思路说明和代码.题目编号与LeetCode对应,方便查找. 题目1:LeetCode 13 ...
- 数据结构与算法 学习笔记(8):字典、集合、哈希表
数据结构与算法 学习笔记(8):字典.集合.哈希表 本次文章记录的是和字典.集合.哈希表等数据结构相关的LeetCode算法题(题号与LeetCode对应),包括其构造和使用,针对每一题或一类题给出了 ...
- 数据结构与算法学习笔记之 从0编号的数组
数据结构与算法学习笔记之 从0编号的数组 前言 数组看似简单,但掌握精髓的却没有多少:他既是编程语言中的数据类型,又是最基础的数据结构: 一个小问题: 为什么数据要从0开始编号,而不是 从1开始呢? ...
- 数据结构与算法学习笔记之 提高读取性能的链表(上)
数据结构与算法学习笔记之 提高读取性能的链表(上) 前言 链表(Linked list)比数组稍微复杂一点,在我们生活中用到最常见的应该是缓存,它是一种提高数据读取性能的技术,常见的如cpu缓存,浏览 ...
- 网络流算法学习笔记——最大流问题基本概念和Ford-Fulkerson方法(标号法C++实现)
屈婉玲<算法设计与分析>第2版第7章网络流算法学习笔记. 基本概念 最大流问题,相当于有从s到t的供水系统,每段路径都有限定流量,除了s.t两地外,每个中间点都不能滞留,从s流入多少,就从 ...
- 数据结构与算法学习笔记——链栈
数据结构与算法学习笔记(C语言) 链栈 在开始链栈的学习之前,我们先实现一下上一篇文章中提到的检查括号匹配的小程序,鉴于水平有限,本人就随便写一下代码好了,目标仅限于对功能的实现. /*用顺序栈这种数 ...
- 数据结构与算法学习笔记4:递归+分治法
数据结构与算法学习笔记4 递归 斐波那契数列 青蛙跳台阶问题 链表倒序打印 分治法 二分查找/折半查找 Binary Search 题目1:快速幂 题目2:如何判断一个数是否为2的次幂 递归 指在函数 ...
- 数据结构与算法学习笔记——图 C++实现
数据结构与算法学习笔记--图 C++实现 1 概念 2 图的表示方法 3 算法 3.1 拓扑排序 3.2 图的搜索算法 3.2.1 广度优先搜索(BFS) 3.2.2 深度优先搜索(DFS) 3.3 ...
最新文章
- golang 读写文件的四种方式
- 重磅 | 神策智能运营 2.0 发布!解锁小程序“拉、留、转”新招式
- 强化学习4——无模型控制model-free control (On-Policy learning:Sarsa和Off-policy learning:Q-learning)
- CodeSmith 5.0工具实例篇系列4——根据表生成修改的存储过程,针对MS Sqlserver
- python大列表分割成小列表_Python有什么方法将列表分割成大小均匀的块?求使用实例...
- Anaconda配置多spyder多python环境
- java数据库配置_java--数据库(文件配置连接,自定义连接池)
- matlab瓶盖盖严检查,盖检机|瓶盖检测|外观检测设备|誉阵科技
- wdatepicker时间段控制
- Java获取姓名的首字母_java获取中文拼音首字母的实例
- 模拟电子技术,电力电子技术
- 关于PC套件显示红外连接出现问题而导致连接不上的解决方案(zz)
- 传说中的世界500强面试题-智力急转弯
- 桌面图标出现蓝色问号
- layer的btn按钮
- php imp,Imp_在线英语听力室
- 网园网络电视 v1.2 官方
- [附源码]Java计算机毕业设计SSM电脑配件仓储后台管理系统
- Rest-assured + testNG1
- matlab object是什么意思,求大神指导一下代码大概是什么意思。。
热门文章
- linux 吃豆人游戏,C++ 使用 openGL 实现吃豆人游戏
- 《Bag of Tricks for Node Classification with Graph Neural Networks》阅读笔记
- springboot初学解决Result Maps collection does not contain value for ...问题
- c语言gga字符串校验和代码,一种新的Java智能卡上字节码校验算法.pdf
- UGUI组件之快速消息提示(飘字)
- 一站式地图服务平台“地图易”——平台架构解析
- python 爬取链家数据_用python爬取链家网的二手房信息
- 模型压缩之剪枝小综述
- 常见的数据库电子图书 [共9本]
- 面试官:MySQL事务的隔离性是如何实现的?