回 帖 发 新 帖 刷新版面

主题:帮帮忙啊,匈牙利算法的matlab实现

function [result,msum]=sbppp(cost,m)
if nargin==1
    dd=cost;
else
    dd=max(max(cost))-cost;
end
[nop,nop]=size(cost);msum=0;
for i=1:nop
    dd(i,:)=dd(i,:)-min(dd(i,:));
end
for j=1:nop
    dd(:,j)=dd(:,j)-min(dd(:,j));
end
backup=dd;
for z=1:nop
    bh=nop;bl=nop;result=[];
    for k=1:nop
        for i=1:nop
            h=find(dd(i,:)==0);
            if length(h)~=0&length(h)<bh
                bh=length(h);
                ch=i;
            end
        end
        L=find(dd(ch,:)==0);
        for j=1:length(L)
            l=find(dd(:,L(j))==0);
            if length(l)<bl
                bl=length(l);
                cl=L(j);
            end
        end
        result(1,k)=ch;result(2,k)=cl;
        dd(ch,:)=1;dd(:,cl)=1;
        bl=nop;bh=nop;
        if length(find(dd==0))==0
            break
        end
    end
    if length(result(1,:))==nop
        break
    end
    dd=backup;DD=dd;d=zeros(nop);
    for i=1:length(result(1,:))
        d(result(1,i),result(2,i))=1;
    end
    D=~(d+dd);
    p=[];q=[];k=1;zx=inf;
    for i=1:nop
        if sum(d(i,:))==0
            p(k)=i;
            k=k+1;
        end
    end
    for j=1:length(p)
        q=find(D(p(j),:)==1);
        for e=1:length(q)
            pp=find(d(:,q(e))==1);
            if pp~=0
                p(k)=pp;
                k=k+1;
            end
         end
     end
     for l=1:length(p)
         q=find(D(p(l),:)==1);
         for u=1:length(q)
             DD(:,q(u))=inf;
         end
     end
     for l=1:length(p)
         if min(DD(p(l),:))<zx
                 zx=min(DD(p(l),:));
         end
     end
     for l=1:length(p)
         q=find(D(p(l),:)==1);
         for u=1:length(q)
             dd(:,q(u))=dd(:,q(u))+zx;
         end
     end
     for l=1:length(p)
         dd(p(l),:)=dd(p(l),:)-zx;
     end
     backup=dd;
end
  for i=1:length(result(1,:))
     msum=msum+cost(result(1,i),result(2,i));
end
这是我找到的匈牙利算法的matlab程序,可我不知道怎么在matlab中实现。请各位大虾帮帮忙啊,帮我看看到底咋实现。谢谢了。

回复列表 (共4个回复)

沙发


运行到42行时,我觉得后面的没有必要了嘛。如果直接给出一个可以完美匹配的矩阵的话,前面的代码就能直接得出一个完美匹配了。谁能告诉我后面的有什么用?给我一个具体矩阵让我试试啊?

板凳


到这个网站看有人的算法没有
算法源码吧  [url=http://www.sfcode.cn/]http://www.sfcode.cn/[/url]

3 楼


楼主,你找到的程序有注释没有?有的话将注释也发上来.

4 楼

程序文件   fenpei.m
function [z,ans]=fenpei(marix)

%//////////////////////////////////////////////////
            %输入效率矩阵 marix 为方阵;
            %若效率矩阵中有 M,则用一充分大的数代替;
            %输出z为最优解,ans为 最优分配矩阵;
%//////////////////////////////////////////////////
a=marix;
b=a;
%确定矩阵维数
s=length(a);
%确定矩阵行最小值,进行行减
ml=min(a');
for i=1:s
    a(i,:)=a(i,:)-ml(i);
end
%确定矩阵列最小值,进行列减
mr=min(a);
for j=1:s
    a(:,j)=a(:,j)-mr(j);
end
% start working
num=0;
while(num~=s)  %终止条件是“(0)”的个数与矩阵的维数相同
    %index用以标记矩阵中的零元素,若a(i,j)=0,则index(i,j)=1,否则index(i,j)=0
    index=ones(s);
    index=a&index;
    index=~index;
    %flag用以标记划线位,flag=0 表示未被划线,
    %flag=1 表示有划线过,flag=2 表示为两直线交点
    %ans用以记录 a 中“(0)”的位置
    %循环后重新初始化flag,ans
    flag = zeros(s);
    ans = zeros(s);
    %一次循环划线全过程,终止条件是所有的零元素均被直线覆盖,
    %即在flag>0位,index=0
    while(sum(sum(index)))
        %按行找出“(0)”所在位置,并对“(0)”所在列划线,
        %即设置flag,同时修改index,将结果填入ans
        for i=1:s
            t=0;
            l=0;
            for j=1:s
                if(flag(i,j)==0&&index(i,j)==1)
                    l=l+1;
                    t=j;
                end
            end
            if(l==1)
                flag(:,t)=flag(:,t)+1;
                index(:,t)=0;
                ans(i,t)=1;
            end
        end
        %按列找出“(0)”所在位置,并对“(0)”所在行划线,
        %即设置flag,同时修改index,将结果填入ans
        for j=1:s
            t=0;
            r=0;
            for i=1:s
                if(flag(i,j)==0&&index(i,j)==1)
                    r=r+1;
                    t=i;
                end
            end
            if(r==1)
                flag(t,:)=flag(t,:)+1;
                index(t,:)=0;
                ans(t,j)=1;
            end
        end
    end  %对 while(sum(sum(index)))
    %处理过程
    %计数器:计算ans中1的个数,用num表示
    num=sum(sum(ans));
    % 判断是否可以终止,若可以则跳出循环
    if(s==num)
        break;
    end
    %否则,进行下一步处理
    %确定未被划线的最小元素,用m表示
    m=max(max(a));
    for i=1:s
        for j=1:s
            if(flag(i,j)==0)
                if(a(i,j)<m)
                    m=a(i,j);
                end
            end
        end
    end
    %未被划线,即flag=0处减去m;线交点,即flag=2处加上m
    for i=1:s
        for j=1:s
            if(flag(i,j)==0)
                a(i,j)=a(i,j)-m;
            end
            if(flag(i,j)==2)
                   a(i,j)=a(i,j)+m;
            end
       end
   end
end  %对while(num~=s) 
%计算最优(min)值
zm=ans.*b;
z=0;
z=sum(sum(zm));
这是我在网上搜到的不知道对你有没有用

我来回复

您尚未登录,请登录后再回复。点此登录或注册