Go to the documentation of this file.00001 #ifndef vnl_hungarian_algorithm_txx_
00002 #define vnl_hungarian_algorithm_txx_
00003
00004 #include "vnl_hungarian_algorithm.h"
00005
00006 #include <vnl/vnl_matrix.h>
00007 #include <vcl_vector.h>
00008 #include <vcl_limits.h>
00009 #include <vcl_algorithm.h>
00010 #include <vcl_cassert.h>
00011
00012 #ifdef DEBUG
00013 #include <vcl_iostream.h>
00014 #endif
00015
00016
00017
00018
00019 template<class T>
00020 void
00021 vnl_hungarian_algorithm<T>::
00022 SetCostMatrix( vnl_matrix<T> const& cost_in )
00023 {
00024 m_Cost_in = cost_in;
00025 m_TotalCost = 0;
00026
00027
00028
00029
00030
00031
00032 m_N = vcl_max( cost_in.rows(), cost_in.cols() );
00033
00034 m_Cost.set_size( m_N, m_N);
00035 m_Cost.fill( static_cast<T>(0) );
00036
00037
00038
00039 m_Cost.update( cost_in, 0, 0 );
00040 }
00041
00042
00043
00044
00045 template <class T>
00046 void
00047 vnl_hungarian_algorithm<T>::
00048 clear_vector( vcl_vector<bool>& v )
00049 {
00050 typedef vcl_vector<bool>::iterator iter;
00051 iter end = v.end();
00052 for ( iter i = v.begin(); i != end; ++i )
00053 {
00054 *i = false;
00055 }
00056 }
00057
00058
00059
00060
00061 template <class T>
00062 void
00063 vnl_hungarian_algorithm<T>::
00064 StartAssignment()
00065 {
00066
00067
00068
00069
00070
00071 Step_0();
00072
00073
00074
00075
00076
00077 Step_1();
00078
00079
00080
00081
00082
00083
00084 Step_2();
00085
00086 STEP_TYPE step = STEP_3;
00087
00088 while ( step != STEP_done )
00089 {
00090 switch ( step )
00091 {
00092 case STEP_3 :
00093
00094
00095
00096
00097 step = Step_3();
00098 break;
00099
00100 case STEP_4 :
00101
00102
00103
00104
00105
00106
00107 step = Step_4();
00108 break;
00109
00110 case STEP_5 :
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 step = Step_5();
00121 break;
00122
00123 case STEP_6 :
00124
00125
00126
00127
00128 step = Step_6();
00129 break;
00130
00131 default :
00132 step = STEP_done;
00133 break;
00134 }
00135 }
00136
00137
00138
00139
00140
00141
00142 Step_done();
00143 }
00144
00145
00146
00147
00148
00149
00150
00151 template <class T>
00152 typename vnl_hungarian_algorithm<T>::STEP_TYPE
00153 vnl_hungarian_algorithm<T>::Step_0()
00154 {
00155
00156
00157
00158
00159 m_M.set_size( m_N, m_N);
00160 m_M.fill( NORMAL );
00161
00162
00163
00164
00165 m_R_cov.assign(m_N, false);
00166 m_C_cov.assign(m_N, false);
00167 return STEP_1;
00168 }
00169
00170
00171
00172
00173
00174
00175 template <class T>
00176 typename vnl_hungarian_algorithm<T>::STEP_TYPE
00177 vnl_hungarian_algorithm<T>::Step_1()
00178 {
00179
00180
00181 for ( unsigned i = 0; i < m_N; ++i )
00182 {
00183 T mn = m_Cost(i,0);
00184 for ( unsigned j = 1; j < m_N; ++j )
00185 {
00186 if ( mn > m_Cost(i,j) )
00187 {
00188 mn = m_Cost(i,j);
00189 }
00190 }
00191 for ( unsigned j = 0; j < m_N; ++j )
00192 {
00193 m_Cost(i,j) -= mn;
00194 }
00195 }
00196 return STEP_2;
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206 template <class T>
00207 typename vnl_hungarian_algorithm<T>::STEP_TYPE
00208 vnl_hungarian_algorithm<T>::Step_2()
00209 {
00210
00211
00212 for ( unsigned i = 0; i < m_N; ++i )
00213 {
00214 if ( ! m_R_cov[i] )
00215 {
00216 for ( unsigned j = 0; j < m_N; ++j )
00217 {
00218 if ( m_Cost(i,j) == 0 && ! m_C_cov[j] )
00219 {
00220 m_M(i,j) = STAR;
00221 m_R_cov[i] = true;
00222 m_C_cov[j] = true;
00223 break;
00224 }
00225 }
00226 }
00227 }
00228 clear_vector( m_R_cov );
00229 clear_vector( m_C_cov );
00230 return STEP_3;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239 template <class T>
00240 typename vnl_hungarian_algorithm<T>::STEP_TYPE
00241 vnl_hungarian_algorithm<T>::Step_3()
00242 {
00243 unsigned count = 0;
00244 for ( unsigned j = 0; j < m_N; ++j )
00245 {
00246 for ( unsigned i = 0; i < m_N; ++i )
00247 {
00248 if ( m_M(i,j) == STAR )
00249 {
00250 m_C_cov[j] = true;
00251 ++count;
00252 break;
00253 }
00254 }
00255 }
00256
00257 if ( count == m_N )
00258 {
00259 return STEP_done;
00260 }
00261 else
00262 {
00263 return STEP_4;
00264 }
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 template <class T>
00276 typename vnl_hungarian_algorithm<T>::STEP_TYPE
00277 vnl_hungarian_algorithm<T>::Step_4()
00278 {
00279 m_Z0_r = m_Z0_c = (unsigned int)(-1);
00280
00281
00282
00283 unsigned i, j;
00284 for (i = 0 ; i < m_N; ++i )
00285 {
00286 if ( ! m_R_cov[i] )
00287 {
00288 for ( j = 0; j < m_N; ++j )
00289 {
00290 #ifdef DEBUG
00291 vcl_cout << m_Cost(i,j) << vcl_endl;
00292 #endif
00293 if ( m_Cost(i,j) == 0 && ! m_C_cov[j] )
00294 {
00295 m_M(i,j) = PRIME;
00296 bool star_in_row = false;
00297 for ( unsigned j2 = 0; j2 < m_N; ++j2 )
00298 {
00299 if ( m_M(i,j2) == STAR )
00300 {
00301 star_in_row = true;
00302
00303 m_R_cov[i] = true;
00304 m_C_cov[j2] = false;
00305 break;
00306 }
00307 }
00308
00309
00310 if ( ! star_in_row )
00311 {
00312 m_Z0_r = i;
00313 m_Z0_c = j;
00314 return STEP_5;
00315 }
00316 return STEP_4;
00317 }
00318 }
00319 }
00320 }
00321
00322
00323
00324
00325 return STEP_6;
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 template <class T>
00340 typename vnl_hungarian_algorithm<T>::STEP_TYPE
00341 vnl_hungarian_algorithm<T>::Step_5()
00342 {
00343 unsigned i = m_Z0_r;
00344 unsigned j = m_Z0_c;
00345 vcl_vector<unsigned> rows, cols;
00346
00347 while ( true )
00348 {
00349
00350 assert( m_M(i,j) == PRIME );
00351 rows.push_back( i );
00352 cols.push_back( j );
00353
00354
00355 for ( i = 0; i < m_N; ++i )
00356 {
00357 if ( m_M(i,j) == STAR )
00358 {
00359 break;
00360 }
00361 }
00362
00363 if ( i == m_N )
00364 {
00365
00366 break;
00367 }
00368
00369
00370 rows.push_back( i );
00371 cols.push_back( j );
00372
00373
00374 for ( j = 0; j < m_N; ++j )
00375 {
00376 if ( m_M(i,j) == PRIME )
00377 {
00378 break;
00379 }
00380 }
00381 assert( j < m_N );
00382
00383
00384 }
00385
00386
00387
00388 for ( unsigned idx = 0; idx < rows.size(); ++idx )
00389 {
00390 unsigned i = rows[idx];
00391 unsigned j = cols[idx];
00392 if ( m_M(i,j) == STAR )
00393 {
00394 m_M(i,j) = NORMAL;
00395 }
00396 else
00397 {
00398 assert( m_M(i,j) == PRIME );
00399 m_M(i,j) = STAR;
00400 }
00401 }
00402
00403
00404 for ( unsigned i = 0; i < m_N; ++i )
00405 {
00406 for ( unsigned j = 0; j < m_N; ++j )
00407 {
00408 if ( m_M(i,j) == PRIME )
00409 {
00410 m_M(i,j) = NORMAL;
00411 }
00412 }
00413 }
00414
00415
00416 clear_vector( m_R_cov );
00417 clear_vector( m_C_cov );
00418
00419 return STEP_3;
00420 }
00421
00422
00423
00424
00425
00426
00427
00428 template <class T>
00429 typename vnl_hungarian_algorithm<T>::STEP_TYPE
00430 vnl_hungarian_algorithm<T>::Step_6()
00431 {
00432
00433 T minval = vcl_numeric_limits<T>::max();
00434 for ( unsigned i = 0; i < m_N; ++i )
00435 {
00436 if ( ! m_R_cov[i] )
00437 {
00438 for ( unsigned j = 0; j < m_N; ++j )
00439 {
00440 if ( ! m_C_cov[j] && m_Cost(i,j) < minval )
00441 {
00442 minval = m_Cost(i,j);
00443 }
00444 }
00445 }
00446 }
00447
00448
00449 for ( unsigned i = 0; i < m_N; ++i )
00450 {
00451 for ( unsigned j = 0; j < m_N; ++j )
00452 {
00453 if ( m_R_cov[i] )
00454 {
00455 m_Cost(i,j) += minval;
00456 }
00457 if ( ! m_C_cov[j] )
00458 {
00459 m_Cost(i,j) -= minval;
00460 }
00461 }
00462 }
00463
00464 return STEP_4;
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474 template <class T>
00475 void
00476 vnl_hungarian_algorithm<T>::Step_done()
00477 {
00478 vcl_vector<unsigned> assign( m_Cost_in.rows(), (unsigned int)(-1) );
00479 m_AssignmentVector = assign;
00480
00481
00482
00483
00484 for ( unsigned j = 0; j < m_Cost_in.cols(); ++j )
00485 {
00486 for ( unsigned i = 0; i < m_Cost_in.rows(); ++i )
00487 {
00488 if ( m_M(i,j) == STAR )
00489 {
00490 m_AssignmentVector[i] = j;
00491 m_TotalCost += m_Cost_in[i][j];
00492 }
00493 }
00494 }
00495 }
00496
00497
00498
00499
00500 template <class T>
00501 T
00502 vnl_hungarian_algorithm<T>::GetTotalCost()
00503 {
00504 return m_TotalCost;
00505 }
00506
00507
00508
00509
00510 template <class T>
00511 typename vnl_hungarian_algorithm<T>::AssignmentMatrixType
00512 vnl_hungarian_algorithm<T>::GetAssignmentMatrix()
00513 {
00514 return m_M;
00515 }
00516
00517
00518
00519
00520 template <class T>
00521 typename vnl_hungarian_algorithm<T>::AssignmentVectorType
00522 vnl_hungarian_algorithm<T>::GetAssignmentVector()
00523 {
00524 return m_AssignmentVector;
00525 }
00526
00527 #undef VNL_HUNGARIAN_ALGORITHM_INSTANTIATE
00528 #define VNL_HUNGARIAN_ALGORITHM_INSTANTIATE(T) \
00529 template class vnl_hungarian_algorithm<T >
00530
00531 #endif // vnl_hungarian_algorithm_txx_