ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Trigger
TrigAnalysis
TriggerMatchingTool
Root
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 <format>
7
8
munkres::munkres
(
matrix_type
costs):
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
20
munkres::result_type
munkres::run
(
vec_type
& costvector,
bool
debug
){
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;
55
result_type
result;
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
71
void
munkres::step_one
(){
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
77
if
(
m_costmatrix
[row][col] <
min
)
min
=
m_costmatrix
[row][col];
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
86
void
munkres::step_two
(){
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){
94
if
(!
m_rowIsCovered
[row] && !
m_colIsCovered
[col] &&
m_costmatrix
[row][col] == 0){
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
109
void
munkres::step_three
(){
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
137
int
munkres::find_in_row
(
const
int
row,
markertype
what){
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
143
int
munkres::find_in_col
(
const
int
col,
markertype
what){
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
149
void
munkres::step_four
(){
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;
159
find_a_zero
(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
196
void
munkres::erase_primes_and_covers
(){
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
206
void
munkres::step_five
(){
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;
218
find_a_zero
(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
241
augment_path
(path);
242
erase_primes_and_covers
();
243
244
m_step
= 3;
245
}
246
247
double
munkres::find_min_uncov
(){
248
double
min
= 1e10;
249
for
(
int
row=0;row<
m_dim
;++row){
250
for
(
int
col=0;col<
m_dim
;++col){
251
if
(!
m_rowIsCovered
[row] && !
m_colIsCovered
[col] &&
m_costmatrix
[row][col] <
min
){
252
min
=
m_costmatrix
[row][col];
253
}
254
}
255
}
256
return
min
;
257
}
258
259
void
munkres::step_six
(){
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
275
void
munkres::printmatrix
(
const
matrix_type
& m){
276
std::cout << std::format(
"{:>5}"
,
"cov|"
);
277
for
(
int
col=0;col<
m_dim
;++col){
278
std::cout << std::format(
"{:>7}"
, (
m_colIsCovered
[col] ?
"+|"
:
"|"
));
279
} std::cout << std::endl;
280
281
for
(
int
row=0;row<
m_dim
;++row){
282
std::cout << std::format(
"{:>5}"
, (
m_rowIsCovered
[row] ?
"+ |"
:
"|"
));
283
for
(
int
col=0;col<
m_dim
;++col){
284
std::cout << std::format(
"{:>5.3g}"
, m[row][col]);
285
if
(
m_maskmatrix
[row][col] ==
kPrime
) std::cout <<
"'"
;
286
if
(
m_maskmatrix
[row][col] ==
kStar
) std::cout <<
"*"
;
287
else
std::cout <<
" "
;
288
std::cout <<
"|"
;
289
} std::cout << std::endl;
290
}
291
}
uint
unsigned int uint
Definition
LArOFPhaseFill.cxx:19
debug
const bool debug
Definition
MakeUncertaintyPlots.cxx:53
size
size_t size() const
Number of registered mappings.
min
#define min(a, b)
Definition
cfImp.cxx:40
munkres::munkres
munkres(matrix_type costs)
Definition
munkres.cxx:8
munkres::m_step
int m_step
Definition
munkres.h:52
munkres::find_in_col
int find_in_col(const int col, markertype what)
Definition
munkres.cxx:143
munkres::markertype
markertype
Definition
munkres.h:24
munkres::kStar
@ kStar
Definition
munkres.h:24
munkres::kPrime
@ kPrime
Definition
munkres.h:24
munkres::m_dim
const int m_dim
Definition
munkres.h:56
munkres::augment_path
void augment_path(const std::vector< coords > &path)
Definition
munkres.cxx:183
munkres::matrix_type
std::vector< vec_type > matrix_type
Definition
munkres.h:20
munkres::erase_primes_and_covers
void erase_primes_and_covers()
Definition
munkres.cxx:196
munkres::step_one
void step_one()
Definition
munkres.cxx:71
munkres::printmatrix
void printmatrix(const matrix_type &)
Definition
munkres.cxx:275
munkres::find_min_uncov
double find_min_uncov()
Definition
munkres.cxx:247
munkres::step_three
void step_three()
Definition
munkres.cxx:109
munkres::find_a_zero
void find_a_zero(int &row, int &col)
Definition
munkres.cxx:126
munkres::run
result_type run(vec_type &costvector, bool debug=false)
Definition
munkres.cxx:20
munkres::printmask
void printmask()
Definition
munkres.h:38
munkres::m_maskmatrix
matrix_type m_maskmatrix
Definition
munkres.h:51
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::step_six
void step_six()
Definition
munkres.cxx:259
munkres::printcosts
void printcosts()
Definition
munkres.h:27
munkres::vec_type
std::vector< double > vec_type
Definition
munkres.h:19
munkres::step_four
void step_four()
Definition
munkres.cxx:149
munkres::find_in_row
int find_in_row(const int row, markertype what)
Definition
munkres.cxx:137
munkres::m_costs_orig
matrix_type m_costs_orig
Definition
munkres.h:50
munkres::coords
std::pair< int, int > coords
Definition
munkres.h:21
munkres::m_costmatrix
matrix_type m_costmatrix
Definition
munkres.h:49
munkres::m_rowIsCovered
std::vector< bool > m_rowIsCovered
Definition
munkres.h:54
munkres::step_two
void step_two()
Definition
munkres.cxx:86
munkres::step_five
void step_five()
Definition
munkres.cxx:206
munkres.h
Generated on
for ATLAS Offline Software by
1.17.0