二分图最大匹配算法的应用及Matlab实现+++
匈牙利算法解决二分图最大匹配
匈⽛利算法解决⼆分图最⼤匹配预备知识 匈⽛利算法是由匈⽛利数学家Edmonds于1965年提出,因⽽得名。
匈⽛利算法是基于Hall定理中充分性证明的思想,它是⼆分图匹配最常见的算法,该算法的核⼼就是寻找增⼴路径,它是⼀种⽤增⼴路径求⼆分图最⼤匹配的算法。
⼆分图 ⼆分图⼜称作⼆部图,是图论中的⼀种特殊模型。
设G=(V,E)是⼀个⽆向图,如果顶点V可分割为两个互不相交的⼦集(A,B),并且图中的每条边(i,j)所关联的两个顶点 i 和 j 分别属于这两个不同的顶点集(i in A,j in B),则称图G为⼀个⼆分图。
匹配 在图论中,⼀个图是⼀个匹配(或称独⽴边集)是指这个图之中,任意两条边都没有公共的顶点。
这时每个顶点都⾄多连出⼀条边,⽽每⼀条边都将⼀对顶点相匹配。
例如,图3、图4中红⾊的边就是图2的匹配。
图3中1、4、5、7为匹配点,其他顶点为⾮匹配点,1-5、4-7为匹配边,其他边为⾮匹配边。
最⼤匹配 ⼀个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最⼤匹配。
图 4 是⼀个最⼤匹配,它包含 4 条匹配边。
任意图中,极⼤匹配的边数不少于最⼤匹配的边数的⼀半。
完美匹配 如果⼀个图的某个匹配中,所有的顶点都是匹配点,那么它就是⼀个完美匹配。
显然,完美匹配⼀定是最⼤匹配,但并⾮每个图都存在完美匹配。
最⼤匹配数:最⼤匹配的匹配边的数⽬。
最⼩点覆盖数:选取最少的点,使任意⼀条边⾄少有⼀个端点被选择。
最⼤独⽴数:选取最多的点,使任意所选两点均不相连。
最⼩路径覆盖数:对于⼀个DAG(有向⽆环图),选取最少条路径,使得每个顶点属于且仅属于⼀条路径,路径长可以为0(即单个点)定理1:Konig定理——最⼤匹配数 = 最⼩点覆盖数定理2:最⼤匹配数 = 最⼤独⽴数定理3:最⼩路径覆盖数 = 顶点数 - 最⼤匹配数匈⽛利算法例⼦ 为了便于理解,选取了dalao博客⾥找妹⼦的例⼦: 通过数代⼈的努⼒,你终于赶上了剩男剩⼥的⼤潮,假设你是⼀位光荣的新世纪媒⼈,在你的⼿上有N个剩男,M个剩⼥,每个⼈都可能对多名异性有好感(惊讶,-_-||暂时不考虑特殊的性取向) 如果⼀对男⼥互有好感,那么你就可以把这⼀对撮合在⼀起,现在让我们⽆视掉所有的单相思(好忧伤的感觉,快哭了),你拥有的⼤概就是下⾯这样⼀张关系图,每⼀条连线都表⽰互有好感。
二分图的最大匹配、完美匹配和匈牙利算法
二分图的最大匹配、完美匹配和匈牙利算法August 1, 2013 / 算法这篇文章讲无权二分图(unweighted bipartite graph)的最大匹配(maximum matching)和完美匹配(perfect matching),以及用于求解匹配的匈牙利算法(Hungarian Algorithm);不讲带权二分图的最佳匹配。
二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是一个二分图。
准确地说:把一个图的顶点划分为两个不相交集U和V,使得每一条边都分别连接U、V中的顶点。
如果存在这样的划分,则此图为一个二分图。
二分图的一个等价定义是:不含有「含奇数条边的环」的图。
图 1 是一个二分图。
为了清晰,我们以后都把它画成图 2 的形式。
匹配:在图论中,一个「匹配」(matching)是一个边的集合,其中任意两条边都没有公共顶点。
例如,图3、图 4 中红色的边就是图 2 的匹配。
我们定义匹配点、匹配边、未匹配点、非匹配边,它们的含义非常显然。
例如图 3 中 1、4、5、7 为匹配点,其他顶点为未匹配点;1-5、4-7为匹配边,其他边为非匹配边。
最大匹配:一个图所有匹配中,所含匹配边数最多的匹配,称为这个图的最大匹配。
图 4 是一个最大匹配,它包含 4 条匹配边。
完美匹配:如果一个图的某个匹配中,所有的顶点都是匹配点,那么它就是一个完美匹配。
图 4 是一个完美匹配。
显然,完美匹配一定是最大匹配(完美匹配的任何一个点都已经匹配,添加一条新的匹配边一定会与已有的匹配边冲突)。
但并非每个图都存在完美匹配。
举例来说:如下图所示,如果在某一对男孩和女孩之间存在相连的边,就意味着他们彼此喜欢。
是否可能让所有男孩和女孩两两配对,使得每对儿都互相喜欢呢?图论中,这就是完美匹配问题。
如果换一个说法:最多有多少互相喜欢的男孩/女孩可以配对儿?这就是最大匹配问题。
基本概念讲完了。
matlab otsu算法
matlab otsu算法什么是Otsu算法?Otsu算法,也被称为最大类间方差法,是一种常用于图像处理和计算机视觉中的图像二值化方法。
该算法是由日本学者大津秀一在1979年提出的。
Otsu算法的主要目标是将图像转化为黑白二值图像,以便进行后续的图像分割和特征提取等操作。
其基本原理是在图像中寻找一个最佳的阈值,将图像的像素点分成两个互补的类别,使得两个类别之间的方差最大化。
如何实现Otsu算法?步骤1:计算灰度直方图首先,我们需要计算图像的灰度直方图。
灰度直方图是一种统计图,用于显示图像中各个灰度级别的像素点的分布情况。
在MATLAB中,我们可以使用imhist函数来计算灰度直方图。
步骤2:计算类间方差接下来,我们需要计算图像的类间方差。
类间方差是指图像中不同类别(即黑色和白色)之间的方差。
在Otsu算法中,我们要找到一个最佳的阈值,使得将图像分为两个类别时,类间方差最大化。
计算类间方差的公式为:\[\sigma^2_w(t) = \omega_1(t)\omega_2(t)[\mu_1(t)-\mu_2(t)]^2\]其中,\(\sigma^2_w(t)\)表示在阈值t处的类间方差,\(\omega_1(t)\)和\(\omega_2(t)\)表示在阈值t处两个类别的像素点比例,\(\mu_1(t)\)和\(\mu_2(t)\)表示在阈值t处两个类别的平均灰度值。
步骤3:寻找最佳阈值在这一步中,我们通过遍历不同的阈值,找到一个使类间方差最大化的阈值。
具体的实现方法如下:1. 根据步骤2中的类间方差公式,计算每个阈值下的类间方差值。
2. 找到类间方差最大的阈值,这个阈值即为最佳阈值。
步骤4:二值化图像最后,我们使用最佳阈值来将图像进行二值化处理。
二值化即将图像中的像素点分为只有黑色和白色两种颜色的情况。
根据最佳阈值,大于阈值的像素点被赋值为白色,小于等于阈值的像素点被赋值为黑色。
在MATLAB中,可以使用下列代码执行Otsu算法:matlab读取图像img = imread('image.jpg');将图像转化为灰度图像gray_img = rgb2gray(img);计算灰度直方图histogram = imhist(gray_img);计算类间方差class_variances = zeros(256, 1);for t = 1:256计算每个阈值下的类间方差omega1 = sum(histogram(1:t)) / numel(gray_img);omega2 = sum(histogram(t+1:end)) / numel(gray_img);mu1 = sum((0:t-1)' .* histogram(1:t)) / sum(histogram(1:t));mu2 = sum((t:255)' .* histogram(t+1:end)) /sum(histogram(t+1:end));class_variances(t) = omega1 * omega2 * (mu1 - mu2)^2;end找到最佳阈值[~, threshold] = max(class_variances);二值化图像binary_img = gray_img > threshold;显示二值化图像imshow(binary_img);总结:Otsu算法是一种常用的图像二值化方法,它能够通过寻找最佳的阈值,将图像转化为黑白二值图像。
静止背景下的多目标追踪(附matlab程序)
静止背景下的多目标追踪随着计算机技术以及智能汽车行业的发展,多目标的检测与追踪的实用性与研究价值逐渐提高。
在计算机视觉的三层结构中,目标跟踪属于中间层,是其他高层任务,例如动作识别以及行为分析等的基础。
其主要应用可包括视频监控,检测异常行为人机交互,对复杂场景中目标交互的识别与处理,以及虚拟现实及医学图像。
目标跟踪又包括单目标跟踪和多目标跟踪。
单目标跟踪可以通过目标的表观建模或者运动建模,以处理光照、形变、遮挡等问题,而多目标跟踪问题则更加复杂,除了单目标跟踪回遇到的问题外,还需要目标间的关联匹配。
另外在多目标跟踪任务中经常会碰到 目标的频繁遮挡、轨迹开始终止时刻未知、目标太小、表观相似、目标间交互、低帧率等等问题。
静止背景下的多目标追踪可分为两步来实现,第一步是在视频文件的每帧中检测出移动的目标,第二步是将检测到的目标与跟踪轨迹实时匹配。
在本次实验中,利用混合高斯模型进行背景减除,使用形态学操作消除噪声,通过卡尔曼滤波预测目标位置,最后利用匈牙利算法进行匹配,实现静止背景下的多目标追踪。
1 实验原理1.1 混合高斯模型单高斯模型是利用高维高斯分布概率来进行模式分类:11()exp[(x )(x )]2T x N C μσμ-=--- 其中μ用训练样本均值代替,σ用样本方差代替,X 为d 维的样本向量。
通过高斯概率公式就可以得出类别C 属于正(负)样本的概率。
而混合高斯模型就是数据从多个高斯分布中产生,每个GMM 由k 个单高斯分布线性叠加而成。
相当于对各个高斯分布进行加权,权系数越大,那么这个数据属于这个高斯分布的可能性越大。
(x)(k)*p(x |k)P p =∑利用混合高斯模型(GMM)可以进行背景减除,将前后景分离,得到移动的目标。
对每个像素点建立由k 个单高斯模型线性叠加而成的模型,在这些混合高斯背景模型中,认为像素之间的颜色信息互不相关,对各像素点的处理都是相互独立的。
单个像素点在t 时刻服从混合高斯分布概率密度函数:,,,1(x )(x ,,)kt i t t i t i t i p w ημτ==∑其中k 为分布模式总数,,,(x ,,)t i t i t ημτ为t 时刻第i 个高斯分布,,i t μ为其均值,,i t τ为其协方差矩阵。
二分图匹配及其应用-PPT精品
例题4. Unstable Systems(SGU218)
• 求一个完备匹配,使得匹配边中权值最大 的边权值最小。
分析
• 算法一
– 二分选择flow,并且进行最大匹配
• 算法二
– 从权值最低的边开始,每次增加一条边。维护 交错树森林,最多只可能增加一个交错轨。
– 因为找到N条交错轨即可,而维护交错树森林 的平摊复杂度为O(1),所以总时间复杂度依然 为O(N3)
– 时间复杂度 O ( n m )
• 基于DFS的算法: 每次选一个未盖点u进行DFS. 如果找不到 增广路则换一个未盖点, 且以后再也不从u出发找增广路.
Hopcroft算法
• 可以证明:如果每次找到的最短增广路集是极大 的,则只需要增广O ( n ) 次
• 关键:用O(m)时间找一个极大最短增广路集 • 步骤1:用距离标号扩展匈牙利树,找到第一个
• 实际上不需要单独建立二分图,直接在图 上操作即可。 点和边都是O(N2)个, 因此时 间复杂度为O(N3)
例题3. Speleology(POI9906)
• 一个山上有一个很大的洞,其中有n个室, 编号为1~n,室与室之间有通道。编号越大 的室在越下方。有一批洞穴学者要从编号 为1的室走到编号为n的室中,途中他们只 能从编号小的地方走到编号大的地方。每 条和1或n相连的通道只允许一个人通过。 问:最多可以有多少名洞穴学者?
分析
• 可以用二分图的最佳匹配 • 因为这个图有特殊性,男孩子一边任一个
点连出的所有边的权值都是相同的,所以 只要将男孩子按照国王的喜欢程度从大到 小排序,先对国王更喜欢的孩子扩展增广 路径,就可以得到最优解。这是为什么呢?
分析
• 由增广路的性质可以知道一条增广路的应 用只可能在匹配的男孩子中加入一个人, 而不可能删去任意一个人。
二分图的最大匹配—匈牙利算法
⼆分图的最⼤匹配—匈⽛利算法【基本概念】:⼆分图:⼆分图⼆分图⼜称作⼆部图,是图论中的⼀种特殊模型。
设G=(V,E)是⼀个⽆向图,如果顶点V可分割为两个互不相交的⼦集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为⼀个⼆分图。
⽆向图G为⼆分图的充分必要条件是,G⾄少有两个顶点,且其所有回路的长度均为偶数。
最⼤匹配最⼤匹配:给定⼀个⼆分图G,在G的⼀个⼦图M中,M的边集中的任意两条边都不依附于同⼀个顶点,则称M是⼀个匹配. 选择这样的边数最⼤的⼦集称为图的最⼤匹配问题,如果⼀个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配.最⼩覆盖:最⼩覆盖要求⽤最少的点(X集合或Y集合的都⾏)让每条边都⾄少和其中⼀个点关联。
可以证明:最少的点(即覆盖数)=最⼤匹配数最⼩路径覆盖:⽤尽量少的不相交简单路径覆盖有向⽆环图G的所有结点。
解决此类问题可以建⽴⼀个⼆分图模型。
把所有顶点i拆成两个:X结点集中的i 和Y结点集中的i',如果有边i->j,则在⼆分图中引⼊边i->j',设⼆分图最⼤匹配为m,则结果就是n-m。
增⼴路(增⼴轨):(增⼴轨):增⼴路若P是图G中⼀条连通两个未匹配顶点的路径,并且属于M的边和不属于M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的⼀条增⼴路径(举例来说,有A、B集合,增⼴路由A中⼀个点通向B中⼀个点,再由B中这个点通向A中⼀个点……交替进⾏)。
增⼴路径的性质:1 有奇数条边。
2 起点在⼆分图的左半边,终点在右半边。
3 路径上的点⼀定是⼀个在左半边,⼀个在右半边,交替出现。
(其实⼆分图的性质就决定了这⼀点,因为⼆分图同⼀边的点之间没有边相连,不要忘记哦。
)4 整条路径上没有重复的点。
5 起点和终点都是⽬前还没有配对的点,⽽其它所有点都是已经配好对的。
用匈牙利算法求二分图的最大匹配
用匈牙利算法求二分图的最大匹配二分图的最大匹配有两种求法,第一种是最大流;第二种就是匈牙利算法。
这个算法说白了就是最大流的算法,但是它跟据二分图匹配这个问题的特点,把最大流算法做了简化,提高了效率。
最大流算法的核心问题就是找增广路径(augment path)。
匈牙利算法也不例外,它的基本模式就是:初始时最大匹配M为空while 找得到增广路径do 把增广路径加入到最大匹配中去可见和最大流算法是一样的。
但是这里的增广路径就有它一定的特殊性,下面我来分析一下。
(注:匈牙利算法虽然根本上是最大流算法,但是它不需要建网络模型,所以图中不再需要源点和汇点,仅仅是一个二分图。
每条边也不需要有方向。
)图1是我给出的二分图中的一个匹配:[1,5]和[2,6]。
图2就是在这个匹配的基础上找到的一条增广路径:3->6->2->5->1->4。
我们借由它来描述一下二分图中的增广路径的性质:(1)有奇数条边。
(2)起点在二分图的左半边,终点在右半边。
(3)路径上的点一定是一个在左半边,一个在右半边,交替出现。
(其实二分图的性质就决定了这一点,因为二分图同一边的点之间没有边相连。
)(4)整条路径上没有重复的点。
(5)起点和终点都是目前还没有配对的点,而其它所有点都是已经配好对的。
(如图1、图2所示,[1,5]和[2,6]在图1中是两对已经配好对的点;而起点3和终点4目前还没有与其它点配对。
)(6)路径上的所有第奇数条边都不在原匹配中,所有第偶数条边都出现在原匹配中。
(如图1、图2所示,原有的匹配是[1,5]和[2,6],这两条配匹的边在图2给出的增广路径中分边是第2和第4条边。
而增广路径的第1、3、5条边都没有出现在图1给出的匹配中。
)(7)最重要的一条,把增广路径上的所有第奇数条边加入到原匹配中去,并把增广路径中的所有第偶数条边从原匹配中删除(这个操作称为增广路径的取反),则新的匹配数就比原匹配数增加了1个。
二分图最大匹配及常用建图方法
算法———艺术二分图匹配剖析很多人说,算法是一种艺术。
但是对于初学者的我,对算法认识不是很深刻,但偶尔也能感受到他强大的魅力与活力。
这让我追求算法的脚步不能停止。
下面我通过分析匈牙利算法以及常用建图方式,与大家一起欣赏算法的美。
匈牙利算法匈牙利算法是用来解决最大二分图匹配问题的,所谓二分图即“一组点集可以分为两部分,且每部分内各点互不相连,两部分的点之间可以有边”。
所谓最大二分图匹配即”对于二分图的所有边,寻找一个子集,这个子集满足两个条件,1:任意两条边都不依赖于同一个点。
2:让这个子集里的边在满足条件一的情况下尽量多。
首先可以想到的是,我们可以通过搜索,找出所有的这样的满足上面条件的边集,然后从所有的边集中选出边数最多的那个集合,但是我们可以感觉到这个算法的时间复杂度是边数的指数级函数,因此我们有必要寻找更加高效的方法。
目前比较有效的方法有匈牙利算法和通过添加汇点和源点的网络流算法,对于点的个数都在200 到300 之间的数据,我们是采取匈牙利算法的,因为匈牙利算法实现起来要比网络流简单些。
下面具体说说匈牙利算法:介绍匈牙利之前,先说说“增广轨”。
定义:若P是图G中一条连通两个未匹配顶点的路径,并且属最大匹配边集M的边和不属M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广轨定义总是抽象的下面通过图来理解它。
图中的线段(2->3, 3->1, 1->4)便是上面所说的p路径,我们假定边(1,3)是以匹配的边,(2,3)(1,4)是未匹配的边,则边(4,1)边(1,3)和边(3,2)在路径p上交替的出现啦,那么p就是相对于M的一条增广轨,这样我们就可以用边1,4 和边2,3来替换边1,3 那么以匹配的边集数量就可以加1,。
匈牙利算法就是同过不断的寻找增广轨实现的。
很明显如果二分图的两部分点分别为n 和m,那么最大匹配的数目应该小于等于MIN(n,m); 因此我们可以枚举任第一部分(的二部分也可以)里的每一个点,我们从每个点出发寻找增广轨,最后吧第一部分的点找完以后,就找到了最大匹配的数目,当然我们也可以通过记录找出这些边。
基于MATLAB的图像分割算法研究
摘要本文从原理和应用效果上对经典的图像分割方法如边缘检测、阈值分割技术和区域增长等进行了分析。
对梯度算法中的Roberts算子、Sobel算子、Prewitt算子、拉普拉斯(Laplacian)算子、LoG(Laplacian-Gauss)算子、坎尼(Canny)算子的分割步骤、分割方式、分割准则相互比较可以看出根据坎尼(Canny)边缘算子的3个准则得出的边缘检测结果最满意。
而阈值分割技术的关键在于阈值的确定,只有阈值确定好了才能有效的划分物体与背景,但这种方法只对于那些灰度分布明显,背景与物体差别大的图像的分割效果才明显。
区域增长的基本思想是将具有相似性质的像素集合起来构成新区域。
与此同时本文还分析了图像分割技术研究的方向。
关键词:图像处理图像分割AbstractThis article analyses the application effect to the classics image segmentation method like the edge examination, territory value division technology, and the region growth and so on.For comparing the Roberts operator, Sobel operator, Prewitt operator, the operator of Laplacian and the operator of LoG(Laplacian-Gauss),Canny operator in gradient algorithm,the step, the way and the standard of the image segmentation,we can find out the three standard of Canny edge operator the edge detection result of reaching most satisfy. And the key point of threshold segmentation lie in fixing the threshold value, it is good to have only threshold value to determine it then can be effective to divide object and background,but this kind of method is good to those gray scales,the big difference image effect between the background and obiect. The basic idea of area is to form the new region from similar nature.And also, this paper analyses the research direction of image segmentation technology at the same time.Key words: image processing image segmentation operator目录(一般目录要求最多是三级目录,不要出现四级目录)第一章绪论 (1)1.1数字图像处理的基本特点 (1)1.1.1数字图像处理的信息大多是二维信息,处理信息量很大(三级标题有问题)1 1.1.2数字图像处理占用的频带较宽 (2)1.1.3数字图像中各个像素是不独立的,其相关性大 (2)1.1.4作合适的假定或附加新的测量 (2)1.1.5数字图像处理后的图像受人的因素影响较大 (2)1.2数字图像处理的优点 (2)1.2.1再现性好 (2)1.2.2处理精度高 (3)1.2.3适用面宽 (3)1.2.4灵活性高 (3)1.3数字图像处理的应用 (4)1.3.1航天和航空技术方面的应用 (4)1.3.2生物医学工程方面的应用 (5)1.3.3通信工程方面的应用 (5)1.3.4工业和工程方面的应用 (5)1.3.5军事公安方面的应用 (5)1.3.6文化艺术方面的应用 (6)1.4数字图像分割技术的发展概况 (6)1.4.1 基于分形的图像分割技术 (6)1.4.2 基于神经网络的图像分割技术 (7)1.5本文的主要流程图 (8)第二章数字图像处理的处理方式 (9)2.1图像变换 (9)2.2图像编码压缩 (9)2.3图像增强和复原 (9)2.4图像分割 (9)2.5图像描述 (10)2.6图像分类(识别) (10)第三章 MATLAB平台及其开发环境 (11)3.1.MATLAB的组成 (11)3.1.1MATLAB主要有以下几个部分 (11)a.数值计算功能 (12)b.符号计算功能 (12)c.数据分析功能 (12)d.动态仿真功能 (12)e.程序借口功能 (13)f.文字处理功能 (13)3.2MATLAB的特点 (13)3.2.1功能强大,可扩展性强 (13)3.2.2界面友好,编程效率高 (14)3.2.3图像功能,灵活且方便 (14)3.3MATLAB在图像处理中的应用 (14)第四章图像分割概念及算法研究 (16)4.1图像分割的基本概念 (16)4.1.1图像分割定义 (16)4.2边缘检测方法(4.1和4.2之间不是并行关系) (17)4.2.1边缘检测概述 (17)4.2.2边缘检测梯度算法 (19)a.梯度边缘检测算法基本步骤及流程图 (19)b.Robert算子 (20)c.Sobel算子 (21)d.Prewitt算子 (21)4.2.3拉普拉斯(Laplacian)算子 (22)4.2.4LoG(Laplacian-Gauss)算子 (24)4.2.5坎尼(Canny)算子 (25)4.3灰度阈值分割 (27)4.3.1阈值分割介绍 (28)a.阈值化分割原则 (28)b.阈值分割算法分类 (29)4.3.2全局阈值 (30)a.极小值点阈值 (31)b.最优阈值 (31)c.迭代阈值分割 (33)4.3.3动态阈值 (34)a.阈值插值 (35)b.水线阈值算法 (35)4.4区域分割 (37)4.4.1区域生长的基本原理、步骤及流程图 (37)4.4.2生长准则和过程 (40)a.灰度差准则 (40)b.灰度分布统计准则 (41)c.区域形状准则 (42)4.4.3分裂合并 (43)第五章总结 (45)5.1对于图像边缘检测的分析 (45)5.2对于图像阈值分割的分析 (45)5.3对于图像区域分割的分析 (46)5.4改进意见(改进可另外做为一章比如说某某算法等的若干改进等,不要放入总结一章中)(总结是对整篇文章的一个概述,应该是写比如得出些什么结论,一些算法间比较等相关问题。
二分法及其matlab程序-经典
避免数值不稳定性
对于涉及大量计算或迭代的过程,要注意数值稳定性问题, 采取适当的算法或技巧,如使用稳定的算法、增加迭代次 数等。
利用MATLAB内置函数
二分法及其matlab程序-经典
目录
• 二分法基本原理 • MATLAB编程实现二分法 • 二分法在数值计算中应用举例 • MATLAB程序优化与改进策略 • 总结与展望
01
二分法基本原理
二分法定义与思想
定义
二分法是一种求解非线性方程近似根的有效算法,其基本思想是通过不断将区间一分为二,逐步缩小求解范围, 直到满足精度要求为止。
end
root = (a + b) / 2;
VS
关键代码片段展示
end
```
运行结果分析与讨论
• 假设我们要求解非线性方程f(x)=x^3-2x-5=0在 区间[2, 3]内的根,可以调用上述bisection函数进 行求解
运行结果分析与讨论
```matlab f = @(x) x^3 - 2*x - 5;
精度控制
当区间长度|b - a|小于给定 精度时,可取中点或任一端 点作为近似最优解。
求解矩阵特征值问题
• 特征多项式构建:对于n阶矩阵A,构建特征多项式f(λ) = |A - λI|。 • 初始区间选择:确定包含特征值的初始区间[a, b]。 • 二分迭代:取中点c = (a + b) / 2,计算f(c)。若f(c) == 0,则c为特征值;否则根据f(a)、f(b)、f(c)的大小关
缺点
二分法收敛速度较慢,需要多次迭代才能得 到精确解,且对于多峰函数或者复杂函数可 能无法找到全局最优解。
二分图最大匹配及其应用
例 1. T HE P ERFECT S TALL
本题就是要求从图中选出尽可能多的边, 满足每个顶点至多是其中一条边的端点。 设G=(V, E)是一个图,M是E的一个子集。 如果M中的任何两条边都没有共同的端点, 则称M为G的一个匹配。G中边数最多的 匹配称为G的最大匹配。 要求一般图的最大匹配是比较困难的,但 是求二分图的匹配就容易得多。本题就是 求二分图最大匹配的问题。
y2
X2
y2
X2
y2
X3
y3
X3
y3
X3
y3
X4
y4
X4
y4
X4
y4
X5
y5
X5
y5
X5
y5
匈牙利算法
function find(i): boolean for j ← 1 to m if g[i][j] and (not c[j]) c[j] ← true if (l[j] = 0) or find(l[j]) l[j] ← i return true end if end if end for return false end function
例 3. 最小路径覆盖
题目来源:经典问题 给出一个含N个顶点的有向无环图G。用 尽量少的不相交路径覆盖G的所有顶点, 即每个顶点严格属于一条路径。允许路径 的长度为0,即只含一个顶点。
例 3. 最小路径覆盖
因为含n条边的路径共覆盖了n+1个顶点, 所以对于任何一个路径覆盖,有一个显然 的关系:路径数+路径覆盖中的边数=N。
匈牙利算法
形象化地说,就是从二分图中找出一条路 径,使得路径的起点和终点都是没有被匹 配的点,而且路径经过的边是一条没被匹 配,一条已经匹配过,再下一条又没匹配 这样交替地出现。找到这样的路径后,显 然路径里没被匹配的边比已经匹配了的边 多一条,于是修改匹配图,把路径里所有 匹配过的边去掉,把没有匹配的边变成匹 配的,这样一来匹配数就比原来多了1。 不断执行上述操作,直到找不到这样的路 径为止。
匹配算法MATLAB
求二部图G 的最大匹配的算法(匈牙利算法), 其基本思想是:从G 的任意匹配M 开始,对X 中所有M 的非饱和点, 寻找M -增广路. 若不存在M -增广路, 则M 为最大匹配; 若存在M -增广路P, 则将P 中M 与非M 的边互换得到比M 多一边的匹配M1 , 再对M1 重复上述过程.设G = ( X, Y, E )为二部图, 其中X = {x1, x2, ⋯, xn }, Y = { y1, y2, ⋯, yn}. 任取G 的一初始匹配M (如任取e∈E, 则M = {e}是一个匹配).①令S = f , T = f , 转向②.②若M 饱和X \ S 的所有点, 则M 是二部图G 的最大匹配. 否则, 任取M 的非饱和点u∈X \ S , 令S = S ∪{ u }, 转向③.③记N (S ) = {v | u∈S, uv∈E }. 若N (S ) = T, 转向②. 否则取y∈N (S ) \ T. 若y 是M的饱和点, 转向④, 否则转向⑤.④设x y∈M, 则令S = S ∪{ x }, T = T ∪{ y }, 转向③.⑤u - y 路是M-增广路, 设为P, 并令M = M⊕P, 转向①. 这里M⊕P = M∪P\ M∩P, 是对称差.由于计算M-增广路P 比较麻烦, 因此将迭代步骤改为:①将X 中M 的所有非饱和点(不是M 中某条边的端点)都给以标号0 和标记*, 转向②.②若X 中所有有标号的点都已去掉了标记*, 则M 是G 的最大匹配. 否则任取X 中一个既有标号又有标记*的点xi , 去掉xi 的标记*, 转向③.③找出在G 中所有与xi 邻接的点yj (即xi yj∈E ), 若所有这样的yj 都已有标号, 则转向②, 否则转向④.④对与xi 邻接且尚未给标号的yj 都给定标号i. 若所有的yj 都是M的饱和点, 则转向⑤,否则逆向返回. 即由其中M的任一个非饱和点yj的标号i 找到xi, 再由xi的标号k找到yk , ⋯,最后由yt 的标号s 找到标号为0 的xs 时结束, 获得M -增广路xs yt ⋯xi yj, 记P = {xs yt, ⋯,xi yj }, 重新记M 为M⊕P, 转向①.⑤将yj在M 中与之邻接的点xk (即xk yj∈M), 给以标号j 和标记*, 转向②.例1 求图6-9 中所示的二部图G 的最大匹配.匈牙利算法的MATLAB 程序代码如下:m=5;n=5;A=[0 1 1 0 01 1 0 1 10 1 1 0 00 1 1 0 00 0 0 1 1];M(m,n)=0;for(i=1:m)for(j=1:n)if(A(i,j))M(i,j)=1;break;end;end %求初始匹配Mif(M(i,j))break;end;end %获得仅含一条边的初始匹配Mwhile(1)for(i=1:m)x(i)=0;end %将记录X中点的标号和标记*for(i=1:n)y(i)=0;end %将记录Y中点的标号和标记*for(i=1:m)pd=1; %寻找X中M的所有非饱和点for(j=1:n)if(M(i,j))pd=0;end;endif(pd)x(i)=-n-1;end;end %将X中M的所有非饱和点都给以标号0 和标记*, 程序中用n+1 表示0 标号, 标号为负数时表示标记*pd=0;while(1)xi=0;for(i=1:m)if(x(i)<0)xi=i;break;end;end %假如X 中存在一个既有标号又有标记*的点, 则任取X中一个既有标号又有标记*的点xiif(xi==0)pd=1;break;end %假如X中所有有标号的点都已去掉了标记*, 算法终止x(xi)=x(xi)*(-1); %去掉xi 的标记*k=1;for(j=1:n)if(A(xi,j)&y(j)==0)y(j)=xi;yy(k)=j;k=k+1;end;end %对与xi 邻接且尚未给标号的yj 都给以标号iif(k>1)k=k-1;for(j=1:k)pdd=1;for(i=1:m)if(M(i,yy(j)))x(i)=-yy(j);pdd=0;break;end;end %将yj 在M中与之邻接的点xk (即xkyj∈M), 给以标号j 和标记*if(pdd)break;end;endif(pdd)k=1;j=yy(j); %yj 不是M的饱和点while(1)P(k,2)=j;P(k,1)=y(j);j=abs(x(y(j))); %任取M的一个非饱和点yj, 逆向返回if (j==n+1)break ;end %找到X 中标号为0 的点时结束, 获得M-增广路P k=k+1;endfor (i=1:k)if (M(P(i,1),P(i,2)))M(P(i,1),P(i,2))=0; %将匹配M 在增广路P 中出现的边去掉else M(P(i,1),P(i,2))=1;end ;end %将增广路P 中没有在匹配M 中出现的边加入 到匹配M 中break ;end ;end ;endif (pd)break ;end ;end %假如X 中所有有标号的点都已去掉了标记*, 算法终止 M %显示最大匹配M, 程序结束图 6-9利用可行点标记求最佳匹配的算法步骤如下:设 G = ( X , Y , E , F )为完备的二部赋权图, L 是其一个初始可行点标记, 通常取 (){}()max |,()0,L L x F xy y Y x X M G L y y Y ⎧=∈∈⎪⎨=∈⎪⎩是的一个匹配 ① 若X 的每个点都是M 的饱和点, 则M 是最佳匹配. 否则取 M 的非饱和点u ∈X , 令S= {u }, T = f , 转向②.② 记NL (S ) = {v | u ∈S , uv ∈EL }. 若NL ( S ) = T , 则GL 没有完美匹配, 转向③. 否则转向④.③ 调整可行点标记, 计算aL = min { L ( x ) + L ( y ) - F (x y ) | x ∈S , y ∈Y \T }.由此得新的可行顶点标记(),,(),,(),L L L a S L v a v T L v νν-∈⎧⎪+∈⎨⎪⎩否则令 L = H , GL = GH , 重新给出GL 的一个匹配M , 转向①.④ 取 y ∈NL ( S ) \T , 若y 是M 的饱和点, 转向⑤. 否则, 转向⑥.⑤ 设 x y ∈M , 则令S = S ∪{ x }, T =T ∪{ y }, 转向②.⑥ 在 GL 中的u - y 路是M -增广路, 记为P , 并令M = M ⊕P , 转向①. 利用可行点标记求最佳匹配算法的 MATLAB 程序代码如下:n=4;A=[4 5 5 12 2 4 64 2 3 35 0 2 1];for (i=1:n)L(i,1)=0;L(i,2)=0;endfor (i=1:n)for (j=1:n)if (L(i,1)<A(i,j))L(i,1)=A(i,j);end ; %初始可行点标记L M(i,j)=0;end ;endfor (i=1:n)for (j=1:n) %生成子图Glif (L(i,1)+L(j,2)==A(i,j))Gl(i,j)=1;else Gl(i,j)=0;end;end;endii=0;jj=0;for(i=1:n)for(j=1:n)if(Gl(i,j))ii=i;jj=j;break;end;endif(ii)break;end;end %获得仅含Gl 的一条边的初始匹配MM(ii,jj)=1;for(i=1:n)S(i)=0;T(i)=0;NlS(i)=0;endwhile(1)for(i=1:n)k=1;否则.for(j=1:n)if(M(i,j))k=0;break;end;endif(k)break;end;endif(k==0)break;end %获得最佳匹配M, 算法终止S(1)=i;jss=1;jst=0; %S={xi}, T=while(1)jsn=0;for(i=1:jss)for(j=1:n)if(Gl(S(i),j))jsn=jsn+1;NlS(jsn)=j; %NL(S)={v|u∈S,uv∈EL} for(k=1:jsn-1)if(NlS(k)==j)jsn=jsn-1;end;end;end;end;endif(jsn==jst)pd=1; %判断NL(S)=T?for(j=1:jsn)if(NlS(j)~=T(j))pd=0;break;end;end;endif(jsn==jst&pd)al=Inf;%如果NL(S)=T, 计算al, Inf 为∞for(i=1:jss)for(j=1:n)pd=1;for(k=1:jst)if(T(k)==j)pd=0;break;end;endif(pd&al>L(S(i),1)+L(j,2)-A(S(i),j))al=L(S(i),1)+L(j,2)-A(S(i),j);end;end;endfor(i=1:jss)L(S(i),1)=L(S(i),1)-al;end %调整可行点标记for(j=1:jst)L(T(j),2)=L(T(j),2)+al;end %调整可行点标记for(i=1:n)for(j=1:n) %生成子图GLif(L(i,1)+L(j,2)==A(i,j))Gl(i,j)=1;else Gl(i,j)=0;endM(i,j)=0;k=0;end;endii=0;jj=0;for(i=1:n)for(j=1:n)if(Gl(i,j))ii=i;jj=j;break;end;endif(ii)break;end;end %获得仅含Gl 的一条边的初始匹配MM(ii,jj)=1;breakelse %NL(S)≠Tfor(j=1:jsn)pd=1; %取y∈NL(S)\Tfor(k=1:jst)if(T(k)==NlS(j))pd=0;break;end;endif(pd)jj=j;break;end;endpd=0; %判断y 是否为M的饱和点for(i=1:n)if(M(i,NlS(jj)))pd=1;ii=i;break;end;endif(pd)jss=jss+1;S(jss)=ii;jst=jst+1;T(jst)=NlS(jj); %S=S∪{x}, T=T∪{y}else %获得Gl 的一条M-增广路, 调整匹配Mfor(k=1:jst)M(S(k),T(k))=1;M(S(k+1),T(k))=0;endif(jst==0)k=0;endM(S(k+1),NlS(jj))=1;break;end;end;end;endMaxZjpp=0;for(i=1:n)for(j=1:n)if(M(i,j))MaxZjpp=MaxZjpp+A(i,j);end;end;end M %显示最佳匹配MMaxZjpp %显示最佳匹配M的权, 程序结束。
基于matlab的图像识别与匹配
基于matlab的图像识别与匹配基于matlab的图像识别与匹配摘要图像的识别与匹配是⽴体视觉的⼀个重要分⽀,该项技术被⼴泛应⽤在航空测绘,星球探测机器⼈导航以及三维重建等领域。
本⽂意在熟练运⽤图像的识别与匹配的⽅法,为此本⽂使⽤⼀个包装袋并对上⾯的数字进⾏识别与匹配。
⾸先在包装袋上提取出来要⽤的数字,然后提取出该数字与包装袋上的特征点,⽤SIFT⽅法对两幅图进⾏识别与匹配,最终得到对应匹配数字的匹配点。
仿真结果表明,该⽅法能够把给定数字与包装袋上的相同数字进⾏识别与匹配,得到了良好的实验结果,基本完成了识别与匹配的任务。
1 研究容图像识别中的模式识别是⼀种从⼤量信息和数据出发,利⽤计算机和数学推理的⽅法对形状、模式、曲线、数字、字符格式和图形⾃动完成识别、评价的过程。
图形辨别是图像识别技术的⼀个重要分⽀,图形辨别指通过对图形的图像采⽤特定算法,从⽽辨别图形或者数字,通过特征点检测,精确定位特征点,通过将模板与图形或数字匹配,根据匹配结果进⾏辨别。
2 研究意义数字图像处理在各个领域都有着⾮常重要的应⽤,随着数字时代的到来,视频领域的数字化也必将到来,视频图像处理技术也将会发⽣⽇新⽉异的变化。
在多媒体技术的各个领域中,视频处理技术占有⾮常重要的地位,被⼴泛的使⽤于农业,智能交通,汽车电⼦,⽹络多媒体通信,实时监控系统等诸多⽅⾯。
因此,现今对技术领域的研究已⽇趋活跃和繁荣。
⽽图像识别也同样有着更重要的作⽤。
3 设计原理3.1 算法选择Harris ⾓点检测器对于图像尺度变化⾮常敏感,这在很⼤程度上限制了它的应⽤围。
对于仅存在平移、旋转以及很⼩尺度变换的图像,基于 Harris 特征点的⽅法都可以得到准确的配准结果,但是对于存在⼤尺度变换的图像,这⼀类⽅法将⽆法保证正确的配准和拼接。
后来,研究⼈员相继提出了具有尺度不变性的特征点检测⽅法,具有仿射不变性的特征点检测⽅法,局部不变性的特征检测⽅法等⼤量的基于不变量技术的特征检测⽅法。
二分图的最优匹配(km算法)
1. 如果 x∈ S 则 Lx(x)= Lx(x)- d。 2. 如果 x∈ T 则 Ly(x)= Ly(x)+ d。 3. 其它情况保持不变。 如此修改后,我们发现对于边<x,y>,顶标 Lx(x)+ Ly(y) 的值为 1. Lx(x)- d+ Ly(y)+ d, x∈ S, y∈ T。 2. Lx(x)+ Ly(y), x∉ S, y∉ T。 3. Lx(x)- d+ Ly(y), x∈ S, y∉ T。 4. Lx(x)+ Ly(y)+ d, x∉ S, y∈ T。 易知,修改后对于任何边仍满足 Lx(x)+ Ly(y)>= W(x,y),并且第三种情况顶标值减少了 d,如此定会 部顶点 1 求增广路径, 得到一个匹配, 如图( 红色代表匹配边 ):
对 X 部顶点 2 求增广路径失败,寻找增广路径的过程为 X 2-> Y 3-> X 1。我们把寻找增广 路径失败的 DFS 的交错树中,在 X 部顶点集称之为 S, 在 Y 部的顶点集称之为 T。则 S= { 1, 2 },T= { 3 }。现 在我们就通过修改顶标值来扩大等价子图,如何修改。 1) 我们寻找一个 d 值,使得 d= min{ (x,y)| Lx(x)+ Ly(y)- W(x,y), x∈ S, y∉ T },因些,这时 d= min{
KM 算法总结
分类: ACM_图论 2010-08-22 09:411090人阅读评论(0)收藏举报
【二分图】二分图是一种特殊的图结构,所有点分为两类,记做 x 和 y,所有的边的两端分别在 x 和 y,不存在两端同 在 x 或 y 的边。 【最大匹配、完备匹配】 给定一个二分图(x,y),找到一种匹配数最大的方案,记做最大匹配。|x|=|y|=匹配数时,我们称该匹配方案为完备匹配。 显然,解决了最大匹配也就解决了完备匹配。 解决二分图的最大匹配可以用网络流或者匈牙利算法,两者本质上是相同的,不过不论从编程复杂度还是运行效率来 讲,匈牙利算法都更加优秀。 关于匈牙利算法,可以参见我以前写的文章:用匈牙利算法求二分图的最大匹配 这里我主要叙述另一类问题: 【最优完备匹配】 对于二分图的每条边都有一个权(非负) ,要求一种完备匹配方案,使得所有匹配边的权和最大,记做最优完备匹配。 (特殊的,当所有边的权为1时,就是最大完备匹配问题) KM 算法: (全称是 Kuhn-Munkras,是这两个人在1957年提出的,有趣的是,匈牙利算法是在1965年提出的) 为每个点设立一个顶标 Li,先不要去管它的意义。 设 vi,j为(i,j)边的权,如果可以求得一个完备匹配,使得每条匹配边 vi,j=Li+Lj,其余边 vi,j≤Li+Lj。 此时的解就是最优的,因为匹配边的权和=∑Li,其余任意解的权和都不可能比这个大 定理:二分图中所有 vi,j=Li+Lj 的边构成一个子图 G,用匈牙利算法求 G 中的最大匹配,如果该匹配是完备匹配,则是 最优完备匹配。 (不知道怎么证明) 问题是,现在连 Li 的意义还不清楚。 其实,我们现在要求的就是 L 的值,使得在该 L 值下达到最优完备匹配。
二分图匹配匈牙利算法和KM算法简介
❖
end else
匈牙利算法
❖ begin
❖ j := queue[st];
❖
while true do
❖
begin
❖
t := match1[j];
❖
match1[j] := i;
❖
match2[i] := j;
❖
if t = 0 then break;
❖
i := t; j := father[t];
1 2
3 4
例题1 Place the Robots(ZOJ)
小结
比较前面的两个模型:模型一过于简单,没有给问 题的求解带来任何便利;模型二则充分抓住了问题的内 在联系,巧妙地建立了二部图模型。为什么会产生这种 截然不同的结果呢?其一是由于对问题分析的角度不同: 模型一以空地为点,模型二以空地为边;其二是由于对 原型中要素的选取有差异:模型一对要素的选取不充分, 模型二则保留了原型中“棋盘”这个重要的性质。由此 可见,对要素的选取,是图论建模中至关重要的一步。
例题3 打猎
❖ 猎人要在n*n的格子里打鸟,他可以在某一行 中打一枪,这样此行中的所有鸟都被打掉, 也可以在某一列中打,这样此列中的所有鸟 都打掉。问至少打几枪,才能打光所有的鸟?
❖ 建图:二分图的X部为每一行,Y部为每一列, 如果(i,j)有一只鸟,那么连接X部的i与Y部的j。
❖ 该二分图的最大匹配数则是最少要打的枪数。
匈牙利算法
❖ for i:=1 to n do
❖ if (father[i]=0)and(a[queue[st],i]=1) then
❖ begin
❖ if match2[i]<>0 then
❖
数字图像处理与应用(MATLAB版)第6章 图像的分割
是边缘;
➢ 使用双阈值算法检测和连接边缘。即使用直方图计
算两个阈值,凡是大于高阈值的一定是边缘;凡是
小于低阈值的一定不是边缘。如果检测结果大于低
阈值但又小于高阈值,那就要看这个像素的邻接像
素中有没有超过高阈值的边缘像素,如果有,则该
像素就是边缘,否则就不是边缘。
0 -1 0 -1 4 -1 0 -1 0
B A
6.1 图像分割的定义和分类
图像分割:是指根据灰度、彩色、纹理等特征把图像 划分成若干个互不相交的区域,使得这些特征在同一区 域内,表现出一致性或相似性,而在不同区域间表现出 明显的不同。
图像分割的作用
图像分割是图像识别和图像理解的前提,图像分 割质量的好坏直接影响后续图像处理的效果。
图像
具体步骤:
➢ 首先用2D高斯滤波模板进行卷积以平滑图像;
➢ 利 用 微 分 算 子 ( 如 Roberts 算 子 、 Prewitt 算 子 和
Sobel算子等),计算梯度的幅值和方向;
➢ 对梯度幅值进行非极大值抑制。即遍历图像,若某
个像素的灰度值与其梯度方向上前后两个像素的灰
,
度值相比不是最大,那么这个像素值置为0,即不
第六章 图像的分割
内 容 1、图像分割的定义和分类; 提 2、基于边缘的图像分割方法;
要 3、基于区域的分割;
4、基于运动的图像分割 ; 5、图像分割技术的发展。
基
本 要
通过对图像分割技术的学习,掌
求 握基于边缘、区域、运动的图像
重
分割技术。
点
难 点
图像分割的定义、分类 基于边缘的图像分割方法
基于区域、运动的图像分割方法
G(i, j) Px Py
二分图匹配算法(最大流匈牙利)
⼆分图匹配算法(最⼤流匈⽛利)⼆分图匹配相关概念⽆向⼆分图G(U⋃V,E):U是⼀个顶点集合,V是另⼀个顶点集合,对于⼀个集合内的点⽆边直接相连,⽽对于不同集合的点可以连边,即(u,v)∈E。
匹配:两两不含公共端点的边的集合M称为匹配(就是两个集合之间连的边,只不过不同边的端点不能重合)最⼤匹配:元素最多的M,即⽽G中两两不含公共端点的边的集合M⊆E的基数|M|的最⼤值就是最⼤匹配。
完美匹配:当最⼤匹配的匹配数满⾜2∗|M|=V时,称为完美匹配。
形象的解释就是⼀各集合的所有点到另⼀个集合都有互不相同且唯⼀对应的点。
(类似于函数的双射),想象⼀下图增⼴路:设M为⼆分图G已匹配边的集合,若P是图G中⼀条连通两个未匹配顶点的路径(P的起点在X部,终点在Y部,反之亦可),并且属M的边和不属M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的⼀条增⼴路径。
(就是连了两个还没有配对的顶点的路径,路径有⼀个配对边,⼀个⾮配对边交替组成)更多详细概念解释见匈⽛利部分的参考⽂章最⼤流的⽅法⼆分图的匹配可以看成是⼀种最⼤流问题(这谁想得出来啊)。
具体过程如下:现在有两个点集U和V,之间已经有了写连边,我们需要引⼊⼀个源,⼀个汇,把源跟集合U的所有点有向地连起来,把V的所有点和汇有向地连起来,就构成了⼀个流⽹络。
现在由于⼆分图匹配的限制,⼀个点不能连⾃⼰内部的点(在原来的⼆分图中这关系已经成⽴),不能连两个或多个边。
那么就把每个边的权值赋为⼀。
这样边的流量只有零壹两种,要么有边,要么不连边。
在上⾯跑最⼤流算法即可(具体讲解参见上篇博客)下⾯是代码:代码:#include <iostream>#include <memory.h>#include <vector>#include <queue>#define max_n 10005#define INF 0x3f3f3f3fusing namespace std;//邻接表struct edge{int v;//到达顶点int cap;//最⼤流量int rev;//对应反向边的编号};vector<edge> G[max_n];int level[max_n];//Dinic算法⽤到的层次图int iter[max_n];//当前弧优化void add_edge(int u,int v,int cap){G[u].push_back((edge){v,cap,G[v].size()});//最后⼀个表⽰uv这条边的反向边在G[v]⾥的标号G[v].push_back((edge){u,0,G[u].size()-1});}void bfs(int s)//处理层次图{memset(level,-1,sizeof(level));queue<int> que;level[s] = 0;que.push(s);while(!que.empty()){int v = que.front();que.pop();for(int i = 0;i<G[v].size();i++){edge& e = G[v][i];if(e.cap>0&&level[e.v]<0){level[e.v] = level[v]+1;que.push(v);}}}}int dfs(int v,int t,int f)//Dinic的dfs{if(v==t) return f;for(int& i = iter[v];i<G[v].size();i++){edge& e = G[v][i];if(e.cap>0&&level[e.v]==level[v]+1){int d = dfs(v,t,min(f,e.cap));if(d>0){G[e.v][e.rev].cap+=d;return d;}}}return 0;}int max_flow(int s,int t)//Dinic算法{int flow = 0;for(;;){bfs(s);if(level[t]<0){return flow;}memset(iter,0,sizeof(iter));int f;while(f=dfs(s,t,INF)>0){flow += f;}}}int N,K;//N,K为两个集合的点数bool can[max_n][max_n];//⼆分图中原有的边void solve(){//0~N-1是U中的点//N~N+K-1是V中的点int s = N+K;int t = s+1;for(int i = 0;i<N;i++)//s与U连边{add_edge(s,i,1);}for(int i = 0;i<K;i++)//t与V连边{add_edge(i+N,t,1);}for(int i = 0;i<N;i++){for(int j = 0;j<K;j++){if(can[i][j]){add_edge(i,j,1);//⼆分图原有边的链接}}}cout << max_flow(s,t) << endl;//求最⼤流即得最⼤匹配}int main(){cin >> N >> K;solve();return 0;}匈⽛利算法这个算法是专门处理⼆分图的最⼤匹配问题的,有很好的博客讲解,下⾯是推荐阅读⽅式:我上⾯的概念可能不太全,那就先来看看⼆分图的相关概念:可能还对增⼴路径不是很理解,什么是增⼴路,⾮配对配对交替什么的很混乱,那不妨先看看这个:现在到了算法流程了,在正式介绍前,先有个有趣⽽深刻的认识,下⾯是⼗分清晰的讲解:好了,该正式⼀点了,相信你也有了⼀定的了解:上⾯的代码其实已经够清晰了,如果还想看⼀下,就这篇吧:代码:#include <iostream>#include <memory.h>#define max_n 200005using namespace std;int n,m;int con_y[max_n];int visit[max_n];int head[max_n];struct edge{int v;int nxt;}e[max_n<<1];int cnt = 0;void add(int u,int v){++cnt;e[cnt].v = v;e[cnt].nxt = head[u];head[u] = cnt;}int dfs(int u){for(int i = head[u];i;i=e[i].nxt){int v = e[i].v;if(visit[v]==0){if(con_y[v]==-1||dfs(v))//结合上⾯算法流程部分的有趣博客再理解了⼀下这⾥的递归,好奇妙 {con_x[u] = v;con_y[v] = u;return 1;}}}return 0;}int Hungary(){memset(con_x,-1,sizeof(con_x));memset(con_y,-1,sizeof(con_y));int ans = 0;for(int i = 1;i<=n;i++){memset(visit,0,sizeof(visit));ans += dfs(i);}return ans;}int main(){cin >> n >> m;for(int i = 1;i<=m;i++){int a,b,c;cin >> a >> b;add(a,b);}cout << Hungary() << endl;return 0;}参考⽂章以上Processing math: 100%。
二分图及匹配算法
Chapter 3
二分图最佳匹配
-二分图最佳匹配-
定义:图G中权值和最大的完全匹配。
Kuhn-Munkras算法:该算法是通过给每个顶点一个标号(叫做顶标) 来把求最大权匹配的问题转化为求完备匹配的问题的。设顶点Xi的顶标 为A[ i ],顶点Yj的顶标为B[ j ],顶点Xi与Yj之间的边权为w[i,j]。在算法 执行过程中的任一时刻,对于任一条边(i,j),A[ i ]+B[j]>=w[i,j]始终成立。 KM算法的正确性基于以下定理: 若由二分图中所有满足A[ i ]+B[j]=w[i,j]的边(i,j)构成的子图(称做相等 子图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配。 KM算法流程: (1)初始化可行顶标的值; (2)用匈牙利算法寻找完备匹配; 这样做是O(n^4)的
-稳定婚姻问题-
Байду номын сангаас
求婚拒绝算法(Gale-Shapley算法/延迟认可算法): 先对所有男生进行单身标记,称其为单身狗男。当存在单身狗男时,进行 以下操作:
①选择一位单身狗男在所有尚未拒绝她的女生中选择一位被他排名最优先 的女神;
②女神将正在追求她的单身狗男与其现任进行比较,选择其中排名优先的 男生作为其男友,即若单身狗男优于现任,则现任被抛弃为前任;否则保 留其男友,拒绝单身狗男。 ③若某男生被其女友抛弃,则重新变成单身狗男,至①重复。
Chapter 5
稳定婚姻问题
-稳定婚姻问题-
你们班上有n位男生和n位女生,每个人对异性都有一个排序,表示对他们 的爱恋程度。现在你的任务是使他们凑成CP,使他们的爱情坚不可摧! 满足一下条件的爱情不是坚不可摧的: 男生u和女生v不是CP,但他们爱恋对方的程度都大于爱恋现任 的程度。 因为这样男生u和女生v会抛下已经是CP的那个她/他,另外组成一对。于 是乎多出了两位前任,这样就会让人再也无法相信爱情了! 怎么能避免悲剧的发生呢?
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一共有RecuCal.m LockMap.m BuildMatrix.m Edmonds.m GUI1.m 这几个文件,我把它们合到一块粘上去了,你再把他们分开保存就可以了.其中前三个文件都是为建立邻接矩阵服务的,Edmonds.m是匈牙利算法的主文件,GUI1.m只是调用Edmonds.m做个界面而已。
调用关系是GUI1.m调用Edmonds.m;Edmonds.m调用BuildMatrix.m和LockMap.m ;LockMap.m调用RecuCal.m最后运行GUI1.m就ok了#LockMap.mfunction [LMA, LMB] = LockMap(n, m)% LOCKMAP - 求解满足条件锁并设置相应的映射% 输入参数:n 表槽数,m 表高度数。
% 输出参数:LMA,LMB 分别为二维矩阵表示自然数到满足条件锁之间的映射。
global jiA ouB ary A B mm NN = n; mm = m;jiA=0; ouB=0;A=[]; B=[];ary = zeros(1, n);RecuCal(n);LMA=A; LMB=B;[lena, n] = size(LMA);[lenb, n] =size(LMB);if lena>lenbtemp = LMA; LMA=LMB;LMB=temp;temp = lena;lena=lenb;lenb=temp;end#RecuCal.mfunction RecuCal(n)% RECUCAL - 递归函数global jiA ouB ary A B mm Nif n ==1for k=1:mm% 调用递归函数时要用到的变量所以% 设为全局ary(1) = k;Max = max(ary); Min = min(ary);num = 0; neighbor = 0;for i=1:Nnum = num + (Max-ary(i))*(ary(i)-Min);if (i~=N)neighbor = max(neighbor, abs(ary(i)-ary(i+1)));endendif (neighbor > mm-1.5)&&(num > 0.5)if mod(sum(ary), 2)% 奇数,属于 A 类jiA = jiA+1;A(jiA,:) = ary;else% 偶数,属于 B 类ouB = ouB+1;B(ouB,:) = ary;endendendelsefor k=1:mmary(n) = k;RecuCal(n-1);endend#BuildMatrix.mfunction AB = BuildMatrix(LMA, LMB)% BUILDMATRIX - 建立邻接矩阵,若 i 与 j 之间可以互开则 AB(i,j)=1,否则为0。
AB = [];[lena, n] = size(LMA);[lenb, n] =size(LMB);for i = 1:lenafor j=1:lenbtmp = 0;for k=1:ntmp = tmp + abs(LMA(i,k)-LMB(j,k));endif tmp == 1AB(i, j)=1;endendend#Edmonds.mfunction str = Edmonds(n, m)% EDMONDS - Edmonds 算法寻找完美匹配str = [];[LMA, LMB] = LockMap(n, m);AB = BuildMatrix(LMA, LMB);lena = length(LMA);lenb = length(LMB);if lena==0disp('其中一个分组为空,无法匹配'); %当 n=m=3 时只有偶数组无奇数组,不能完成匹配return;endMatA = zeros(1, lena);MatB = zeros(1, lenb);X = MatA; Y=MatB; Z=Y;NumNoMat = 0;% 无法匹配的点的个数% 最初匹配,只有一个匹配j = find(AB(1,:), 1);MatA(1)=j; MatB(j)=1;while length(find(MatA==0)) ~= 0% 存在不匹配的元素J = find(MatA==0); i = J(1);% 第 i 个元素未被匹配init = i; X(i)=0;J = find(AB(i,:));% J 为所有与 i 相邻结点Y(J) = i; j=J(1);while ~isempty(find(Y~=Z))if MatB(j) ~= 0% j 是匹配点Z(j) = Y(j);i = MatB(j);X(i)=j;J = find(AB(i,:));Y(J)=i;J = find(Y);JJ = find(Z);J = setxor(intersect(J, JJ), J);j=J(1);else% j 不是匹配点i = Y(j);MatA(i) = j;MatB(j) = i;while X(i)j = X(i);i = Z(j);MatA(i) = j;MatB(j) = i;endbreak;endend% 如果 Y==Z 则表明该点没有与之相应的匹配,即不存在完美匹配,在 MatA 中标 % 记为-1。
if isempty(find(Y~=Z, 1))NumNoMat = NumNoMat + 1;MatA(init) = -1;endX(1:lena)=0; Y(1:lenb)=0; Z=Y;endtotal = 0;for i=1:lenak = MatA(i);if k<=0continue; end% k<=0时表明匹配不存在stra = ''; strb = '';for j=1:nstra = [stra, num2str(LMA(i, j)), ''];strb = [strb, num2str(LMB(k, j)), ''];endstr = [str, stra, '------ ', strb, 10];total = total + 1;endstr = [str, '匹配个数有:', num2str(total)];#GUI1.mfunction varargout = GUI1(varargin)gui_Singleton = 1;gui_State = struct('gui_Name',mfilename, ...'gui_Singleton', gui_Singleton, ...'gui_OpeningFcn', @GUI1_OpeningFcn, ...'gui_OutputFcn', @GUI1_OutputFcn, ...'gui_LayoutFcn', [] , ...'gui_Callback', []);if nargin && ischar(varargin{1})gui_State.gui_Callback = str2func(varargin{1});endif nargout[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); elsegui_mainfcn(gui_State, varargin{:});end% End initialization code - DO NOT EDIT% --- Executes just before GUI1 is made visible.function GUI1_OpeningFcn(hObject, eventdata, handles, varargin) handles.output = hObject;guidata(hObject, handles);function varargout = GUI1_OutputFcn(hObject, eventdata, handles) varargout{1} = handles.output;function pushbutton1_Callback(hObject, eventdata, handles)a = get(handles.edit1, 'String');b = get(handles.edit2, 'String');str = Edmonds(str2num(a), str2num(b));set(handles.edit4, 'String', str);guidata(hObject, handles);function edit1_Callback(hObject, eventdata, handles)input = str2num(get(hObject, 'String'));guidata(hObject, handles);function edit1_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'),get(0,'defaultUicontrolBackgroundColor'))set(hObject,'BackgroundColor','white');endfunction edit2_Callback(hObject, eventdata, handles)input = str2num(get(hObject, 'String'));guidata(hObject, handles);function edit2_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'),get(0,'defaultUicontrolBackgroundColor'))set(hObject,'BackgroundColor','white');endfunction slider1_Callback(hObject, eventdata, handles) function slider1_CreateFcn(hObject, eventdata, handles)if isequal(get(hObject,'BackgroundColor'),get(0,'defaultUicontrolBackgroundColor'))set(hObject,'BackgroundColor',[.9 .9 .9]);endfunction text_result_Callback(hObject, eventdata, handles) function text_result_CreateFcn(hObject, eventdata, handles) if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))set(hObject,'BackgroundColor','white');endfunction edit4_Callback(hObject, eventdata, handles) function edit4_CreateFcn(hObject, eventdata, handles)if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))set(hObject,'BackgroundColor','white');endfunction pushbutton2_Callback(hObject, eventdata, handles) set(handles.edit4, 'String', '');set(handles.edit1, 'String', '');set(handles.edit2, 'String', '');。