/* * * Linear assignment problem solution * [modifies matrix in-place.] * matrix(row,col): row major format assumed. * * Assignments are remaining 0 values * (extra 0 values are replaced with -1) * */ void Munkres::solve(cv::Mat_<int> &m) { const unsigned int rows = m.rows, columns = m.cols, size = std::max<unsigned int>(rows, columns); if(isDiag) { std::cout << "Munkres input matrix:" << std::endl; for ( unsigned int row = 0 ; row < rows ; row++ ) { for ( unsigned int col = 0 ; col < columns ; col++ ) { std::cout.width(4); std::cout << m(row, col) << ","; } std::cout << std::endl; } std::cout << std::endl; } bool notdone = true; int step = 1; // Copy input matrix this->matrix = m; if ( rows != columns ) { // If the input matrix isn't square, make it square // and fill the empty values with the largest value present // in the matrix. extendMat(matrix, size, size, maxValue(matrix)); } // STAR == 1 == starred, PRIME == 2 == primed // mask_matrix.resize(size, size); extendMat(mask_matrix, size, size); row_mask = new bool[size]; col_mask = new bool[size]; for ( unsigned int i = 0 ; i < size ; i++ ) { row_mask[i] = false; } for ( unsigned int i = 0 ; i < size ; i++ ) { col_mask[i] = false; } // Prepare the matrix values... // If there were any infinities, replace them with a value greater // than the maximum value in the matrix. replace_infinites(matrix); minimize_along_direction(matrix, false); minimize_along_direction(matrix, true); // Follow the steps while ( notdone ) { switch ( step ) { case 0: notdone = false; // end the step flow break; case 1: step = step1(); // step is always 2 break; case 2: step = step2(); // step is always either 0 or 3 break; case 3: step = step3(); // step in [3, 4, 5] break; case 4: step = step4(); // step is always 2 break; case 5: step = step5(); // step is always 3 break; } } // Store results for ( unsigned int row = 0 ; row < size ; row++ ) { for ( unsigned int col = 0 ; col < size ; col++ ) { if ( mask_matrix(row, col) == STAR ) { matrix(row, col) = 0; } else { matrix(row, col) = -1; } } } if(isDiag) { std::cout << "Munkres output matrix:" << std::endl; for ( unsigned int row = 0 ; row < rows ; row++ ) { for ( unsigned int col = 0 ; col < columns ; col++ ) { std::cout.width(2); std::cout << matrix(row, col) << ","; } std::cout << std::endl; } std::cout << std::endl; } // Remove the excess rows or columns that we added to fit the // input to a square matrix. // matrix.resize(rows, columns); extendMat(matrix, rows, columns); m = matrix; delete [] row_mask; delete [] col_mask; }
/* * * Linear assignment problem solution * [modifies matrix in-place.] * matrix(row,col): row major format assumed. * * Assignments are remaining 0 values * (extra 0 values are replaced with -1) * */ void Munkres::solve(Matrix<double> &m) { const size_t rows = m.rows(), columns = m.columns(), size = std::max(rows, columns); #ifdef DEBUG std::cout << "Munkres input matrix:" << std::endl; for ( size_t row = 0 ; row < rows ; row++ ) { for ( size_t col = 0 ; col < columns ; col++ ) { std::cout.width(8); std::cout << m(row, col) << ","; } std::cout << std::endl; } std::cout << std::endl; #endif // Copy input matrix this->matrix = m; if ( rows != columns ) { // If the input matrix isn't square, make it square // and fill the empty values with the largest value present // in the matrix. matrix.resize(size, size, matrix.max()); } // STAR == 1 == starred, PRIME == 2 == primed mask_matrix.resize(size, size); row_mask = new bool[size]; col_mask = new bool[size]; for ( size_t i = 0 ; i < size ; i++ ) { row_mask[i] = false; } for ( size_t i = 0 ; i < size ; i++ ) { col_mask[i] = false; } // Prepare the matrix values... // If there were any infinities, replace them with a value greater // than the maximum value in the matrix. replace_infinites(matrix); minimize_along_direction(matrix, false); minimize_along_direction(matrix, true); // Follow the steps int step = 1; while ( step ) { switch ( step ) { case 1: step = step1(); // step is always 2 break; case 2: step = step2(); // step is always either 0 or 3 break; case 3: step = step3(); // step in [3, 4, 5] break; case 4: step = step4(); // step is always 2 break; case 5: step = step5(); // step is always 3 break; } } // Store results for ( size_t row = 0 ; row < size ; row++ ) { for ( size_t col = 0 ; col < size ; col++ ) { if ( mask_matrix(row, col) == STAR ) { matrix(row, col) = 0; } else { matrix(row, col) = -1; } } } #ifdef DEBUG std::cout << "Munkres output matrix:" << std::endl; for ( size_t row = 0 ; row < rows ; row++ ) { for ( size_t col = 0 ; col < columns ; col++ ) { std::cout.width(1); std::cout << matrix(row, col) << ","; } std::cout << std::endl; } std::cout << std::endl; #endif // Remove the excess rows or columns that we added to fit the // input to a square matrix. matrix.resize(rows, columns); m = matrix; delete [] row_mask; delete [] col_mask; }