匹配问题与匈牙利算法和较大基数匹配

合集下载

匈牙利算法解决二分图最大匹配

匈牙利算法解决二分图最大匹配

匈⽛利算法解决⼆分图最⼤匹配预备知识 匈⽛利算法是由匈⽛利数学家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 是一个完美匹配。

显然,完美匹配一定是最大匹配(完美匹配的任何一个点都已经匹配,添加一条新的匹配边一定会与已有的匹配边冲突)。

但并非每个图都存在完美匹配。

举例来说:如下图所示,如果在某一对男孩和女孩之间存在相连的边,就意味着他们彼此喜欢。

是否可能让所有男孩和女孩两两配对,使得每对儿都互相喜欢呢?图论中,这就是完美匹配问题。

如果换一个说法:最多有多少互相喜欢的男孩/女孩可以配对儿?这就是最大匹配问题。

基本概念讲完了。

二分图匹配题目类型总结.

二分图匹配题目类型总结.

二分图匹配题目类型总结二分图最大匹配的匈牙利算法二分图是这样一个图,它的顶点可以分类两个集合X和Y,所有的边关联在两个顶点中,恰好一个属于集合X,另一个属于集合Y。

最大匹配:图中包含边数最多的匹配称为图的最大匹配。

完美匹配:如果所有点都在匹配边上(x=y=m),称这个最大匹配是完美匹配。

最小点覆盖:(二分图)最小覆盖要求用最少的点(X集合或Y集合的都行)让每条边都至少和其中一个点关联。

可以证明:最少的点(即覆盖数)=最大匹配数。

支配集:(二分图)最小点覆盖数+孤立点最小边覆盖:找最大匹配(注意可能是任意图最大匹配)m则有2*m 个点被m 条两两不相交的边覆盖。

对于剩下的n-2*m 个点,每个点用一条边覆盖,总边数为n-m条;最小路径覆盖:用尽量少的不相交简单路径覆盖有向无环图G的所有结点。

解决此类问题可以建立一个二分图模型。

把所有顶点i拆成两个:X结点集中的i和Y结点集中的i',如果有边i->j,则在二分图中引入边i->j',设二分图最大匹配为m,则结果就是n-m。

最大独立集问题:(二分图)n-最小点覆盖;任意图最大匹配:(没有奇环)转换为二分图:把所有顶点i拆成两个:X结点集中的i和Y结点集中的i',如果原图中有边i->j,则在二分图中引入边i-> j',j->i’;设二分图最大匹配为m,则结果就是m/2。

最大完全子图:补图的最大独立集三大博弈问题威佐夫博奕(Wythoff Game):有两堆各若干个物品,两个人轮流从某一堆或同时从两堆中取同样多的物品,规定每次至少取一个,多者不限,最后取光者得胜。

这种情况下是颇为复杂的。

我们用(ak,bk)(ak ≤bk ,k=0,1,2,...,n)表示两堆物品的数量并称其为局势,如果甲面对(0,0),那么甲已经输了,这种局势我们称为奇异局势。

前几个奇异局势是:(0,0)、(1,2)、(3,5)、(4,7)、(6,10)、(8,13)、(9,15)、(11,18)、(12,20)。

二分图匹配(匈牙利算法和KM算法)

二分图匹配(匈牙利算法和KM算法)

前言:高中时候老师讲这个就听得迷迷糊糊,有一晚花了通宵看KM的Pascal代码,大概知道过程了,后来老师说不是重点,所以忘的差不多了。

都知道二分图匹配是个难点,我这周花了些时间研究了一下这两个算法,总结一下1.基本概念M代表匹配集合未盖点:不与任何一条属于M的边相连的点交错轨:属于M的边与不属于M的边交替出现的轨(链)可增广轨:两端点是未盖点的交错轨判断M是最大匹配的标准:M中不存在可增广轨2.最大匹配,匈牙利算法时间复杂度:O(|V||E|)原理:寻找M的可增广轨P,P包含2k+1条边,其中k条属于M,k+1条不属于M。

修改M 为M&P。

即这条轨进行与M进行对称差分运算。

所谓对称差分运算,就是比如X和Y都是集合,X&Y=(X并Y)-(x交Y)有一个定理是:M&P的边数是|M|+1,因此对称差分运算扩大了M实现:关于这个实现,有DFS和BFS两种方法。

先列出DFS的代码,带注释。

这段代码来自中山大学的教材核心部分在dfs(x),来寻找可增广轨。

如果找到的话,在Hungarian()中,最大匹配数加一。

这是用了刚才提到的定理。

大家可以想想初始状态是什么,又是如何变化的view plaincopy to clipboardprint?第二种方法BFS,来自我的学长cnhawk核心步骤还是寻找可增广链,过程是:1.从左的一个未匹配点开始,把所有她相连的点加入队列2.如果在右边找到一个未匹配点,则找到可增广链3.如果在右边找到的是一个匹配的点,则看它是从左边哪个点匹配而来的,将那个点出发的所有右边点加入队列这么说还是不容易明白,看代码吧view plaincopy to clipboardprint?3.最佳匹配加权图中,权值最大的最大匹配KM算法:概念:f(v)是每个点的一个值,使得对任意u,v C V,f(u)+f(v)>=w[e u,v]集合H:一个边集,使得H中所有u,v满足f(u)+f(v)=w[e u,v]等价子图:G f(V,H),标有f函数的G图理论:对于f和G f,如果有一个理想匹配集合M p,则M p最优。

指派问题匈牙利算法最大值

