二分图的匹配.

二分图的匹配.
二分图的匹配.

第九章二分图中的匹配

三个典型问题:

(1)在一个有禁止位置的m×n棋盘上,能放置非攻击型车的最多个数是多少?

(2)在一个有禁止位置的m×n棋盘上,能放置多米诺牌覆盖的最多个数是多少?

(3)一个公司有n个工作空缺,需要有一定技能的人填补,同时有m个人申请这些项工作,每人能胜任n项工作中的若干项,问最多有多少项工作能找到合适的

人选?

9.1 一般的问题描述

定义1:

令X={x1, x2, …,x m}, Y={y1,y2, …,y n},且X∩Y=Ф,而△是序偶e=(x,y)的集合,其中x ∈X,y∈Y,那么三元组G=(X,△,Y)称作二分图。

定义2:

令G=(X,△,Y)是一个二分图,边集△的子集M,若M中没有两条边存在公共点,称M是二分图G的一个匹配。

定义3:

设G是一个二分图,定义ρ(G)={∣M∣:M是G的一个匹配}为二分图G的最大匹配边数。

9.2 匹配

定义1:

G=(X,△,Y),X={x1, x2, …,x m}, Y={y1,y2, …,y n},满足∣M*∣=ρ(G)的匹配M*称为二分图G的最大匹配。一般M*不唯一,且∣M*∣=ρ(G)≤min{m,n}。

寻找M*的困难点:

(1)若已知ρ(G),那么遍历所有可能的匹配会找到M*,但搜索量巨大;

(2)一般ρ(G)并不事先知道,要找到M*,并求出ρ(G)=∣M*∣难度更大。

定义2:

令u和v是二分图G=(X,△,Y)的任意两个顶点,连接u和v的互异顶点序列:γ:u=u0, u1, u2, …, u p-1, u p=v

使得任意两个相邻顶点有一条边连接,即:{ u0, u1},{ u1, u2},…, { u p-1, u p}∈△,那么称序列γ为二分图G的一个链。链长等于序列的边数p,若u=v, 链γ也叫圈。

定义3:

令M为二分图G=(X,△,Y)中的一个匹配,令M是M的补集,即G的不属于M的边集合,M∪M=△。令u和v是顶点,且u和v一个是左顶点(即属于X),一个是右顶点(即属于Y),若连接u和v的链满足下列性质:

(1)γ的第一、三、五、、、边属于M;

(2)γ的第二、四、六、、、边属于M;

(3)u和v都不与M的边相连。

那么称γ为关于匹配M的交错链,简称M-交错链。

M-交错链的性质:

(1)M-交错链γ的长是奇数2k+1, k≧0;

(2)设Mγ表示γ的属于M的边集合,Mγ表示γ的属于M的边集合,那么有:∣Mγ∣=∣Mγ∣+1

例:

定理9.2.1:

令M为二分图G=(X,△,Y)中的一个匹配,则M是最大匹配当且仅当不存在M-交错链。

推论9.2.1:

若M不是二分图G的最大匹配,那么必存在M-交错链。

进展:

得到了最大匹配的特征,即只需找M-交错链,找不到,则M就是最大匹配。

困难:

搜索M-交错链类似于穷举,算法上不可行,即在构造最大匹配的时候不知算法何时结束。

怎么办?

当找到一个匹配M时,希望能有一种方法直接直接验证其是否为最大匹配,若不是,则继续找(肯定能找到);若是,则算法结束。

定义4:

令G=(X,△,Y)是一个二分图,S是G的顶点X∪Y的子集,若G中任一条边的两个顶点至少有一个属于S,即:

{x,y}∩S≠Ф,对?{x,y}∈△

则称S是G的一个覆盖。

例:

定义5:

令c(G)=min{∣S∣:S是G的覆盖},即c(G)是G的覆盖的最小顶点个数,称c (G)为G的覆盖数。显然,G的任一个覆盖S满足∣S∣≧c(G),把满足∣S∣=c(G)的覆盖S称为G的最小覆盖。

****图的最小顶点覆盖问题是典型的NP难题。

引理9.2.2:

如果G是一个二分图,那么ρ(G)≦c(G),即二分图G的最大匹配边数不会超过G 的覆盖数。

例:

求二分图G的最大匹配和最小覆盖的算法:

令G=(X,△,Y)是一个二分图,其中X={x1, x2, …,x m}, Y={y1,y2, …,y n},令M为得到的G的任一匹配。

(1)将X的所有不与M的边相关联的顶点标上(*),并称所有的顶点为未被扫描的,转(2);

(2)如果在上一步没有新的标记(例如(*),(y j))加到X的顶点上,则停止。否则,转(3);

(3)当存在X的被标记但未被扫描的顶点时,选择一个被标记但未被扫描的顶点,比如x i, 用(x i)标记Y的所有顶点,这些顶点被不属于M且尚未标记的边连到x i。现在顶点x i是被扫描的,若X中不存在被标记但未被扫描的顶点时,转(4);

(4)若在步骤(3)中没有新的标记加到Y中顶点上,则停止;否则,转(5);

(5)当存在Y中被标记但未被扫描的顶点时,选择Y中一个被标记但未被扫描的顶点,比如y j, 用(y j)标记X 的所有顶点,这些顶点被属于M且尚未标记的边连到y j。现在顶点y j是被扫描的,若Y中不存在被标记但未被扫描的顶点时,转(2);

例1:

如图,确定二分图G的最大匹配和最小覆盖。

算法的收敛性证明:

定义6:

突破点:存在Y中的被标记的点,该点不与M的边关联;

非突破点:算法终止,但未出现突破点,即Y中每一个被标记的顶点都与M的边关联。

