34
Munkres Assignment Example Program Development

Munkres Assignment

  • Upload
    ova

  • View
    91

  • Download
    0

Embed Size (px)

DESCRIPTION

Munkres Assignment. Example Program Development. Introduction. - PowerPoint PPT Presentation

Citation preview

Page 1: Munkres Assignment

Munkres AssignmentExample Program Development

Page 2: Munkres Assignment

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.

Page 3: Munkres Assignment

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.

Page 4: Munkres Assignment

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.

Munkres' Assignment Algorithm modified for Rectangular Matrices

Page 5: Munkres Assignment

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.

Page 6: Munkres Assignment

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.

Page 7: Munkres Assignment

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; }}

Munkres' Assignment Main Loop

Page 8: Munkres Assignment

private void 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;}

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.

Page 9: Munkres Assignment

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);}

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.

Page 10: Munkres Assignment

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;}

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.

Page 11: Munkres Assignment

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; } } }}

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.

Page 12: Munkres Assignment

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; }}

Page 13: Munkres Assignment

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;}

Page 14: Munkres Assignment

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;}

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.

Page 15: Munkres Assignment

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;}

Page 16: Munkres Assignment

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;}

Page 17: Munkres Assignment

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];}

Page 18: Munkres Assignment

GUI Layout

picture Box

show Mask Matrixwith starred and primed

zeros highlighted

rich text Box

display Cost Matrix,Mask Matrix with Row and

Column Covers

controls

resetgenerate random and test matricesrunstep or no-step execution

Page 19: Munkres Assignment

blue box - a non-zero value in the cost matrixgreen circle - indicates location of a zero in the cost matrixred 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

load cost matrix as text file 2D array of integers separated by one or more spaces

generates test matrix random or i*j

not implemented

Page 20: Munkres Assignment

Minimum value in each row is subtracted from each value in its row.

Step 1

Example Execution of Munkres Assignment GUI

Page 21: Munkres Assignment

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.

Step 2

Page 22: Munkres Assignment

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.

Page 23: Munkres Assignment

Step 4

Page 24: Munkres Assignment

Step 3

Page 25: Munkres Assignment

Step 4

Page 26: Munkres Assignment

Step 6

Page 27: Munkres Assignment

Step 4

Page 28: Munkres Assignment

Step 6

Page 29: Munkres Assignment

Step 4

Page 30: Munkres Assignment

Step 6

Page 31: Munkres Assignment

Step 4

Page 32: Munkres Assignment

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.

Page 33: Munkres Assignment

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

The Augmenting Path

Page 34: Munkres Assignment

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.