指派问题匈牙利算法最大值

指派问题匈牙利算法最大值
指派问题是一个优化问题,旨在确定如何将 n 个任务分配给 n 个人员,以便完成总成本最小或总利润最大。

匈牙利算法是解决指派问题的经典算法之一,通过寻找增广路径来找到最大权值的匹配。

在指派问题中,我们有一个 n x n 的成本矩阵,其中的每个元素表
示将特定任务分配给特定人员的成本或利润。

问题的目标是找到一种分配方式,使得总成本最小或总利润最大。

匈牙利算法是一种基于图论的算法,它通过构建二分图和寻找增广路径来解决指派问题。

算法的核心思想是通过不断改进当前的匹配,直到找到最优解。

具体来说,匈牙利算法的步骤如下:
1. 初始化一个空的匹配集合。

2. 对于每个任务,找到一个未被分配的人员,并将其分配给该任务。

如果该任务没有未被分配的人员,则考虑将其他任务分配给当前人员,并将当前任务分配给其它人员。

3. 如果存在一个未被匹配的任务,寻找一条从该任务出发的增广路径。

增广路径是一条交替经过匹配边和非匹配边的路径,起点和终点都是未匹配的任务。

4. 如果存在增广路径,则改进当前的匹配,即通过将增广路径上的
非匹配边变为匹配边,并将增广路径上的匹配边变为非匹配边。

5. 重复步骤3和步骤4,直到不存在增广路径为止。

匈牙利算法的运行时间复杂度为 O(n^3),其中 n 是任务或人员的数量。

该算法可以找到指派问题的最优解,并且在实践中表现良好。

总之,指派问题是一个重要的优化问题,而匈牙利算法是一种解决指派问题的经典算法。

通过构建二分图并寻找增广路径,匈牙利算法可以找到指派问题的最优解。

python实现匈牙利算法求解二分图最大匹配

python实现匈牙利算法求解二分图最大匹配

python实现匈⽛利算法求解⼆分图最⼤匹配重点:理解和取反1. 匈⽛利算法求解⽬标:找到⼆分图的最⼤匹配整体思路:每⼀步寻找⼀条增⼴路径,取反2. 关键步骤⼆分图的顶点分为左边点集X和右边点集Y,假定遍历的点集是X。

对于每⼀次迭代的点x_i,1. 搜索增⼴路径:遍历x_i的邻接节点y_j1. 如果y_j未匹配,则找到增⼴路2. 如果y_j已匹配,则寻找y_j的匹配节点的增⼴路径(深搜或者⼴搜)2. 取反:把增⼴路径中的已经匹配边改成未匹配;未匹配的改成匹配3. python代码算法输⼊为字典形式的特殊邻接表。

特殊之处在于字典的键和值的顶点分别属于⼆分图的左右点集合。

深度搜索增⼴路径函数的参数中的visited_set的作⽤是避免重复访问。

# 匈⽛利算法(dfs)class Hungarian:def search_extend_path(self, l_node, adjoin_map, l_match, r_match, visited_set):'''深度搜索增⼴路径'''for r_node in adjoin_map[l_node]: # 邻接节点if r_node not in r_match.keys(): # 情况1:未匹配, 则找到增⼴路径,取反l_match[l_node] = r_noder_match[r_node] = l_nodereturn Trueelse: # 情况2: 已匹配next_l_node = r_match[r_node]if next_l_node not in visited_set:visited_set.add(next_l_node)if self.search_extend_path(next_l_node, adjoin_map, l_match, r_match, visited_set): # 找到增⼴路径,取反l_match[l_node] = r_noder_match[r_node] = l_nodereturn Truereturn Falsedef run(self, adjoin_map):''':param adjoin_map: {x_i: [y_j, y_k]}:return:'''l_match, r_match = {}, {} # 存放匹配for lNode in adjoin_map.keys():self.search_extend_path(lNode, adjoin_map, l_match, r_match, set())return l_match。

匹配问题与匈牙利算法和较大基数匹配

匹配问题与匈牙利算法和较大基数匹配

3.1 婚配问题
婚配问题可以说是一个相对经典的图论匹配算法的入门问题。 假设对于 n 个男人的集合和 n 个女人的集合。 在男人女人进行匹配的情况下, 就会产生一个如何进行完美匹配的问题。在这个问题背景下,进一步加入优先的 概念:根据实际情况,每个男人 m 将对所有女人进行排名,如果 m 给 w 的排名高 于, 那么我们就说 m 偏爱 w 超过,因此我们将把 m 的按顺序的排名作为他的优先 表。 依照常理来看, 每个男人都会按照自己的优先表顺序从高向低依次进行求婚, 直到被接受为止。 那么,接下来本文将讨论如何生成一个稳定的完美匹配。 Gale 和 Shapley 两人根据自己对申请人-雇主之间关系的研究,提出了 Gale-Shapley 算法,具体算法描述如下: 初始所有的 while 存在男人 m 是自由的且还没对每个女人都求过婚 选择这样的一个男人 m 令 w 为 m 的优先表中还没有求过婚的最高排名的女人 if w 是自由的 (m,w)变为约会状态 else w 当前与约会 if w 是更加偏爱而不爱 m m 保持自由 else w 更加偏爱 m 而不爱 (m,w)变为约会状态 变为自由 end end end 输出约会状态的所有匹配集合 S 分析 Gale-Shapley 算法,可以得到以下结论: 结论 1: G-S 算法至多在次 while 循环的迭代之后终止; 结论 2: 程序终止时返回的集合 S 为一个完美匹配; 结论 3: 考虑 G-S 算法的一次执行, 结果为一个集合 S, 且 S 是一个稳定匹配; 结论 4: G-S 算法的每次执行最终得到的匹配集合是相同的; 结论 5: 稳定匹配集合 S 中,每个女人与她最差(即排名最低)的有效伴侣
6/7
图论-浅谈匹配问题
M(t1,:)=0; M(t2,:)=0; M(:,t1)=0; M(:,t2)=0; end S

