二分图匹配及其相关问题

二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图   

二分图将图分成两个点集,而使用匈牙利算法的前提是问题中存在这样的两个点集。

 

匈牙利算法:

  匈牙利算法(Hungarian method)是由匈牙利数学家Edmonds于1965年提出,因而得名。匈牙利算法是基于Hall定理中充分性证明的思想,它是二部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法。

 

增广路(也称增广轨或交错轨):

  若P是图G中一条连通两个未匹配顶点的路径,并且属于M的边和不属于M的边(即已匹配和待匹配的边)在P上交替出现,则称P为相对于M的一条增广路径。

 

增广路的定义可以推出下述三个结论
 
  (1)P的路径个数必定为奇数,第一条边和最后一条边都不属于M。
  (2)将M和P进行取反操作可以得到一个更大的匹配
  (3)M为G的最大匹配当且仅当不存在M的增广路径。
 
算法轮廓:
 
  (1)置M为空。
  (2)找出一条增广路径P,通过异或操作获得更大的匹配代替M。
  (3)重复(2)操作直到找不出增广路径为止。
 
复杂度:
  时间复杂度邻接矩阵:最坏为邻接表:
  空间复杂度 邻接矩阵:邻接表:

  完美匹配: 如果所有点都在匹配边上,称这个最大匹配是完美匹配。 

  最小覆盖: 最小覆盖要求用最少的点(X集合或Y集合的都行)让每条边都至少和其中一个点关联。可以证明:最少的点(即覆盖数)=最大匹配数

  最小路径覆盖
    用尽量少的不相交简单路径覆盖有向无环图G的所有结点。解决此类问题可以建立一个二分图模型。把所有顶点i拆成两个:X结点集中的i和Y结点集中的i',如果有边i->j,则在二分图中引入边i->j',设二分图最大匹配为m,则结果就是n-m。

  最大独立集问题
    在N个点的图G中选出m个点,使这m个点两两之间没有边.求m最大值.
如果图G满足二分图条件,则可以用二分图匹配来做.最大独立集点数 = N - 最大匹配数

  二分图最大匹配问题的匈牙利算法

    分图的最大匹配有两种求法,第一种是最大流(我在此假设读者已有网络流的知识);第二种就是我现在要讲的匈牙利算法。这个算法说白了就是最大流的算法,但是它跟据二分图匹配这个问题的特点,把最大流算法做了简化,提高了效率。
              最大流算法的核心问题就是找增广路径(augment path)。匈牙利算法也不例外,它的基本模式就是:

 1 #define N 202
 2 int useif[N];   //记录y中节点是否使用 0表示没有访问过,1为访问过
 3 int link[N];   //记录当前与y节点相连的x的节点
 4 int mat[N][N]; //记录连接x和y的边,如果i和j之间有边则为1,否则为0
 5 int gn,gm;    //二分图中x和y中点的数目
 6 int can(int t)
 7 {
 8     int i;
 9     for(i=1;i<=gm;i++)
10     {
11        if(useif[i]==0 && mat[t][i])
12        {
13            useif[i]=1;
14            if(link[i]==-1 || can(link[i]))
15            {
16               link[i]=t;
17               return 1;
18            }
19        }
20     }
21     return 0;
22 }
23 int MaxMatch()
24 {
25     int i,num;
26     num=0;
27     memset(link,0xff,sizeof(link));
28     for(i=1;i<=gn;i++)
29     {
30       memset(useif,0,sizeof(useif));
31        if(can(i)) num++;
32     }
33     return num;
34 }

 

 

posted @ 2018-01-23 17:19  翛宁  阅读(200)  评论(0编辑  收藏  举报