ATLAS Offline Software
munkres.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "munkres.h"
6 #include "boost/io/ios_state.hpp"
7 
9  m_costmatrix(costs),
10  m_costs_orig(costs),
11  m_step(0),
12  m_dim(costs.size())
13 {
14  m_rowIsCovered = std::vector<bool>(m_dim,false);
15  m_colIsCovered = std::vector<bool>(m_dim,false);
16  vec_type maskrow(m_dim,0);
17  for(int i=0;i<m_dim;++i) m_maskmatrix.push_back(maskrow);
18 }
19 
21  if(debug) printcosts();
22  bool done = false;
23  m_step = 1;
24  while(!done){
25  if(debug){
26  std::cout << "doing step " << m_step << std::endl;
27  printcosts();
28  printmask();
29  }
30  switch(m_step){
31  case 1:
32  step_one();
33  break;
34  case 2:
35  step_two();
36  break;
37  case 3:
38  step_three();
39  break;
40  case 4:
41  step_four();
42  break;
43  case 5:
44  step_five();
45  break;
46  case 6:
47  step_six();
48  break;
49  case 7:
50  done = true;
51  break;
52  }
53  }
54  if(debug) std::cout << "done running munkres algorithm: " << std::endl;
56  costvector.clear();
57 
58  for(int row=0;row<m_dim;++row){
59  int col = find_in_row(row,kStar);
60  result.push_back(col);
61  costvector.push_back(m_costs_orig[row][result.back()]);
62  }
63 
64  if(debug){
65  printcosts();
66  for(uint i=0;i<result.size();++i) std::cout << "row: " << i << " -> col: " << result[i] << " cost: " << m_costs_orig[i][result[i]]<< std::endl;
67  }
68  return result;
69 }
70 
72  //subtract row minimum from each row element
73  //then go to step 2
74  for(int row=0;row<m_dim;++row){
75  double min = m_costmatrix[row][0];
76  for(int col=0;col<m_dim;++col){ // find minimum
78  }
79  for(int col=0;col<m_dim;++col){ // subtract from all elements
80  m_costmatrix[row][col] -= min;
81  }
82  }
83  m_step = 2;
84 }
85 
87  //star a zero matrix element if there is no other zero in it column or row
88  //we will cover each row and column that have a zero so we know we don't have to
89  //check these rows and columns anymore for zeros to star
90  //then go to step 3
91 
92  for(int row=0;row<m_dim;++row){
93  for(int col=0;col<m_dim;++col){
95  m_rowIsCovered[row] = true;
96  m_colIsCovered[col] = true;
97  m_maskmatrix[row][col] = 1;
98  }
99  }
100  }
101  //reset cover vectors
102  for(int i=0;i<m_dim;++i){
103  m_rowIsCovered[i] = false;
104  m_colIsCovered[i] = false;
105  }
106  m_step = 3;
107 }
108 
110  //cover each column with a starred zero
111  //if we have m_dim coered columns we're done and exit
112  //else we continue with step four
113 
114  for(int row=0;row<m_dim;++row){
115  for(int col=0;col<m_dim;++col){
116  if(m_maskmatrix[row][col] == 1) m_colIsCovered[col] = true; // this is a starred zero cover column
117  }
118  }
119 
120  int nCoveredCols = 0;
121  for(int col=0;col<m_dim;++col) if(m_colIsCovered[col]) nCoveredCols++;
122 
123  m_step = (nCoveredCols == m_dim) ? 7 : 4;
124 }
125 
126 void munkres::find_a_zero(int& row, int& col){
127  for(row=0;row<m_dim;++row){
128  for(col=0;col<m_dim;++col){
129  if(m_costmatrix[row][col] == 0 && !m_colIsCovered[col] && !m_rowIsCovered[row]) return;
130  }
131  }
132  //not returned until now set flags
133  row = -1;
134  col = -1;
135 }
136 
138  for(int col = 0;col<m_dim;++col) if(m_maskmatrix[row][col] == what) return col;
139  //not returned until now
140  return -1;
141 }
142 
144  for(int row = 0;row<m_dim;++row) if(m_maskmatrix[row][col] == what) return row;
145  //not returned until now
146  return -1;
147 }
148 
150  // Find a noncovered zero and prime it.
151  // If there is no starred zero in the row containing this primed zero, Go to Step 5.
152  // Otherwise, cover this row and uncover the column containing the starred zero.
153  // Continue in this manner until there are no uncovered zeros left.
154  // Save the smallest uncovered value and Go to Step 6.
155 
156  bool done = false;
157  while(!done){
158  int row, col;
160  if(row == -1){
161  //there is no uncovered zero go to step 6
162  done = true;
163  m_step = 6;
164  }
165  else{
166  // std::cout << "found uncovered zero at " << row << ", " << col << std::endl;
167  //check if there is a starred zero in this row
168  m_maskmatrix[row][col]=2;
169  int starred0atcol = find_in_row(row,kStar);
170  if(starred0atcol != -1){
171  m_rowIsCovered[row] = true;
172  m_colIsCovered[starred0atcol] = false;
173  // printcosts();
174  // printmask();
175  }else{
176  done = true;
177  m_step = 5;
178  }
179  }
180  }
181 }
182 
183 void munkres::augment_path(const std::vector<coords>& p){
184  for(unsigned int i = 0;i<p.size();++i){
185  const int row = p[i].first;
186  const int col = p[i].second;
187  if(m_maskmatrix[row][col] == kStar){
188  m_maskmatrix[row][col] = 0; //unstar each star;
189  }
190  else{//primed zeros
191  m_maskmatrix[row][col] = kStar; //star each primed and unprime it;
192  }
193  }
194 }
195 
197  for(int row=0;row<m_dim;++row){
198  m_rowIsCovered[row] = false;
199  m_colIsCovered[row] = false;//queadratic matrix
200  for(int col=0;col<m_dim;++col){
201  if(m_maskmatrix[row][col] == kPrime) m_maskmatrix[row][col] = 0;
202  }
203  }
204 }
205 
207  // Construct a series of alternating primed and starred zeros as follows.
208  // Let Z0 represent the uncovered primed zero found in Step 4.
209  // Let Z1 denote the starred zero in the column of Z0 (if any).
210  // Let Z2 denote the primed zero in the row of Z1 (there will always be one).
211  // Continue until the series terminates at a primed zero that has no starred zero in its column.
212  // Unstar each starred zero of the series, star each primed zero of the series,
213  // erase all primes and uncover every line in the matrix. Return to Step 3.
214 
215  bool done = false;
216  std::vector<coords> path;
217  int row,col;
219 
220  path.push_back(coords(row,col));
221 
222  int n = 0;
223  while(!done && n<4){n++;
224  int starred0atrow = find_in_col(path.back().second,kStar);
225  if(starred0atrow > -1){
226  path.push_back(coords(starred0atrow,path.back().second));
227  }
228  else{
229  done = true;
230  }
231  if(!done){
232  int primed0atcol = find_in_row(path.back().first,kPrime);
233  path.push_back(coords(path.back().first,primed0atcol));
234  }
235  }
236  // std::cout << "found path: " << std::endl;
237  // for(unsigned int i=0;i<path.size();++i){
238  // std::cout << "(" << path[i].first << "," << path[i].second << ")" << ((i<path.size()-1) ? "->" : "" );
239  // } std::cout << std::endl;
240 
243 
244  m_step = 3;
245 }
246 
248  double min = 1e10;
249  for(int row=0;row<m_dim;++row){
250  for(int col=0;col<m_dim;++col){
252  min = m_costmatrix[row][col];
253  }
254  }
255  }
256  return min;
257 }
258 
260  // Add the value found in Step 4 to every element of each covered row,
261  // and subtract it from every element of each uncovered column.
262  // Return to Step 4 without altering any stars, primes, or covered lines.
263  // Notice that this step uses the smallest uncovered value in the cost matrix to modify the matrix.
264 
265  double minuncov = find_min_uncov();
266  for(int row=0;row<m_dim;++row){
267  for(int col=0;col<m_dim;++col){
268  if(m_rowIsCovered[row]) m_costmatrix[row][col] += minuncov;
269  if(!m_colIsCovered[col]) m_costmatrix[row][col] -= minuncov;
270  }
271  }
272  m_step = 4;
273 }
274 
276  boost::io::ios_all_saver ias(std::cout);
277  std::cout << std::setw(5) << std::setprecision(3) << "cov|";
278  for(int col=0;col<m_dim;++col){
279  std::cout << std::setw(7) << std::setprecision(3) << (m_colIsCovered[col] ? "+|" : "|");
280  } std::cout << std::endl;
281 
282  for(int row=0;row<m_dim;++row){
283  std::cout << std::setw(5) << std::setprecision(3) << (m_rowIsCovered[row] ? "+ |" : "|");
284  for(int col=0;col<m_dim;++col){
285  std::cout << std::setw(5) << std::setprecision(3) << m[row][col];
286  if(m_maskmatrix[row][col] == kPrime) std::cout << "'";
287  if(m_maskmatrix[row][col] == kStar) std::cout << "*";
288  else std::cout << " ";
289  std::cout << "|";
290  } std::cout << std::endl;
291  }
292 }
query_example.row
row
Definition: query_example.py:24
get_generator_info.result
result
Definition: get_generator_info.py:21
munkres::step_three
void step_three()
Definition: munkres.cxx:109
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:128
munkres::erase_primes_and_covers
void erase_primes_and_covers()
Definition: munkres.cxx:196
munkres::find_min_uncov
double find_min_uncov()
Definition: munkres.cxx:247
munkres::find_in_row
int find_in_row(const int row, markertype what)
Definition: munkres.cxx:137
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
munkres::m_costs_orig
matrix_type m_costs_orig
Definition: munkres.h:50
munkres::m_rowIsCovered
std::vector< bool > m_rowIsCovered
Definition: munkres.h:54
munkres::matrix_type
std::vector< vec_type > matrix_type
Definition: munkres.h:20
munkres.h
munkres::printmask
void printmask()
Definition: munkres.h:38
munkres::step_six
void step_six()
Definition: munkres.cxx:259
munkres::augment_path
void augment_path(const std::vector< coords > &path)
Definition: munkres.cxx:183
munkres::m_step
int m_step
Definition: munkres.h:52
munkres::printcosts
void printcosts()
Definition: munkres.h:27
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
uint
unsigned int uint
Definition: LArOFPhaseFill.cxx:20
munkres::step_two
void step_two()
Definition: munkres.cxx:86
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
munkres::run
result_type run(vec_type &costvector, bool debug=false)
Definition: munkres.cxx:20
lumiFormat.i
int i
Definition: lumiFormat.py:85
beamspotman.n
n
Definition: beamspotman.py:731
munkres::step_four
void step_four()
Definition: munkres.cxx:149
munkres::kStar
@ kStar
Definition: munkres.h:24
munkres::munkres
munkres(matrix_type costs)
Definition: munkres.cxx:8
python.ExitCodes.what
def what(code)
Definition: ExitCodes.py:73
munkres::coords
std::pair< int, int > coords
Definition: munkres.h:21
munkres::vec_type
std::vector< double > vec_type
Definition: munkres.h:19
munkres::m_costmatrix
matrix_type m_costmatrix
Definition: munkres.h:49
debug
const bool debug
Definition: MakeUncertaintyPlots.cxx:53
munkres::step_one
void step_one()
Definition: munkres.cxx:71
munkres::m_maskmatrix
matrix_type m_maskmatrix
Definition: munkres.h:51
query_example.col
col
Definition: query_example.py:7
munkres::find_in_col
int find_in_col(const int col, markertype what)
Definition: munkres.cxx:143
munkres::printmatrix
void printmatrix(const matrix_type &)
Definition: munkres.cxx:275
munkres::markertype
markertype
Definition: munkres.h:24
munkres::result_type
std::vector< int > result_type
Definition: munkres.h:22
munkres::m_colIsCovered
std::vector< bool > m_colIsCovered
Definition: munkres.h:55
munkres::find_a_zero
void find_a_zero(int &row, int &col)
Definition: munkres.cxx:126
munkres::m_dim
const int m_dim
Definition: munkres.h:56
munkres::kPrime
@ kPrime
Definition: munkres.h:24
munkres::step_five
void step_five()
Definition: munkres.cxx:206