00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <mtt/munkres.h>
00025
00026 #include <iostream>
00027 #include <cmath>
00028
00029 bool
00030 Munkres::find_uncovered_in_matrix(double item, int &row, int &col) {
00031 for ( row = 0 ; row < matrix.rows() ; row++ )
00032 if ( !row_mask[row] )
00033 for ( col = 0 ; col < matrix.columns() ; col++ )
00034 if ( !col_mask[col] )
00035 if ( matrix(row,col) == item )
00036 return true;
00037
00038 return false;
00039 }
00040
00041 bool
00042 Munkres::pair_in_list(const std::pair<int,int> &needle, const std::list<std::pair<int,int> > &haystack) {
00043 for ( std::list<std::pair<int,int> >::const_iterator i = haystack.begin() ; i != haystack.end() ; i++ ) {
00044 if ( needle == *i )
00045 return true;
00046 }
00047
00048 return false;
00049 }
00050
00051 int
00052 Munkres::step1(void) {
00053 for ( int row = 0 ; row < matrix.rows() ; row++ )
00054 for ( int col = 0 ; col < matrix.columns() ; col++ )
00055 if ( matrix(row,col) == 0 ) {
00056 bool isstarred = false;
00057 for ( int nrow = 0 ; nrow < matrix.rows() ; nrow++ )
00058 if ( mask_matrix(nrow,col) == STAR ) {
00059 isstarred = true;
00060 break;
00061 }
00062
00063 if ( !isstarred ) {
00064 for ( int ncol = 0 ; ncol < matrix.columns() ; ncol++ )
00065 if ( mask_matrix(row,ncol) == STAR ) {
00066 isstarred = true;
00067 break;
00068 }
00069 }
00070
00071 if ( !isstarred ) {
00072 mask_matrix(row,col) = STAR;
00073 }
00074 }
00075
00076 return 2;
00077 }
00078
00079 int
00080 Munkres::step2(void) {
00081 int rows = matrix.rows();
00082 int cols = matrix.columns();
00083 int covercount = 0;
00084 for ( int row = 0 ; row < rows ; row++ )
00085 for ( int col = 0 ; col < cols ; col++ )
00086 if ( mask_matrix(row,col) == STAR ) {
00087 col_mask[col] = true;
00088 covercount++;
00089 }
00090
00091 int k = matrix.minsize();
00092
00093 if ( covercount >= k ) {
00094 #ifdef DEBUG
00095 std::cout << "Final cover count: " << covercount << std::endl;
00096 #endif
00097 return 0;
00098 }
00099
00100 #ifdef DEBUG
00101 std::cout << "Munkres matrix has " << covercount << " of " << k << " Columns covered:" << std::endl;
00102 for ( int row = 0 ; row < rows ; row++ ) {
00103 for ( int col = 0 ; col < cols ; col++ ) {
00104 std::cout.width(8);
00105 std::cout << matrix(row,col) << ",";
00106 }
00107 std::cout << std::endl;
00108 }
00109 std::cout << std::endl;
00110 #endif
00111
00112
00113 return 3;
00114 }
00115
00116 int
00117 Munkres::step3(void) {
00118
00119
00120
00121
00122
00123
00124
00125 if ( find_uncovered_in_matrix(0, saverow, savecol) ) {
00126 mask_matrix(saverow,savecol) = PRIME;
00127 } else {
00128 return 5;
00129 }
00130
00131 for ( int ncol = 0 ; ncol < matrix.columns() ; ncol++ )
00132 if ( mask_matrix(saverow,ncol) == STAR ) {
00133 row_mask[saverow] = true;
00134 col_mask[ncol] = false;
00135 return 3;
00136 }
00137
00138 return 4;
00139 }
00140
00141 int
00142 Munkres::step4(void) {
00143 int rows = matrix.rows();
00144 int cols = matrix.columns();
00145
00146 std::list<std::pair<int,int> > seq;
00147
00148 std::pair<int,int> z0(saverow, savecol);
00149 std::pair<int,int> z1(-1,-1);
00150 std::pair<int,int> z2n(-1,-1);
00151 seq.insert(seq.end(), z0);
00152 int row, col = savecol;
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 bool madepair;
00166 do {
00167 madepair = false;
00168 for ( row = 0 ; row < rows ; row++ )
00169 if ( mask_matrix(row,col) == STAR ) {
00170 z1.first = row;
00171 z1.second = col;
00172 if ( pair_in_list(z1, seq) )
00173 continue;
00174
00175 madepair = true;
00176 seq.insert(seq.end(), z1);
00177 break;
00178 }
00179
00180 if ( !madepair )
00181 break;
00182
00183 madepair = false;
00184
00185 for ( col = 0 ; col < cols ; col++ )
00186 if ( mask_matrix(row,col) == PRIME ) {
00187 z2n.first = row;
00188 z2n.second = col;
00189 if ( pair_in_list(z2n, seq) )
00190 continue;
00191 madepair = true;
00192 seq.insert(seq.end(), z2n);
00193 break;
00194 }
00195 } while ( madepair );
00196
00197 for ( std::list<std::pair<int,int> >::iterator i = seq.begin() ;
00198 i != seq.end() ;
00199 i++ ) {
00200
00201 if ( mask_matrix(i->first,i->second) == STAR )
00202 mask_matrix(i->first,i->second) = NORMAL;
00203
00204
00205
00206 if ( mask_matrix(i->first,i->second) == PRIME )
00207 mask_matrix(i->first,i->second) = STAR;
00208 }
00209
00210
00211 for ( int row = 0 ; row < mask_matrix.rows() ; row++ )
00212 for ( int col = 0 ; col < mask_matrix.columns() ; col++ )
00213 if ( mask_matrix(row,col) == PRIME )
00214 mask_matrix(row,col) = NORMAL;
00215
00216 for ( int i = 0 ; i < rows ; i++ ) {
00217 row_mask[i] = false;
00218 }
00219
00220 for ( int i = 0 ; i < cols ; i++ ) {
00221 col_mask[i] = false;
00222 }
00223
00224
00225 return 2;
00226 }
00227
00228 int
00229 Munkres::step5(void) {
00230 int rows = matrix.rows();
00231 int cols = matrix.columns();
00232
00233
00234
00235
00236
00237
00238
00239
00240 double h = 0;
00241 for ( int row = 0 ; row < rows ; row++ ) {
00242 if ( !row_mask[row] ) {
00243 for ( int col = 0 ; col < cols ; col++ ) {
00244 if ( !col_mask[col] ) {
00245 if ( (h > matrix(row,col) && matrix(row,col) != 0) || h == 0 ) {
00246 h = matrix(row,col);
00247 }
00248 }
00249 }
00250 }
00251 }
00252
00253 for ( int row = 0 ; row < rows ; row++ )
00254 if ( row_mask[row] )
00255 for ( int col = 0 ; col < cols ; col++ )
00256 matrix(row,col) += h;
00257
00258 for ( int col = 0 ; col < cols ; col++ )
00259 if ( !col_mask[col] )
00260 for ( int row = 0 ; row < rows ; row++ )
00261 matrix(row,col) -= h;
00262
00263 return 3;
00264 }
00265
00266 double Munkres::solve(MatrixXd& m_in,vector<orderedPairPtr>& results)
00267 {
00268
00269
00270
00271
00272
00273
00274
00275 Matrix<double> m(m_in.rows(),m_in.cols());
00276
00277 double highValue = 0;
00278
00279 for(int row=0;row<m_in.rows();++row)
00280 for(int col=0;col<m_in.cols();++col)
00281 {
00282 if(!isinf(m_in(row,col)))
00283 {
00284 highValue = m_in(row,col);
00285 m(row,col) = m_in(row,col);
00286 }
00287 }
00288
00289 highValue++;
00290
00291 for(int row=0;row<m_in.rows();++row)
00292 for(int col=0;col<m_in.cols();++col)
00293 {
00294 if(isinf(m_in(row,col)))
00295 {
00296 m(row,col) = highValue ;
00297 }
00298 }
00299
00300 bool notdone = true;
00301 int step = 1;
00302
00303 this->matrix = m;
00304
00305 mask_matrix.resize(matrix.rows(), matrix.columns());
00306
00307 row_mask = new bool[matrix.rows()];
00308 col_mask = new bool[matrix.columns()];
00309
00310 for ( int i = 0 ; i < matrix.rows() ; i++ ) {
00311 row_mask[i] = false;
00312 }
00313
00314 for ( int i = 0 ; i < matrix.columns() ; i++ ) {
00315 col_mask[i] = false;
00316 }
00317
00318 while ( notdone ) {
00319 switch ( step ) {
00320 case 0:
00321 notdone = false;
00322 break;
00323 case 1:
00324 step = step1();
00325 break;
00326 case 2:
00327 step = step2();
00328 break;
00329 case 3:
00330 step = step3();
00331 break;
00332 case 4:
00333 step = step4();
00334 break;
00335 case 5:
00336 step = step5();
00337 break;
00338 }
00339 }
00340
00341 double cost=0;
00342
00343 for ( int row = 0 ; row < matrix.rows() ; row++ )
00344 for ( int col = 0 ; col < matrix.columns() ; col++ )
00345 if ( mask_matrix(row,col) == STAR )
00346 {
00347 orderedPairPtr op(new orderedPair);
00348
00349 op->row=row;
00350 op->col=col;
00351
00352 results.push_back(op);
00353
00354 cost+=m(row,col);
00355 }
00356
00357 delete [] row_mask;
00358 delete [] col_mask;
00359
00360 return cost;
00361 }
00362
00363 void
00364 Munkres::solve(Matrix<double>&m) {
00365
00366
00367
00368
00369
00370
00371
00372 double highValue = 0;
00373 for ( int row = 0 ; row < m.rows() ; row++ ) {
00374 for ( int col = 0 ; col < m.columns() ; col++ ) {
00375 if ( m(row,col) != INFINITY && m(row,col) > highValue )
00376 highValue = m(row,col);
00377 }
00378 }
00379 highValue++;
00380
00381 for ( int row = 0 ; row < m.rows() ; row++ )
00382 for ( int col = 0 ; col < m.columns() ; col++ )
00383 if ( m(row,col) == INFINITY )
00384 m(row,col) = highValue;
00385
00386 bool notdone = true;
00387 int step = 1;
00388
00389 this->matrix = m;
00390
00391 mask_matrix.resize(matrix.rows(), matrix.columns());
00392
00393 row_mask = new bool[matrix.rows()];
00394 col_mask = new bool[matrix.columns()];
00395 for ( int i = 0 ; i < matrix.rows() ; i++ ) {
00396 row_mask[i] = false;
00397 }
00398
00399 for ( int i = 0 ; i < matrix.columns() ; i++ ) {
00400 col_mask[i] = false;
00401 }
00402
00403 while ( notdone ) {
00404 switch ( step ) {
00405 case 0:
00406 notdone = false;
00407 break;
00408 case 1:
00409 step = step1();
00410 break;
00411 case 2:
00412 step = step2();
00413 break;
00414 case 3:
00415 step = step3();
00416 break;
00417 case 4:
00418 step = step4();
00419 break;
00420 case 5:
00421 step = step5();
00422 break;
00423 }
00424 }
00425
00426
00427 for ( int row = 0 ; row < matrix.rows() ; row++ )
00428 for ( int col = 0 ; col < matrix.columns() ; col++ )
00429 if ( mask_matrix(row,col) == STAR )
00430 matrix(row,col) = 0;
00431 else
00432 matrix(row,col) = -1;
00433
00434 #ifdef DEBUG
00435 std::cout << "Munkres output matrix:" << std::endl;
00436 for ( int row = 0 ; row < matrix.rows() ; row++ ) {
00437 for ( int col = 0 ; col < matrix.columns() ; col++ ) {
00438 std::cout.width(1);
00439 std::cout << matrix(row,col) << ",";
00440 }
00441 std::cout << std::endl;
00442 }
00443 std::cout << std::endl;
00444 #endif
00445
00446 m = matrix;
00447
00448 delete [] row_mask;
00449 delete [] col_mask;
00450 }