Hungarian Algorithm: How to cover 0 elements with minimum lines?

前端 未结 2 1204
清歌不尽
清歌不尽 2020-12-31 06:46

I am trying to implement the Hungarian algorithm in Java. I have an NxN cost matrix. I am following this guide step by step. So I have the costMatrix[N][N] and 2 arrays to t

2条回答
  •  情深已故
    2020-12-31 06:51

    I know this question has been solved long time ago, but I would like to share my implementation for the step 3 where minimum lines should be drawn in a way that all zeros are covered.

    Here's a brief explanation on how my algorithm for this step works:

    • Loop on all cells, the cell that has a value zero, we need to draw a line passing by it, and its neighbours
    • To know in which direction the line should be drawn, I created a method called maxVH() that will count the zeros vertically vs horizontally, and returns an integer. If the integer is positive, draw a vertical line, else if zero or negative, draw a horizontal line.
    • colorNeighbors() method will draw the lines and will count them as well. Moreover, it will place 1 on the elements where the line passes vertically. -1 on the elements where the line passes horizontally. 2 on the elements where 2 intersecting lines passes (horizontal and vertical).

    The advantage of having those 3 methods is that we know the elements that are covered twice, we know which elements are covered, and which are not covered. In addition, while drawing the lines, we increment the number of line counter.

    For the full implementation of the Hungarian Algorithm + Example: Github

    Code + Detailed Comments for step 3:

    /**
         * Step 3.1
         * Loop through all elements, and run colorNeighbors when the element visited is equal to zero
         * */
        public void coverZeros(){
            numLines = 0;
            lines = new int[values.length][values.length];
    
            for(int row=0; row 0 && lines[row][col] == 1) // if cell colored vertically and needs to be recolored vertically, don't color it again (Allowing this step, will color the same line (result won't change), but the num of line will be incremented (wrong value for the num of line drawn))
                return;
    
            if(maxVH <= 0 && lines[row][col] == -1) // if cell colored horizontally and needs to be recolored horizontally, don't color it again (Allowing this step, will color the same line (result won't change), but the num of line will be incremented (wrong value for the num of line drawn))
                return;
    
            for(int i=0; i 0)   // if value of maxVH is positive, color vertically
                    lines[i][col] = lines[i][col] == -1 || lines[i][col] == 2 ? 2 : 1; // if cell was colored before as horizontal (-1), and now needs to be colored vertical (1), so this cell is an intersection (2). Else if this value was not colored before, color it vertically
                else            // if value of maxVH is zero or negative color horizontally
                    lines[row][i] = lines[row][i] == 1 || lines[row][i] == 2 ? 2 : -1; // if cell was colored before as vertical (1), and now needs to be colored horizontal (-1), so this cell is an intersection (2). Else if this value was not colored before, color it horizontally
            }
    
            // increment line number
            numLines++;
    //      printMatrix(lines); // Monitor the line draw steps
        }//End step 3
    

提交回复
热议问题