匈牙利算法
2015-08-08 09:46
183 查看
首先,他是一个求二分图最大匹配的算法。
二分图
有两个独立的点集U,V,二分图的任意一个边的两个端点分别来自U和V;所谓最大匹配就是找到最大匹配的个数。
算法思想
:就是找可增广轨(若图中有一轨,其边交替地在对集 内外出现,则称此轨为 的交错轨,交错轨的起止顶点都未被许配时,此交错轨称为可增广轨);找到之后,把可增广轨上在 外的边纳入对集,把 内的边从对集中删除,则被许配的顶点数增加2,对集中的“对儿”增加一个。直到找不到可增广轨。
matlab代码
function [Matching,Cost] = Edmonds(a) Matching = zeros(size(a)); num_y = sum(~isinf(a),1); num_x = sum(~isinf(a),2); x_con = find(num_x~=0); y_con = find(num_y~=0); P_size = max(length(x_con),length(y_con)); P_cond = zeros(P_size); P_cond(1:length(x_con),1:length(y_con)) = a(x_con,y_con); if isempty(P_cond) Cost = 0; return end Edge = P_cond; Edge(P_cond~=Inf) = 0; cnum = min_line_cover(Edge); Pmax = max(max(P_cond(P_cond~=Inf))); P_size = length(P_cond)+cnum; P_cond = ones(P_size)*Pmax; P_cond(1:length(x_con),1:length(y_con)) = a(x_con,y_con); exit_flag = 1; stepnum = 1; while exit_flag switch stepnum case 1 [P_cond,stepnum] = step1(P_cond); case 2 [r_cov,c_cov,M,stepnum] = step2(P_cond); case 3 [c_cov,stepnum] = step3(M,P_size); case 4 [M,r_cov,c_cov,Z_r,Z_c,stepnum] = step4(P_cond,r_cov,c_cov,M); case 5 [M,r_cov,c_cov,stepnum] = step5(M,Z_r,Z_c,r_cov,c_cov); case 6 [P_cond,stepnum] = step6(P_cond,r_cov,c_cov); case 7 exit_flag = 0; end end Matching(x_con,y_con) = M(1:length(x_con),1:length(y_con)); Cost = sum(sum(a(Matching==1))); function [P_cond,stepnum] = step1(P_cond) P_size = length(P_cond); for ii = 1:P_size rmin = min(P_cond(ii,:)); P_cond(ii,:) = P_cond(ii,:)-rmin; end stepnum = 2; function [r_cov,c_cov,M,stepnum] = step2(P_cond) P_size = length(P_cond); r_cov = zeros(P_size,1); c_cov = zeros(P_size,1); M = zeros(P_size); for ii = 1:P_size for jj = 1:P_size if P_cond(ii,jj) == 0 && r_cov(ii) == 0 && c_cov(jj) == 0 M(ii,jj) = 1; r_cov(ii) = 1; c_cov(jj) = 1; end end end r_cov = zeros(P_size,1); % A vector that shows if a row is covered c_cov = zeros(P_size,1); % A vector that shows if a column is covered stepnum = 3; function [c_cov,stepnum] = step3(M,P_size) c_cov = sum(M,1); if sum(c_cov) == P_size stepnum = 7; else stepnum = 4; end function [M,r_cov,c_cov,Z_r,Z_c,stepnum] = step4(P_cond,r_cov,c_cov,M) P_size = length(P_cond); zflag = 1; while zflag row = 0; col = 0; exit_flag = 1; ii = 1; jj = 1; while exit_flag if P_cond(ii,jj) == 0 && r_cov(ii) == 0 && c_cov(jj) == 0 row = ii; col = jj; exit_flag = 0; end jj = jj + 1; if jj > P_size; jj = 1; ii = ii+1; end if ii > P_size; exit_flag = 0; end end if row == 0 stepnum = 6; zflag = 0; Z_r = 0; Z_c = 0; else M(row,col) = 2; if sum(find(M(row,:)==1)) ~= 0 r_cov(row) = 1; zcol = find(M(row,:)==1); c_cov(zcol) = 0; else stepnum = 5; zflag = 0; Z_r = row; Z_c = col; end end end function [M,r_cov,c_cov,stepnum] = step5(M,Z_r,Z_c,r_cov,c_cov) zflag = 1; ii = 1; while zflag rindex = find(M(:,Z_c(ii))==1); if rindex > 0 ii = ii+1; Z_r(ii,1) = rindex; Z_c(ii,1) = Z_c(ii-1); else zflag = 0; end if zflag == 1; cindex = find(M(Z_r(ii),:)==2); ii = ii+1; Z_r(ii,1) = Z_r(ii-1); Z_c(ii,1) = cindex; end end for ii = 1:length(Z_r) if M(Z_r(ii),Z_c(ii)) == 1 M(Z_r(ii),Z_c(ii)) = 0; else M(Z_r(ii),Z_c(ii)) = 1; end end r_cov = r_cov.*0; c_cov = c_cov.*0; M(M==2) = 0; stepnum = 3; function [P_cond,stepnum] = step6(P_cond,r_cov,c_cov) a = find(r_cov == 0); b = find(c_cov == 0); minval = min(min(P_cond(a,b))); P_cond(find(r_cov == 1),:) = P_cond(find(r_cov == 1),:) + minval; P_cond(:,find(c_cov == 0)) = P_cond(:,find(c_cov == 0)) - minval; stepnum = 4; function cnum = min_line_cover(Edge) [r_cov,c_cov,M,stepnum] = step2(Edge); [c_cov,stepnum] = step3(M,length(Edge)); [M,r_cov,c_cov,Z_r,Z_c,stepnum] = step4(Edge,r_cov,c_cov,M); cnum = length(Edge)-sum(r_cov)-sum(c_cov);
其中matching为匹配矩阵
cost为权值最小。
相关文章推荐
- 使用高德地图根据坐标点画出路线
- 常用STL总结
- 客户端跳转与服务器端跳转的区别以及路径
- 慕课网 Java 入门 第二季 学习笔记
- 南邮 OJ 1983 比赛成绩排序问题II
- 安装双系统后Ubuntu下不能访问windows下磁盘解决方案
- 架构师速成8.3-可用性之分布式
- POJ Fibonacci 3070【矩阵快速幂】
- 关于mysql自增id的获取和重置
- 函数返回值的情况
- HDU 1426 Sudoku Killer
- HDU 1394 Minimum Inversion Number(暴力/线段树)
- Android WebView坑摘要
- Jquery获取select,dropdownlist,checkbox下拉列表框的值
- Java集合类详解
- android使用service和activity获取屏幕尺寸的方法
- java之redis篇(spring-data-redis整合)
- JAVA 信号量
- 南邮 OJ 1982 参赛选手信息更新问题II
- Java项目生成帮助文档教程