⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 12345.m

📁 指派问题的匈牙利算法(matlab语言)
💻 M
字号:
clear
a=[61	53	47	56	52	44	53	55	55	41	44	59	47	47	53	52;
61	58	44	57	52	47	52	57	55	41	38	55	41	44	52	52;
61	58	44	57	52	47	52	57	55	41	38	55	41	44	52	52;
60	57	39	57	51	54	51	57	60	48	51	57	45	54	51	51;
60	57	39	57	51	54	51	57	60	48	51	57	45	54	51	51;
58	52	41	54	50	47	50	54	55	44	47	55	44	50	50	50;
58	52	41	54	50	47	50	54	55	44	47	55	44	50	50	50;
0 0 0 0 0 0  0  0   0   0   0    0   0   0  0    0;
0 0 0 0 0 0  0  0   0   0   0    0   0   0  0    0;
0 0 0 0 0 0  0  0   0   0   0    0   0   0  0    0;
0 0 0 0 0 0  0  0   0   0   0    0   0   0  0    0;
0 0 0 0 0 0  0  0   0   0   0    0   0   0  0    0;
0 0 0 0 0 0  0  0   0   0   0    0   0   0  0    0;
0 0 0 0 0 0  0  0   0   0   0    0   0   0  0    0;
0 0 0 0 0 0  0  0   0   0   0    0   0   0  0    0;
0 0 0 0 0 0  0  0   0   0   0    0   0   0  0    0];
a1=max(max(a'));
% 第一步
a=abs(a-a1);
b=a;    %b表示始矩
mina=min(a');
for row =1:16  %row表示行
     for col =1:16  %col表示列
          a(row,col)=a(row,col)-mina(row) ;         
     end
end
mina=min(a);
for col =1:16  %col表示列
     for row =1:16  %row表示行
          a(row,col)=a(row,col)-mina(row) ;         
     end
end
%初始化标矩阵
zerobznum=0;
for row=1:16
    for col =1:16
        if a(row,col)~=0 
            bz(row,col)=3;
        else
            bz(row,col)=0;
            zerobznum=zerobznum+1;
        end
    end 
end 
% 第2步:求最优解
while zerobznum>0
     for row =1:16  %row表示行
           zeronum=0; %zeronum表示每行0的个数
           zerocol=0;
           for col =1:16  %col表示列
                if a(row,col)==0
                     zeronum=zeronum+1;
                     zerocol=col;
                 end 
           end
           if zeronum==1
                 bz(row,zerocol)=1;
                 a(row,zerocol)=1;
                 zerobznum=zerobznum-1;
                 for rowbz=1:16
                      if a(rowbz,zerocol)==0 & rowbz~=row
                           bz(rowbz,zerocol)=-1;  %如果该列有0则划去
                           a(rowbz,zerocol)=-1;
                           zerobznum=zerobznum-1;
                      end 
                 end 
            end 
       end

       for col =1:16  %col表示列
            zeronum=0; %zeronum表示每列0的个数
            zerorow=0;
            for row =1:16  %row表示行
                  if a(row,col)==0 & bz(row,col)~=1
                        zeronum=zeronum+1;
                        zerorow=row;
                   end 
             end
             if zeronum==1
                  bz(zerorow,col)=1;
                   a(zerorow,col)=1;
                   zerobznum=zerobznum-1;
                   for colbz=1:16
                         if a(zerorow,colbz)==0 & colbz~=col & a(zerorow,colbz)~=1
                               bz(zerorow,colbz)=-1;  %如果该列有0则划去
                               a(zerorow,colbz)=-1;
                               zerobznum=zerobznum-1;
                         end 
                   end 
             end 
        end     
        
        %如果zerobznum>=0
        %求出0个数最少的行
        if zerobznum>0
            zerorownum1=zeros(1,16)
             for row=1:16   
                 zerorownum0=0;
                 for col=1:16
                     if a(row,col) ==0 
                        zerorownum0=zerorownum0+1;
                     end
                 end 
                 if zerorownum0>=2
                     zerorownum1(1,row)=zerorownum0;
                 end
             end             
             mi=99999;
             mr=0;
             for r=1:16
                   if zerorownum1(r)~=0  zerorownum1(r)<mi
                       mi=zerorownum1(r) ;
                        mr=r  ;%0最少的行
                   end 
             end
            zerocolnum1=zeros(1,16)
            for c=1:16
                 if a(mr,c)==0  
                     n=0  %该列0的个数
                     for  r=1 :16
                        if a(c,r)==0
                             n=n+1;
                        end
                    end
                    zerocolnum1(1,c)=n;
                 end 
             end
             
             mm=99999;
             mc=0;
             for i=1:16
                 if zerocolnum1(i)~=0  zerocolnum1(i)<mm
                        mm=zerorownum1(r) ;
                        mc=i  ;%0最少的行
                   end        
             end
             %把该行该列上的作标记
             bz(mr,mc)=1;
             a(mr,mc)=1;
             zerobznum=zerobznum-1;
             %划掉行
             for i=1:16
                 if a(mr,i)==0
                     bz(mr,i)=-1;
                     a(mr,i)=-1 ;
                     zerobznum=zerobznum-1;
                 end 
             end 
             %划掉列
             for i=1:16
                 if a(i,mc)==0
                     bz(i,mc)=-1;
                     a(i,mc)=-1 ;
                     zerobznum=zerobznum-1;
                 end 
             end 
            zerorownum1=zeros(1,16) ;
        end
end


%第三步
azeronum=0;
for row=1:16
    for col=1:16
        if bz(row,col)==1
            azeronum=azeronum+1;
        end 
    end
end
%如果0原索的个数等于系数矩阵的阶乘,本题为7那么帮助bz就是最优解
if azeronum==7
    bz
else
    %第三步的程序
    grow=zeros(1,16);
    gcol=zeros(1,16); 
    for row=1:16   
        growbz=0;
        for col=1:16
            if  bz(row,col)==1  
               growbz=growbz+1;
            end
        end  %  growbz=growbz+1;    
        if growbz~=1
            grow(1,row)=1   ;
            for icol=1:16                
                   if bz(row,icol) ==-1   
                       gcol(1,icol)=1  ;
                       for irow=1:16 
                           if bz(irow,icol)==1
                              grow(1,irow)=1;
                           end 
                      end
                   end 
            end
       end   
   end
end 

%第四步
%还员a
for row=1:16
    for col=1:16
        if a(row,col)==1 || a(row,col)==-1
            a(row,col)=0;
        end         
    end 
end

%找出没划线的最小直
min4=99999;
for row=1:16   %
    if grow(row)==1
         for col=1:16
            if gcol(col)==0 &  min4>a(row,col)
                    min4=a(row,col)  ;  
            end 
         end 
    end
end
%行减最小直
for row=1:16
    if grow(1,row)==1
         for col=1:16
            a(row,col)=a(row,col)-min4  ;  
        end 
    end 
end 
%列家最小直
for col=1:16
    if gcol(1,col)==1
         for row=1:16
            a(row,col)=a(row,col)+min4  ;  
        end 
    end 
end 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -