《匹配算法MATLAB.docx》由会员分享,可在线阅读,更多相关《匹配算法MATLAB.docx(7页珍藏版)》请在三一办公上搜索。
1、匹配算法MATLAB求二部图G 的最大匹配的算法(匈牙利算法), 其基本思想是:从G 的任意匹配M 开始, 对X 中所有M 的非饱和点, 寻找M -增广路. 若不存在M -增广路, 则M 为最大匹配; 若存 在M -增广路P, 则将P 中M 与非M 的边互换得到比M 多一边的匹配M1 , 再对M1 重复上 述过程. 设 G = ( X, Y, E )为二部图, 其中X = x1, x2, , xn , Y = y1, y2, , yn. 任取G 的一初 始匹配M (如任取eE, 则M = e是一个匹配). 令 S = f , T = f , 转向. 若 M 饱和X S 的所有点, 则M 是二部
2、图G 的最大匹配. 否则, 任取M 的非饱和点 uX S , 令S = S u , 转向. 记 N (S ) = v | uS, uvE . 若N (S ) = T, 转向. 否则取yN (S ) T. 若y 是M 的饱和点, 转向, 否则转向. 设 x yM, 则令S = S x , T = T y , 转向. u - y 路是M-增广路, 设为P, 并令M = MP, 转向. 这里MP = MP M P, 是对称差. 由于计算 M-增广路P 比较麻烦, 因此将迭代步骤改为: 将 X 中M 的所有非饱和点(不是M 中某条边的端点)都给以标号0 和标记*, 转向. 若 X 中所有有标号的点都已
3、去掉了标记*, 则M 是G 的最大匹配. 否则任取X 中一 个既有标号又有标记*的点xi , 去掉xi 的标记*, 转向. 找出在 G 中所有与xi 邻接的点yj (即xi yjE ), 若所有这样的yj 都已有标号, 则转向 , 否则转向. 对与 xi 邻接且尚未给标号的yj 都给定标号i. 若所有的yj 都是M的饱和点, 则转向, 否则逆向返回. 即由其中M的任一个非饱和点yj的标号i 找到xi, 再由xi的标号k 找到yk , , 最后由 yt 的标号s 找到标号为0 的xs 时结束, 获得M -增广路xs yt xi yj, 记P = xs yt, , xi yj , 重新记M 为MP
4、, 转向. 将 yj在M 中与之邻接的点xk (即xk yjM), 给以标号j 和标记*, 转向. 例1 求图 6-9 中所示的二部图G 的最大匹配. 匈牙利算法的 MATLAB 程序代码如下: m=5;n=5;A=0 1 1 0 0 1 1 0 1 1 0 1 1 0 0 0 1 1 0 0 0 0 0 1 1; M(m,n)=0; for(i=1:m)for(j=1:n)if(A(i,j)M(i,j)=1;break;end;end %求初始匹配M if(M(i,j)break;end;end %获得仅含一条边的初始匹配M while(1) for(i=1:m)x(i)=0;end %将记
5、录X中点的标号和标记* for(i=1:n)y(i)=0;end %将记录Y中点的标号和标记* for(i=1:m)pd=1; %寻找X中M的所有非饱和点 for(j=1:n)if(M(i,j)pd=0;end;end if(pd)x(i)=-n-1;end;end %将X中M的所有非饱和点都给以标号0 和标记*, 程序中用n+1 表 示0 标号, 标号为负数时表示标记* pd=0; while(1)xi=0; for(i=1:m)if(x(i)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
6、;end %将yj 在M中与之邻接的 点xk (即xkyjM), 给以标号j 和标记* if(pdd)break;end;end if(pdd)k=1;j=yy(j); %yj 不是M的饱和点 while(1)P(k,2)=j;P(k,1)=y(j);j=abs(x(y(j); %任取M的一个非饱和点yj, 逆向返回 if(j=n+1)break;end %找到X中标号为0 的点时结束, 获得M-增广路P k=k+1;end for(i=1:k)if(M(P(i,1),P(i,2)M(P(i,1),P(i,2)=0; %将匹配M 在增广路P 中出现的边 去掉 else M(P(i,1),P(i
7、,2)=1;end;end %将增广路P 中没有在匹配M中出现的边加入 到匹配M中 break;end;end;end if(pd)break;end;end %假如X中所有有标号的点都已去掉了标记*, 算法终止 M %显示最大匹配M, 程序结束 图 6-9 利用可行点标记求最佳匹配的算法步骤如下: 设 G = ( X, Y, E , F )为完备的二部赋权图, L 是其一个初始可行点标记, 通常取 L(x)=maxF(xy)|yY,xXM是GL的一个匹配 L(y)=0,yY 若X 的每个点都是M 的饱和点, 则M 是最佳匹配. 否则取 M 的非饱和点uX, 令S = u , T = f ,
8、转向. 记NL (S ) = v | uS, uvEL . 若NL ( S ) = T , 则GL没有完美匹配, 转向. 否则转 向. 调整可行点标记, 计算 aL = min L ( x ) + L ( y ) - F (x y) | xS, yY T . 由此得新的可行顶点标记 L(n)-aL,nS,L(v)+aL,vT, L(v),否则 令 L = H, GL= GH , 重新给出GL 的一个匹配M, 转向. 取 yNL ( S ) T , 若y 是M 的饱和点, 转向. 否则, 转向. 设 x yM, 则令S = S x , T =T y , 转向. 在 GL 中的u - y 路是M
9、-增广路, 记为P, 并令M = MP, 转向. 利用可行点标记求最佳匹配算法的 MATLAB 程序代码如下: n=4;A=4 5 5 1 2 2 4 6 4 2 3 3 5 0 2 1; for(i=1:n)L(i,1)=0;L(i,2)=0;end for(i=1:n)for(j=1:n)if(L(i,1)L(S(i),1)+L(j,2)-A(S(i),j)al=L(S(i),1)+L(j,2)-A(S(i),j);end;end;end for(i=1:jss)L(S(i),1)=L(S(i),1)-al;end %调整可行点标记 for(j=1:jst)L(T(j),2)=L(T(j)
10、,2)+al;end %调整可行点标记 for(i=1:n)for(j=1:n) %生成子图GL if(L(i,1)+L(j,2)=A(i,j)Gl(i,j)=1; else Gl(i,j)=0;end M(i,j)=0;k=0;end;end ii=0;jj=0; for(i=1:n)for(j=1:n)if(Gl(i,j)ii=i;jj=j;break;end;end if(ii)break;end;end %获得仅含Gl 的一条边的初始匹配M M(ii,jj)=1;break else %NL(S)T for(j=1:jsn)pd=1; %取yNL(S)T for(k=1:jst)if(
11、T(k)=NlS(j)pd=0;break;end;end if(pd)jj=j;break;end;end pd=0; %判断y 是否为M的饱和点 for(i=1:n)if(M(i,NlS(jj)pd=1;ii=i;break;end;end if(pd)jss=jss+1;S(jss)=ii;jst=jst+1;T(jst)=NlS(jj); %S=Sx, T=Ty else %获得Gl 的一条M-增广路, 调整匹配M for(k=1:jst)M(S(k),T(k)=1;M(S(k+1),T(k)=0;end if(jst=0)k=0;end M(S(k+1),NlS(jj)=1;break;end;end;end;end MaxZjpp=0; for(i=1:n)for(j=1:n)if(M(i,j)MaxZjpp=MaxZjpp+A(i,j);end;end;end M %显示最佳匹配M MaxZjpp %显示最佳匹配M的权, 程序结束