31 #include <lemon/tolerance.h> |
31 #include <lemon/tolerance.h> |
32 #include <lemon/connectivity.h> |
32 #include <lemon/connectivity.h> |
33 |
33 |
34 namespace lemon { |
34 namespace lemon { |
35 |
35 |
36 /// \brief Default traits class of HartmannOrlin algorithm. |
36 /// \brief Default traits class of HartmannOrlinMmc class. |
37 /// |
37 /// |
38 /// Default traits class of HartmannOrlin algorithm. |
38 /// Default traits class of HartmannOrlinMmc class. |
39 /// \tparam GR The type of the digraph. |
39 /// \tparam GR The type of the digraph. |
40 /// \tparam LEN The type of the length map. |
40 /// \tparam CM The type of the cost map. |
41 /// It must conform to the \ref concepts::Rea_data "Rea_data" concept. |
41 /// It must conform to the \ref concepts::Rea_data "Rea_data" concept. |
42 #ifdef DOXYGEN |
42 #ifdef DOXYGEN |
43 template <typename GR, typename LEN> |
43 template <typename GR, typename CM> |
44 #else |
44 #else |
45 template <typename GR, typename LEN, |
45 template <typename GR, typename CM, |
46 bool integer = std::numeric_limits<typename LEN::Value>::is_integer> |
46 bool integer = std::numeric_limits<typename CM::Value>::is_integer> |
47 #endif |
47 #endif |
48 struct HartmannOrlinDefaultTraits |
48 struct HartmannOrlinMmcDefaultTraits |
49 { |
49 { |
50 /// The type of the digraph |
50 /// The type of the digraph |
51 typedef GR Digraph; |
51 typedef GR Digraph; |
52 /// The type of the length map |
52 /// The type of the cost map |
53 typedef LEN LengthMap; |
53 typedef CM CostMap; |
54 /// The type of the arc lengths |
54 /// The type of the arc costs |
55 typedef typename LengthMap::Value Value; |
55 typedef typename CostMap::Value Cost; |
56 |
56 |
57 /// \brief The large value type used for internal computations |
57 /// \brief The large cost type used for internal computations |
58 /// |
58 /// |
59 /// The large value type used for internal computations. |
59 /// The large cost type used for internal computations. |
60 /// It is \c long \c long if the \c Value type is integer, |
60 /// It is \c long \c long if the \c Cost type is integer, |
61 /// otherwise it is \c double. |
61 /// otherwise it is \c double. |
62 /// \c Value must be convertible to \c LargeValue. |
62 /// \c Cost must be convertible to \c LargeCost. |
63 typedef double LargeValue; |
63 typedef double LargeCost; |
64 |
64 |
65 /// The tolerance type used for internal computations |
65 /// The tolerance type used for internal computations |
66 typedef lemon::Tolerance<LargeValue> Tolerance; |
66 typedef lemon::Tolerance<LargeCost> Tolerance; |
67 |
67 |
68 /// \brief The path type of the found cycles |
68 /// \brief The path type of the found cycles |
69 /// |
69 /// |
70 /// The path type of the found cycles. |
70 /// The path type of the found cycles. |
71 /// It must conform to the \ref lemon::concepts::Path "Path" concept |
71 /// It must conform to the \ref lemon::concepts::Path "Path" concept |
72 /// and it must have an \c addFront() function. |
72 /// and it must have an \c addFront() function. |
73 typedef lemon::Path<Digraph> Path; |
73 typedef lemon::Path<Digraph> Path; |
74 }; |
74 }; |
75 |
75 |
76 // Default traits class for integer value types |
76 // Default traits class for integer cost types |
77 template <typename GR, typename LEN> |
77 template <typename GR, typename CM> |
78 struct HartmannOrlinDefaultTraits<GR, LEN, true> |
78 struct HartmannOrlinMmcDefaultTraits<GR, CM, true> |
79 { |
79 { |
80 typedef GR Digraph; |
80 typedef GR Digraph; |
81 typedef LEN LengthMap; |
81 typedef CM CostMap; |
82 typedef typename LengthMap::Value Value; |
82 typedef typename CostMap::Value Cost; |
83 #ifdef LEMON_HAVE_LONG_LONG |
83 #ifdef LEMON_HAVE_LONG_LONG |
84 typedef long long LargeValue; |
84 typedef long long LargeCost; |
85 #else |
85 #else |
86 typedef long LargeValue; |
86 typedef long LargeCost; |
87 #endif |
87 #endif |
88 typedef lemon::Tolerance<LargeValue> Tolerance; |
88 typedef lemon::Tolerance<LargeCost> Tolerance; |
89 typedef lemon::Path<Digraph> Path; |
89 typedef lemon::Path<Digraph> Path; |
90 }; |
90 }; |
91 |
91 |
92 |
92 |
93 /// \addtogroup min_mean_cycle |
93 /// \addtogroup min_mean_cycle |
95 |
95 |
96 /// \brief Implementation of the Hartmann-Orlin algorithm for finding |
96 /// \brief Implementation of the Hartmann-Orlin algorithm for finding |
97 /// a minimum mean cycle. |
97 /// a minimum mean cycle. |
98 /// |
98 /// |
99 /// This class implements the Hartmann-Orlin algorithm for finding |
99 /// This class implements the Hartmann-Orlin algorithm for finding |
100 /// a directed cycle of minimum mean length (cost) in a digraph |
100 /// a directed cycle of minimum mean cost in a digraph |
101 /// \ref amo93networkflows, \ref dasdan98minmeancycle. |
101 /// \ref amo93networkflows, \ref dasdan98minmeancycle. |
102 /// It is an improved version of \ref Karp "Karp"'s original algorithm, |
102 /// It is an improved version of \ref Karp "Karp"'s original algorithm, |
103 /// it applies an efficient early termination scheme. |
103 /// it applies an efficient early termination scheme. |
104 /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e). |
104 /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e). |
105 /// |
105 /// |
106 /// \tparam GR The type of the digraph the algorithm runs on. |
106 /// \tparam GR The type of the digraph the algorithm runs on. |
107 /// \tparam LEN The type of the length map. The default |
107 /// \tparam CM The type of the cost map. The default |
108 /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>". |
108 /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>". |
109 /// \tparam TR The traits class that defines various types used by the |
109 /// \tparam TR The traits class that defines various types used by the |
110 /// algorithm. By default, it is \ref HartmannOrlinDefaultTraits |
110 /// algorithm. By default, it is \ref HartmannOrlinMmcDefaultTraits |
111 /// "HartmannOrlinDefaultTraits<GR, LEN>". |
111 /// "HartmannOrlinMmcDefaultTraits<GR, CM>". |
112 /// In most cases, this parameter should not be set directly, |
112 /// In most cases, this parameter should not be set directly, |
113 /// consider to use the named template parameters instead. |
113 /// consider to use the named template parameters instead. |
114 #ifdef DOXYGEN |
114 #ifdef DOXYGEN |
115 template <typename GR, typename LEN, typename TR> |
115 template <typename GR, typename CM, typename TR> |
116 #else |
116 #else |
117 template < typename GR, |
117 template < typename GR, |
118 typename LEN = typename GR::template ArcMap<int>, |
118 typename CM = typename GR::template ArcMap<int>, |
119 typename TR = HartmannOrlinDefaultTraits<GR, LEN> > |
119 typename TR = HartmannOrlinMmcDefaultTraits<GR, CM> > |
120 #endif |
120 #endif |
121 class HartmannOrlin |
121 class HartmannOrlinMmc |
122 { |
122 { |
123 public: |
123 public: |
124 |
124 |
125 /// The type of the digraph |
125 /// The type of the digraph |
126 typedef typename TR::Digraph Digraph; |
126 typedef typename TR::Digraph Digraph; |
127 /// The type of the length map |
127 /// The type of the cost map |
128 typedef typename TR::LengthMap LengthMap; |
128 typedef typename TR::CostMap CostMap; |
129 /// The type of the arc lengths |
129 /// The type of the arc costs |
130 typedef typename TR::Value Value; |
130 typedef typename TR::Cost Cost; |
131 |
131 |
132 /// \brief The large value type |
132 /// \brief The large cost type |
133 /// |
133 /// |
134 /// The large value type used for internal computations. |
134 /// The large cost type used for internal computations. |
135 /// By default, it is \c long \c long if the \c Value type is integer, |
135 /// By default, it is \c long \c long if the \c Cost type is integer, |
136 /// otherwise it is \c double. |
136 /// otherwise it is \c double. |
137 typedef typename TR::LargeValue LargeValue; |
137 typedef typename TR::LargeCost LargeCost; |
138 |
138 |
139 /// The tolerance type |
139 /// The tolerance type |
140 typedef typename TR::Tolerance Tolerance; |
140 typedef typename TR::Tolerance Tolerance; |
141 |
141 |
142 /// \brief The path type of the found cycles |
142 /// \brief The path type of the found cycles |
143 /// |
143 /// |
144 /// The path type of the found cycles. |
144 /// The path type of the found cycles. |
145 /// Using the \ref HartmannOrlinDefaultTraits "default traits class", |
145 /// Using the \ref HartmannOrlinMmcDefaultTraits "default traits class", |
146 /// it is \ref lemon::Path "Path<Digraph>". |
146 /// it is \ref lemon::Path "Path<Digraph>". |
147 typedef typename TR::Path Path; |
147 typedef typename TR::Path Path; |
148 |
148 |
149 /// The \ref HartmannOrlinDefaultTraits "traits class" of the algorithm |
149 /// The \ref HartmannOrlinMmcDefaultTraits "traits class" of the algorithm |
150 typedef TR Traits; |
150 typedef TR Traits; |
151 |
151 |
152 private: |
152 private: |
153 |
153 |
154 TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); |
154 TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); |
155 |
155 |
156 // Data sturcture for path data |
156 // Data sturcture for path data |
157 struct PathData |
157 struct PathData |
158 { |
158 { |
159 LargeValue dist; |
159 LargeCost dist; |
160 Arc pred; |
160 Arc pred; |
161 PathData(LargeValue d, Arc p = INVALID) : |
161 PathData(LargeCost d, Arc p = INVALID) : |
162 dist(d), pred(p) {} |
162 dist(d), pred(p) {} |
163 }; |
163 }; |
164 |
164 |
165 typedef typename Digraph::template NodeMap<std::vector<PathData> > |
165 typedef typename Digraph::template NodeMap<std::vector<PathData> > |
166 PathDataNodeMap; |
166 PathDataNodeMap; |
167 |
167 |
168 private: |
168 private: |
169 |
169 |
170 // The digraph the algorithm runs on |
170 // The digraph the algorithm runs on |
171 const Digraph &_gr; |
171 const Digraph &_gr; |
172 // The length of the arcs |
172 // The cost of the arcs |
173 const LengthMap &_length; |
173 const CostMap &_cost; |
174 |
174 |
175 // Data for storing the strongly connected components |
175 // Data for storing the strongly connected components |
176 int _comp_num; |
176 int _comp_num; |
177 typename Digraph::template NodeMap<int> _comp; |
177 typename Digraph::template NodeMap<int> _comp; |
178 std::vector<std::vector<Node> > _comp_nodes; |
178 std::vector<std::vector<Node> > _comp_nodes; |
179 std::vector<Node>* _nodes; |
179 std::vector<Node>* _nodes; |
180 typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs; |
180 typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs; |
181 |
181 |
182 // Data for the found cycles |
182 // Data for the found cycles |
183 bool _curr_found, _best_found; |
183 bool _curr_found, _best_found; |
184 LargeValue _curr_length, _best_length; |
184 LargeCost _curr_cost, _best_cost; |
185 int _curr_size, _best_size; |
185 int _curr_size, _best_size; |
186 Node _curr_node, _best_node; |
186 Node _curr_node, _best_node; |
187 int _curr_level, _best_level; |
187 int _curr_level, _best_level; |
188 |
188 |
189 Path *_cycle_path; |
189 Path *_cycle_path; |
195 std::vector<Node> _process; |
195 std::vector<Node> _process; |
196 |
196 |
197 Tolerance _tolerance; |
197 Tolerance _tolerance; |
198 |
198 |
199 // Infinite constant |
199 // Infinite constant |
200 const LargeValue INF; |
200 const LargeCost INF; |
201 |
201 |
202 public: |
202 public: |
203 |
203 |
204 /// \name Named Template Parameters |
204 /// \name Named Template Parameters |
205 /// @{ |
205 /// @{ |
206 |
206 |
207 template <typename T> |
207 template <typename T> |
208 struct SetLargeValueTraits : public Traits { |
208 struct SetLargeCostTraits : public Traits { |
209 typedef T LargeValue; |
209 typedef T LargeCost; |
210 typedef lemon::Tolerance<T> Tolerance; |
210 typedef lemon::Tolerance<T> Tolerance; |
211 }; |
211 }; |
212 |
212 |
213 /// \brief \ref named-templ-param "Named parameter" for setting |
213 /// \brief \ref named-templ-param "Named parameter" for setting |
214 /// \c LargeValue type. |
214 /// \c LargeCost type. |
215 /// |
215 /// |
216 /// \ref named-templ-param "Named parameter" for setting \c LargeValue |
216 /// \ref named-templ-param "Named parameter" for setting \c LargeCost |
217 /// type. It is used for internal computations in the algorithm. |
217 /// type. It is used for internal computations in the algorithm. |
218 template <typename T> |
218 template <typename T> |
219 struct SetLargeValue |
219 struct SetLargeCost |
220 : public HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > { |
220 : public HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > { |
221 typedef HartmannOrlin<GR, LEN, SetLargeValueTraits<T> > Create; |
221 typedef HartmannOrlinMmc<GR, CM, SetLargeCostTraits<T> > Create; |
222 }; |
222 }; |
223 |
223 |
224 template <typename T> |
224 template <typename T> |
225 struct SetPathTraits : public Traits { |
225 struct SetPathTraits : public Traits { |
226 typedef T Path; |
226 typedef T Path; |
233 /// type of the found cycles. |
233 /// type of the found cycles. |
234 /// It must conform to the \ref lemon::concepts::Path "Path" concept |
234 /// It must conform to the \ref lemon::concepts::Path "Path" concept |
235 /// and it must have an \c addFront() function. |
235 /// and it must have an \c addFront() function. |
236 template <typename T> |
236 template <typename T> |
237 struct SetPath |
237 struct SetPath |
238 : public HartmannOrlin<GR, LEN, SetPathTraits<T> > { |
238 : public HartmannOrlinMmc<GR, CM, SetPathTraits<T> > { |
239 typedef HartmannOrlin<GR, LEN, SetPathTraits<T> > Create; |
239 typedef HartmannOrlinMmc<GR, CM, SetPathTraits<T> > Create; |
240 }; |
240 }; |
241 |
241 |
242 /// @} |
242 /// @} |
243 |
243 |
244 protected: |
244 protected: |
245 |
245 |
246 HartmannOrlin() {} |
246 HartmannOrlinMmc() {} |
247 |
247 |
248 public: |
248 public: |
249 |
249 |
250 /// \brief Constructor. |
250 /// \brief Constructor. |
251 /// |
251 /// |
252 /// The constructor of the class. |
252 /// The constructor of the class. |
253 /// |
253 /// |
254 /// \param digraph The digraph the algorithm runs on. |
254 /// \param digraph The digraph the algorithm runs on. |
255 /// \param length The lengths (costs) of the arcs. |
255 /// \param cost The costs of the arcs. |
256 HartmannOrlin( const Digraph &digraph, |
256 HartmannOrlinMmc( const Digraph &digraph, |
257 const LengthMap &length ) : |
257 const CostMap &cost ) : |
258 _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph), |
258 _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph), |
259 _best_found(false), _best_length(0), _best_size(1), |
259 _best_found(false), _best_cost(0), _best_size(1), |
260 _cycle_path(NULL), _local_path(false), _data(digraph), |
260 _cycle_path(NULL), _local_path(false), _data(digraph), |
261 INF(std::numeric_limits<LargeValue>::has_infinity ? |
261 INF(std::numeric_limits<LargeCost>::has_infinity ? |
262 std::numeric_limits<LargeValue>::infinity() : |
262 std::numeric_limits<LargeCost>::infinity() : |
263 std::numeric_limits<LargeValue>::max()) |
263 std::numeric_limits<LargeCost>::max()) |
264 {} |
264 {} |
265 |
265 |
266 /// Destructor. |
266 /// Destructor. |
267 ~HartmannOrlin() { |
267 ~HartmannOrlinMmc() { |
268 if (_local_path) delete _cycle_path; |
268 if (_local_path) delete _cycle_path; |
269 } |
269 } |
270 |
270 |
271 /// \brief Set the path structure for storing the found cycle. |
271 /// \brief Set the path structure for storing the found cycle. |
272 /// |
272 /// |
273 /// This function sets an external path structure for storing the |
273 /// This function sets an external path structure for storing the |
274 /// found cycle. |
274 /// found cycle. |
275 /// |
275 /// |
276 /// If you don't call this function before calling \ref run() or |
276 /// If you don't call this function before calling \ref run() or |
277 /// \ref findMinMean(), it will allocate a local \ref Path "path" |
277 /// \ref findCycleMean(), it will allocate a local \ref Path "path" |
278 /// structure. The destuctor deallocates this automatically |
278 /// structure. The destuctor deallocates this automatically |
279 /// allocated object, of course. |
279 /// allocated object, of course. |
280 /// |
280 /// |
281 /// \note The algorithm calls only the \ref lemon::Path::addFront() |
281 /// \note The algorithm calls only the \ref lemon::Path::addFront() |
282 /// "addFront()" function of the given path structure. |
282 /// "addFront()" function of the given path structure. |
283 /// |
283 /// |
284 /// \return <tt>(*this)</tt> |
284 /// \return <tt>(*this)</tt> |
285 HartmannOrlin& cycle(Path &path) { |
285 HartmannOrlinMmc& cycle(Path &path) { |
286 if (_local_path) { |
286 if (_local_path) { |
287 delete _cycle_path; |
287 delete _cycle_path; |
288 _local_path = false; |
288 _local_path = false; |
289 } |
289 } |
290 _cycle_path = &path; |
290 _cycle_path = &path; |
310 } |
310 } |
311 |
311 |
312 /// \name Execution control |
312 /// \name Execution control |
313 /// The simplest way to execute the algorithm is to call the \ref run() |
313 /// The simplest way to execute the algorithm is to call the \ref run() |
314 /// function.\n |
314 /// function.\n |
315 /// If you only need the minimum mean length, you may call |
315 /// If you only need the minimum mean cost, you may call |
316 /// \ref findMinMean(). |
316 /// \ref findCycleMean(). |
317 |
317 |
318 /// @{ |
318 /// @{ |
319 |
319 |
320 /// \brief Run the algorithm. |
320 /// \brief Run the algorithm. |
321 /// |
321 /// |
322 /// This function runs the algorithm. |
322 /// This function runs the algorithm. |
323 /// It can be called more than once (e.g. if the underlying digraph |
323 /// It can be called more than once (e.g. if the underlying digraph |
324 /// and/or the arc lengths have been modified). |
324 /// and/or the arc costs have been modified). |
325 /// |
325 /// |
326 /// \return \c true if a directed cycle exists in the digraph. |
326 /// \return \c true if a directed cycle exists in the digraph. |
327 /// |
327 /// |
328 /// \note <tt>mmc.run()</tt> is just a shortcut of the following code. |
328 /// \note <tt>mmc.run()</tt> is just a shortcut of the following code. |
329 /// \code |
329 /// \code |
330 /// return mmc.findMinMean() && mmc.findCycle(); |
330 /// return mmc.findCycleMean() && mmc.findCycle(); |
331 /// \endcode |
331 /// \endcode |
332 bool run() { |
332 bool run() { |
333 return findMinMean() && findCycle(); |
333 return findCycleMean() && findCycle(); |
334 } |
334 } |
335 |
335 |
336 /// \brief Find the minimum cycle mean. |
336 /// \brief Find the minimum cycle mean. |
337 /// |
337 /// |
338 /// This function finds the minimum mean length of the directed |
338 /// This function finds the minimum mean cost of the directed |
339 /// cycles in the digraph. |
339 /// cycles in the digraph. |
340 /// |
340 /// |
341 /// \return \c true if a directed cycle exists in the digraph. |
341 /// \return \c true if a directed cycle exists in the digraph. |
342 bool findMinMean() { |
342 bool findCycleMean() { |
343 // Initialization and find strongly connected components |
343 // Initialization and find strongly connected components |
344 init(); |
344 init(); |
345 findComponents(); |
345 findComponents(); |
346 |
346 |
347 // Find the minimum cycle mean in the components |
347 // Find the minimum cycle mean in the components |
349 if (!initComponent(comp)) continue; |
349 if (!initComponent(comp)) continue; |
350 processRounds(); |
350 processRounds(); |
351 |
351 |
352 // Update the best cycle (global minimum mean cycle) |
352 // Update the best cycle (global minimum mean cycle) |
353 if ( _curr_found && (!_best_found || |
353 if ( _curr_found && (!_best_found || |
354 _curr_length * _best_size < _best_length * _curr_size) ) { |
354 _curr_cost * _best_size < _best_cost * _curr_size) ) { |
355 _best_found = true; |
355 _best_found = true; |
356 _best_length = _curr_length; |
356 _best_cost = _curr_cost; |
357 _best_size = _curr_size; |
357 _best_size = _curr_size; |
358 _best_node = _curr_node; |
358 _best_node = _curr_node; |
359 _best_level = _curr_level; |
359 _best_level = _curr_level; |
360 } |
360 } |
361 } |
361 } |
362 return _best_found; |
362 return _best_found; |
363 } |
363 } |
364 |
364 |
365 /// \brief Find a minimum mean directed cycle. |
365 /// \brief Find a minimum mean directed cycle. |
366 /// |
366 /// |
367 /// This function finds a directed cycle of minimum mean length |
367 /// This function finds a directed cycle of minimum mean cost |
368 /// in the digraph using the data computed by findMinMean(). |
368 /// in the digraph using the data computed by findCycleMean(). |
369 /// |
369 /// |
370 /// \return \c true if a directed cycle exists in the digraph. |
370 /// \return \c true if a directed cycle exists in the digraph. |
371 /// |
371 /// |
372 /// \pre \ref findMinMean() must be called before using this function. |
372 /// \pre \ref findCycleMean() must be called before using this function. |
373 bool findCycle() { |
373 bool findCycle() { |
374 if (!_best_found) return false; |
374 if (!_best_found) return false; |
375 IntNodeMap reached(_gr, -1); |
375 IntNodeMap reached(_gr, -1); |
376 int r = _best_level + 1; |
376 int r = _best_level + 1; |
377 Node u = _best_node; |
377 Node u = _best_node; |
401 /// functions.\n |
401 /// functions.\n |
402 /// The algorithm should be executed before using them. |
402 /// The algorithm should be executed before using them. |
403 |
403 |
404 /// @{ |
404 /// @{ |
405 |
405 |
406 /// \brief Return the total length of the found cycle. |
406 /// \brief Return the total cost of the found cycle. |
407 /// |
407 /// |
408 /// This function returns the total length of the found cycle. |
408 /// This function returns the total cost of the found cycle. |
409 /// |
409 /// |
410 /// \pre \ref run() or \ref findMinMean() must be called before |
410 /// \pre \ref run() or \ref findCycleMean() must be called before |
411 /// using this function. |
411 /// using this function. |
412 Value cycleLength() const { |
412 Cost cycleCost() const { |
413 return static_cast<Value>(_best_length); |
413 return static_cast<Cost>(_best_cost); |
414 } |
414 } |
415 |
415 |
416 /// \brief Return the number of arcs on the found cycle. |
416 /// \brief Return the number of arcs on the found cycle. |
417 /// |
417 /// |
418 /// This function returns the number of arcs on the found cycle. |
418 /// This function returns the number of arcs on the found cycle. |
419 /// |
419 /// |
420 /// \pre \ref run() or \ref findMinMean() must be called before |
420 /// \pre \ref run() or \ref findCycleMean() must be called before |
421 /// using this function. |
421 /// using this function. |
422 int cycleArcNum() const { |
422 int cycleSize() const { |
423 return _best_size; |
423 return _best_size; |
424 } |
424 } |
425 |
425 |
426 /// \brief Return the mean length of the found cycle. |
426 /// \brief Return the mean cost of the found cycle. |
427 /// |
427 /// |
428 /// This function returns the mean length of the found cycle. |
428 /// This function returns the mean cost of the found cycle. |
429 /// |
429 /// |
430 /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the |
430 /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the |
431 /// following code. |
431 /// following code. |
432 /// \code |
432 /// \code |
433 /// return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum(); |
433 /// return static_cast<double>(alg.cycleCost()) / alg.cycleSize(); |
434 /// \endcode |
434 /// \endcode |
435 /// |
435 /// |
436 /// \pre \ref run() or \ref findMinMean() must be called before |
436 /// \pre \ref run() or \ref findCycleMean() must be called before |
437 /// using this function. |
437 /// using this function. |
438 double cycleMean() const { |
438 double cycleMean() const { |
439 return static_cast<double>(_best_length) / _best_size; |
439 return static_cast<double>(_best_cost) / _best_size; |
440 } |
440 } |
441 |
441 |
442 /// \brief Return the found cycle. |
442 /// \brief Return the found cycle. |
443 /// |
443 /// |
444 /// This function returns a const reference to the path structure |
444 /// This function returns a const reference to the path structure |
611 } |
611 } |
612 } |
612 } |
613 } |
613 } |
614 |
614 |
615 // If at least one cycle is found, check the optimality condition |
615 // If at least one cycle is found, check the optimality condition |
616 LargeValue d; |
616 LargeCost d; |
617 if (_curr_found && k < n) { |
617 if (_curr_found && k < n) { |
618 // Find node potentials |
618 // Find node potentials |
619 for (int i = 0; i < n; ++i) { |
619 for (int i = 0; i < n; ++i) { |
620 u = (*_nodes)[i]; |
620 u = (*_nodes)[i]; |
621 pi[u] = INF; |
621 pi[u] = INF; |
622 for (int j = 0; j <= k; ++j) { |
622 for (int j = 0; j <= k; ++j) { |
623 if (_data[u][j].dist < INF) { |
623 if (_data[u][j].dist < INF) { |
624 d = _data[u][j].dist * _curr_size - j * _curr_length; |
624 d = _data[u][j].dist * _curr_size - j * _curr_cost; |
625 if (_tolerance.less(d, pi[u])) pi[u] = d; |
625 if (_tolerance.less(d, pi[u])) pi[u] = d; |
626 } |
626 } |
627 } |
627 } |
628 } |
628 } |
629 |
629 |
630 // Check the optimality condition for all arcs |
630 // Check the optimality condition for all arcs |
631 bool done = true; |
631 bool done = true; |
632 for (ArcIt a(_gr); a != INVALID; ++a) { |
632 for (ArcIt a(_gr); a != INVALID; ++a) { |
633 if (_tolerance.less(_length[a] * _curr_size - _curr_length, |
633 if (_tolerance.less(_cost[a] * _curr_size - _curr_cost, |
634 pi[_gr.target(a)] - pi[_gr.source(a)]) ) { |
634 pi[_gr.target(a)] - pi[_gr.source(a)]) ) { |
635 done = false; |
635 done = false; |
636 break; |
636 break; |
637 } |
637 } |
638 } |
638 } |
639 return done; |
639 return done; |
640 } |
640 } |
641 return (k == n); |
641 return (k == n); |
642 } |
642 } |
643 |
643 |
644 }; //class HartmannOrlin |
644 }; //class HartmannOrlinMmc |
645 |
645 |
646 ///@} |
646 ///@} |
647 |
647 |
648 } //namespace lemon |
648 } //namespace lemon |
649 |
649 |
650 #endif //LEMON_HARTMANN_ORLIN_H |
650 #endif //LEMON_HARTMANN_ORLIN_MMC_H |