现在的位置: 首页 > 综合 > 正文

二分匹配_最佳匹配KM算法

2017年12月12日 ⁄ 综合 ⁄ 共 3529字 ⁄ 字号 评论关闭

二分图最佳匹配有匹配后总权值最大和最小两种,求最佳匹配的一个有效算法KM算法。KM算法很复杂很费解。现在只能总结步骤。

KM算法步骤( 以下有层次关系,㈠ > 1 > (1) > > Ⅰ

(一)  建图:所有点分为两部分,一部分属于L端,一部分属于R端,两端的点各有n个,现在要为L端的所有点在R端的点中找它们的匹配,使最后总权值最大或最小,设有一条边联通Li点与Rj点,权值为w[i][j],设二维数组gragh_m保存图,graph_m[i][j]= w[i][j]

(二)  为每个点设一个顶标,L端的为plR端的为pr,将pr的全赋为0pl全赋为与这个点联通的权值最大的边的权值,例如与L端第i个联通的最大权值的边的权值为m,则pl[i]=m

(三)  用一个循环枚举L中的每个点,为每个点在R中找其最佳匹配

1.设一辅助数组slack(可在全局定义)大小为n,slack全赋为MAX_INT(无穷大)。

2、用一个死循环为L中的每个点找匹配,直到找到这个匹配时候break掉此循环,

⑴定义两个数组vl,vr,全赋为0,分别表示L中的某个点没有被访问过和R中的某个点没有被需要过(需要表示R中的某个点满足L中的某个点的最佳匹配要求,但被需要不表示最后能肯定配到它)

⑵以当前的为其找匹配的点作为实参调用匹配函数match,这里假定这个点位置为pos

   match 函数体如下:

     vl[pos]赋为1(访问过

     用个循环枚举R中的每个点,设当前点为j,如果这个点还没有被需要过(vr[j]==0)则执行:定义变量val=pl[pos]+pr[j]-graph_m[pos][j];

如果val==0(满足匹配条件)

{

   .vr[j]=1;

.如果pre[j]==-1或者matchpre[j]==1(pre[j]表示L中与Rj点的匹配点),则pre[j]=pos,返回真。

}

否则如果(val>0

{

如果val<slack[j],slack[j]=val;

}

                 ③返回假。

         ⑶.如果match返回真,break当前循环。

         ⑷定义变量d=MAX_INT,枚举R中每个点,如果vr[j]==0(没被访问过)并且slack[j]<val,则d赋值为slack[kj]

               ⑸枚举L中每个点和R中每个点,假设当前点为j,如果vl[j]=1,pl-=d;如果vr[j]==1,pr[j]+=d;

3.将匹配后每个匹配对的权值加起来。

 

      KM算法C++模板,模板的注释为上面所描述的步骤

最佳匹配题目

POJ2195 这里求的是最小匹配,模板的返回值要变成负的,代码

            

 

抱歉!评论已关闭.