KM算法(可能是是网络上仅有正确的matlab版)

function result = KM()
 clear all;
 global n;
 global nx;
 global ny; 
 global lx;
 global ly;
 %global g;
 global  slack;
 global visx;
 global visy;
 global INF;
global g; 
global linker;
g=[ 3 5 5 4 1;
 2 2 0 2 2 ;	
 2 4 4 1 0	;
 0 1 1 0 0;	
 1 2 1 3 3];
 INF = 7000000000;
 n = 5;
  nx =n;
  ny = n;
%%%%%%%%%%%%%%%%%KM算法O(n3)
  %%%%%%%%%%进行初始化
 for i = 1:1:400
linker(i) = -1;
end

for i = 1: 1:10000
lx(i) = 0;
end
%lx[]=0;

for i = 1:1: 10000
ly(i) = 0;
end
for i = 1:1:nx
    
        lx(i) = -1 * inf;  
      %  for(int j = 1; j <= ny; j++)  
       for j = 1: ny
      if g(i,j) > lx(i) 
                lx(i) = g(i,j);  
      end
       end
end  
    for x =1 :1:nx
        %(int x = 1; x <= nx; x++)  
      for i =1 :ny 
            slack(i) = INF;  
      end
        while 1 
        
            for i =1 :1: 1000
            visx(i) = 0;
            end
             for i =1 :1: 1000
            visy(i) = 0;
             end
            %if(DFS(x)),break; 
           % disp(x);
            m = dfs1(x);
            if m
            break;     %%%%%%%%%%%%结束条件
            end
             d = INF;  
          for i =1:1 :ny              % dfs(x)失败了所以x一定在交错树中,y不在交错树中,第二类边
              if visy(i) == 0 && d > slack(i) 
                  d = slack(i)
              end
          end
            for i =1:1 :nx
                if visx(i)
                    lx(i) =lx(i) - d;
                end
            end
                for i =1 : ny
                    if visy(i)
                        ly(i) = ly(i) +d;
                    else slack(i) = slack(i) -d;
                    end
                end
        end
	end
         result = 0;  
		for i =1 :nx
			if linker(i) ~= -1  
				result =result +g(linker(i),i); 
			end
		end
   %%%%%%%%%%%%//修改顶标后,要把所有的slack值都减去delta
   %%%%%%%%%%%%这是因为lx[i] 减小了delta
   %%%%%%%%%%%%     //slack[j] = min(lx[i] + ly[j] -g[i][j]) --d不属于交错树--也需要减少delta,第二类边
   % fprintf('%d\n',result);

%%%%%%%%%%%%%%%%%%%%%%%%
function res = dfs1(x)
 
 global lx;
 global ly;
 global visx;
 global visy;
global g;
  global linker;
   global  slack;
   disp(x);
visx(x) = 1;
for y =1:1:5

 if visy(y)
  continue;
 end
  tmp = lx(x) + ly(y) - g(x,y);
  if tmp == 0   %(x,y)在相等子图中
   visy(y) = true;
   %back = linker(y) == -1 ;
  if linker(y) == -1
      back =1;
  else back = 0;
  end 
  % if linker(y) 
  if linker(y) > 0
   res = dfs1(linker(y));
  end
 %  end
   if back || res
   linker(y) = x;
   res = true;
   return 
   end
   
   else if slack(y) > tmp   %%%%%%%%%% (x,y)不在相等子图中且y不在交错树中
   slack(y) = tmp
   end
  end
end
   res = false;
  • 7
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 29
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值