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;
KM算法(可能是是网络上仅有正确的matlab版)
最新推荐文章于 2022-12-12 14:48:10 发布