55 { |
55 { |
56 typedef typename Graph::Node Node; |
56 typedef typename Graph::Node Node; |
57 typedef typename Graph::NodeIt NodeIt; |
57 typedef typename Graph::NodeIt NodeIt; |
58 typedef typename Graph::Edge Edge; |
58 typedef typename Graph::Edge Edge; |
59 typedef typename Graph::EdgeIt EdgeIt; |
59 typedef typename Graph::EdgeIt EdgeIt; |
60 typedef typename Graph::InEdgeIt InEdgeIt; |
|
61 typedef typename Graph::OutEdgeIt OutEdgeIt; |
60 typedef typename Graph::OutEdgeIt OutEdgeIt; |
62 |
61 |
63 typedef typename LengthMap::Value Length; |
62 typedef typename LengthMap::Value Length; |
64 |
63 |
65 typedef typename Graph::template NodeMap<int> IntNodeMap; |
64 typedef typename Graph::template NodeMap<int> IntNodeMap; |
66 typedef typename Graph::template NodeMap<Edge> PredNodeMap; |
65 typedef typename Graph::template NodeMap<Edge> PredNodeMap; |
67 typedef Path<Graph> Path; |
66 typedef Path<Graph> Path; |
68 typedef std::vector<Node> NodeVector; |
67 typedef std::vector<Node> NodeVector; |
69 typedef typename NodeVector::iterator NodeVectorIt; |
68 typedef typename NodeVector::iterator NodeVectorIt; |
70 |
69 |
71 protected: |
70 protected: |
72 |
71 |
73 /// \brief Data sturcture for path data. |
72 /// \brief Data sturcture for path data. |
74 struct PathData { |
73 struct PathData |
|
74 { |
75 bool found; |
75 bool found; |
76 Length dist; |
76 Length dist; |
77 Edge pred; |
77 Edge pred; |
78 PathData(bool _found = false, Length _dist = 0) : |
78 PathData(bool _found = false, Length _dist = 0) : |
79 found(_found), dist(_dist), pred(INVALID) {} |
79 found(_found), dist(_dist), pred(INVALID) {} |
80 PathData(bool _found, Length _dist, Edge _pred) : |
80 PathData(bool _found, Length _dist, Edge _pred) : |
81 found(_found), dist(_dist), pred(_pred) {} |
81 found(_found), dist(_dist), pred(_pred) {} |
82 }; |
82 }; |
83 |
83 |
84 private: |
84 private: |
85 |
85 |
86 typedef typename Graph::template NodeMap<std::vector<PathData> > PathVectorNodeMap; |
86 typedef typename Graph::template NodeMap<std::vector<PathData> > |
87 |
87 PathDataNodeMap; |
|
88 |
88 protected: |
89 protected: |
89 |
90 |
90 /// \brief Node map for storing path data. |
91 /// \brief Node map for storing path data. |
91 /// |
92 /// |
92 /// Node map for storing path data of all nodes in the current |
93 /// Node map for storing path data of all nodes in the current |
93 /// component. dmap[v][k] is the length of a shortest directed walk |
94 /// component. dmap[v][k] is the length of a shortest directed walk |
94 /// to node v from the starting node containing exactly k edges. |
95 /// to node v from the starting node containing exactly k edges. |
95 PathVectorNodeMap dmap; |
96 PathDataNodeMap dmap; |
96 |
97 |
97 /// \brief The directed graph the algorithm runs on. |
98 /// \brief The directed graph the algorithm runs on. |
98 const Graph& graph; |
99 const Graph& graph; |
99 /// \brief The length of the edges. |
100 /// \brief The length of the edges. |
100 const LengthMap& length; |
101 const LengthMap& length; |
101 |
102 |
102 /// \brief The total length of the found cycle. |
103 /// \brief The total length of the found cycle. |
103 Length cycle_length; |
104 Length cycle_length; |
104 /// \brief The number of edges in the found cycle. |
105 /// \brief The number of edges in the found cycle. |
105 int cycle_size; |
106 int cycle_size; |
|
107 /// \brief A node for obtaining a minimum mean cycle. |
|
108 Node cycle_node; |
|
109 |
106 /// \brief The found cycle. |
110 /// \brief The found cycle. |
107 Path *cycle_path; |
111 Path *cycle_path; |
108 /// \brief The found cycle. |
112 /// \brief The algorithm uses local \ref lemon::Path "Path" |
|
113 /// structure to store the found cycle. |
109 bool local_path; |
114 bool local_path; |
110 |
115 |
111 /// \brief Node map for identifying strongly connected components. |
116 /// \brief Node map for identifying strongly connected components. |
112 IntNodeMap comp; |
117 IntNodeMap comp; |
113 /// \brief The number of strongly connected components. |
118 /// \brief The number of strongly connected components. |
114 int comp_num; |
119 int comp_num; |
115 /// \brief %Counter for identifying the current component. |
120 /// \brief Counter for identifying the current component. |
116 int comp_cnt; |
121 int comp_cnt; |
117 /// \brief Nodes of the current component. |
122 /// \brief Nodes of the current component. |
118 NodeVector nodes; |
123 NodeVector nodes; |
119 /// \brief The processed nodes in the last round. |
124 /// \brief The processed nodes in the last round. |
120 NodeVector process; |
125 NodeVector process; |
127 /// |
132 /// |
128 /// \param _graph The directed graph the algorithm runs on. |
133 /// \param _graph The directed graph the algorithm runs on. |
129 /// \param _length The length (cost) of the edges. |
134 /// \param _length The length (cost) of the edges. |
130 MinMeanCycle( const Graph& _graph, |
135 MinMeanCycle( const Graph& _graph, |
131 const LengthMap& _length ) : |
136 const LengthMap& _length ) : |
132 graph(_graph), length(_length), dmap(_graph), |
137 graph(_graph), length(_length), dmap(_graph), comp(_graph), |
133 cycle_length(0), cycle_size(-1), comp(_graph), |
138 cycle_length(0), cycle_size(-1), cycle_node(INVALID), |
134 cycle_path(NULL), local_path(false) |
139 cycle_path(NULL), local_path(false) |
135 { } |
140 { } |
136 |
141 |
137 /// \brief The destructor of the class. |
142 /// \brief The destructor of the class. |
138 ~MinMeanCycle() { |
143 ~MinMeanCycle() { |
139 if (local_path) delete cycle_path; |
144 if (local_path) delete cycle_path; |
140 } |
145 } |
141 |
146 |
142 protected: |
147 protected: |
143 |
|
144 /// \brief Initializes the internal data structures. |
|
145 void init() { |
|
146 comp_num = stronglyConnectedComponents(graph, comp); |
|
147 if (!cycle_path) { |
|
148 local_path = true; |
|
149 cycle_path = new Path; |
|
150 } |
|
151 } |
|
152 |
148 |
153 /// \brief Initializes the internal data structures for the current |
149 /// \brief Initializes the internal data structures for the current |
154 /// component. |
150 /// component. |
155 void initCurrent() { |
151 void initCurrent() { |
156 nodes.clear(); |
152 nodes.clear(); |
157 // Finding the nodes of the current component |
153 // Finding the nodes of the current component |
158 for (NodeIt v(graph); v != INVALID; ++v) { |
154 for (NodeIt v(graph); v != INVALID; ++v) { |
159 if (comp[v] == comp_cnt) nodes.push_back(v); |
155 if (comp[v] == comp_cnt) nodes.push_back(v); |
160 } |
156 } |
161 |
|
162 // Creating vectors for all nodes |
157 // Creating vectors for all nodes |
163 int n = nodes.size(); |
158 int n = nodes.size(); |
164 for (NodeVectorIt vi = nodes.begin(); vi != nodes.end(); ++vi) { |
159 for (NodeVectorIt vi = nodes.begin(); vi != nodes.end(); ++vi) { |
165 dmap[*vi].resize(n + 1); |
160 dmap[*vi].resize(n + 1); |
166 } |
161 } |
167 } |
162 } |
168 |
163 |
169 /// \brief Processes all rounds of computing required path data. |
164 /// \brief Processes all rounds of computing required path data for |
|
165 /// the current component. |
170 void processRounds() { |
166 void processRounds() { |
171 dmap[nodes[0]][0] = PathData(true, 0); |
167 dmap[nodes[0]][0] = PathData(true, 0); |
172 process.clear(); |
168 process.clear(); |
173 for (OutEdgeIt oe(graph, nodes[0]); oe != INVALID; ++oe) { |
169 // Processing the first round |
174 Node v = graph.target(oe); |
170 for (OutEdgeIt e(graph, nodes[0]); e != INVALID; ++e) { |
|
171 Node v = graph.target(e); |
175 if (comp[v] != comp_cnt || v == nodes[0]) continue; |
172 if (comp[v] != comp_cnt || v == nodes[0]) continue; |
176 dmap[v][1] = PathData(true, length[oe], oe); |
173 dmap[v][1] = PathData(true, length[e], e); |
177 process.push_back(v); |
174 process.push_back(v); |
178 } |
175 } |
|
176 // Processing other rounds |
179 int n = nodes.size(), k; |
177 int n = nodes.size(), k; |
180 for (k = 2; k <= n && process.size() < n; ++k) { |
178 for (k = 2; k <= n && process.size() < n; ++k) { |
181 processNextBuildRound(k); |
179 processNextBuildRound(k); |
182 } |
180 } |
183 for ( ; k <= n; ++k) { |
181 for ( ; k <= n; ++k) { |
188 /// \brief Processes one round of computing required path data and |
186 /// \brief Processes one round of computing required path data and |
189 /// rebuilds \ref process vector. |
187 /// rebuilds \ref process vector. |
190 void processNextBuildRound(int k) { |
188 void processNextBuildRound(int k) { |
191 NodeVector next; |
189 NodeVector next; |
192 for (NodeVectorIt ui = process.begin(); ui != process.end(); ++ui) { |
190 for (NodeVectorIt ui = process.begin(); ui != process.end(); ++ui) { |
193 for (OutEdgeIt oe(graph, *ui); oe != INVALID; ++oe) { |
191 for (OutEdgeIt e(graph, *ui); e != INVALID; ++e) { |
194 Node v = graph.target(oe); |
192 Node v = graph.target(e); |
195 if (comp[v] != comp_cnt) continue; |
193 if (comp[v] != comp_cnt) continue; |
196 if ( !dmap[v][k].found || (dmap[v][k].dist > dmap[*ui][k-1].dist + length[oe]) ) { |
194 if (!dmap[v][k].found) { |
197 if (!dmap[v][k].found) next.push_back(v); |
195 next.push_back(v); |
198 dmap[v][k] = PathData(true, dmap[*ui][k-1].dist + length[oe], oe); |
196 dmap[v][k] = PathData(true, dmap[*ui][k-1].dist + length[e], e); |
|
197 } |
|
198 else if (dmap[*ui][k-1].dist + length[e] < dmap[v][k].dist) { |
|
199 dmap[v][k] = PathData(true, dmap[*ui][k-1].dist + length[e], e); |
199 } |
200 } |
200 } |
201 } |
201 } |
202 } |
202 process.swap(next); |
203 process.swap(next); |
203 } |
204 } |
204 |
205 |
205 /// \brief Processes one round of computing required path data |
206 /// \brief Processes one round of computing required path data |
206 /// using \ref nodes vector instead of \ref process vector. |
207 /// using \ref nodes vector instead of \ref process vector. |
207 void processNextFullRound(int k) { |
208 void processNextFullRound(int k) { |
208 for (NodeVectorIt ui = nodes.begin(); ui != nodes.end(); ++ui) { |
209 for (NodeVectorIt ui = nodes.begin(); ui != nodes.end(); ++ui) { |
209 for (OutEdgeIt oe(graph, *ui); oe != INVALID; ++oe) { |
210 for (OutEdgeIt e(graph, *ui); e != INVALID; ++e) { |
210 Node v = graph.target(oe); |
211 Node v = graph.target(e); |
211 if (comp[v] != comp_cnt) continue; |
212 if (comp[v] != comp_cnt) continue; |
212 if ( !dmap[v][k].found || (dmap[v][k].dist > dmap[*ui][k-1].dist + length[oe]) ) { |
213 if ( !dmap[v][k].found || |
213 dmap[v][k] = PathData(true, dmap[*ui][k-1].dist + length[oe], oe); |
214 dmap[*ui][k-1].dist + length[e] < dmap[v][k].dist ) { |
|
215 dmap[v][k] = PathData(true, dmap[*ui][k-1].dist + length[e], e); |
214 } |
216 } |
215 } |
217 } |
216 } |
218 } |
217 } |
219 } |
218 |
220 |
219 /// \brief Finds the minimum cycle mean value according to the path |
221 /// \brief Finds the minimum cycle mean value in the current |
220 /// data stored in \ref dmap. |
222 /// component. |
221 /// |
223 bool findCurrentMin(Length &min_length, int &min_size, Node &min_node) { |
222 /// Finds the minimum cycle mean value according to the path data |
|
223 /// stored in \ref dmap. |
|
224 /// |
|
225 /// \retval min_length The total length of the found cycle. |
|
226 /// \retval min_size The number of edges in the found cycle. |
|
227 /// \retval min_node A node for obtaining a critical cycle. |
|
228 /// |
|
229 /// \return \c true if a cycle exists in the graph. |
|
230 bool findMinCycleMean(Length &min_length, int &min_size, Node &min_node) { |
|
231 bool found_min = false; |
224 bool found_min = false; |
232 for (NodeVectorIt vi = nodes.begin(); vi != nodes.end(); ++vi) { |
225 for (NodeVectorIt vi = nodes.begin(); vi != nodes.end(); ++vi) { |
|
226 int n = nodes.size(); |
|
227 if (!dmap[*vi][n].found) continue; |
233 Length len; |
228 Length len; |
234 int size; |
229 int size; |
235 bool found_one = false; |
230 bool found_one = false; |
236 int n = nodes.size(); |
|
237 for (int k = 0; k < n; ++k) { |
231 for (int k = 0; k < n; ++k) { |
|
232 if (!dmap[*vi][k].found) continue; |
238 Length _len = dmap[*vi][n].dist - dmap[*vi][k].dist; |
233 Length _len = dmap[*vi][n].dist - dmap[*vi][k].dist; |
239 int _size = n - k; |
234 int _size = n - k; |
240 if ( dmap[*vi][n].found && dmap[*vi][k].found && (!found_one || len * _size < _len * size) ) { |
235 if (!found_one || len * _size < _len * size) { |
241 found_one = true; |
236 found_one = true; |
242 len = _len; |
237 len = _len; |
243 size = _size; |
238 size = _size; |
244 } |
239 } |
245 } |
240 } |
246 if (found_one && (!found_min || len * min_size < min_length * size)) { |
241 if ( found_one && |
|
242 (!found_min || len * min_size < min_length * size) ) { |
247 found_min = true; |
243 found_min = true; |
248 min_length = len; |
244 min_length = len; |
249 min_size = size; |
245 min_size = size; |
250 min_node = *vi; |
246 min_node = *vi; |
251 } |
247 } |
252 } |
248 } |
253 return found_min; |
249 return found_min; |
254 } |
250 } |
255 |
251 |
256 /// \brief Finds a critical (minimum mean) cycle according to the |
252 public: |
257 /// path data stored in \ref dmap. |
253 |
258 void findCycle(const Node &min_n) { |
|
259 IntNodeMap reached(graph, -1); |
|
260 int r = reached[min_n] = dmap[min_n].size() - 1; |
|
261 Node u = graph.source(dmap[min_n][r].pred); |
|
262 while (reached[u] < 0) { |
|
263 reached[u] = --r; |
|
264 u = graph.source(dmap[u][r].pred); |
|
265 } |
|
266 r = reached[u]; |
|
267 Edge ce = dmap[u][r].pred; |
|
268 cycle_path->addFront(ce); |
|
269 Node v; |
|
270 while ((v = graph.source(ce)) != u) { |
|
271 ce = dmap[v][--r].pred; |
|
272 cycle_path->addFront(ce); |
|
273 } |
|
274 } |
|
275 |
|
276 public: |
|
277 |
|
278 /// \brief Runs the algorithm. |
254 /// \brief Runs the algorithm. |
279 /// |
255 /// |
280 /// Runs the algorithm. |
256 /// Runs the algorithm. |
281 /// |
257 /// |
282 /// \return \c true if a cycle exists in the graph. |
258 /// \return \c true if a cycle exists in the graph. |
|
259 /// |
|
260 /// \note Apart from the return value, m.run() is just a shortcut |
|
261 /// of the following code. |
|
262 /// \code |
|
263 /// m.init(); |
|
264 /// m.findMinMean(); |
|
265 /// m.findCycle(); |
|
266 /// \endcode |
283 bool run() { |
267 bool run() { |
284 init(); |
268 init(); |
285 // Searching for the minimum mean cycle in all components |
269 findMinMean(); |
286 bool found_cycle = false; |
270 return findCycle(); |
287 Node cycle_node; |
271 } |
|
272 |
|
273 /// \brief Initializes the internal data structures. |
|
274 void init() { |
|
275 comp_num = stronglyConnectedComponents(graph, comp); |
|
276 if (!cycle_path) { |
|
277 local_path = true; |
|
278 cycle_path = new Path; |
|
279 } |
|
280 } |
|
281 |
|
282 /// \brief Finds the minimum cycle mean value in the graph. |
|
283 /// |
|
284 /// Computes all the required path data and finds the minimum cycle |
|
285 /// mean value in the graph. |
|
286 /// |
|
287 /// \return \c true if a cycle exists in the graph. |
|
288 /// |
|
289 /// \pre \ref init() must be called before using this function. |
|
290 bool findMinMean() { |
|
291 cycle_node = INVALID; |
288 for (comp_cnt = 0; comp_cnt < comp_num; ++comp_cnt) { |
292 for (comp_cnt = 0; comp_cnt < comp_num; ++comp_cnt) { |
289 |
|
290 initCurrent(); |
293 initCurrent(); |
291 processRounds(); |
294 processRounds(); |
292 |
295 |
293 Length min_length; |
296 Length min_length; |
294 int min_size; |
297 int min_size; |
295 Node min_node; |
298 Node min_node; |
296 bool found_min = findMinCycleMean(min_length, min_size, min_node); |
299 bool found_min = findCurrentMin(min_length, min_size, min_node); |
297 |
300 |
298 if ( found_min && (!found_cycle || min_length * cycle_size < cycle_length * min_size) ) { |
301 if ( found_min && (cycle_node == INVALID || |
299 found_cycle = true; |
302 min_length * cycle_size < cycle_length * min_size) ) { |
300 cycle_length = min_length; |
303 cycle_length = min_length; |
301 cycle_size = min_size; |
304 cycle_size = min_size; |
302 cycle_node = min_node; |
305 cycle_node = min_node; |
303 } |
306 } |
304 } |
307 } |
305 if (found_cycle) findCycle(cycle_node); |
308 return (cycle_node != INVALID); |
306 return found_cycle; |
309 } |
307 } |
310 |
308 |
311 /// \brief Finds a critical (minimum mean) cycle. |
309 /// \brief Returns the total length of the found critical cycle. |
312 /// |
310 /// |
313 /// Finds a critical (minimum mean) cycle using the path data |
311 /// Returns the total length of the found critical cycle. |
314 /// stored in \ref dmap. |
|
315 /// |
|
316 /// \return \c true if a cycle exists in the graph. |
|
317 /// |
|
318 /// \pre \ref init() and \ref findMinMean() must be called before |
|
319 /// using this function. |
|
320 bool findCycle() { |
|
321 if (cycle_node == INVALID) return false; |
|
322 cycle_length = 0; |
|
323 cycle_size = 0; |
|
324 IntNodeMap reached(graph, -1); |
|
325 int r = reached[cycle_node] = dmap[cycle_node].size() - 1; |
|
326 Node u = graph.source(dmap[cycle_node][r].pred); |
|
327 while (reached[u] < 0) { |
|
328 reached[u] = --r; |
|
329 u = graph.source(dmap[u][r].pred); |
|
330 } |
|
331 r = reached[u]; |
|
332 Edge e = dmap[u][r].pred; |
|
333 cycle_path->addFront(e); |
|
334 cycle_length = cycle_length + length[e]; |
|
335 ++cycle_size; |
|
336 Node v; |
|
337 while ((v = graph.source(e)) != u) { |
|
338 e = dmap[v][--r].pred; |
|
339 cycle_path->addFront(e); |
|
340 cycle_length = cycle_length + length[e]; |
|
341 ++cycle_size; |
|
342 } |
|
343 return true; |
|
344 } |
|
345 |
|
346 /// \brief Resets the internal data structures. |
|
347 /// |
|
348 /// Resets the internal data structures so that \ref findMinMean() |
|
349 /// and \ref findCycle() can be called again (e.g. when the |
|
350 /// underlaying graph has been modified). |
|
351 void reset() { |
|
352 for (NodeIt u(graph); u != INVALID; ++u) |
|
353 dmap[u].clear(); |
|
354 cycle_node = INVALID; |
|
355 if (cycle_path) cycle_path->clear(); |
|
356 comp_num = stronglyConnectedComponents(graph, comp); |
|
357 } |
|
358 |
|
359 /// \brief Returns the total length of the found cycle. |
|
360 /// |
|
361 /// Returns the total length of the found cycle. |
312 /// |
362 /// |
313 /// \pre \ref run() must be called before using this function. |
363 /// \pre \ref run() must be called before using this function. |
314 Length cycleLength() const { |
364 Length cycleLength() const { |
315 return cycle_length; |
365 return cycle_length; |
316 } |
366 } |
317 |
367 |
318 /// \brief Returns the number of edges in the found critical |
368 /// \brief Returns the number of edges in the found cycle. |
319 /// cycle. |
369 /// |
320 /// |
370 /// Returns the number of edges in the found cycle. |
321 /// Returns the number of edges in the found critical cycle. |
|
322 /// |
371 /// |
323 /// \pre \ref run() must be called before using this function. |
372 /// \pre \ref run() must be called before using this function. |
324 int cycleEdgeNum() const { |
373 int cycleEdgeNum() const { |
325 return cycle_size; |
374 return cycle_size; |
326 } |
375 } |
327 |
376 |
328 /// \brief Returns the mean length of the found critical cycle. |
377 /// \brief Returns the mean length of the found cycle. |
329 /// |
378 /// |
330 /// Returns the mean length of the found critical cycle. |
379 /// Returns the mean length of the found cycle. |
331 /// |
380 /// |
332 /// \pre \ref run() must be called before using this function. |
381 /// \pre \ref run() must be called before using this function. |
333 /// |
382 /// |
334 /// \warning LengthMap::Value must be convertible to double. |
383 /// \warning LengthMap::Value must be convertible to double. |
|
384 /// |
|
385 /// \note m.minMean() is just a shortcut of the following code. |
|
386 /// \code |
|
387 /// return m.cycleEdgeNum() / double(m.cycleLength()); |
|
388 /// \endcode |
335 double minMean() const { |
389 double minMean() const { |
336 return (double)cycle_length / (double)cycle_size; |
390 return cycle_length / (double)cycle_size; |
337 } |
391 } |
338 |
392 |
339 /// \brief Returns a const reference to the \ref lemon::Path "Path" |
393 /// \brief Returns a const reference to the \ref lemon::Path "Path" |
340 /// structure of the found flow. |
394 /// structure of the found cycle. |
341 /// |
395 /// |
342 /// Returns a const reference to the \ref lemon::Path "Path" |
396 /// Returns a const reference to the \ref lemon::Path "Path" |
343 /// structure of the found flow. |
397 /// structure of the found cycle. |
344 /// |
398 /// |
345 /// \pre \ref run() must be called before using this function. |
399 /// \pre \ref run() must be called before using this function. |
346 /// |
400 /// |
347 /// \sa \ref cyclePath() |
401 /// \sa \ref cyclePath() |
348 const Path &cycle() const { |
402 const Path &cycle() const { |