Implementation of the Hungarian Method in C

This algorithm allows you to find the minimum weight matching of a bipartite graph. The graph can be of arbitrary size and connectedness. The edge weights are captured by a MxN weight matrix where an infinite(Inf) weight designates that that pair of vertices given by that position are not connected.

Code:

  1.     #include<stdio.h>
  2.     #include<conio.h>
  3.     #define max 20    
  4.    /*Author : Mohammad Usman
  5.        Date :06/10/09
  6.    */    
  7.     void main()
  8.     {
  9.         int tr,size,m,av,i,j,r,c,diff,l=0,rz[max],cz[max],rc[max],cc[max];
  10.         int a[max][max],t[max][max],s[max][max],minr[max],minc[max],ct[max][max],minnew;
  11.         int cross[max][max],alloccount=0,minrow,mincol;
  12.         int nrz[max],ncz[max],nrc[max],ncc[max],nl=0;
  13.         int fzr[max][max],fzc[max][max];
  14.         int fz[max][max],k,flag=0,alloc[max][max];
  15.         int ffz[max][max],fffz[max][max];
  16.         int cost[max][max],costm=0;
  17.         clrscr();
  18.         //inputting array
  19.         printf("Enter the size of matrix\n enter no of rows");
  20.         scanf("%d",&r);
  21.         printf("enter no of column");
  22.         scanf("%d",&c);
  23.         //inputting array
  24.         for(i=0;i<r;i++)
  25.         {
  26.             for(j=0;j<c;j++)
  27.             {       printf("Enter element a[%d][%d] - ",i,j);
  28.                 scanf("%d",&a[i][j]);
  29.             }
  30.         }
  31.         if(r!=c)
  32.         {
  33.             if(r>c)
  34.             {
  35.                 diff=r-c;
  36.                 while(diff!=0)
  37.                 {
  38.                     for(i=0;i<r;i++)
  39.                     {
  40.                         a[i][c]=0;
  41.                     }
  42.                     c++;diff--;
  43.                 }
  44.             }
  45.             if(r<c)
  46.             {
  47.                 diff=c-r;
  48.                 while(diff!=0)
  49.                 {
  50.                     for(i=0;i<c;i++)
  51.                     {
  52.                         a[r][i]=0;
  53.                     }
  54.                     r++;diff--;
  55.                 }
  56.             }
  57.         }
  58.         if(r==c)
  59.         {
  60.             size=r;
  61.         }
  62.         //displaying array
  63.         for(i=0;i<size;i++)
  64.         {
  65.             for(j=0;j<size;j++)
  66.             {
  67.                 printf(" %d ",a[i][j]);
  68.             }
  69.             printf("\n");
  70.         }
  71.         //making cost matrix
  72.         for(i=0;i<size;i++)
  73.         {
  74.             for(j=0;j<size;j++)
  75.             {
  76.                 cost[i][j]=a[i][j];
  77.             }
  78.         }
  79.         //initializing all matrices
  80.         for(i=0;i<size;i++)
  81.         {
  82.             rz[i]=cz[i]=rc[i]=cc[i]=0;
  83.             nrz[i]=ncz[i]=nrc[i]=ncc[i]=0;
  84.             for(j=0;j<size;j++)
  85.             {
  86.                 fzr[i][j]=fzc[i][j]=fz[i][j]=ffz[i][j]=fffz[i][j]=0;
  87.                 cross[i][j]=-1,alloc[i][j]=0;
  88.             }
  89.         }
  90.         //calculating min row
  91.         for(i=0;i<size;i++)
  92.         {
  93.             minr[i]=a[i][0];
  94.             for(j=0;j<size;j++)
  95.             {
  96.                 if(minr[i]>a[i][j])
  97.                 {
  98.                     minr[i]=a[i][j];
  99.                 }
  100.             }
  101.         }
  102.         //subtracting min row from respective row
  103.         for(i=0;i<size;i++)
  104.         {
  105.             for(j=0;j<size;j++)
  106.             {
  107.                 a[i][j]=a[i][j]-minr[i];
  108.             }
  109.         }
  110.         //calculating min column
  111.         for(i=0;i<size;i++)
  112.         {
  113.             minc[i]=a[0][i];
  114.             for(j=0;j<size;j++)
  115.             {
  116.                 if(minc[i]>a[j][i])
  117.                 {
  118.                     minc[i]=a[j][i];
  119.                 }
  120.             }
  121.         }
  122.         //subtracting min column from respective column
  123.         for(i=0;i<size;i++)
  124.         {
  125.             for(j=0;j<size;j++)
  126.             {
  127.                 a[j][i]=a[j][i]-minc[i];
  128.             }
  129.         }
  130.         //displaying reduced matrix
  131.         printf("\nreduced matrix\n");
  132.         for(i=0;i<size;i++)
  133.         {
  134.             for(j=0;j<size;j++)
  135.             {
  136.                 printf(" %d ",a[i][j]);
  137.      
  138.             }
  139.             printf("\n");
  140.         }
  141.         //copying reduced matrix
  142.         for(i=0;i<size;i++)
  143.         {
  144.             for(j=0;j<size;j++)
  145.             {
  146.                 t[i][j]=a[i][j];
  147.                 //t[i][j] is row column reduced matrix
  148.      
  149.             }
  150.         }
  151.         //calculating row zero i.e. no of zeros in row
  152.         for(i=0;i<size;i++)
  153.         {
  154.             for(j=0;j<size;j++)
  155.             {
  156.                 if(a[i][j]==0)
  157.                 {
  158.                     rz[i]=rz[i]+1;
  159.                 }
  160.             }
  161.         }
  162.         tr=size;
  163.         if(size%2>0)
  164.         {
  165.             av=(size+1)/2;
  166.         }
  167.         else
  168.         {
  169.             av=size/2;
  170.         }
  171.         while(tr>=av)
  172.         {
  173.             //striking lines in row
  174.             for(i=0;i<size;i++)
  175.             {
  176.                 if(rz[i]==tr)
  177.                 {
  178.                     for(j=0;j<size;j++)
  179.                     {
  180.                         a[i][j]=-1;
  181.                         cross[i][j]=cross[i][j]+1;
  182.                     }
  183.                 }
  184.             }
  185.             tr--;
  186.         }
  187.         //calculating colomn zero
  188.         for(j=0;j<size;j++)
  189.         {
  190.             for(i=0;i<size;i++)
  191.             {
  192.                 if(a[i][j]==0)
  193.                 {
  194.                     cz[j]=cz[j]+1;
  195.                 }
  196.             }
  197.         }
  198.         //striking lines in coloumn
  199.         for(j=0;j<size;j++)
  200.         {
  201.             if(cz[j]>=1)
  202.             {
  203.                 for(i=0;i<size;i++)
  204.                 {
  205.                     a[i][j]=-1;
  206.                     cross[i][j]=cross[i][j]+1;
  207.                 }
  208.             }
  209.         }
  210.         //calculating no of rows and columns crossed
  211.         for(i=0;i<size;i++)
  212.         {
  213.             for(j=0;j<size;j++)
  214.             {
  215.                    if(a[i][j]==-1)
  216.                    {
  217.                     rc[i]=rc[i]+1;
  218.                    }
  219.             }
  220.         }
  221.         for(i=0;i<size;i++)
  222.         {
  223.             for(j=0;j<size;j++)
  224.             {
  225.                    if(a[j][i]==-1)
  226.                    {
  227.                     cc[i]=cc[i]+1;
  228.                    }
  229.             }
  230.         }
  231.         for(i=0;i<size;i++)
  232.         {
  233.             if(rc[i]==size)
  234.             {
  235.                 l=l+1;
  236.             }
  237.         }
  238.         if(l!=size)
  239.         {
  240.         for(i=0;i<size;i++)
  241.         {
  242.             if(cc[i]==size)
  243.             {
  244.                 l=l+1;
  245.             }
  246.         }
  247.         }
  248.         //cross matrix
  249.         printf("cross matrix  \n");
  250.         for(i=0;i<size;i++)
  251.         {
  252.             for(j=0;j<size;j++)
  253.             {
  254.                 printf(" %d ",cross[i][j]);
  255.             }
  256.             printf("\n");
  257.         }
  258.         printf("\nno of lines striked = %d ",l);
  259.         if(l==size)
  260.         {
  261.             printf("we are done\n");
  262.             for(i=0;i<size;i++)
  263.             {
  264.                 for(j=0;j<size;j++)
  265.                 {
  266.                     if(t[i][j]==0)
  267.                     {
  268.                         nrz[i]=nrz[i]+1;//new row zero
  269.                     }
  270.                 }
  271.             }
  272.             minrow=nrz[0];
  273.             printf("nrz matrix\n");
  274.             for(i=0;i<size;i++)
  275.             {
  276.                 printf(" %d ",nrz[i]);
  277.                 if(minrow>nrz[i])
  278.                 {
  279.                     minrow=nrz[i];
  280.                 }
  281.                 //printf("min row =%d",minrow);
  282.             }
  283.             while(alloccount!=size)
  284.             {
  285.                 for(i=0;i<size;i++)
  286.                 {
  287.                     if(nrz[i]==minrow)
  288.                     {
  289.                         for(j=0;j<size;j++)
  290.                         {
  291.                             if(t[i][j]==0)
  292.                             {
  293.                                 alloc[i][j]=1;
  294.                                 alloccount=alloccount+1;
  295.                                 for(k=0;k<size;k++)
  296.                                 {
  297.                                     t[i][k]=-1;
  298.                                     t[k][j]=-1;
  299.                                 }
  300.                                 for(i=0;i<size;i++)
  301.                                 {
  302.                                     nrz[i]=0;
  303.                                 }
  304.                                 for(i=0;i<size;i++)
  305.                                 {
  306.                                     for(j=0;j<size;j++)
  307.                                     {
  308.                                         if(t[i][j]==0)
  309.                                         {
  310.                                             nrz[i]=nrz[i]+1;//new row zero
  311.                                         }
  312.                                     }
  313.                                 }
  314.                                 for(i=0;i<size;i++)
  315.                                 {
  316.                                     if(nrz[i]==0)
  317.                                     {
  318.                                         nrz[i]=100;
  319.                                     }
  320.                                 }
  321.                                 //minrow=nrz[0];
  322.                                 for(i=0;i<size;i++)
  323.                                 {
  324.                                     if(minrow>nrz[i])
  325.                                     {
  326.                                         minrow=nrz[i];
  327.                                     }
  328.                                 }
  329.      
  330.                             }
  331.                         }
  332.                     }
  333.      
  334.      
  335.                 }
  336.             }
  337.             for(i=0;i<size;i++)
  338.             {
  339.                 for(j=0;j<size;j++)
  340.                 {
  341.                     if(alloc[i][j]==1)
  342.                     {
  343.                           printf("\ntask %d is allocated to processor %d",i+1,j+1);
  344.                           costm=costm+cost[i][j];
  345.                     }
  346.                 }
  347.             }
  348.             if(l==size&&alloccount==size)
  349.             {
  350.                 printf("we have done it!");
  351.                 printf("cost = %d",costm);
  352.                 flag=1;
  353.             }
  354.      
  355.         }
  356.         if(l!=size&&flag==0)//if no of line striked is not equal to the size
  357.         {
  358.             for(i=0;i<size;i++)
  359.             {
  360.                 for(j=0;j<size;j++)
  361.                 {
  362.                     printf("%d",a[i][j]);
  363.                 }
  364.             }
  365.             for(i=0;i<size;i++)
  366.             {
  367.                 for(j=0;j<size;j++)
  368.                 {
  369.                     if(a[i][j]>0)
  370.                     {
  371.                         minnew=a[i][j];
  372.                     }
  373.                 }
  374.             }
  375.             //finding new min
  376.             for(i=0;i<size;i++)
  377.             {
  378.                 for(j=0;j<size;j++)
  379.                 {
  380.                     if(a[i][j]>0&&minnew>a[i][j])
  381.                     minnew=a[i][j];
  382.                 }
  383.             }
  384.             //subtracting new min from reduced
  385.             printf("\nmin new = %d\n",minnew);
  386.             for(i=0;i<size;i++)
  387.             {
  388.                 for(j=0;j<size;j++)
  389.                 {
  390.                     if(a[i][j]>0)          //mistake in this part
  391.                     a[i][j]=a[i][j]-minnew;
  392.                 }
  393.             }
  394.             //copying reduced part in original reduced
  395.             for(i=0;i<size;i++)
  396.             {
  397.                 for(j=0;j<size;j++)
  398.                 {
  399.                     if(a[i][j]>=0)
  400.                     t[i][j]=a[i][j];
  401.                 }
  402.             }
  403.             //adding min new to cross point
  404.             for(i=0;i<size;i++)
  405.             {
  406.                 for(j=0;j<size;j++)
  407.                 {
  408.                     if(cross[i][j]==1)
  409.                     {
  410.                         t[i][j]=t[i][j]+minnew;
  411.                     }
  412.                 }
  413.             }
  414.             //final reduced
  415.             printf("final reduced\n");
  416.             for(i=0;i<size;i++)
  417.             {
  418.                 for(j=0;j<size;j++)
  419.                 {
  420.                     printf(" %d ",t[i][j]);
  421.      
  422.                 }
  423.                 printf("\n");
  424.             }
  425.             for(i=0;i<size;i++)//saving final reduced
  426.             {
  427.                 for(j=0;j<size;j++)
  428.                 {
  429.                     s[i][j]=t[i][j];
  430.      
  431.                 }
  432.             }
  433.             for(i=0;i<size;i++)
  434.             {
  435.                 nrz[i]=0,ncz[i]=0;rz[i]=0,cz[i]=0;//resseting row zero
  436.                 for(j=0;j<size;j++)
  437.                 {
  438.                     cross[i][j]=-1;
  439.                 }
  440.             }
  441.             //calculating colomn zero
  442.             for(j=0;j<size;j++)
  443.             {
  444.                 for(i=0;i<size;i++)
  445.                 {
  446.                     if(a[i][j]==0)
  447.                     {
  448.                         cz[j]=cz[j]+1;
  449.                     }
  450.                 }
  451.             }
  452.             tr=size;
  453.             if(size%2>0)
  454.             {
  455.                 av=(size+1 )/2;
  456.             }
  457.             else
  458.             {
  459.                 av=size/2;
  460.             }
  461.             while(tr>=av)
  462.             {
  463.                 //striking lines in col
  464.                 for(j=0;j<size;j++)
  465.                 {
  466.                     if(cz[j]==tr)
  467.                     {
  468.                         for(i=0;i<size;i++)
  469.                         {
  470.                             a[i][j]=-1;
  471.                             cross[i][j]=cross[i][j]+1;
  472.                         }
  473.                     }
  474.                 }
  475.                 tr--;
  476.             }
  477.             //calculating row zero i.e. no of zeros in row
  478.             for(i=0;i<size;i++)
  479.             {
  480.                 for(j=0;j<size;j++)
  481.                 {
  482.                     if(a[i][j]==0)
  483.                     {
  484.                         rz[i]=rz[i]+1;
  485.                     }
  486.                 }
  487.             }
  488.      
  489.             //striking lines in row
  490.             for(i=0;i<size;i++)
  491.             {
  492.                 if(rz[j]>=1)
  493.                 {
  494.                     for(j=0;j<size;j++)
  495.                     {
  496.                         a[i][j]=-1;
  497.                         cross[i][j]=cross[i][j]+1;
  498.                     }
  499.                 }
  500.             }
  501.             //cros mat
  502.             printf("new cross");
  503.             for(i=0;i<size;i++)
  504.             {
  505.                 for(j=0;j<size;j++)
  506.                 {
  507.                     printf("%d",cross[i][j]);
  508.                 }
  509.                 printf("\n");
  510.             }
  511.             //calculating new row zero
  512.             for(i=0;i<size;i++)
  513.             {
  514.                 for(j=0;j<size;j++)
  515.                 {
  516.                     if(t[i][j]==0)
  517.                     {
  518.                         nrz[i]=nrz[i]+1;
  519.                     }
  520.                 }
  521.             }
  522.             for(i=0;i<size;i++)
  523.             {
  524.                 if(nrz[i]>=2)
  525.                 {
  526.                     for(j=0;j<size;j++)
  527.                     {
  528.                         t[i][j]=-1;
  529.                     }
  530.                 }
  531.             }
  532.             //restoring t[i][j]
  533.             for(i=0;i<size;i++)//saving final reduced
  534.             {
  535.                 for(j=0;j<size;j++)
  536.                 {
  537.                     t[i][j]=s[i][j];
  538.      
  539.                 }
  540.             }
  541.             //calculating new colomn zero
  542.             for(i=0;i<size;i++)
  543.             {
  544.                 for(j=0;j<size;j++)
  545.                 {
  546.                     if(t[j][i]==0)
  547.                     {
  548.                         ncz[j]=ncz[j]+1;
  549.                     }
  550.                 }
  551.             }
  552.             for(j=0;j<size;j++)
  553.             {
  554.                 if(ncz[j]>=1)
  555.                 {
  556.                     for(i=0;i<size;i++)
  557.                     {
  558.                         t[i][j]=-1;
  559.                     }
  560.                 }
  561.             }
  562.             //calculating no of rows and columns crossed in new matrix
  563.             for(i=0;i<size;i++)
  564.             {
  565.                 for(j=0;j<size;j++)
  566.                 {
  567.                        if(t[i][j]==-1)
  568.                        {
  569.                         nrc[i]=nrc[i]+1;
  570.                        }
  571.                 }
  572.             }
  573.             for(i=0;i<size;i++)
  574.             {
  575.                 for(j=0;j<size;j++)
  576.                 {
  577.                        if(t[j][i]==-1)
  578.                        {
  579.                         ncc[i]=ncc[i]+1;
  580.                        }
  581.                 }
  582.             }
  583.             //counting no of lines striked
  584.             for(i=0;i<size;i++)
  585.             {
  586.                 if(nrc[i]==size&&ncc[i]==size)
  587.                 {
  588.                     nl=nl+1;
  589.                 }
  590.      
  591.             }
  592.             printf("\nno of lines striked = %d",nl);
  593.             if(nl==size)
  594.             {
  595.                 printf("now we are done \n");
  596.             }
  597.      
  598.      
  599.             for(i=0;i<size;i++)
  600.             {
  601.                 for(j=0;j<size;j++)
  602.                 {
  603.                     if(t[i][j]==0)
  604.                     {
  605.                         nrz[i]=nrz[i]+1;//new row zero
  606.                     }
  607.                 }
  608.             }
  609.             minrow=nrz[0];
  610.             printf("nrz matrix\n");
  611.             for(i=0;i<size;i++)
  612.             {
  613.                 printf(" %d ",nrz[i]);
  614.                 if(minrow>nrz[i])
  615.                 {
  616.                     minrow=nrz[i];
  617.                 }
  618.             }
  619.             printf("minrow = %d",minrow);
  620.             alloccount=0;
  621.      
  622.      
  623.             while(alloccount!=size&&flag!=1)
  624.             {
  625.                 for(i=0;i<size;i++)
  626.                 {
  627.                     if(nrz[i]==minrow&&flag!=1)
  628.                     {
  629.                         for(j=0;j<size;j++)
  630.                         {
  631.                             if(t[i][j]==0)
  632.                             {
  633.                                 alloc[i][j]=1;
  634.                                 alloccount=alloccount+1;
  635.                                 for(k=0;k<size;k++)
  636.                                 {
  637.                                     t[i][k]=-1;
  638.                                     t[k][j]=-1;
  639.                                 }
  640.                             }
  641.                         }
  642.                         if(j==size)
  643.                         {
  644.                             flag=1;
  645.                             break;
  646.                         }
  647.      
  648.                     }
  649.                     /*else
  650.                     {
  651.                         for(p=0;p<size;p++)
  652.                         {
  653.                             for(q=0;q<size;q++)
  654.                             {
  655.                                 if(t[p][q]==0)
  656.                                 {
  657.                                     nrz[p]=nrz[p]+1;//new row zero
  658.                                 }
  659.                             }
  660.                         }
  661.                         minrow=nrz[0];
  662.                         for(i=0;i<size;i++)
  663.                         {
  664.                             if(minrow>nrz[i])
  665.                             {
  666.                                 minrow=nrz[i];
  667.                             }
  668.                         }
  669.                     }*/
  670.                 }
  671.             }
  672.             if(flag==1)//it means row allocation failed
  673.             {
  674.                 for(i=0;i<size;i++)
  675.                 {
  676.                     ncz[i]=0;
  677.                 }
  678.                 //restoring t[i][j]
  679.                 for(i=0;i<size;i++)//saving final reduced
  680.                 {
  681.                     for(j=0;j<size;j++)
  682.                     {
  683.                         t[i][j]=s[i][j];
  684.                     }
  685.                 }
  686.                 for(i=0;i<size;i++)
  687.                 {
  688.                     for(j=0;j<size;j++)
  689.                     {
  690.                         if(t[j][i]==0)
  691.                         {
  692.                             ncz[i]=ncz[i]+1;//new row zero
  693.                         }
  694.                     }
  695.                 }
  696.                 mincol=ncz[0];
  697.                 //printf("ncz matrix\n");
  698.                 for(i=0;i<size;i++)
  699.                 {
  700.                     //printf(" %d ",ncz[i]);
  701.                     if(mincol>ncz[i])
  702.                     {
  703.                         mincol=ncz[i];
  704.                     }
  705.                 }
  706.                 //printf("mincol = %d",mincol);
  707.                 alloccount=0;
  708.                 while(alloccount!=size)
  709.                 {
  710.                     for(i=0;i<size;i++)
  711.                     {
  712.                         if(ncz[i]==mincol)
  713.                         {
  714.                             for(j=0;j<size;j++)
  715.                             {
  716.                                 if(t[j][i]==0)
  717.                                 {
  718.                                     alloc[j][i]=1;
  719.                                     alloccount=alloccount+1;
  720.                                     for(k=0;k<size;k++)
  721.                                     {
  722.                                         t[j][k]=-1;
  723.                                         t[k][i]=-1;
  724.                                     }
  725.                                     for(i=0;i<size;i++)
  726.                                     {
  727.                                         ncz[i]=0;
  728.                                     }
  729.                                     for(i=0;i<size;i++)
  730.                                     {
  731.                                         for(j=0;j<size;j++)
  732.                                         {
  733.                                             if(t[j][i]==0)
  734.                                             {
  735.                                                 ncz[i]=ncz[i]+1;//new row zero
  736.                                             }
  737.                                         }
  738.                                     }
  739.                                     for(i=0;i<size;i++)
  740.                                     {
  741.                                         if(ncz[i]==0)
  742.                                         {
  743.                                             ncz[i]=100;
  744.                                         }
  745.                                     }
  746.                                     mincol=ncz[0];
  747.                                     //printf("ncz matrix\n");
  748.                                     for(i=0;i<size;i++)
  749.                                     {
  750.                                         //printf(" %d ",ncz[i]);
  751.                                         if(mincol>ncz[i])
  752.                                         {
  753.                                             mincol=ncz[i];
  754.                                         }
  755.                                     }
  756.                                     //printf("mincol = %d",mincol);
  757.                                 }
  758.                             }
  759.                         }
  760.                     }
  761.                 }
  762.                 }
  763.                 for(i=0;i<size;i++)
  764.                 {
  765.                     for(j=0;j<size;j++)
  766.                     {
  767.                         if(alloc[i][j]==1)
  768.                         {
  769.                               printf("\ntask %d is allocated to processor %d",i+1,j+1);
  770.                               costm=costm+cost[i][j];
  771.                         }
  772.                     }
  773.                 }
  774.             }
  775.             if(alloccount==size)
  776.             {
  777.                 printf("we have done it!");
  778.                 printf("cost = %d",costm);
  779.             }
  780.      
  781. getch();
  782. }

3 comments:

  1. assalamu'alaikum...
    firstly, i say thank ypu so much for this article about C++ code for hungarian method for minimum weight. Can you help me for the maximum weight?
    I hope you can help me..
    thank you

    ReplyDelete
  2. @Anonymous Sure I will help you! :-)

    ReplyDelete
  3. can u explain logic of your striking row code, why it is different from striking column ??

    ReplyDelete

Comment On Facebook