利用匈牙利算法求完美匹配例题

利用匈牙利算法求完美匹配例题

一、概述匈牙利算法是一种用于求解二分图最大匹配的经典算法,它的时间复杂度为O(n^3),在实际应用中具有广泛的用途。

本文将通过一个具体的例题,详细介绍利用匈牙利算法求解完美匹配的具体步骤和方法。

二、问题描述假设有一个二分图G=(V, E),其中V={U,V},U={u1,u2,u3},V={v1,v2,v3},E={(u1,v1),(u1,v2),(u2,v2),(u3,v3)},现在希望求解这个二分图的最大匹配。

三、匈牙利算法详解1. 初始化:需要初始化一个大小为|U|的数组match[],用来记录每一个U中的顶点匹配的V中的顶点,初始化为-1,表示初始时没有匹配的顶点。

2. 寻找增广路径:通过遍历U中的每一个顶点,逐个寻找增广路径。

对于每一个未匹配的顶点,都尝试进行增广路径的寻找。

3. 匹配顶点:如果找到了一条增广路径,将增广路径上的顶点逐个匹配,并更新match[]数组。

4. 寻找最大匹配:重复上述步骤,直至无法继续寻找增广路径为止,此时match[]数组中记录的就是二分图的最大匹配。

四、具体例题求解接下来通过一个具体的例题来详细介绍匈牙利算法的求解过程。

假设有一个二分图G=(V, E),其中V={U,V},U={u1,u2,u3},V={v1,v2,v3},E={(u1,v1),(u1,v2),(u2,v2),(u3,v3)}。

首先初始化match[]数组为{-1,-1,-1}。

(1)对u1进行增广路径的寻找由于u1未匹配,从u1开始寻找增广路径。

首先考虑与u1相连的v1和v2。

对v1进行匹配,得到match[0]为1。

对v2进行匹配,得到match[0]为1。

(2)对u2进行增广路径的寻找由于u2未匹配,从u2开始寻找增广路径。

考虑与u2相连的v2。

对v2进行匹配,得到match[1]为2。

(3)对u3进行增广路径的寻找由于u3未匹配,从u3开始寻找增广路径。

考虑与u3相连的v3。

对v3进行匹配,得到match[2]为3。

整数规划---匈牙利法

整数规划---匈牙利法

x1 (1) 1 0 0 0 x2 0 (1) 1 0 0 x3 0 1 0 0 (1) x4 0 0 (1) 0 0 x5 0 0 1 (1) 1
y1
y2
y3
y4
y5
但礼让原则未必都能得到最大 匹配,其次礼让原则当规模大 时无法使用,且无法用计算机 实现
z' = ∑∑C'ij xij =∑∑Cij xij − a∑xij + b∑xij = ∑Cij xij − a + b = z − a + b
j =1 i =1 n n
利用这个性质,可使原效益矩阵变换为含有很多零 元素的新的矩阵(即每行减去该行的最小值,再每列 也类似),其余C’ij ≥0. 如果C=(C’ij)有n个不同行,不同列的零元素,以下 简称为独立的零元素,则令矩阵x=( xij )中,对这n个独 立的零元素位置取1,其余取0,代入目标函数得z’= 0,它一定是最小(因为C’ij ≥0 )
Step4:增加(转移)零元素 a.求出未被直线覆盖的元素中的最小值k(本例中 k=2). b.对打√行减去k,对打√列加上k go to step2
2 (0) 8 11 (0) 5 2 3 (0) 0 13 4

5 √ 4 0 √ 5
0 (0) 6 13 (0) 5 4 3 (0) 0 11 2
进一步考虑
指派问题用匈牙利法计算,模型需要满足的形式: (1)目标函数是求最小值 (2)效益矩阵必须是n阶方阵 (3)效益矩阵中每个元素Cij ≥0,且是常数
如人员分配问题:
x1 x2 x3 x4 x5 y1 y2 y3 y4 y5
x1 x2 A = (aij ) = x3 x4 x5 1 0 0 0 0

5匹配