结论:

在突破点情况,算法成功找到一个M-交错链,因此,可以构造一个比M更大的匹配,再重新应用匹配算法。

算法的正确性证明:

定理9.2.3:

设非突破点在匹配算法中发生,令X un由X中所有未被标记的顶点组成,并令Y lab由Y的所有被标记的顶点组成,则下列两个结论成立:

(1)S=X un∪Y lab是二分图G的最小覆盖;

(2)∣M∣=∣S∣,且M是G的最大匹配。

推论9.24(Konig定理):

令G=(X,△,Y)是一个二分图,则ρ(G)=c(G),即二分图G的最大匹配边数

等于G的最小覆盖的顶点数。

定义7:

令G=(X,△,Y)是一个二分图,X和Y的顶点数均为n,G中有n条边的匹配称为完美匹配。

定义8:

若二分图G=(X,△,Y)的每一个顶点都与p 条边关联,则称G是p阶正则的。

性质:

若G是p阶正则的,那么X和Y必有相同的顶点数。

定理9.2.5

p≥1阶正则的二分图G=(X,△,Y)总有完美匹配。

9.3 互异代表系统

定义1:

令Y为有限集合,A=(A1, A2, …,A n)为Y的n 个子集序列,那么,Y中的元素序列(e1, e2, …,e n),其中e n∈A i(I=1,2,…,n)称为A的代表系统。若e1, e2, …,e n是互异的,称为互异代表系统(System of Distinct Representatives)。简称SDR。

引理9.3.1 (SDR存在的必要条件)

为使集合序列A=(A1, A2, …,A n)有SDR,必须满足下列条件:

(MC:成婚条件):对每一个k=1,2,…,n,以及从{1,2,…,n}选出的k个互异指标i1, i2, …,i k, 都有:

∣A i

1∪A i

2

∪…∪A i

k

∣≥k.

定理9.3.2:

集合序列A=(A1, A2, …,A n)有SDR,当且仅当成婚条件成立。

定理9.3.3:

A=(A1, A2, …,A n)是集合Y的子集序列,那么A的能够选出使得有SDR的子集的最大个数ρ由下式给出:

ρ=∣A i

1∪A i

2

∪…∪A i

k

∣+n-k

其中表达式右侧表示对于k=1,2,…n的所有选择,以及相应的取自{1,2,…,n}的k个互异指标i1, i2, …,i k的所有选择得到的最小值。

例1:

设集合序列A1={a,b,c}, A2={b,c}, A3={b,c}, A4={b,c}, A5={c}, A6={a,b,c,d},确定集合序列可以选出的有SDR的最大子集个数。

9.4 稳定婚姻

设有n位女士和n位男士,每位女士按照其对每位男士作为配偶的偏爱程度给每位男士排名次,不允许并列名次出现,因此,每位女士都会给男士排成1,2,…,n的顺序;类似地,每位男士给女士也会有1,2,…,n的顺序排名。使所有n男士和女士都成婚,称为完备婚姻。显然,实现完备婚姻地方法数有n!种。若一个完备婚姻中存在两位女士A和B及两位男士a和b,满足:

(1)A和a成婚;

(2)B和b成婚;

(3)A更偏爱b(排名在前)而非a;

(4)b更偏爱A而非B。

那么,称此完备婚姻为不稳定的;一个非不稳定的完备婚姻称为稳定的。

问题:稳定的完备婚姻总存在吗?

问题的二分图G的表示:

X={w1, w2, …,w n}表示n位女士;

Y={m1,m2, …,m n}表示n位男士;

△表示所有可能的{ w i, m j}(i,j=1,2,…,n)边连接,每条边都有一个数对p,q, 其中p表示w i对m j的排名,q表示m j对w i的排名。

显然,每一个完备婚姻对应二分图G的一个完美匹配。为考虑稳定的完备婚姻,用优先秩评定矩阵表示这一模型,具体方法:

(1)n行对应每位女士,w1, w2, …,w n;

(2)n列对应每位男士,m1,m2, …,m n;

(3)第i行,第j列位置上的数对p,q代表w i对m j的排名和m j对w i的排名。

定理9.4.1:

对于每一个优先秩评定矩阵都存在稳定的完备婚姻。

例2:

试求一个稳定的完备婚姻。

定义2:

在一个稳定婚姻中,如果一位女士得到的作为配偶的男士比她在所有其他完备婚姻中得到的配偶在排名上至少有同样的优先级,那么,此完备婚姻是对该女士最优的。如果完备婚姻是对每一位女士都是最优的,则称此完备婚姻是对女士最优的。

定理9.4.2:

通过延迟算法,用女士选择男士得到的稳定的完备婚姻是女士最优的;同理,用男士

选择女士得到的稳定的完备婚姻是男士最优的。

在女士最优的稳定完备婚姻中,每一位男士都会和一位对他可行的配偶中排序级别最低的女士配对。

Ku二分图最大权匹配(KM算法)hn

