Пример #1
0
/*
 *
 * 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;
}
Пример #2
0
/*
 *
 * 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;
}