5匹配
3 2 W 2 0 1
0
5 5 4 1 2 0 2 2 4 4 1 0 1 1 0 0 2 1 3 3
0 0 0 0
5 2
x1
x2 x3
x4
x5
4
1 3 y1 y2 y3 y4 y5
G l=(X, Y)
最优匹配算法
定理 设 l 是赋权完全偶图G=(X, Y的可行顶点标号,若 相等子图Gl有完美匹配M*,则M*是G的最优匹配。 证明:设M*是Gl的完美匹配,则:
注:该算法把匈牙利算法用于其中,主要是用来判定 和求完美匹配。
最优匹配算法
例2,设如下矩阵是赋权完全偶图G的权值矩阵,求出 其最优匹配。
3 2 W 2 0 1 5 2 4 1 2 5 0 4 1 1 4 2 1 0 1 2 0 0 3
3
解:给出初始可行顶点标号 l 为:
基本概念
3 、 M-可增广路径 给定图G的一个匹配M,如果G的一条路径P中的边 交替的出现在M和Mc中,则称P为一条M-交错路径. 两 端点均为M-不饱和顶点的M-交错路径称为M-可增广路径.
4 、二分图(偶图) 图G=(V,E)的点集V可以分为两各非空子集X,Y,集 X∪Y=V,X∩Y=Ø,使得同一集合中任意两个顶点均不相邻, 称这样的图为二部图(偶图) .
y2
y3
y4
y5
G=(X, Y)
(c) y2为M非饱和点,加上y2和边x3y2生长树H。此时, 置M=MΔE(P)={x1y1, x2y3, x3y2}
x1 y2 x2 x3 x4 x5
x3
y1
y2
y3
y4
y5
G=(X, Y)
匈牙利算法
x1 x2 x3 x4 x5

两个点集配对问题 匈牙利算法

两个点集配对问题 匈牙利算法

两个点集配对问题匈牙利算法目录1.引言2.两个点集配对问题的定义和背景3.匈牙利算法的原理和步骤4.匈牙利算法的应用实例5.总结正文1.引言在图论中,点集配对问题(也称为任务分配问题或车辆路径问题)是一个经典的问题。

给定两个点集,分别代表供应点和需求点,我们需要找到一种方式,使得从供应点到需求点的距离总和最小。

匈牙利算法(Hungarian algorithm)是解决这类问题的一种经典算法,它通过不断地寻找最短路径,将供应点与需求点一一对应,使得总距离最小。

2.两个点集配对问题的定义和背景假设我们有两个点集 A 和 B,分别有 m 个供应点和 n 个需求点。

每个供应点可以被分配给任意一个需求点,而每个需求点只能被分配给一个供应点。

我们的目标是找到一种分配方案,使得从每个供应点到其对应的需求点的距离总和最小。

3.匈牙利算法的原理和步骤匈牙利算法的基本思想是:对于没有分配的供应点和需求点,我们寻找一条最短路径,将这两个点连接起来。

这样,我们就可以将问题规模缩小,直到所有的供应点和需求点都被分配。

匈牙利算法的具体步骤如下:(1) 初始化:将所有的供应点和需求点都视为未分配,计算每个供应点到其他所有需求点的距离。

(2) 寻找最短路径:遍历所有的供应点和需求点,找到一条最短路径,将一对供应点和需求点连接起来。

(3) 更新距离:更新已经被连接的供应点和需求点的距离,将它们之间的距离设为 0,同时将其他供应点到这个需求点的距离加 1。

(4) 重复步骤 2 和 3:回到步骤 2,继续寻找最短路径,直到所有的供应点和需求点都被连接。

4.匈牙利算法的应用实例匈牙利算法广泛应用于实际问题中,如物流配送、任务分配、基因匹配等。

其中一个著名的应用实例是旅行商问题(Traveling Salesman Problem, TSP),即给定一组城市和它们之间的距离,我们需要找到一个访问每个城市一次并返回出发点的最短路径。

虽然 TSP 问题目前没有已知的多项式时间算法,但匈牙利算法可以应用于其子问题,如最小生成树问题(Minimum Spanning Tree, MST),帮助我们找到一个较好的解决方案。

用匈牙利算法求二分图的最大匹配.

用匈牙利算法求二分图的最大匹配.

一、用匈牙利算法求二分图(二部图,偶图的最大匹配算法中的几个术语说明:1。

二部图:如果图G=(V,E的顶点集何V可分为两个集合X,Y,且满足X∪Y =V, X∩Y=Φ,则G称为二部图;图G的边集用E(G表示,点集用V(G表示。

2。

匹配:设M是E(G的一个子集,如果M中任意两条边在G中均不邻接,则称M是G的一个匹配。

M中的—条边的两个端点叫做在M是配对的。

3。

饱和与非饱和:若匹配M的某条边与顶点v关联,则称M饱和顶点v,并且称v是M-饱和的,否则称v是M-不饱和的。

4。

交互道:若M是二分图G=(V,E的一个匹配。

设从图G中的一个顶点到另一个顶点存在一条道路,这条道路是由属于M的边和不属于M的边交替出现组成的,则称这条道路为交互道。

5。

可增广路:若一交互道的两端点为关于M非饱和顶点时,则称这条交互路是可增广路。

显然,一条边的两端点非饱和,则这条边也是可增广路。

6。

最大匹配:如果M是一匹配,而不存在其它匹配M',使得|M'|>|M|,则称M是最大匹配。

其中|M|表示匹配M的边数。

7。

对称差:A,B是两个集合,定义A⊕B = (A∪B\(A∩B ,则称A⊕B为A和B的对称差。

定理:M为G的最大匹配的充要条件是G中不存在可增广道路。

Hall定理:对于二部图G,存在一个匹配M,使得X的所有顶点关于M饱和的充要条件是:对于X的任意一个子集A,和A邻接的点集为T(A,恒有:|T(A| >= |A|。

匈牙利算法是基于Hall定理中充分性证明的思想,其基本步骤为:1。

任给初始匹配M;2。

若X已饱和则结束,否则进行第3步;3。

在X中找到一个非饱和顶点x0,作V1 ←{x0},V2 ←Φ ;4。

若T(V1 = V2则因为无法匹配而停止,否则任选一点y∈T(V1\V2;5。

若y已饱和则转6,否则做一条从x0→y的可增广路P,M←M⊕E(P,转2;6。

由于y已饱和,所以M中有一条边(y,z,作V1 ←V1∪{z}, V2←V2∪{y},转4;二、用匈牙利算法求二分图的最大匹配(伪代码给定一个二分图(x,y,x中的点和y中点的连接情况,一个匹配是二分图的子图,其中任一个x中的点只能和最多一个y中的点连接,一个y中的点也只能和一个x中的点连接,最大匹配就是使子图中的边数(我们称为匹配边最多的匹配。

两个点集配对问题 匈牙利算法

两个点集配对问题 匈牙利算法

两个点集配对问题匈牙利算法摘要:1.两个点集配对问题简介2.匈牙利算法的基本原理3.匈牙利算法的应用场景4.匈牙利算法的优缺点5.实际案例分析正文:在我们的生活中,经常遇到需要将两个点集进行配对的问题,例如在线约会平台为用户推荐匹配的伴侣,或者学校为学生分配宿舍等。

为了解决这类问题,匈牙利算法应运而生。

本文将详细介绍两个点集配对问题、匈牙利算法的基本原理、应用场景以及优缺点。

一、两个点集配对问题简介两个点集配对问题,是指在给定两个点集A和B的情况下,寻找一种最优的配对方式,使得A中的每个点都与B中的一个点配对,且配对数量最大化。

这是一个典型的组合优化问题,可以用图论中的匹配概念来表示。

二、匈牙利算法的基本原理匈牙利算法(Hungarian algorithm),又称霍夫曼编码算法,是由匈牙利数学家Alfréd Rényi和Miklós匈格尔于1957年独立发现的。

该算法基于图论中的最大匹配问题,通过不断地交换相邻顶点来实现最优匹配。

1.将A、B两个点集分别表示为两个矩阵A和B,其中A[:, i]表示A中第i个点的坐标,B[:, j]表示B中第j个点的坐标。

2.计算A和B的匹配矩阵C,C[:, i]表示A中第i个点与B中哪个点匹配。

3.初始化一个长度为A中点数的空矩阵,用于存放已匹配的点。

4.遍历A中的每个点,判断其相邻点是否已匹配,若未匹配,则尝试与B 中未匹配的点进行配对,并更新匹配矩阵C。

5.重复步骤4,直到A和B中的所有点都完成匹配。

6.输出匹配矩阵C,即为最优配对结果。

三、匈牙利算法的应用场景1.任务分配:将一组任务分配给多个人完成,使得每个人的任务量尽量均衡。

2.资源调度:在多个资源供应者和需求者之间分配资源,使得供需平衡且整体效益最大化。

3.生产线调度:将多个生产任务分配给生产线上的机器,使得生产效率最大化。

4.配对问题:如在线约会平台为用户推荐匹配的伴侣,学校为学生分配宿舍等。

二分图匹配算法(最大流匈牙利)

二分图匹配算法(最大流匈牙利)

⼆分图匹配算法(最⼤流匈⽛利)⼆分图匹配相关概念⽆向⼆分图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%。

整数规划---匈牙利法

整数规划---匈牙利法

Step4:增加(转移)零元素 a.求出未被直线覆盖的元素中的最小值k(本例中 k=2). b.对打√行减去k,对打√列加上k go to step2
2 (0) 8 11 (0) 5 2 3 (0) 0 13 4

5 √ 4 0 √ 5
0 (0) 6 13 (0) 5 4 3 (0) 0 11 2
i =1 j =1 n n
∑x
i =1 n j =1
n
ij
=1 =1
∑x
ij
xij = 0或 ,i = 1 ~ n, j = 1 ~ n 1
显然,这是一个典型的0-1规划问题。也可以看成是一 个产量和销量为1的运输问题。可以用相应方法求解。 但有解分配问题更有效的方法—匈牙利法
匈牙利法
由最大匹配问题的讨论可知,可行解可用一个0-1矩阵 给出。如前例
2 2 4 4 0 0 4 3 6 5 0 4 2 1 0 2 5 0 3 6 3 2 3 1 7 -1 -2
指派问题与匈牙利法
2)试指派(找独立0元素) )试指派(找独立 元素 元素)
2 2 4 4 0
0 4 2 4 5 0 3 0 1 0 1 3 0 3 5 1 2 3 0 5
所以,给出求最大匹配的匈牙利算法
x1 x2 设A = x3 x4 x5
1 0 0 0 0
y1
y2
1 0 0 0 1 1 0 0 1 0 0 1 0 1 0 0 0 1 1 1
y3
y4
y5
求最大匹配。
有一份中文说明书,需译成英、日、德、俄四种文字,分别 记为E、J、G、R,现有A、B、C、D四人,他们将中文翻 译成不同语种,所需时间如表3-1.问应分配何人去完成何工 作,使所需总时间最少(一人做一件事)。

最大匹配算法匈牙利算法

最大匹配算法匈牙利算法

经有的匹配做下修改,即和2进行匹配, 4
这样沿着已有匹配去寻找到
4‘
的新匹配叫增广路。
5
匈牙利算法
1.对于左边的每个点,看看右边有没有 增广路,如果有,那么进行增广,没有 就不添加新的匹配。
2.当对最后一个点做完增广路以后,整 个图就形成了一个最大匹配。
二分图的最小覆盖数
问最少画多少笔才能将所有的点全部盖 住
poj1422
最小路径覆盖
将n个点拆成2n个点,如1号变为1和1’, 1代表出边,1’代表进边。对于每个结点, 将与其相临的边连出来。
对已经连好的图求最大匹配数
最小路径覆盖
最小路径覆盖数=顶点数n-最大匹配数
Nkoj 1684 courses 1465 Taxi Cab Scheme 1681 Girls and boys 1070 信和信封的问题
poj 2239 Selecting Courses 1422 Air Raid 最小路径覆盖 1325 Machine Schedule 1719 Shooting Contest 2594 Treasure Exploration
2195 Going Home带权二分图(km算法) 2446 Chessboard 1904 King's Quest 3342 Party at Hali-Bula 3216 Repairing Company POJ3020 - Antenna Placement
一张残缺的棋盘,用1*2的矩形去覆盖它, 要求矩形不互相重叠。
求矩形最多可以放多少个。
二分图的最大独立数
将棋盘染成黑白相间,黑色方格作为左 边的点,白色方格作为右边的点,相邻 的黑白方格中间连一条边。
对已经建好的图求最大匹配

匈牙利匹配算法步骤

匈牙利匹配算法步骤

匈牙利匹配算法步骤匈牙利匹配算法是一种求解二分图最大匹配问题的高效算法。

它由匈牙利数学家Eduard Czuber和König于1931年提出,后被Kuhn在1955年重新发现并加以改进。

该算法能够解决许多实际问题,如婚配问题、任务分配问题等。

本文将详细介绍匈牙利匹配算法的步骤。

首先,我们需要理解什么是二分图和匹配。

一个二分图是由两个不相交的集合V1和V2构成的图,其中每条边都连接着V1中的一个顶点和V2中的一个顶点。

而一个匹配则是图中的一组边,这些边两两之间没有公共顶点。

最大匹配是指在所有可能的匹配中,包含的边数最多的匹配。

接下来,我们来看看匈牙利匹配算法的具体步骤:1. 初始化:为每个顶点v赋予一个权值d(v) = 0。

2. 找增广路径:从一个未匹配的顶点u开始,寻找一条增广路径P。

这条路径的特点是:它的起点是未匹配的顶点,终点是未匹配的顶点,且路径上的边交替地属于匹配M和不属于匹配M。

3. 更新权值:如果找到了增广路径P,那么就更新路径上所有顶点的权值。

具体来说,对于路径上的每一个顶点v,有以下两种情况:- 如果v是一个奇顶点(即在路径P中位置为奇数),则令d(v) = d(v) + 1。

- 如果v是一个偶顶点(即在路径P中位置为偶数),则令d(v) = d(v) - 1。

4. 检查是否结束:如果找不到增广路径了,那么算法结束;否则回到第二步继续找增广路径。

以上就是匈牙利匹配算法的主要步骤。

这个算法的基本思想是通过不断地找增广路径和更新权值,使得最后能找到一个最大的匹配。

匈牙利匹配算法的优点在于它的效率高。

在最坏的情况下,匈牙利匹配算法的时间复杂度是O(n^3),其中n是图中顶点的数量。

而在实际情况中,由于可以使用各种优化技巧,例如使用数据结构来加速查找增广路径的过程,所以通常情况下算法的运行时间会远小于理论上的最坏情况。

此外,匈牙利匹配算法还有很好的可扩展性。

它可以很容易地推广到一些更复杂的问题,例如带权重的最大匹配问题、多对多匹配问题等。

第5讲匹配问题及算法

第5讲匹配问题及算法
若图的顶点集分为两个非空子集X和Y,并且每 条边都有一个顶点在X中,一个顶点在Y中,则称 此图为二分图,或者偶图;进一步,若X中每个顶 点都与Y中每个顶点相连,则称为完全二分图或完 全偶图。 若完全二分图的顶点个数分别为m和n,则此 二分图可记为Km,n
匹配、完美匹配、最大匹配
设M是图G中边集E的子集,如果M中任何两边 都不邻接,则称M为G的一个匹配(或对集);匹 配M中边元素个数称为此匹配的基数,而在匹配M 中边的端点称为M-饱和点,其他顶点称为未饱和 点。 进一步,若G中每个顶点都是M-饱和点,即匹 配M将G中所有顶点都匹配成功,则称M为G的完 美匹配;而若在图G中不存在另一个匹配M2,使得 |M2|>|M|,则称M为最大匹配,其中|M|称为G的匹 配数。
Kuhn-Munkras算法步骤
1. 初始化可行顶标的值
2. 用匈牙利算法寻找完备匹配
3.若未找到完备匹配则修改可行顶标的值 4. 重复(2)(3)直到找到相等子图的完备匹配为止
【KM算法的Matlab实现】
见Word文档
第五讲习题
1. 给定指派问题的矩阵,用匈牙利算法求出最大解 和最小解。
707 506 505 b 340 265 202 101 343 187 245 125 95 98 49 616 460 440 320 290 176 88 686 535 490 375 350 196 98 805 663 575 469 453 230 115 448 302 320 210 190 128 64 686 530 490 370 340 196 98
2. 圈0元素。在C’中未被直线通过的含0元素最少 的行(列)中圈出0元素,通过这个0元素作一 条竖(或横)线。重复此步,若能圈出不同行 列的n个0元素,转4,否则转3

匈牙利算法解决两个坐标列表匹配的问题

匈牙利算法解决两个坐标列表匹配的问题

匈⽛利算法解决两个坐标列表匹配的问题遇到⼀个问题,有⼀个坐标列表A:[[10,20],[20,30],[42,41]],和⼀个坐标列表B:[[14,24],[41,42],[20,31],[42,41]],需要看这两个坐标列表之间谁与谁更加匹配,这时候就可以使⽤匈⽛利算法来实现。

原理不再赘述,直接显⽰代码:from scipy.optimize import linear_sum_assignmentimport numpy as np# 先前的坐标position_a = [[10,20],[20,30],[42,41]]# 之后的坐标position_b = [[14,24],[41,42],[20,31],[42,41]]# 使⽤坐标计算代价矩阵cost_matrix = [[np.power((np.array(a)-np.array(b)),2).sum() for a in position_a] for b in position_b ]print("代价矩阵")print(cost_matrix)# 进⾏匈⽛利算法匹配row_ind, col_ind = linear_sum_assignment(cost_matrix)for x,y in zip(row_ind, col_ind):print("列表B中的%s,应该与列表A中坐标%s匹配,距离消耗为%d"%(position_b[x],position_a[y],cost_matrix[x][y]))结果:代价矩阵[[32, 72, 1073], [1445, 585, 2], [221, 1, 584], [1465, 605, 0]]列表B中的[14, 24],应该与列表A中坐标[10, 20]匹配,距离消耗为32列表B中的[20, 31],应该与列表A中坐标[20, 30]匹配,距离消耗为1列表B中的[42, 41],应该与列表A中坐标[42, 41]匹配,距离消耗为0。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

3.3 较大基数匹配算法
对于图 G,求其较大基数匹配算法的基本步骤为: 1. 任意取得图 G 中一边,将其存入匹配 M 中; 2. 从图 G 中将与匹配 M 中的每一条边相邻的所有边删除; 3. 直到所剩子图全为孤立顶点,算法结束;否则,转 1 编程对其进行实现,代码如下: (其中,M 表示图 G 的邻接矩阵,S 表示匹配 结束时所有顶点之间的邻接矩阵)
3.1 婚配问题
婚配问题可以说是一个相对经典的图论匹配算法的入门问题。 假设对于 n 个男人的集合和 n 个女人的集合。 在男人女人进行匹配的情况下, 就会产生一个如何进行完美匹配的问题。在这个问题背景下,进一步加入优先的 概念:根据实际情况,每个男人 m 将对所有女人进行排名,如果 m 给 w 的排名高 于, 那么我们就说 m 偏爱 w 超过,因此我们将把 m 的按顺序的排名作为他的优先 表。 依照常理来看, 每个男人都会按照自己的优先表顺序从高向低依次进行求婚, 直到被接受为止。 那么,接下来本文将讨论如何生成一个稳定的完美匹配。 Gale 和 Shapley 两人根据自己对申请人-雇主之间关系的研究,提出了 Gale-Shapley 算法,具体算法描述如下: 初始所有的 while 存在男人 m 是自由的且还没对每个女人都求过婚 选择这样的一个男人 m 令 w 为 m 的优先表中还没有求过婚的最高排名的女人 if w 是自由的 (m,w)变为约会状态 else w 当前与约会 if w 是更加偏爱而不爱 m m 保持自由 else w 更加偏爱 m 而不爱 (m,w)变为约会状态 变为自由 end end end 输出约会状态的所有匹配集合 S 分析 Gale-Shapley 算法,可以得到以下结论: 结论 1: G-S 算法至多在次 while 循环的迭代之后终止; 结论 2: 程序终止时返回的集合 S 为一个完美匹配; 结论 3: 考虑 G-S 算法的一次执行, 结果为一个集合 S, 且 S 是一个稳定匹配; 结论 4: G-S 算法的每次执行最终得到的匹配集合是相同的; 结论 5: 稳定匹配集合 S 中,每个女人与她最差(即排名最低)的有效伴侣
n=size(M,1);%这里 M 表示邻接矩阵 S=zeros(n,n);%S 为程序的输出结果,这里 S 表示较大基数的匹配矩阵 while sum(sum(M))~=0 a=find(M~=0); t1=mod(a(1),n); if t1==0 t1=n; end if a(1)/n>floor(a(1)/n) t2=floor(a(1)/n)+1; else t2=floor(a(1)/n); end S(t1,t2)=1; S(t2,t1)=1;
7/7
3/7
图论-浅谈匹配问题
end end if(M(i,j)) break; end end while(1) for(i=1:m) x(i)=0; end for(i=1:n) y(i)=0; end for(i=1:m) pd=1; for(j=1:n) if(M(i,j)) pd=0; end end if(pd)x(i)=-n-1; end end pd=0; while(1) xi=0; for(i=1:m) if(x(i)<0) xi=i; break; end end if(xi==0) pd=1; break; end x(xi)=x(xi)*(-1); k=1; for(j=1:n) if(A(xi,j)&y(j)==0) y(j)=xi; yy(k)=j; k=k+1; end
6/7
图论-浅谈匹配问题
M(t1,:)=0; M(t2,:)=0; M(:,t1)=0; M(:,t2)=0; end S
同样举例说明其运行过程:
例: 假设图G=(X,Y),其中X、Y的邻接矩阵A为: 0 1 1 0 0 1 0 0 1 1 A = 0 1 1 0 0 0 1 1 0 0 0 0 0 0 1 则利用上述代码,进行较大基数匹配可以得到最终的匹配结果S: 0 1 0 0 0 1 0 0 0 0 S = 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1
2/7
图论-浅谈匹配问题
匹配。 由结论 5, 在 G-S 算法中,主动进行求婚的一方以最佳可能的稳定匹配结束, 而另一方则以最差可能的稳定匹配结束。
3.2 匈牙利算法
二分图的匹配问题是图的最大匹配问题的特殊类型。对于一个二分图G= (X,Y,E) ,我们可以利用匈牙利算法对其进行最大匹配。其基本的思想为:从G 的任意匹配M开始,对X中所有M的非饱和点,寻找M-增广路。 若不存在M-增广路, 则M为其最大匹配;若存在M-增广路P,则将P中M与非M的边互换得到比M多一边的 匹配,再对重复上述过程。 匈牙利算法具体的运行过程为: 输入:G 的一个初始匹配 M 输出:满足要求的最大匹配 任意给出 G 的一个初始匹配 M if M 饱和了 X 中的所有节点 则 M 是 G 的一个完全匹配 else 找出 X 中的非饱和点 x,令 A={x},B={}; 考察 A 的邻接点 if N(A)=B 计算结束 else 在 Y 中找出一点 y 属于 N(A)-B if y 为 M 的饱和点 在 X 中找出 y 的配对点 z,令,B=B,转 6; else 存在一条从 x 到 y 的可扩路 P,故 M 不是 G 的最大匹配 end end end 令 M=M+E(P),转 2。
4.结束语
本文中仅仅讨论了图论中几个比较典型的算法,其中,婚配问题可以称之为 图论匹配算法的入门问题; 匈牙利算法则可以用来解决众多需要进行最大匹配的 实际问题,例如申请人与雇主之间的匹配、某些指派问题等。由于时间紧促,因 此并没有列出更多的算法, 只是将目前已经熟悉掌握述运行过程,利用matlab可以很方便的进行算法的实现,程序代码 如下: (其中A为X与Y的邻接矩阵,M为X与Y之间的匹配,m为X中顶点个数,n 为Y中顶点个数,最终的最大匹配结果为矩阵M)
m= n= ; ;
M(m,n)=0; for(i=1:m) for(j=1:n) if(A(i,j)) M(i,j)=1; break;
4/7
图论-浅谈匹配问题
end if(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 if(pdd) break; end; end if(pdd) k=1; j=yy(j); while(1) P(k,2)=j; P(k,1)=y(j); j=abs(x(y(j))); if(j==n+1) break; end k=k+1; end for(i=1:k) if(M(P(i,1),P(i,2))) M(P(i,1),P(i,2))=0; else M(P(i,1),P(i,2))=1; end end break; end end end if(pd) break; end end M;
图论-浅谈匹配问题
1.匹配问题的起源
匹配理论起源于组合数学中著名的婚配问题:若在一个团体中有若干待婚的 小伙子和姑娘,所有人都已到结婚年龄,若没有其他条件的限制,为了满足姑娘 的愿望, 唯一的必备条件就是小伙子的人数至少和姑娘的人数一样多。但是在事 实上,所有人都不会草率地处理自己的终身大事,以姑娘为例(与小伙子的情况 是完全相同的) ,每个姑娘往往会排除一些小伙子作为她们可能的配偶,也即每 个姑娘都会有一个有序的可接受的配偶名单。那么会有一个问题出现:在这个团 体中是否每个姑娘都可以嫁给自己认可的小伙子? 显然,上述问题并非是永远可以的,因为或许有几个姑娘手头上的名单是完 全一样的。 而既然上述问题并非永远可行,那么什么条件下可以满足上述要求? 在并满足这些条件的时候,最多会有几位姑娘可以实现自己的愿望?如何配对, 才能使得最终的团体中婚后的家庭更为美满? 为了解决诸如此类的问题,人们发展得到了一种匹配理论和诸多有效算法。
2.图论相关知识
若图 G 的所有顶点能够分为两个非空子集 X 和Y,并且每条边都有一个顶点 在X中,而另一个顶点在 Y 中,则称此图是二分图或者偶图;而如果 X 的每个顶 点都与 Y 的每个顶点相连,则称此图为完全二分图或者完全偶图。 设 M 是图 G=(V,E)的边集 E 的子集,如果 M 的任何两边都不邻接,则称 M 为 G 的一个匹配; 匹配 M 中边元素个数称为此匹配的基数,而在匹配 M 中边的端 点称为 M-饱和点,其他的端点称为 M-未饱和点。 若 G 中的每个顶点都是 M-饱和点, 也即匹配 M 将 G 中的所有顶点进行了配对, 那么称 M 为 G 的完美匹配;而在图 G 中不存在另一个匹配,使得>,则称 M 为最 大匹配,其中称为图 G 的匹配数。 设 M 是 G 的一个匹配, G 的 M 交错路是指其边在 E\M 和 M 中交错出现的路。M 可扩路是指其起点和终点都是 M 未饱和的 M 交错路。 以下结论是在二分图中寻找最大匹配和最佳匹配算法的理论基础: 定理 1: G 的匹配 M 是最大匹配当且仅当 G 不包含 M 可扩路。 定理 2: 设 X,Y 为二分图 G 的二分类,则 G 包含饱和 X 的每个顶点的匹配当 且仅当 其中为 G 中 S 的临集,即为与 S 的顶点相邻的所有顶点的集合。 定理 3: G 有完美匹配当且仅当 其中,为图 G 的奇分支(图的分支根据它有奇数或者偶数个顶点而分别 称为奇分支或偶分支)的个数。
1/7
图论-浅谈匹配问题
3.几个典型的匹配算法
由于刚接触到图论知识,碍于在图论方面能力有限,因此本文在本节中选择 性地介绍了三个图论匹配问题中比较经典的算法:婚配问题的 Gale-Shapley 算 法、 最大匹配的匈牙利算法和图论中的较大基数匹配算法,并且对匈牙利算法和 较大基数匹配算法进行了 matlab 代码实现。
5/7
图论-浅谈匹配问题
相关文档
最新文档