87 PathDataNodeMap; |
81 PathDataNodeMap; |
88 |
82 |
89 protected: |
83 protected: |
90 |
84 |
91 /// \brief Node map for storing path data. |
85 /// \brief Node map for storing path data. |
92 /// |
86 /// |
93 /// Node map for storing path data of all nodes in the current |
87 /// Node map for storing path data of all nodes in the current |
94 /// component. dmap[v][k] is the length of a shortest directed walk |
88 /// component. dmap[v][k] is the length of a shortest directed walk |
95 /// to node v from the starting node containing exactly k edges. |
89 /// to node v from the starting node containing exactly k edges. |
96 PathDataNodeMap dmap; |
90 PathDataNodeMap dmap; |
97 |
91 |
98 /// \brief The directed graph the algorithm runs on. |
92 /// \brief The directed graph the algorithm runs on. |
99 const Graph& graph; |
93 const Graph &graph; |
100 /// \brief The length of the edges. |
94 /// \brief The length of the edges. |
101 const LengthMap& length; |
95 const LengthMap &length; |
102 |
96 |
103 /// \brief The total length of the found cycle. |
97 /// \brief The total length of the found cycle. |
104 Length cycle_length; |
98 Length cycle_length; |
105 /// \brief The number of edges in the found cycle. |
99 /// \brief The number of edges in the found cycle. |
106 int cycle_size; |
100 int cycle_size; |
107 /// \brief A node for obtaining a minimum mean cycle. |
101 /// \brief A node for obtaining a minimum mean cycle. |
108 Node cycle_node; |
102 Node cycle_node; |
109 |
103 |
110 /// \brief The found cycle. |
104 /// \brief The found cycle. |
111 Path *cycle_path; |
105 Path *cycle_path; |
112 /// \brief The algorithm uses local \ref lemon::Path "Path" |
106 /// \brief The algorithm uses local \ref lemon::Path "Path" |
113 /// structure to store the found cycle. |
107 /// structure to store the found cycle. |
114 bool local_path; |
108 bool local_path; |
115 |
109 |
116 /// \brief Node map for identifying strongly connected components. |
110 /// \brief Node map for identifying strongly connected components. |
117 IntNodeMap comp; |
111 IntNodeMap comp; |
118 /// \brief The number of strongly connected components. |
112 /// \brief The number of strongly connected components. |
119 int comp_num; |
113 int comp_num; |
120 /// \brief Counter for identifying the current component. |
114 /// \brief Counter for identifying the current component. |
121 int comp_cnt; |
115 int comp_cnt; |
122 /// \brief Nodes of the current component. |
116 /// \brief Nodes of the current component. |
123 NodeVector nodes; |
117 NodeVector nodes; |
124 /// \brief The processed nodes in the last round. |
118 /// \brief The processed nodes in the last round. |
125 NodeVector process; |
119 NodeVector process; |
126 |
120 |
127 public : |
121 public : |
128 |
122 |
129 /// \brief The constructor of the class. |
123 /// \brief The constructor of the class. |
130 /// |
124 /// |
131 /// The constructor of the class. |
125 /// The constructor of the class. |
132 /// |
126 /// |
133 /// \param _graph The directed graph the algorithm runs on. |
127 /// \param _graph The directed graph the algorithm runs on. |
134 /// \param _length The length (cost) of the edges. |
128 /// \param _length The length (cost) of the edges. |
135 MinMeanCycle( const Graph& _graph, |
129 MinMeanCycle( const Graph &_graph, |
136 const LengthMap& _length ) : |
130 const LengthMap &_length ) : |
137 graph(_graph), length(_length), dmap(_graph), comp(_graph), |
131 graph(_graph), length(_length), dmap(_graph), comp(_graph), |
138 cycle_length(0), cycle_size(-1), cycle_node(INVALID), |
132 cycle_length(0), cycle_size(-1), cycle_node(INVALID), |
139 cycle_path(NULL), local_path(false) |
133 cycle_path(NULL), local_path(false) |
140 { } |
134 { } |
141 |
135 |
142 /// \brief The destructor of the class. |
136 /// \brief The destructor of the class. |
143 ~MinMeanCycle() { |
137 ~MinMeanCycle() { |
144 if (local_path) delete cycle_path; |
138 if (local_path) delete cycle_path; |
145 } |
139 } |
146 |
140 |
147 protected: |
141 protected: |
148 |
142 |
154 for (NodeIt v(graph); v != INVALID; ++v) { |
148 for (NodeIt v(graph); v != INVALID; ++v) { |
155 if (comp[v] == comp_cnt) nodes.push_back(v); |
149 if (comp[v] == comp_cnt) nodes.push_back(v); |
156 } |
150 } |
157 // Creating vectors for all nodes |
151 // Creating vectors for all nodes |
158 int n = nodes.size(); |
152 int n = nodes.size(); |
159 for (NodeVectorIt vi = nodes.begin(); vi != nodes.end(); ++vi) { |
153 for (int i = 0; i < nodes.size(); ++i) { |
160 dmap[*vi].resize(n + 1); |
154 dmap[nodes[i]].resize(n + 1); |
161 } |
155 } |
162 } |
156 } |
163 |
157 |
164 /// \brief Processes all rounds of computing required path data for |
158 /// \brief Processes all rounds of computing required path data for |
165 /// the current component. |
159 /// the current component. |
166 void processRounds() { |
160 void processRounds() { |
167 dmap[nodes[0]][0] = PathData(true, 0); |
161 dmap[nodes[0]][0] = PathData(true, 0); |
168 process.clear(); |
162 process.clear(); |
169 // Processing the first round |
163 // Processing the first round |
171 Node v = graph.target(e); |
165 Node v = graph.target(e); |
172 if (comp[v] != comp_cnt || v == nodes[0]) continue; |
166 if (comp[v] != comp_cnt || v == nodes[0]) continue; |
173 dmap[v][1] = PathData(true, length[e], e); |
167 dmap[v][1] = PathData(true, length[e], e); |
174 process.push_back(v); |
168 process.push_back(v); |
175 } |
169 } |
176 // Processing other rounds |
170 // Processing other rounds |
177 int n = nodes.size(), k; |
171 int n = nodes.size(), k; |
178 for (k = 2; k <= n && process.size() < n; ++k) { |
172 for (k = 2; k <= n && process.size() < n; ++k) |
179 processNextBuildRound(k); |
173 processNextBuildRound(k); |
180 } |
174 for ( ; k <= n; ++k) |
181 for ( ; k <= n; ++k) { |
|
182 processNextFullRound(k); |
175 processNextFullRound(k); |
183 } |
176 } |
184 } |
177 |
185 |
|
186 /// \brief Processes one round of computing required path data and |
178 /// \brief Processes one round of computing required path data and |
187 /// rebuilds \ref process vector. |
179 /// rebuilds \ref process vector. |
188 void processNextBuildRound(int k) { |
180 void processNextBuildRound(int k) { |
189 NodeVector next; |
181 NodeVector next; |
190 for (NodeVectorIt ui = process.begin(); ui != process.end(); ++ui) { |
182 for (int i = 0; i < process.size(); ++i) { |
191 for (OutEdgeIt e(graph, *ui); e != INVALID; ++e) { |
183 for (OutEdgeIt e(graph, process[i]); e != INVALID; ++e) { |
192 Node v = graph.target(e); |
184 Node v = graph.target(e); |
193 if (comp[v] != comp_cnt) continue; |
185 if (comp[v] != comp_cnt) continue; |
194 if (!dmap[v][k].found) { |
186 if (!dmap[v][k].found) { |
195 next.push_back(v); |
187 next.push_back(v); |
196 dmap[v][k] = PathData(true, dmap[*ui][k-1].dist + length[e], e); |
188 dmap[v][k] = PathData(true, dmap[process[i]][k-1].dist + length[e], e); |
197 } |
189 } |
198 else if (dmap[*ui][k-1].dist + length[e] < dmap[v][k].dist) { |
190 else if (dmap[process[i]][k-1].dist + length[e] < dmap[v][k].dist) { |
199 dmap[v][k] = PathData(true, dmap[*ui][k-1].dist + length[e], e); |
191 dmap[v][k] = PathData(true, dmap[process[i]][k-1].dist + length[e], e); |
200 } |
192 } |
201 } |
193 } |
202 } |
194 } |
203 process.swap(next); |
195 process.swap(next); |
204 } |
196 } |
205 |
197 |
206 /// \brief Processes one round of computing required path data |
198 /// \brief Processes one round of computing required path data |
207 /// using \ref nodes vector instead of \ref process vector. |
199 /// using \ref nodes vector instead of \ref process vector. |
208 void processNextFullRound(int k) { |
200 void processNextFullRound(int k) { |
209 for (NodeVectorIt ui = nodes.begin(); ui != nodes.end(); ++ui) { |
201 for (int i = 0; i < nodes.size(); ++i) { |
210 for (OutEdgeIt e(graph, *ui); e != INVALID; ++e) { |
202 for (OutEdgeIt e(graph, nodes[i]); e != INVALID; ++e) { |
211 Node v = graph.target(e); |
203 Node v = graph.target(e); |
212 if (comp[v] != comp_cnt) continue; |
204 if (comp[v] != comp_cnt) continue; |
213 if ( !dmap[v][k].found || |
205 if ( !dmap[v][k].found || |
214 dmap[*ui][k-1].dist + length[e] < dmap[v][k].dist ) { |
206 dmap[nodes[i]][k-1].dist + length[e] < dmap[v][k].dist ) { |
215 dmap[v][k] = PathData(true, dmap[*ui][k-1].dist + length[e], e); |
207 dmap[v][k] = PathData(true, dmap[nodes[i]][k-1].dist + length[e], e); |
216 } |
208 } |
217 } |
209 } |
218 } |
210 } |
219 } |
211 } |
220 |
212 |
221 /// \brief Finds the minimum cycle mean value in the current |
213 /// \brief Finds the minimum cycle mean value in the current |
222 /// component. |
214 /// component. |
223 bool findCurrentMin(Length &min_length, int &min_size, Node &min_node) { |
215 bool findCurrentMin(Length &min_length, int &min_size, Node &min_node) { |
224 bool found_min = false; |
216 bool found_min = false; |
225 for (NodeVectorIt vi = nodes.begin(); vi != nodes.end(); ++vi) { |
217 for (int i = 0; i < nodes.size(); ++i) { |
226 int n = nodes.size(); |
218 int n = nodes.size(); |
227 if (!dmap[*vi][n].found) continue; |
219 if (!dmap[nodes[i]][n].found) continue; |
228 Length len; |
220 Length len; |
229 int size; |
221 int size; |
230 bool found_one = false; |
222 bool found_one = false; |
231 for (int k = 0; k < n; ++k) { |
223 for (int k = 0; k < n; ++k) { |
232 if (!dmap[*vi][k].found) continue; |
224 if (!dmap[nodes[i]][k].found) continue; |
233 Length _len = dmap[*vi][n].dist - dmap[*vi][k].dist; |
225 Length _len = dmap[nodes[i]][n].dist - dmap[nodes[i]][k].dist; |
234 int _size = n - k; |
226 int _size = n - k; |
235 if (!found_one || len * _size < _len * size) { |
227 if (!found_one || len * _size < _len * size) { |
236 found_one = true; |
228 found_one = true; |
237 len = _len; |
229 len = _len; |
238 size = _size; |
230 size = _size; |
239 } |
231 } |
240 } |
232 } |
241 if ( found_one && |
233 if ( found_one && |
242 (!found_min || len * min_size < min_length * size) ) { |
234 (!found_min || len * min_size < min_length * size) ) { |
243 found_min = true; |
235 found_min = true; |
244 min_length = len; |
236 min_length = len; |
245 min_size = size; |
237 min_size = size; |
246 min_node = *vi; |
238 min_node = nodes[i]; |
247 } |
239 } |
248 } |
240 } |
249 return found_min; |
241 return found_min; |
250 } |
242 } |
251 |
243 |
252 public: |
244 public: |
253 |
245 |
254 /// \brief Runs the algorithm. |
246 /// \brief Runs the algorithm. |
255 /// |
247 /// |
256 /// Runs the algorithm. |
248 /// Runs the algorithm. |
257 /// |
249 /// |
258 /// \return \c true if a cycle exists in the graph. |
250 /// \return \c true if a cycle exists in the graph. |
259 /// |
251 /// |
260 /// \note Apart from the return value, m.run() is just a shortcut |
252 /// \note Apart from the return value, m.run() is just a shortcut |
261 /// of the following code. |
253 /// of the following code. |
262 /// \code |
254 /// \code |
263 /// m.init(); |
255 /// m.init(); |
264 /// m.findMinMean(); |
256 /// m.findMinMean(); |
265 /// m.findCycle(); |
257 /// m.findCycle(); |
283 /// |
275 /// |
284 /// Computes all the required path data and finds the minimum cycle |
276 /// Computes all the required path data and finds the minimum cycle |
285 /// mean value in the graph. |
277 /// mean value in the graph. |
286 /// |
278 /// |
287 /// \return \c true if a cycle exists in the graph. |
279 /// \return \c true if a cycle exists in the graph. |
288 /// |
280 /// |
289 /// \pre \ref init() must be called before using this function. |
281 /// \pre \ref init() must be called before using this function. |
290 bool findMinMean() { |
282 bool findMinMean() { |
291 cycle_node = INVALID; |
283 cycle_node = INVALID; |
292 for (comp_cnt = 0; comp_cnt < comp_num; ++comp_cnt) { |
284 for (comp_cnt = 0; comp_cnt < comp_num; ++comp_cnt) { |
293 initCurrent(); |
285 initCurrent(); |
294 processRounds(); |
286 processRounds(); |
295 |
287 |
296 Length min_length; |
288 Length min_length; |
297 int min_size; |
289 int min_size; |
298 Node min_node; |
290 Node min_node; |
299 bool found_min = findCurrentMin(min_length, min_size, min_node); |
291 bool found_min = findCurrentMin(min_length, min_size, min_node); |
300 |
292 |
301 if ( found_min && (cycle_node == INVALID || |
293 if ( found_min && (cycle_node == INVALID || |
302 min_length * cycle_size < cycle_length * min_size) ) { |
294 min_length * cycle_size < cycle_length * min_size) ) { |
303 cycle_length = min_length; |
295 cycle_length = min_length; |
304 cycle_size = min_size; |
296 cycle_size = min_size; |
305 cycle_node = min_node; |
297 cycle_node = min_node; |
306 } |
298 } |
307 } |
299 } |
308 return (cycle_node != INVALID); |
300 return (cycle_node != INVALID); |
309 } |
301 } |
310 |
302 |
311 /// \brief Finds a critical (minimum mean) cycle. |
303 /// \brief Finds a critical (minimum mean) cycle. |
312 /// |
304 /// |
313 /// Finds a critical (minimum mean) cycle using the path data |
305 /// Finds a critical (minimum mean) cycle using the path data |
314 /// stored in \ref dmap. |
306 /// stored in \ref dmap. |
315 /// |
307 /// |
316 /// \return \c true if a cycle exists in the graph. |
308 /// \return \c true if a cycle exists in the graph. |
317 /// |
309 /// |
318 /// \pre \ref init() and \ref findMinMean() must be called before |
310 /// \pre \ref init() and \ref findMinMean() must be called before |
319 /// using this function. |
311 /// using this function. |
320 bool findCycle() { |
312 bool findCycle() { |
321 if (cycle_node == INVALID) return false; |
313 if (cycle_node == INVALID) return false; |
322 cycle_length = 0; |
314 cycle_length = 0; |
323 cycle_size = 0; |
315 cycle_size = 0; |
343 return true; |
335 return true; |
344 } |
336 } |
345 |
337 |
346 /// \brief Resets the internal data structures. |
338 /// \brief Resets the internal data structures. |
347 /// |
339 /// |
348 /// Resets the internal data structures so that \ref findMinMean() |
340 /// Resets the internal data structures so that \ref findMinMean() |
349 /// and \ref findCycle() can be called again (e.g. when the |
341 /// and \ref findCycle() can be called again (e.g. when the |
350 /// underlaying graph has been modified). |
342 /// underlaying graph has been modified). |
351 void reset() { |
343 void reset() { |
352 for (NodeIt u(graph); u != INVALID; ++u) |
344 for (NodeIt u(graph); u != INVALID; ++u) |
353 dmap[u].clear(); |
345 dmap[u].clear(); |
354 cycle_node = INVALID; |
346 cycle_node = INVALID; |
355 if (cycle_path) cycle_path->clear(); |
347 if (cycle_path) cycle_path->clear(); |
356 comp_num = stronglyConnectedComponents(graph, comp); |
348 comp_num = stronglyConnectedComponents(graph, comp); |
357 } |
349 } |
358 |
350 |
359 /// \brief Returns the total length of the found cycle. |
351 /// \brief Returns the total length of the found cycle. |
360 /// |
352 /// |
361 /// Returns the total length of the found cycle. |
353 /// Returns the total length of the found cycle. |
362 /// |
354 /// |
363 /// \pre \ref run() must be called before using this function. |
355 /// \pre \ref run() must be called before using this function. |
364 Length cycleLength() const { |
356 Length cycleLength() const { |
365 return cycle_length; |
357 return cycle_length; |
366 } |
358 } |
367 |
359 |
368 /// \brief Returns the number of edges in the found cycle. |
360 /// \brief Returns the number of edges in the found cycle. |
369 /// |
361 /// |
370 /// Returns the number of edges in the found cycle. |
362 /// Returns the number of edges in the found cycle. |
371 /// |
363 /// |
372 /// \pre \ref run() must be called before using this function. |
364 /// \pre \ref run() must be called before using this function. |
373 int cycleEdgeNum() const { |
365 int cycleEdgeNum() const { |
374 return cycle_size; |
366 return cycle_size; |
375 } |
367 } |
376 |
368 |
377 /// \brief Returns the mean length of the found cycle. |
369 /// \brief Returns the mean length of the found cycle. |
378 /// |
370 /// |
379 /// Returns the mean length of the found cycle. |
371 /// Returns the mean length of the found cycle. |
380 /// |
372 /// |
381 /// \pre \ref run() must be called before using this function. |
373 /// \pre \ref run() must be called before using this function. |
397 /// structure of the found cycle. |
389 /// structure of the found cycle. |
398 /// |
390 /// |
399 /// \pre \ref run() must be called before using this function. |
391 /// \pre \ref run() must be called before using this function. |
400 /// |
392 /// |
401 /// \sa \ref cyclePath() |
393 /// \sa \ref cyclePath() |
402 const Path &cycle() const { |
394 const Path& cycle() const { |
403 return *cycle_path; |
395 return *cycle_path; |
404 } |
396 } |
405 |
397 |
406 /// \brief Sets the \ref lemon::Path "Path" structure storing the |
398 /// \brief Sets the \ref lemon::Path "Path" structure storing the |
407 /// found cycle. |
399 /// found cycle. |
408 /// |
400 /// |
409 /// Sets the \ref lemon::Path "Path" structure storing the found |
401 /// Sets the \ref lemon::Path "Path" structure storing the found |
410 /// cycle. If you don't use this function before calling |
402 /// cycle. If you don't use this function before calling |
411 /// \ref run(), it will allocate one. The destuctor deallocates |
403 /// \ref run(), it will allocate one. The destuctor deallocates |
412 /// this automatically allocated map, of course. |
404 /// this automatically allocated map, of course. |
413 /// |
405 /// |
414 /// \note The algorithm calls only the \ref lemon::Path::addFront() |
406 /// \note The algorithm calls only the \ref lemon::Path::addFront() |
415 /// "addFront()" method of the given \ref lemon::Path "Path" |
407 /// "addFront()" method of the given \ref lemon::Path "Path" |
416 /// structure. |
408 /// structure. |
417 /// |
409 /// |
418 /// \return \c (*this) |
410 /// \return \c (*this) |
419 MinMeanCycle &cyclePath(Path& path) { |
411 MinMeanCycle& cyclePath(Path &path) { |
420 if (local_path) { |
412 if (local_path) { |
421 delete cycle_path; |
413 delete cycle_path; |
422 local_path = false; |
414 local_path = false; |
423 } |
415 } |
424 cycle_path = &path; |
416 cycle_path = &path; |