1 / 34

Munkres Assignment

Munkres Assignment. Example Program Development. Introduction.

ova
Télécharger la présentation

Munkres Assignment

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Munkres Assignment Example Program Development

  2. Introduction The example problem shown below is called the Assignment Problem.  In this problem you are to find a minimal cost assignment of jobs to workers.  We will use this example to illustate (in detail) the method of algorithm implementation. Let C be an nxn matrix representing the costs of each of n workers to perform any of n jobs.  The assignment problem is to assign jobs to workers so as to minimize the total cost. Since each worker can perform only one job and each job can be assigned to only one worker the assignments constitute an independent set of the matrix C. An arbitrary assignment is shown above in which worker a is assigned job q, worker b is assigned job s and so on.  The total cost of this assignment is 23.  Can you find a lower cost assignment? Can you find the minimal cost assignment? Remember that each assignment must be unique in its row and column.

  3. A brute-force algorithm for solving the assignment problem involves generating all independent sets of the matrix C, computing the total costs of each assignment and a search of all assignment to find a minimal-sum independent set. The complexity of this method is driven by the number of independent assignments possible in an nxn matrix. There are n choices for the first assignment, n-1 choices for the second assignment and so on, giving n! possible assignment sets. Therefore, this approach has, at least, an exponential runtime complexity. As each assignment is chosen that row and column are eliminated from consideration.  The question is raised as to whether there is a better algorithm.  In fact there exists a polynomial runtime complexity algorithm for solving the assignment problem developed by James Munkre's in the late 1950's despite the fact that some references still describe this as a problem of exponential complexity.

  4. Munkres' Assignment Algorithmmodified for Rectangular Matrices Munkres' Assignment Algorithm is a 6-step process is a modified form of the original Munkres' Assignment Algorithm (sometimes referred to as the Hungarian Algorithm).  This algorithm describes to the manual manipulation of a two-dimensional matrix by starring and priming zeros and by covering and uncovering rows and columns.  This is because, at the time of publication (1957), few people had access to a computer and the algorithm was implemented by hand.

  5. Step 1:  For each row of the matrix, find the smallest element and subtract it from every element in its row.  Go to Step 2. Step 2:  Find a zero (Z) in the resulting matrix.  If there is no starred zero in its row or column, star Z. Repeat for each element in the matrix. Go to Step 3. Step 3:  Cover each column containing a starred zero.  If K columns are covered, the starred zeros describe a complete set of unique assignments.  In this case, Go to DONE, otherwise, Go to Step 4. Step 4:  Find a noncovered zero and prime it.  If there is no starred zero in the row containing this primed zero, Go to Step 5.  Otherwise, cover this row and uncover the column containing the starred zero. Continue in this manner until there are no uncovered zeros left. Save the smallest uncovered value and Go to Step 6. Step 5:  Construct a series of alternating primed and starred zeros as follows.  Let Z0 represent the uncovered primed zero found in Step 4.  Let Z1 denote the starred zero in the column of Z0 (if any). Let Z2 denote the primed zero in the row of Z1 (there will always be one).  Continue until the series terminates at a primed zero that has no starred zero in its column.  Unstar each starred zero of the series, star each primed zero of the series, erase all primes and uncover every line in the matrix.  Return to Step 3. Step 6:  Add the value found in Step 4 to every element of each covered row, and subtract it from every element of each uncovered column.  Return to Step 4 without altering any stars, primes, or covered lines.

  6. Some of the step-wise descriptions require careful interpretation.  In Step 4, for example, the possible situations are, that there is a noncovered zero which get primed and if there is no starred zero in its row the program goes onto Step 5.  The other possible way out of Step 4 is that there are no noncovered zeros at all, in which case the program goes to Step 6. This step can cause notable confusion for the programmer, which can best be aleviated through the use of graphical representations of the states of the Cost and Mask matrices. In the following we will walk through the process of implementation of Munkres' Algorithm in Visual Studio.NET and C#. We will make each step of the algorithm a separate method that returns the next step number. These methods will be accessed in a switch statement using the current step number as to select the next method to call.

  7. Munkres' Assignment Main Loop while (!done) { switch (step) { case 1: step_one(ref step); break; case 2: step_two(ref step); break; case 3: step_three(ref step); break; case 4: step_four(ref step); break; case 5: step_five(ref step); break; case 6: step_six(ref step); break; case 7: done = true; break; }}

  8. Step 1:  For each row of the matrix, find the smallest element and subtract it from every element in its row.  Go to Step 2. privatevoid step_one(ref int step) { int min_in_row; for (int r = 0; r < nrow; r++) { min_in_row = C[r, 0]; for (int c = 0; c < ncol; c++) if (C[r, c] < min_in_row) min_in_row = C[r, c]; for (int c = 0; c < ncol; c++) C[r, c] -= min_in_row; } step = 2; }

  9. Step 2:  Find a zero (Z) in the resulting matrix.  If there is no starred zero in its row or column, star Z. Repeat for each element in the matrix. Go to Step 3. private void step_two(ref int step) { for(int r=0;r<nrow;r++) for (int c = 0; c < ncol; c++) { if (C[r, c] == 0 && RowCover[r] == 0 && ColCover[c] == 0) { M[r, c] = 1; RowCover[r] = 1; ColCover[c] = 1; } } for (int r = 0; r < nrow; r++) RowCover[r] = 0; for (int c = 0; c < ncol; c++) ColCover[c] = 0; step = 3; txtStepNum.Text = Convert.ToString(step); }

  10. Step 3:  Cover each column containing a starred zero.  If K columns are covered, the starred zeros describe a complete set of unique assignments.  In this case, Go to DONE, otherwise, Go to Step 4. private void step_three(ref int step) { int colcount; for (int r = 0; r < nrow; r++) for (int c = 0; c < ncol; c++) if (M[r, c] == 1) ColCover[c] = 1; colcount = 0; for (int c = 0; c < ncol; c++) if (ColCover[c] == 1) colcount += 1; if (colcount == asgn) step = 7; else step = 4; }

  11. Step 4:  Find a noncovered zero and prime it.  If there is no starred zero in the row containing this primed zero, Go to Step 5.  Otherwise, cover this row and uncover the column containing the starred zero. Continue in this manner until there are no uncovered zeros left. Save the smallest uncovered value and Go to Step 6. private void step_four(ref int step) { int row = -1; int col = -1; bool done; done = false; while (!done) { find_a_zero(ref row, ref col); if (row == -1) { done = true; step = 6; } else { M[row, col] = 2; if (star_in_row(row)) { find_star_in_row(row, ref col); RowCover[row] = 1; ColCover[col] = 0; } else { done = true; step = 5; path_row_0 = row; path_col_0 = col; } } } }

  12. private void find_a_zero(ref int row, ref int col) { int r = 0; int c; bool done; row = -1; col = -1; done = false; while(!done) { c = 0; while (true) { if (C[r, c] == 0 && RowCover[r] == 0 && ColCover[c] == 0) { row = r; col = c; done = true; } c += 1; if (c >= ncol || done) break; } r += 1; if (r >= nrow) done = true; } }

  13. private bool star_in_row(int row) { bool tmp = false; for(int c=0;c<ncol;c++) if(M[row,c]==1) tmp = true; return tmp; } private void find_star_in_row(int row, ref int col) { col = -1; for(int c=0;c<ncol;c++) if(M[row,c]==1) col=c; }

  14. Step 5:  Construct a series of alternating primed and starred zeros as follows.  Let Z0 represent the uncovered primed zero found in Step 4.  Let Z1 denote the starred zero in the column of Z0 (if any). Let Z2 denote the primed zero in the row of Z1 (there will always be one).  Continue until the series terminates at a primed zero that has no starred zero in its column.  Unstar each starred zero of the series, star each primed zero of the series, erase all primes and uncover every line in the matrix.  Return to Step 3. private void step_five(ref int step) { bool done; int r = -1; int c = -1; path_count = 1; path[path_count-1, 0] = path_row_0; path[path_count-1, 1] = path_col_0; done = false; while (!done) { find_star_in_col(path[path_count-1, 1], ref r); if (r > -1) { path_count += 1; path[path_count-1, 0] = r; path[path_count-1, 1] = path[path_count - 2, 1]; } else done = true; if (!done) { find_prime_in_row(path[path_count-1, 0], ref c); path_count += 1; path[path_count-1, 0] = path[path_count - 2, 0]; path[path_count-1, 1] = c; } } augment_path(); clear_covers(); erase_primes(); step = 3; }

  15. private void find_star_in_col(int c, ref int r) { r = -1; for (int i = 0; i < nrow; i++) if (M[i, c] == 1) r = i; } private void find_prime_in_row(int r, ref int c) { for (int j = 0; j < ncol; j++) if (M[r, j] == 2) c = j; } private void augment_path() { for(int p=0;p<path_count;p++) if(M[path[p,0],path[p,1]]==1) M[path[p,0],path[p,1]]=0; else M[path[p,0],path[p,1]]=1; }

  16. private void clear_covers() { for (int r = 0; r < nrow; r++) RowCover[r] = 0; for (int c = 0; c < ncol; c++) ColCover[c] = 0; } private void erase_primes() { for (int r = 0; r < nrow; r++) for (int c = 0; c < ncol; c++) if (M[r, c] == 2) M[r, c] = 0; }

  17. Step 6:  Add the value found in Step 4 to every element of each covered row, and subtract it from every element of each uncovered column.  Return to Step 4 without altering any stars, primes, or covered lines. private void step_six(ref int step) { int minval = int.MaxValue; find_smallest(ref minval); for(int r=0;r<nrow;r++) for (int c = 0; c < ncol; c++) { if (RowCover[r] == 1) C[r, c] += minval; if(ColCover[c]==0) C[r,c] -= minval; } step = 4; } private void find_smallest(ref int minval) { for (int r = 0; r < nrow; r++) for (int c = 0; c < ncol; c++) if (RowCover[r] == 0 && ColCover[c] == 0) if (minval > C[r, c]) minval = C[r, c]; }

  18. GUI Layout picture Box show Mask Matrix with starred and primed zeros highlighted rich text Box display Cost Matrix, Mask Matrix with Row and Column Covers controls reset generate random and test matrices run step or no-step execution

  19. blue box - a non-zero value in the cost matrix green circle - indicates location of a zero in the cost matrix red box - starred zero (assignment) yellow box - primed zero (candidate assignment) yellow line - augmenting path toggles graphics display on and off toggles step-by-step execution on and off when stepping, press Run to execute next step generates test matrix random or i*j load cost matrix as text file 2D array of integers separated by one or more spaces not implemented

  20. Example Execution of Munkres Assignment GUI Step 1 Minimum value in each row is subtracted from each value in its row.

  21. Step 2 Find a zero (Z) in the resulting matrix.  If there is no starred zero in its row or column, star Z. Repeat for each element in the matrix.

  22. Step 6 Add the value found in Step 4 to every element of each covered row, and subtract it from every element of each uncovered column.  Return to Step 4 without altering any stars, primes, or covered lines.

  23. Step 4

  24. Step 3

  25. Step 4

  26. Step 6

  27. Step 4

  28. Step 6

  29. Step 4

  30. Step 6

  31. Step 4

  32. Step 5 Augmenting path begins and ends with a primed zero, alternating between primed and starred zeros. Once the augmenting path is found the starred zeros are unstarred and the primed zeros are starred.

  33. The Augmenting Path The Augmenting Path can be up to 2n-1 elements in length.

  34. Summary Munkres' Assignment Algorithm was published in 1957 in the Journal of the Society of Industrial and Applied Mathematics (SIAM). Some source still refer to the general solution of the Assignment Problem as an NP-Complete problem. However, Munkres' Assignment has worst-case order of complexity of O(n3). The extension of Munkre's Assignment to rectangular matrixces was introduced in 1967. The assignment algorithm can be used in a wide variety of applications including pattern matching.

More Related