Advertisement
LinKin

Hungarian Algorithm

Jun 25th, 2013
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.14 KB | None | 0 0
  1. /*
  2.  * Algorithm : Hungarian algorithm
  3.  *             Max Weighted Bi-partite Matching
  4.  * Complexity : O( N^3 )
  5.  * Note : 0 base indexing
  6.  */
  7.  
  8. #include<stdio.h>
  9. #include<string.h>
  10. #include<vector>
  11. #include<algorithm>
  12. using namespace std;
  13.  
  14. #define MAX 107          // Max number of vertices in one part
  15. #define INF 100000000    // Just infinity
  16.  
  17. long cost[MAX][MAX];      // cost matrix
  18. long N,max_match;         // N workers and N jobs
  19. long lx[MAX], ly[MAX];    // Labels of X and Y parts
  20. long xy[MAX];             // xy[x] - vertex that is matched with x,
  21. long yx[MAX];             // yx[y] - vertex that is matched with y
  22. bool S[MAX], T[MAX];     // Sets S and T in algorithm
  23. long slack[MAX];
  24. long slackx[MAX];         // slackx[y] such a vertex, that
  25.                          // l(slackx[y]) + l(y) - w(slackx[y],y) = slack[y]
  26. long Prev[MAX];           // Array for memorizing alternating paths
  27.  
  28. void Init_Labels(){
  29.     memset(lx, 0, sizeof(lx)); memset(ly, 0, sizeof(ly));
  30.     long x,y; for( x=0;x<N;x++ ) for( y=0;y<N;y++ ) lx[x] = max(lx[x], cost[x][y]);
  31. }
  32. void Update_Labels(){
  33.     long x, y, delta = INF;
  34.     for( y=0;y<N;y++ ) if(!T[y]) delta = min(delta, slack[y]);
  35.     for( x=0;x<N;x++ ) if(S[x]) lx[x] -= delta;
  36.     for( y=0;y<N;y++ ) if(T[y]) ly[y] += delta;
  37.     for( y=0;y<N;y++ ) if(!T[y]) slack[y] -= delta;
  38. }
  39. void Add_To_Tree(long x, long prevx) {
  40.     S[x] = true; Prev[x] = prevx;
  41.     long y;
  42.     for( y=0;y<N;y++ )
  43.         if (lx[x] + ly[y] - cost[x][y] < slack[y]){
  44.             slack[y] = lx[x] + ly[y] - cost[x][y]; slackx[y] = x;
  45.         }
  46. }
  47. void Augment(){
  48.     if (max_match == N) return;
  49.     long x, y, root; long q[MAX], wr = 0, rd = 0;
  50.     memset(S, false, sizeof(S)); memset(T, false, sizeof(T)); memset(Prev, -1, sizeof(Prev));
  51.     for( x=0;x<N;x++ ) if (xy[x] == -1){ q[wr++] = root = x; Prev[x] = -2; S[x] = true; break; }
  52.     for( y=0;y<N;y++ ){ slack[y] = lx[root] + ly[y] - cost[root][y]; slackx[y] = root; }
  53.     while( true ){
  54.         while (rd < wr){
  55.             x = q[rd++];
  56.             for( y=0;y<N;y++ ){
  57.                 if (cost[x][y] == lx[x] + ly[y] &&  !T[y]){
  58.                     if (yx[y] == -1) break;
  59.                     T[y] = true; q[wr++] = yx[y];
  60.                     Add_To_Tree(yx[y], x);
  61.                 }
  62.             } if (y < N) break;
  63.         } if (y < N) break;
  64.         Update_Labels();
  65.         wr = rd = 0;
  66.         for( y=0;y<N;y++ ){
  67.             if (!T[y] &&  slack[y] == 0){
  68.                 if (yx[y] == -1){ x = slackx[y]; break;
  69.                 } else{
  70.                     T[y] = true;
  71.                     if (!S[yx[y]]){
  72.                         q[wr++] = yx[y]; Add_To_Tree(yx[y], slackx[y]);
  73.                     }
  74.                 }
  75.             }
  76.         } if (y < N) break;
  77.     }
  78.     if (y < N){ max_match++;
  79.         for (long cx = x, cy = y, ty; cx != -2; cx = Prev[cx], cy = ty){
  80.             ty = xy[cx]; yx[cy] = cx; xy[cx] = cy;
  81.         } Augment();
  82.     }
  83. }
  84. long Hungarian(){
  85.     long x,ret = 0; max_match = 0;
  86.     memset(xy, -1, sizeof(xy)); memset(yx, -1, sizeof(yx));
  87.     Init_Labels(); Augment();
  88.     for( x=0;x<N;x++ ) ret += cost[x][xy[x]];
  89.     return ret;
  90. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement