• KuhnMunkres算法(二分图最大权匹配)


             二分图如果是没有权值的,求最大匹配。则是用匈牙利算法求最大匹配。如果带了权值,求最大或者最小权匹配,则必须用KM算法。

             其实最大和最小权匹配都是一样的问题。只要会求最大匹配,如果要求最小权匹配,则将权值取相反数,再把结果取相反数,那么最小权匹配就求出来了。

            KM算法及其难理解。。。看了几天还无头绪。

          先拿上一直采用的KM算法模板,按照吉林大学的模板写的。试试了好多次感觉都没有出错。

        

    /******************************************************
    二分图最佳匹配 (kuhn munkras 算法 O(m*m*n)).
    邻接矩阵形式 。  返回最佳匹配值,传入二分图大小m,n
    邻接矩阵 mat ,表示权,match1,match2返回一个最佳匹配,为匹配顶点的match值为-1,
    一定注意m<=n,否则循环无法终止,最小权匹配可将全职取相反数。
    初始化:  for(i=0;i<MAXN;i++)
                 for(j=0;j<MAXN;j++) mat[i][j]=-inf;
    对于存在的边:mat[i][j]=val;//注意不能负值 
    ********************************************************/
    #include<string.h>
    #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;i<m;i++)
        {
            l1[i]=-inf;
            for(j=0;j<n;j++)
                l1[i]=mat[i][j]>l1[i]?mat[i][j]:l1[i];
            if(l1[i]==-inf)  return -1;
        } 
        for(i=0;i<n;i++)
            l2[i]=0;
        _clr(match1);
        _clr(match2);
        for(i=0;i<m;i++)
        {
            _clr(t);
            p=0;q=0;
            for(s[0]=i;p<=q&&match1[i]<0;p++)
            {
                for(k=s[p],j=0;j<n&&match1[i]<0;j++)
                {
                    if(l1[k]+l2[j]==mat[k][j]&&t[j]<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;
                            }    
                        }    
                    }    
                }    
            } 
            if(match1[i]<0)
            {
                i--;
                p=inf;
                for(k=0;k<=q;k++)
                {
                    for(j=0;j<n;j++)
                    {
                        if(t[j]<0&&l1[s[k]]+l2[j]-mat[s[k]][j]<p)
                           p=l1[s[k]]+l2[j]-mat[s[k]][j];
                    }    
                }  
                for(j=0;j<n;j++)
                   l2[j]+=t[j]<0?0:p;
                for(k=0;k<=q;k++)
                   l1[s[k]]-=p;  
            }       
        } 
        for(i=0;i<m;i++)
            ret+=mat[i][match1[i]];
        return ret;      
    }   

              下面是从网上的博客摘抄的一些零散的总结。。。。。

            

    [二分图带权匹配与最佳匹配]

    什么是二分图的带权匹配?二分图的带权匹配就是求出一个匹配集合,使得集合中边的权值之和最大或最小。而二分图的最佳匹配则一定为完备匹配,在此基础上,才要求匹配的边权值之和最大或最小。二分图的带权匹配与最佳匹配不等价,也不互相包含

    这两个的关系比较悬乎。我的理解就是带权匹配是不考虑是不是完备,只求最大或最小权匹配。而最佳匹配则必须在完备匹配的基础上找最大或最小权匹配。

    这两个还是结合具体题目比较好理解些。

    KM算法是求最大权完备匹配,如果要求最小权完备匹配怎么办?方法很简单,只需将所有的边权值取其相反数,求最大权完备匹配,匹配的值再取相反数即可。

    KM算法的运行要求是必须存在一个完备匹配,如果求一个最大权匹配(不一定完备)该如何办?依然很简单,把不存在的边权值赋为0。

    KM算法求得的最大权匹配是边权值和最大,如果我想要边权之积最大,又怎样转化?还是不难办到,每条边权取自然对数,然后求最大和权匹配,求得的结果a再算出e^a就是最大积匹配。至于精度问题则没有更好的办法了。

    二分图最优匹配:对于二分图的每条边都有一个权(非负),要求一种完备匹配方案,使得所有匹配边的权和最大,记做最优完备匹配。(特殊的,当所有边的权为1时,就是最大完备匹配问题)

     

     

    定义     设G=<V1,V2,E>为二部图,|V1|≤|V2|,M为G中一个最大匹配,且|M|=|V1|,则称M为V1到V2完备匹配

    在上述定义中,若|V2|=|V1|,则完备匹配即为完美匹配,若|V1|<|V2|,则完备匹配为G中最大匹配

     

     

     

    KM算法是通过给每个顶点一个标号(叫做顶标)来把求最大权匹配的问题转化为求完备匹配的问题的。设顶点Xi的顶标为A[i],顶点Yi的顶标为B[i],顶点Xi与Yj之间的边权为w[i,j]。在算法执行过程中的任一时刻,对于任一条边(i,j),A[i]+B[j]>=w[i,j]始终成立,初始A[i]为与xi相连的边的最大边权,B[j]=0。KM算法的正确性基于以下定理:

    设 G(V,E) 为二部图, G'(V,E') 为二部图的子图。如果对于 G' 中的任何边<x,y> 满足, L(x)+ L(y)== Wx,y,我们称 G'(V,E') 为 G(V,E) 的等价子图或相等子图(是G的生成子图)。

    若由二分图中所有满足A[i]+B[j]=w[i,j]的边(i,j)构成的子图(称做相等子图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配。

    因为对于二分图的任意一个匹配,如果它包含于相等子图,那么它的边权和等于所有顶点的顶标和;如果它有的边不包含于相等子图,那么它的边权和小于所有顶点的顶标和(即不是最优匹配)。所以相等子图的完备匹配一定是二分图的最大权匹配。

             

    该算法是通过给每个顶点一个标号(叫做顶标)来把求最大权匹配的问题转化为求完备匹配的问题的。设顶点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]的值有所减小。也就说,它原来不属于相等子图,现在可能进入了相等子图,因而使相等子图得到了扩大。

     

      现在的问题就是求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。

     

      Kuhn-Munkras算法流程:

     

      (1)初始化可行顶标的值

     

      (2)用匈牙利算法寻找完备匹配

     

      (3)若未找到完备匹配则修改可行顶标的值

     

      (4)重复(2)(3)直到找到相等子图的完备匹配为止 

    最后还是强调一点:

    KM算法用来解决最大权匹配问题: 在一个二分图内,左顶点为X,右顶点为Y,现对于每组左右连接XiYj有权wij,求一种匹配使得所有wij的和最大。

    也就是最大权匹配一定是完备匹配。如果两边的点数相等则是完美匹配。

    如果点数不相等,其实可以虚拟一些点,使得点数相等,也成为了完美匹配。

    最大权匹配还可以用最大流去解决。。。有待以后的学习。。

  • 相关阅读:
    js获取html参数。
    jquery判断单选按钮是否选中
    js滑动触屏事件监听
    单例模式之Java
    Android开发把项目打包成apk
    jdom解析XML 中文
    PhoneGap Connection
    java 文件操作
    html参数编码
    JS 判断字符串包含
  • 原文地址:https://www.cnblogs.com/kuangbin/p/2646535.html
Copyright © 2020-2023  润新知