Maigo的KM算法讲解(的确精彩) 顶点Yi的顶标为B[i],顶点Xi与Yj之间的边权为w[i,j]。在算法执行过程中的任一时刻,对于任一条边(i,j),A[i]+B[j]>=w[i,j]始终成立。KM 算法的正确性基于以下定理: * 若由二分图中所有满足A[i]+B[j]=w[i,j]的边(i,j)构成的子图(称做相等子图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配。 这个定理是显然的。因为对于二分图的任意一个匹配,如果它包含于相等子图,那么它的边权和等于所有顶点的顶标和;如果它有的边不包含于相等子图,那么它的边权和小于所有顶点的顶标和。所以相等子图的完备匹配一定是二分图的最大权匹配。 初始时为了使A[i]+B[j]>=w[i,j]恒成立,令A[i]为所有与顶点Xi关联的边的最大权,B[j]=0。如果当前的相等子图没有完备匹配,就按下面的方法修改顶标以使扩大相等子图,直到相等子图具有完备匹配为止。 我们求当前相等子图的完备匹配失败了,是因为对于某个X顶点,我们找不到一条从它出发的交错路。这时我们获得了一棵交错树,它的叶子结点全部是X顶点。现在我们把交错树中X顶点的顶标全都减小某个值d,Y顶点的顶标全都增加同一个值d,那么我们会发现:

两端都在交错树中的边(i,j),A[i]+B[j]的值没有变化。也就是说,它原来属于相等子图,现在仍属于相等子图。 两端都不在交错树中的边(i,j),A[i]和B[j]都没有变化。也就是说,它原来属于(或不属于)相等子图,现在仍属于(或不属于)相等子图。 X端不在交错树中,Y端在交错树中的边(i,j),它的A[i]+B[j]的值有所增大。它原来不属于相等子图,现在仍不属于相等子图。 X端在交错树中,Y端不在交错树中的边(i,j),它的A[i]+B[j]的值有所减小。也就说,它原来不属于相等子图,现在可能进入了相等子图,因而使相等子图得到了扩大。 现在的问题就是求d值了。为了使A[i]+B[j]>=w[i,j]始终成立,且至少有一条边进入相等子图,d应该等于min{A[i]+B[j]-w[i,j]|Xi在交错树中,Yi不在交错树中}。 以上就是KM算法的基本思路。但是朴素的实现方法,时间复杂度为 O(n4)——需要找O(n)次增广路,每次增广最多需要修改O(n)次顶标,每次修改顶标时由于要枚举边来求d值,复杂度为O(n2)。实际上KM算法的复杂度是可以做到O(n3)的。我们给每个Y顶点一个“松弛量”函数slack,每次开始找增广路时初始化为无穷大。在寻找增广路的过程中,检查边(i,j)时,如果它不在相等子图中,则让slack[j]变成原值与A[i]+B[j]-w[i,j]的较小值。这样,在修改顶标时,取所有不在交错树中的Y顶点的slack值中的最小值作为d值即可。但还要注意一点:修改顶标后,要把所有的slack值都减去d。

二分图匹配(匈牙利算法和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.如果在右边找到的是一个匹配的点,则看它是从左边哪个点匹配而来的,将那个点出发的所有右边点加入队列 这么说还是不容易明白,看代码吧

算法学习:图论之二分图的最优匹配(KM算法)

二分图的最优匹配(KM算法) KM算法用来解决最大权匹配问题:在一个二分图内,左顶点为X,右顶点为Y,现对于每组左右连接XiYj有权wij,求一种匹配使得所有wij的和最大。 基本原理 该算法是通过给每个顶点一个标号(叫做顶标)来把求最大权匹配的问题转化为求完备匹配的问题的。设顶点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)构成的子图(称做相等子图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配。 首先解释下什么是完备匹配,所谓的完备匹配就是在二部图中,X点集中的所有点都有对应的匹配或者是 Y点集中所有的点都有对应的匹配,则称该匹配为完备匹配。 这个定理是显然的。因为对于二分图的任意一个匹配,如果它包含于相等子图,那么它的边权和等于所有顶点的顶标和;如果它有的边不包含于相等子图,那么它的边权和小于所有顶点的顶标和。所以相等子图的完备匹配一定是二分图的最大权匹配。 初始时为了使A[ i ]+B[j]>=w[i,j]恒成立,令A[ i ]为所有与顶点Xi关联的边的最大权,B[j]=0。如果当前的相等子图没有完备匹配,就按下面的方法修改顶标以使扩大相等子图,直到相等子图具有完备匹配为止。 我们求当前相等子图的完备匹配失败了,是因为对于某个X顶点,我们找不到一条从它出发的交错路。这时我们获得了一棵交错树,它的叶子结点全部是X顶点。现在我们把交错树中X顶点的顶标全都减小某个值d,Y顶点的顶标全都增加同一个值d,那么我们会发现: 1)两端都在交错树中的边(i,j),A[ i ]+B[j]的值没有变化。也就是说,它原来属于相等子图,现在仍属于相等子图。 2)两端都不在交错树中的边(i,j),A[ i ]和B[j]都没有变化。也就是说,它原来属于(或不属于)相等子图,现在仍属于(或不属于)相等子图。 3)X端不在交错树中,Y端在交错树中的边(i,j),它的A[ i ]+B[j]的值有所增大。它原来不属于相等子图,现在仍不属于相等子图。 4)X端在交错树中,Y端不在交错树中的边(i,j),它的A[ i ]+B[j]的值有所减小。也就说,它原来不属于相等子图,现在可能进入了相等子图,因而使相等子图得到了扩大。(针对之后例子中x1->y4这条边) 现在的问题就是求d值了。为了使A[ i ]+B[j]>=w[i,j]始终成立,且至少有一条边进入相等子图,d应该等于: Min{A[i]+B[j]-w[i,j] | Xi在交错树中,Yi不在交错树中}。 改进 以上就是KM算法的基本思路。但是朴素的实现方法,时间复杂度为O(n4)——需要找O(n)次增广路,每次增广最多需要修改O(n)次顶标,每次修改顶标时由于要枚举边来求d值,复杂度为O(n2)。实际上KM算法的复杂度是可以做到O(n3)的。我们给每个Y顶点一个“松弛量”函数slack,每次开始找增广路时初始化为无穷大。在寻找增广路的过程中,检查边(i,j)时,如果它不在相等子图中,则让slack[j]变成原值与A[ i ]+B[j]-w[i,j]的较小值。这样,在修改顶标时,取所有不在交错树中的Y 顶点的slack值中的最小值作为d值即可。但还要注意一点:修改顶标后,要把所有的不在交错树中的Y顶点的slack值都减去d(因为:d的定义为 min{ (x,y)| Lx(x)+ Ly(y)- W(x,y), x∈ S, y? T }

二分图匹配

二分图匹配 1.最大匹配(hdu1068) Girls and Boys Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6410 Accepted Submission(s): 2888 Problem Description the second year of the university somebody started a study on the romantic relations between the students. The relation “romantically involved” is defined between one girl and one boy. For the study reasons it is necessary to find out the maximum set satisfying the condition: there are no two students in the set who have been “romantically involved”. The result of the program is the number of students in such a set. The input contains several data sets in text format. Each data set represents one set of subjects of the study, with the following description: the number of students the description of each student, in the following format student_identifier:(number_of_romantic_relations) student_identifier1 student_identifier2 student_identifier3 ... or student_identifier:(0) The student_identifier is an integer number between 0 and n-1, for n subjects. For each given data set, the program should write to standard output a line containing the result. Sample Input 7 0: (3) 4 5 6 1: (2) 4 6 2: (0) 3: (0) 4: (2) 0 1 5: (1) 0 6: (2) 0 1 3

二分图的最大匹配完美匹配和匈牙利算法

二分图的最大匹配完美匹配和匈牙利算法 匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名。匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。这篇文章讲无权二分图(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 是一个完美匹配。显然,完美匹配一定是最大匹配(完美匹配的任何一个点都已经匹配,添加一条新的匹配边一定会与已有的匹配边冲突)。但并非每个图都存在完美匹配。举例来说:如下图所示,如果在某一对男孩和女孩之间存在相连的边,就意味着他们彼此喜欢。是否可能让所有男孩和女孩两两配对,使得每对儿都互相喜欢呢?图论中,这就是完美匹配问题。如果换一个说法:最多有多少互相喜欢的男孩/女孩可以配对儿?这就是最大匹配问题。基本概念讲完了。求解最大匹配问题的一个算法是匈牙利算法,下面讲的概念都为这个算法服务。交替路:从一个未匹配点出发,依次经过非匹配边、匹配边、非匹配边…形成的路径叫交替路。增广路:从一个未匹配点出发,走交替路,如果途径另一个未匹配点(出发的点不算),则这条交替路称为增广路(agumenting path)。例如,图5 中的一条增广路如图6 所示(图中的匹配点均用红色标出):增广路有一个重要特点:非匹配边比匹配边多一条。因此,研究增广路的意义是改进匹配。只要把增广路中的匹配边和非匹配边的身份交换即可。由于中间的匹配节点不存在其他相连的匹配边,所以这样做不会破坏匹配的性质。交换后,图中的匹配边数

二分图的最大匹配经典之匈牙利算法

Doctor的图论计划之——二分图最大匹配 第一讲二分图的最大匹配经典之匈牙利算法 二分图,顾名思义就是分成了两个部分的图……很白痴的解释(自己吐槽了先),但吐槽的同时我们也要发现一些二分图的基本性质! 性质1 二分图之所以分成了两个部分,那是因为单独的一个部分中的任意两点不连通! 性质2 二分图匹配——匈牙利算法中我们只需记录集合1到集合2的单向边就可以了(注意看上边的图,箭头是单向的)思考这是为什么! 但是!二分图确实是无向图!!!只不过匈牙利算法只是从一个集合另一个集合走一遍罢了!!!! 性质3 树是一种特殊的二分图! 紫色的结点构成集合1,绿色的结点构成集合2,换句话说,儿子和爸爸打仗时爷爷和

孙子站在同一战线!(也可以认为是儿子和爸妈吵架时总是爷爷奶奶护着,小时候有这样的记忆没有?反正我没有!) PS:树就是无回路懂不? 性质3 对于任意二分图,其包含的环一定全部是偶环!(充要可证) 可以证明,含有奇数条边的环一定有两个在相同集合内的点有边相连! 也就是说——二分图的bfs子树一定不含奇环! 接下来说一下二分图求最大匹配的算法——匈牙利算法 【例1】传说中的多米诺骨牌覆盖问题 在一个n*m的棋盘上,摆放一些1*2大小的多米诺骨牌,但棋盘某些地方是坏 掉的,即不能将骨牌置于这些坏掉的格子上,求最多能摆上的骨牌数量 【例2】传说中的猎人打鸟问题 猎人要在n*n的格子里打鸟,他可以在某一行中打一枪,这样此行中的所有鸟都被 打掉,也可以在某一列中打,这样此列中的所有鸟都打掉.问至少打几枪,才能打光 所有的鸟? 【例3】传说中的搞对象问题 一保守教师想带学生郊游, 却怕他们途中谈恋爱,他认为满足下面条件之一的两 人谈恋爱几率很小: (1)身高差>40 (2) 性别相同(3) 爱好不同类型的音乐(4) 爱好同类型的运动 告诉你每个同学的信息,问老师最多能带多少学生? 这样的问题如何解决?搜索?怎么搜?会不会超时?答案很简单,三道题中的元素都可以用很简单的方式分成两个互不相干的部分,因此可以用二分图匹配来解决这个问题:形象的说,我们规定搞基和百合都是不允许的,已知一群男人和女人,他们可以看做图中的顶点,男人构成了集合A,女人构成了集合B,边表示这名男人和这名女人互相有好感(可以配成一对)不考虑个人因素,现在希望为这些饥渴的男男女女找到最多的配对数(脚踏两只船也是不允许的!)为了解决这样的问题我们才引入了二分图的匹配算法——匈牙利算法! 匈牙利算法是一种用增广路求二分图最大匹配的算法。它由匈牙利数学家Edmonds于1965年提出,因而得名。 如果暴搜的话那么无疑时间复杂度将成为O(2^E)!无法快速实现,于是我们就提出了更为高效的算法,这种算法是从网络流演变而来,但这里我们抛开所有网络流的知识,但从这一算法的角度来进行阐释! 解释一些常用的名词 交错轨:所谓交错轨,还有一种更为文雅的说法叫增广轨,这种说法让人不禁联想到蛋疼的网络流算法,所以我更喜欢用一种与网络流无关的说法来称呼它,下面我们来举几个交错轨的例子:

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

用匈牙利算法求二分图的最大匹配 什么是二分图,什么是二分图的最大匹配,这些定义我就不讲了,网上随便都找得到。二分图的最大匹配有两种求法,第一种是最大流(我在此假设读者已有网络流的知识);第二种就是我现在要讲的匈牙利算法。这个算法说白了就是最大流的算法,但是它跟据二分图匹配这个问题的特点,把最大流算法做了简化,提高了效率。匈牙利算法其实很简单,但是网上搜不到什么说得清楚的文章。所以我决定要写一下。 最大流算法的核心问题就是找增广路径(augment path)。匈牙利算法也不例外,它的基本模式就是: 初始时最大匹配为空 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)最后,也是最重要的一条,把增广路径上的所有第奇数条边加入到原匹配中

二分图最大匹配算法的应用及Matlab实现+++

一共有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.m function [LMA, LMB] = LockMap(n, m) % LOCKMAP - 求解满足条件锁并设置相应的映射 % 输入参数:n 表槽数,m 表高度数。 % 输出参数:LMA,LMB 分别为二维矩阵表示自然数到满足条件锁之间的映射。 global jiA ouB ary A B mm N N = 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>lenb temp = LMA; LMA=LMB;LMB=temp; temp = lena;lena=lenb;lenb=temp; end #RecuCal.m function RecuCal(n) % RECUCAL - 递归函数 global jiA ouB ary A B mm N if n ==1 for k=1:mm % 调用递归函数时要用到的变量所以 % 设为全局 ary(1) = k; Max = max(ary); Min = min(ary); num = 0; neighbor = 0; for i=1:N num = num + (Max-ary(i))*(ary(i)-Min);

Ku二分图最大权匹配(KM算法)hn

Kuhn-Munkres 算法
Maigo 的 KM 算法讲解(的确精彩)
KM 算法是通过给每个顶点一个标号(叫做顶标)来把求最大权匹配的问题转 化为求完备匹配的问题的。设顶点 Xi 的顶标为 A[i],
顶点 Yi 的顶标为 B[i],顶点 Xi 与 Yj 之间的边权为 w[i,j]。在算法执行过程中 的任一时刻,对于任一条边(i,j), A[i]+B[j]>=w[i,j]始终成立。KM 算法的正确 性基于以下定理: * 若由二分图中所有满足 A[i]+B[j]=w[i,j]的边(i,j)构成的子图 (称做相等子 图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配。 这个定理是显然的。因为对于二分图的任意一个匹配,如果它包含于相 等子图,那么它的边权和等于所有顶点的顶标和;如果它有的边不包含于相 等子图,那么它的边权和小于所有顶点的顶标和。所以相等子图的完备匹配 一定是二分图的最大权匹配。 初始时为了使 A[i]+B[j]>=w[i,j]恒成立,令 A[i]为所有与顶点 Xi 关联的边 的最大权,B[j]=0。如果当前的相等子图没有完备匹配,就按下面的方法修改 顶标以使扩大相等子图,直到相等子图具有完备匹配为止。 我们求当前相等子图的完备匹配失败了,是因为对于某个 X 顶点,我们 找不到一条从它出发的交错路。这时我们获得了一棵交错树,它的叶子结点 全部是 X 顶点。现在我们把交错树中 X 顶点的顶标全都减小某个值 d,Y 顶 点的顶标全都增加同一个值 d,那么我们会发现:

两端都在交错树中的边(i,j),A[i]+B[j]的值没有变化。也就是说,它原来属于 相等子图,现在仍属于相等子图。 两端都不在交错树中的边(i,j),A[i]和 B[j]都没有变化。也就是说,它原来属于 (或不属于)相等子图,现在仍属于(或不属于)相等子图。 X 端不在交错树中,Y 端在交错树中的边(i,j),它的 A[i]+B[j]的值有所增大。 它原来不属于相等子图,现在仍不属于相等子图。 X 端在交错树中,Y 端不在交错树中的边(i,j),它的 A[i]+B[j]的值有所减小。 也就说,它原来不属于相等子图,现在可能进入了相等子图,因而使相等子 图得到了扩大。 现在的问题就是求 d 值了。为了使 A[i]+B[j]>=w[i,j]始终成立,且至少有 一条边进入相等子图,d 应该等于 min{A[i]+B[j]-w[i,j]|Xi 在交错树中,Yi 不在 交错树中}。 以上就是 KM 算法的基本思路。但是朴素的实现方法,时间复杂度为 O(n4)——需要找 O(n)次增广路,每次增广最多需要修改 O(n)次顶标,每次 修改顶标时由于要枚举边来求 d 值,复杂度为 O(n2)。实际上 KM 算法的复 杂度是可以做到 O(n3)的。我们给每个 Y 顶点一个“松弛量”函数 slack,每次 开始找增广路时初始化为无穷大。在寻找增广路的过程中,检查边(i,j)时,如 果它不在相等子图中, 则让 slack[j]变成原值与 A[i]+B[j]-w[i,j]的较小值。 这样, 在修改顶标时,取所有不在交错树中的 Y 顶点的 slack 值中的最小值作为 d 值即可。但还要注意一点:修改顶标后,要把所有的 slack 值都减去 d。

二分图及二分图匹配

9.1 二 分 图 9.1.1 二分图的基本概念 定义9.1 无向图G = 称为二分图(bipartite graph),如果有非空集合X,Y使X∪Y = V,X∩Y =φ,且对每一 e∈E,Y(e) = (x, y),x∈X,y∈Y。此时常用表示二分图G。若对X中任一x及Y中任一y恰有一边e∈E,使Y(e) = (x, y), 则称G为完全二分图(complete bipartite graph)。当|X| = m,|Y| = n时,完全二分图G记为K m,n。 简而言之,就是顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属于这两个互不相交的子集。 例9.1 图9.1中(a),(b)为二分图,(c)为完全二分图K3,3,(d), (e)不是二分图。 二分图的下列特征性是重要的。 定理9.1 无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的长度均为偶数。

证 先证必要性。 设G为二分图。由于X,Y非空,故G至少有两个顶点。若C 为G中任一回路,令 C = ( v0,v 1,v2,…,v l-1,v l = v0 ) 其中诸v i ( i = 0,1,…,l )必定相间出现于X及Y中,不妨设 {v0,v2,v4,…, v l = v0} í X {v1,v3,v5,…, v l-1} í Y 因此l必为偶数,从而C中有偶数条边。 再证充分性。 设G的所有回路具有偶数长度,并设G为连通图(不失一般性,若G 不连通,则可对G的各连通分支作下述讨论)。 令G的顶点集为V,边集为E,现构作X,Y,使 = G。取 v0?V,置 X = {v | v= v0或v到v0有偶数长度的通路} Y = V-X X显然非空。现需证Y非空,且没有任何边的两个端点都在X中或都在Y 中。 由于|V|≥2并且G为一连通图,因此v0必定有相邻顶点,设为v1,那么v1?Y;故Y不空。 设有边(u, v), 使u?X,v?X。那么,v0到u有偶数长度的通路,或u = v0;v0到v有偶数长度的通路,或v = v0。无论何种情况,均有一条从v0到v0的奇数长度的闭路径,因而有从v0到v0的奇数长度的回路(因从闭路径上可能删去的回路长度总为偶数),与题设矛盾。故不可能有边(u, v)使u, v均在X中。 “没有任何边的两个端点全在Y中”的证明可仿上进行,请读者思考。 二分图是十分有用的一种数学模型,许多问题可以用它来刻划。例

二分图最大匹配及常用建图方法

算法———艺术 二分图匹配剖析 很多人说,算法是一种艺术。但是对于初学者的我,对算法认识不是很深刻,但偶尔也能感受到他强大的魅力与活力。这让我追求算法的脚步不能停止。下面我通过分析匈牙利算法以及常用建图方式,与大家一起欣赏算法的美。 匈牙利算法 匈牙利算法是用来解决最大二分图匹配问题的,所谓二分图即“一组点集可以分为两部分,且每部分内各点互不相连,两部分的点之间可以有边”。所谓最大二分图匹配即”对于二分图的所有边,寻找一个子集,这个子集满足两个条件, 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,。

二分图的匹配.

第九章二分图中的匹配 三个典型问题: (1)在一个有禁止位置的m×n棋盘上,能放置非攻击型车的最多个数是多少? (2)在一个有禁止位置的m×n棋盘上,能放置多米诺牌覆盖的最多个数是多少? (3)一个公司有n个工作空缺,需要有一定技能的人填补,同时有m个人申请这些项工作,每人能胜任n项工作中的若干项,问最多有多少项工作能找到合适的 人选? 9.1 一般的问题描述 定义1: 令X={x1, x2, …,x m}, Y={y1,y2, …,y n},且X∩Y=Ф,而△是序偶e=(x,y)的集合,其中x ∈X,y∈Y,那么三元组G=(X,△,Y)称作二分图。 定义2: 令G=(X,△,Y)是一个二分图,边集△的子集M,若M中没有两条边存在公共点,称M是二分图G的一个匹配。 定义3: 设G是一个二分图,定义ρ(G)={∣M∣:M是G的一个匹配}为二分图G的最大匹配边数。 9.2 匹配 定义1: G=(X,△,Y),X={x1, x2, …,x m}, Y={y1,y2, …,y n},满足∣M*∣=ρ(G)的匹配M*称为二分图G的最大匹配。一般M*不唯一,且∣M*∣=ρ(G)≤min{m,n}。 寻找M*的困难点: (1)若已知ρ(G),那么遍历所有可能的匹配会找到M*,但搜索量巨大; (2)一般ρ(G)并不事先知道,要找到M*,并求出ρ(G)=∣M*∣难度更大。 定义2: 令u和v是二分图G=(X,△,Y)的任意两个顶点,连接u和v的互异顶点序列:γ:u=u0, u1, u2, …, u p-1, u p=v 使得任意两个相邻顶点有一条边连接,即:{ u0, u1},{ u1, u2},…, { u p-1, u p}∈△,那么称序列γ为二分图G的一个链。链长等于序列的边数p,若u=v, 链γ也叫圈。 定义3: 令M为二分图G=(X,△,Y)中的一个匹配,令M是M的补集,即G的不属于M的边集合,M∪M=△。令u和v是顶点,且u和v一个是左顶点(即属于X),一个是右顶点(即属于Y),若连接u和v的链满足下列性质: (1)γ的第一、三、五、、、边属于M;

二分图匹配模板.

1、图论—匹配 4。1 二分图最大匹配(hungary邻接表) //二分图最大匹配,hungary算法,邻接表形式,复杂度O(m*e) //返回最大匹配数,传入二分图大小m,n和邻接表list(只需一边) //match1,match2返回一个最大匹配,未匹配顶点match值为-1 #include #define MAXN 310 #define _clr(x) memset(x,0xff,sizeof(int)*MAXN) struct edge_t{ int from,to; edge_t* next; }; int hungary(int m,int n,edge_t* list[],int* match1,int* match2){ int s[MAXN],t[MAXN],p,q,ret=0,i,j,k;edge_t* e; for (_clr(match1),_clr(match2),i=0;i=0)) for (_clr(t),s[p=q=0]=i;p<=q&&match1[i]<0;p++) for (e=list[k=s[p]];e&&match1[i]<0;e=e->next) if (t[j=e->to]<0){ s[++q]=match2[j],t[j]=k; if (s[q]<0) for (p=j;p>=0;j=p) match2[j]=k=t[j],p=match1[k],match1[k]=j; } return ret; } 4。2 二分图最大匹配(hungary邻接阵) //二分图最大匹配,hungary算法,邻接阵形式,复杂度O(m*m*n) //返回最大匹配数,传入二分图大小m,n和邻接阵mat,非零元素表示有边//match1,match2返回一个最大匹配,未匹配顶点match值为-1 #include #define MAXN 310 #define _clr(x) memset(x,0xff,sizeof(int)*MAXN) int hungary(int m,int n,int mat[][MAXN],int* match1,int* match2){ int s[MAXN],t[MAXN],p,q,ret=0,i,j,k; for (_clr(match1),_clr(match2),i=0;i=0))

二分图匹配算法及其应用【文献综述】

文献综述 数学与应用数学 二分图匹配算法及其应用 图的匹配理论简单的说就是使得图G 中每两个点之间都有联系. 匹配理论是图论中的一个重要内容, 它在运筹学、系统工程中都有着广泛的应用, 近几十年来, 随着组合数学的迅速发展, 匹配理论成为许多重要理论的基础和源泉. 二分图的最大匹配算法是匹配理论研究的热点之一. KM 算法是求最大匹配的经典算法, 它是在匈牙利算法的进一步提高, 它是解决数学中一类存在性问题的基本工具, 广泛应用于社会、经济、科技、自然等各个领域中. 本文主要研究KM 算法的具体原理, 步骤, 以及它一些实际问题中的应用. 图的匹配问题起源于1935年霍尔的“婚姻问题”. KM 算法是Kuhn 和Munkras 分别于1955年和1957年独立提出来的, 他们在研究图论中最大权匹配问题时很巧妙运用KM 算法去解决问题. 定义1 图G 有三部分所组成 (1) 非空集合)(G V , 称为G 的结点集, 其成员称为结点或顶点. (2) 集合)(G E , 称为G 的边集, 其成员称为边. (3) 函数 ))(),(()(:G V G V G E G →ψ, 称为边和顶点的关联映射. 这里))(),((G V G V 称为)(G V 的偶对集, 其成员偶对形如),(v u , u ,v 为结点, 它们未必不同. 当),()(v u e G =ψ时, 称边e 关联端点u ,v . 当),(v u 用作序偶时 )()())(),((G V G V G V G V ?=, e 称为有向边, e 以u 为起点, 以v 为终点, 图G 称为有向图; 当),(v u 用作无序偶对时, ),(),(u v v u =, 称e 为无向边(或边), 图G 称为无向图(或图). 定义2 无向图?ψ?=,,E V G 称为二分图, 如果有非空集合X ,Y 使

Kuhn-Munkres算法(二分图最大权匹配)

Kuhn-Munkres算法(二分图最大权匹配) 二分图如果是没有权值的,求最大匹配。则是用匈牙利算法求最大匹配。如果带了权值,求最大或者最小权匹配,则必须用KM算法。 其实最大和最小权匹配都是一样的问题。只要会求最大匹配,如果要求最小权匹配,则将权值取相反数,再把结果取相反数,那么最小权匹配就求出来了。 KM算法及其难理解。。。看了几天还无头绪。 先拿上一直采用的KM算法模板,按照吉林大学的模板写的。试试了好多次感觉都没有出错。 /****************************************************** 二分图最佳匹配(kuhn munkras 算法 O(m*m*n)). 邻接矩阵形式。返回最佳匹配值,传入二分图大小m,n 邻接矩阵 mat ,表示权,match1,match2返回一个最佳匹配,为匹配顶点的match值为-1, 一定注意m<=n,否则循环无法终止,最小权匹配可将全职取相反数。

初始化: for(i=0;i#define MAXN 310#define inf 1000000000 #define _clr(x) memset(x,-1,sizeof(int)*MAXN)int KM(int m,int n,int mat[][MAXN],int *match1,int *match2) { int s[MAXN],t[MAXN],l1[MAXN],l2[MAXN]; int p,q,i,j,k,ret=0; for(i=0;il1[i]?mat[i][j]:l1[i]; if(l1[i]==-inf) return -1; } for(i=0;i

二分图匹配

二分图匹配 一、二分图 定义: 二分图又称作二部图、两偶图,是图论中的一种特殊模型。设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。 简而言之,就是顶点集V可分割为两个互不相交的子集,并且图中每条边依附的两个顶点都分属于这两个互不相交的子集。 二、二分图匹配 给定一个二分图G,M为G边集的一个子集,如果M满足当中的任意两条边都不依附于同一个顶点,则称M是一个匹配。 定义: 极大匹配(Maximal Matching)是指在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹配的边数。最大匹配(maximum matching)是所有极大匹配当中边数最大的一个匹配。选择这样的边数最大的子集称为图的最大匹配问题。 如果一个匹配中,图中的每个顶点都和图中某条边相关联,则称此匹配为完全匹配,也称作完备匹配。 必要条件: 无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的长度均为偶数。证先证必要性。 设G为二分图。由于X,Y非空,故G至少有两个顶点。若C为G中任一回路,令 C = (v0,v 1,v2,…,v l-1,v l = v0) 其中诸vi (i = 0,1,…,l)必定相间出现于X及Y中,不妨设 {v0,v2,v4,…,v l = v0} Í X {v1,v3,v5,…,v l-1} Í Y 因此l必为偶数,从而C中有偶数条边。 再证充分性。

设G的所有回路具有偶数长度,并设G为连通图(不失一般性,若G不连通,则可对G的各连通分支作下述讨论)。 令G的顶点集为V,边集为E,现构作X,Y,使 = G。取v0ÎV,置 X = {v | v= v0或v到v0有偶数长度的通路} Y = V-X X显然非空。现需证Y非空,且没有任何边的两个端点都在X中或都在Y中。 由于|V|≥2并且G为一连通图,因此v0必定有相邻顶点,设为v1,那么v1ÎY;故Y 不空。 设有边(u,v),使uÎX,vÎX。那么,v0到u有偶数长度的通路,或u = v0;v0到v有偶数长度的通路,或v = v0。无论何种情况,均有一条从v0到v0的奇数长度的闭路径,因而有从v0到v0的奇数长度的回路(因从闭路径上可能删去的回路长度总为偶数),与题设矛盾。故不可能有边(u,v)使u,v均在X中。 三、稳定婚姻问题 简介: 问题来自于一场“3分钟相亲”活动,参加活动的有n位男士和n位女士。要求每位男士都要和所有的女士进行短暂的单独交流,并为她们打分,然后按照喜欢程度,对每一位女士进行排序;同样的,每位女士也要对所有男士进行打分和排序。 这个是数学界切切实实研究过的问题。对于以前没有接触过这个问题的人,这个理论最出人意外的结论是: 传统的求爱,结婚过程是male-optimal的,也就是说,男性能够得到尽可能好的心上人,女性却不然。这就是所谓的稳定匹配问题(Stable Marriage Problem,也叫稳定婚姻问题)。 四、求婚-拒绝算法 活动方式: 1962 年,美国数学家David Gale和Lloyd Shapley发明了一种寻找稳定婚姻的策略,人们称之为延迟认可算法(Gale-Shapley算法)。 先对所有男士进行落选标记,称其为自由男。当存在自由男时,进行以下操作: ①每一位自由男在所有尚未拒绝她的女士中选择一位被他排名最优先的女士; ②每一位女士将正在追求她的自由男与其当前男友进行比较,选择其中排名优先的男士作为其男友,即若自由男优于当前男友,则抛弃前男友;否则保留其男友,拒绝自由男。 ③若某男士被其女友抛弃,重新变成自由男。 在算法执行期间,自由男们主动出击,依次对最喜欢和次喜欢的女人求爱,一旦被接受,即失去自由身,进入订婚状态;而女人们则采取“守株待兔”和“喜新厌旧”策略,对前来求爱的男士进行选择:若该男子比未婚夫强,则悔婚,选择新的未婚夫;否则拒绝该男子的求婚。被女友抛弃的男人重获自由身,重新拥有了追求女人的权利——当然,新的追求对象比不过前女友。 这样,在算法执行期间,每个人都有可能订婚多次——也有可能一开始就找到了自己的

二分图最大匹配算法的应用及Matlab实现

[num h] = maxnum(g);%g是二分图邻接矩阵 %调用了一个自己写maxnum函数,返回num就是最大值,h是hij(不唯一) 以下是maxnum.m的内容,用的是匈牙利算法 其中还用了一个递归的incpath函数,寻找增广路径 function[num h] = maxnum(g) s=size(g); global G_h;%矩阵hij记录选中 global G_g;%矩阵gij记录匹配 global G_v;%记录当前一次路径访问过的节点 G_h=false(s);%矩阵hij初始为空 G_g=g;%矩阵gij就是传递进来的参数g for i=1:s(1) G_v=false(1,s(2));%每次初始化径访问过的节点为空 incpath(i);%从Ai开始寻找增广路径 end h=G_h;num=sum(h(:));%输出最大匹配数,和匹配矩阵h clear global 'G_h';clear global 'G_g'; end function OK = incpath(i)%从Ai开始 global G_h;global G_g;global G_v;OK=false; j=find(~G_h(i,:)&G_g(i,:)&~G_v,1);%寻找合条件的Bj if isempty(j),return;end%找不到返回false G_v(j)=true;%找到了,标记Bj为以访问节点 ii=find(G_h(:,j));%寻找Bj在原来匹配中 if isempty(ii)%如果不在原匹配中 G_h(i,j)=true;OK=true;return;end%找到增广路径末端,返回true ok=incpath(ii);%如果在原来的匹配中,根据匹配对应的Aii递归调用incpath寻找 if ok %如果递归寻找返回成功 G_h(i,j)=~G_h(i,j);G_h(ii,j)=~G_h(ii,j);OK=true;return;end%路径反色返回true end

相关文档
最新文档