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 Karp algorithm. |
36 /// \brief Default traits class of KarpMmc class. |
37 /// |
37 /// |
38 /// Default traits class of Karp algorithm. |
38 /// Default traits class of KarpMmc 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::ReadMap "ReadMap" concept. |
41 /// It must conform to the \ref concepts::ReadMap "ReadMap" 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 KarpDefaultTraits |
48 struct KarpMmcDefaultTraits |
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 KarpDefaultTraits<GR, LEN, true> |
78 struct KarpMmcDefaultTraits<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 Karp's algorithm for finding a minimum |
96 /// \brief Implementation of Karp's algorithm for finding a minimum |
97 /// mean cycle. |
97 /// mean cycle. |
98 /// |
98 /// |
99 /// This class implements Karp's algorithm for finding a directed |
99 /// This class implements Karp's algorithm for finding a directed |
100 /// cycle of minimum mean length (cost) in a digraph |
100 /// cycle of minimum mean cost in a digraph |
101 /// \ref amo93networkflows, \ref dasdan98minmeancycle. |
101 /// \ref amo93networkflows, \ref dasdan98minmeancycle. |
102 /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e). |
102 /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e). |
103 /// |
103 /// |
104 /// \tparam GR The type of the digraph the algorithm runs on. |
104 /// \tparam GR The type of the digraph the algorithm runs on. |
105 /// \tparam LEN The type of the length map. The default |
105 /// \tparam CM The type of the cost map. The default |
106 /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>". |
106 /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>". |
107 /// \tparam TR The traits class that defines various types used by the |
107 /// \tparam TR The traits class that defines various types used by the |
108 /// algorithm. By default, it is \ref KarpDefaultTraits |
108 /// algorithm. By default, it is \ref KarpMmcDefaultTraits |
109 /// "KarpDefaultTraits<GR, LEN>". |
109 /// "KarpMmcDefaultTraits<GR, CM>". |
110 /// In most cases, this parameter should not be set directly, |
110 /// In most cases, this parameter should not be set directly, |
111 /// consider to use the named template parameters instead. |
111 /// consider to use the named template parameters instead. |
112 #ifdef DOXYGEN |
112 #ifdef DOXYGEN |
113 template <typename GR, typename LEN, typename TR> |
113 template <typename GR, typename CM, typename TR> |
114 #else |
114 #else |
115 template < typename GR, |
115 template < typename GR, |
116 typename LEN = typename GR::template ArcMap<int>, |
116 typename CM = typename GR::template ArcMap<int>, |
117 typename TR = KarpDefaultTraits<GR, LEN> > |
117 typename TR = KarpMmcDefaultTraits<GR, CM> > |
118 #endif |
118 #endif |
119 class Karp |
119 class KarpMmc |
120 { |
120 { |
121 public: |
121 public: |
122 |
122 |
123 /// The type of the digraph |
123 /// The type of the digraph |
124 typedef typename TR::Digraph Digraph; |
124 typedef typename TR::Digraph Digraph; |
125 /// The type of the length map |
125 /// The type of the cost map |
126 typedef typename TR::LengthMap LengthMap; |
126 typedef typename TR::CostMap CostMap; |
127 /// The type of the arc lengths |
127 /// The type of the arc costs |
128 typedef typename TR::Value Value; |
128 typedef typename TR::Cost Cost; |
129 |
129 |
130 /// \brief The large value type |
130 /// \brief The large cost type |
131 /// |
131 /// |
132 /// The large value type used for internal computations. |
132 /// The large cost type used for internal computations. |
133 /// By default, it is \c long \c long if the \c Value type is integer, |
133 /// By default, it is \c long \c long if the \c Cost type is integer, |
134 /// otherwise it is \c double. |
134 /// otherwise it is \c double. |
135 typedef typename TR::LargeValue LargeValue; |
135 typedef typename TR::LargeCost LargeCost; |
136 |
136 |
137 /// The tolerance type |
137 /// The tolerance type |
138 typedef typename TR::Tolerance Tolerance; |
138 typedef typename TR::Tolerance Tolerance; |
139 |
139 |
140 /// \brief The path type of the found cycles |
140 /// \brief The path type of the found cycles |
141 /// |
141 /// |
142 /// The path type of the found cycles. |
142 /// The path type of the found cycles. |
143 /// Using the \ref KarpDefaultTraits "default traits class", |
143 /// Using the \ref KarpMmcDefaultTraits "default traits class", |
144 /// it is \ref lemon::Path "Path<Digraph>". |
144 /// it is \ref lemon::Path "Path<Digraph>". |
145 typedef typename TR::Path Path; |
145 typedef typename TR::Path Path; |
146 |
146 |
147 /// The \ref KarpDefaultTraits "traits class" of the algorithm |
147 /// The \ref KarpMmcDefaultTraits "traits class" of the algorithm |
148 typedef TR Traits; |
148 typedef TR Traits; |
149 |
149 |
150 private: |
150 private: |
151 |
151 |
152 TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); |
152 TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); |
153 |
153 |
154 // Data sturcture for path data |
154 // Data sturcture for path data |
155 struct PathData |
155 struct PathData |
156 { |
156 { |
157 LargeValue dist; |
157 LargeCost dist; |
158 Arc pred; |
158 Arc pred; |
159 PathData(LargeValue d, Arc p = INVALID) : |
159 PathData(LargeCost d, Arc p = INVALID) : |
160 dist(d), pred(p) {} |
160 dist(d), pred(p) {} |
161 }; |
161 }; |
162 |
162 |
163 typedef typename Digraph::template NodeMap<std::vector<PathData> > |
163 typedef typename Digraph::template NodeMap<std::vector<PathData> > |
164 PathDataNodeMap; |
164 PathDataNodeMap; |
165 |
165 |
166 private: |
166 private: |
167 |
167 |
168 // The digraph the algorithm runs on |
168 // The digraph the algorithm runs on |
169 const Digraph &_gr; |
169 const Digraph &_gr; |
170 // The length of the arcs |
170 // The cost of the arcs |
171 const LengthMap &_length; |
171 const CostMap &_cost; |
172 |
172 |
173 // Data for storing the strongly connected components |
173 // Data for storing the strongly connected components |
174 int _comp_num; |
174 int _comp_num; |
175 typename Digraph::template NodeMap<int> _comp; |
175 typename Digraph::template NodeMap<int> _comp; |
176 std::vector<std::vector<Node> > _comp_nodes; |
176 std::vector<std::vector<Node> > _comp_nodes; |
177 std::vector<Node>* _nodes; |
177 std::vector<Node>* _nodes; |
178 typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs; |
178 typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs; |
179 |
179 |
180 // Data for the found cycle |
180 // Data for the found cycle |
181 LargeValue _cycle_length; |
181 LargeCost _cycle_cost; |
182 int _cycle_size; |
182 int _cycle_size; |
183 Node _cycle_node; |
183 Node _cycle_node; |
184 |
184 |
185 Path *_cycle_path; |
185 Path *_cycle_path; |
186 bool _local_path; |
186 bool _local_path; |
191 std::vector<Node> _process; |
191 std::vector<Node> _process; |
192 |
192 |
193 Tolerance _tolerance; |
193 Tolerance _tolerance; |
194 |
194 |
195 // Infinite constant |
195 // Infinite constant |
196 const LargeValue INF; |
196 const LargeCost INF; |
197 |
197 |
198 public: |
198 public: |
199 |
199 |
200 /// \name Named Template Parameters |
200 /// \name Named Template Parameters |
201 /// @{ |
201 /// @{ |
202 |
202 |
203 template <typename T> |
203 template <typename T> |
204 struct SetLargeValueTraits : public Traits { |
204 struct SetLargeCostTraits : public Traits { |
205 typedef T LargeValue; |
205 typedef T LargeCost; |
206 typedef lemon::Tolerance<T> Tolerance; |
206 typedef lemon::Tolerance<T> Tolerance; |
207 }; |
207 }; |
208 |
208 |
209 /// \brief \ref named-templ-param "Named parameter" for setting |
209 /// \brief \ref named-templ-param "Named parameter" for setting |
210 /// \c LargeValue type. |
210 /// \c LargeCost type. |
211 /// |
211 /// |
212 /// \ref named-templ-param "Named parameter" for setting \c LargeValue |
212 /// \ref named-templ-param "Named parameter" for setting \c LargeCost |
213 /// type. It is used for internal computations in the algorithm. |
213 /// type. It is used for internal computations in the algorithm. |
214 template <typename T> |
214 template <typename T> |
215 struct SetLargeValue |
215 struct SetLargeCost |
216 : public Karp<GR, LEN, SetLargeValueTraits<T> > { |
216 : public KarpMmc<GR, CM, SetLargeCostTraits<T> > { |
217 typedef Karp<GR, LEN, SetLargeValueTraits<T> > Create; |
217 typedef KarpMmc<GR, CM, SetLargeCostTraits<T> > Create; |
218 }; |
218 }; |
219 |
219 |
220 template <typename T> |
220 template <typename T> |
221 struct SetPathTraits : public Traits { |
221 struct SetPathTraits : public Traits { |
222 typedef T Path; |
222 typedef T Path; |
229 /// type of the found cycles. |
229 /// type of the found cycles. |
230 /// It must conform to the \ref lemon::concepts::Path "Path" concept |
230 /// It must conform to the \ref lemon::concepts::Path "Path" concept |
231 /// and it must have an \c addFront() function. |
231 /// and it must have an \c addFront() function. |
232 template <typename T> |
232 template <typename T> |
233 struct SetPath |
233 struct SetPath |
234 : public Karp<GR, LEN, SetPathTraits<T> > { |
234 : public KarpMmc<GR, CM, SetPathTraits<T> > { |
235 typedef Karp<GR, LEN, SetPathTraits<T> > Create; |
235 typedef KarpMmc<GR, CM, SetPathTraits<T> > Create; |
236 }; |
236 }; |
237 |
237 |
238 /// @} |
238 /// @} |
239 |
239 |
240 protected: |
240 protected: |
241 |
241 |
242 Karp() {} |
242 KarpMmc() {} |
243 |
243 |
244 public: |
244 public: |
245 |
245 |
246 /// \brief Constructor. |
246 /// \brief Constructor. |
247 /// |
247 /// |
248 /// The constructor of the class. |
248 /// The constructor of the class. |
249 /// |
249 /// |
250 /// \param digraph The digraph the algorithm runs on. |
250 /// \param digraph The digraph the algorithm runs on. |
251 /// \param length The lengths (costs) of the arcs. |
251 /// \param cost The costs of the arcs. |
252 Karp( const Digraph &digraph, |
252 KarpMmc( const Digraph &digraph, |
253 const LengthMap &length ) : |
253 const CostMap &cost ) : |
254 _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph), |
254 _gr(digraph), _cost(cost), _comp(digraph), _out_arcs(digraph), |
255 _cycle_length(0), _cycle_size(1), _cycle_node(INVALID), |
255 _cycle_cost(0), _cycle_size(1), _cycle_node(INVALID), |
256 _cycle_path(NULL), _local_path(false), _data(digraph), |
256 _cycle_path(NULL), _local_path(false), _data(digraph), |
257 INF(std::numeric_limits<LargeValue>::has_infinity ? |
257 INF(std::numeric_limits<LargeCost>::has_infinity ? |
258 std::numeric_limits<LargeValue>::infinity() : |
258 std::numeric_limits<LargeCost>::infinity() : |
259 std::numeric_limits<LargeValue>::max()) |
259 std::numeric_limits<LargeCost>::max()) |
260 {} |
260 {} |
261 |
261 |
262 /// Destructor. |
262 /// Destructor. |
263 ~Karp() { |
263 ~KarpMmc() { |
264 if (_local_path) delete _cycle_path; |
264 if (_local_path) delete _cycle_path; |
265 } |
265 } |
266 |
266 |
267 /// \brief Set the path structure for storing the found cycle. |
267 /// \brief Set the path structure for storing the found cycle. |
268 /// |
268 /// |
269 /// This function sets an external path structure for storing the |
269 /// This function sets an external path structure for storing the |
270 /// found cycle. |
270 /// found cycle. |
271 /// |
271 /// |
272 /// If you don't call this function before calling \ref run() or |
272 /// If you don't call this function before calling \ref run() or |
273 /// \ref findMinMean(), it will allocate a local \ref Path "path" |
273 /// \ref findCycleMean(), it will allocate a local \ref Path "path" |
274 /// structure. The destuctor deallocates this automatically |
274 /// structure. The destuctor deallocates this automatically |
275 /// allocated object, of course. |
275 /// allocated object, of course. |
276 /// |
276 /// |
277 /// \note The algorithm calls only the \ref lemon::Path::addFront() |
277 /// \note The algorithm calls only the \ref lemon::Path::addFront() |
278 /// "addFront()" function of the given path structure. |
278 /// "addFront()" function of the given path structure. |
279 /// |
279 /// |
280 /// \return <tt>(*this)</tt> |
280 /// \return <tt>(*this)</tt> |
281 Karp& cycle(Path &path) { |
281 KarpMmc& cycle(Path &path) { |
282 if (_local_path) { |
282 if (_local_path) { |
283 delete _cycle_path; |
283 delete _cycle_path; |
284 _local_path = false; |
284 _local_path = false; |
285 } |
285 } |
286 _cycle_path = &path; |
286 _cycle_path = &path; |
306 } |
306 } |
307 |
307 |
308 /// \name Execution control |
308 /// \name Execution control |
309 /// The simplest way to execute the algorithm is to call the \ref run() |
309 /// The simplest way to execute the algorithm is to call the \ref run() |
310 /// function.\n |
310 /// function.\n |
311 /// If you only need the minimum mean length, you may call |
311 /// If you only need the minimum mean cost, you may call |
312 /// \ref findMinMean(). |
312 /// \ref findCycleMean(). |
313 |
313 |
314 /// @{ |
314 /// @{ |
315 |
315 |
316 /// \brief Run the algorithm. |
316 /// \brief Run the algorithm. |
317 /// |
317 /// |
318 /// This function runs the algorithm. |
318 /// This function runs the algorithm. |
319 /// It can be called more than once (e.g. if the underlying digraph |
319 /// It can be called more than once (e.g. if the underlying digraph |
320 /// and/or the arc lengths have been modified). |
320 /// and/or the arc costs have been modified). |
321 /// |
321 /// |
322 /// \return \c true if a directed cycle exists in the digraph. |
322 /// \return \c true if a directed cycle exists in the digraph. |
323 /// |
323 /// |
324 /// \note <tt>mmc.run()</tt> is just a shortcut of the following code. |
324 /// \note <tt>mmc.run()</tt> is just a shortcut of the following code. |
325 /// \code |
325 /// \code |
326 /// return mmc.findMinMean() && mmc.findCycle(); |
326 /// return mmc.findCycleMean() && mmc.findCycle(); |
327 /// \endcode |
327 /// \endcode |
328 bool run() { |
328 bool run() { |
329 return findMinMean() && findCycle(); |
329 return findCycleMean() && findCycle(); |
330 } |
330 } |
331 |
331 |
332 /// \brief Find the minimum cycle mean. |
332 /// \brief Find the minimum cycle mean. |
333 /// |
333 /// |
334 /// This function finds the minimum mean length of the directed |
334 /// This function finds the minimum mean cost of the directed |
335 /// cycles in the digraph. |
335 /// cycles in the digraph. |
336 /// |
336 /// |
337 /// \return \c true if a directed cycle exists in the digraph. |
337 /// \return \c true if a directed cycle exists in the digraph. |
338 bool findMinMean() { |
338 bool findCycleMean() { |
339 // Initialization and find strongly connected components |
339 // Initialization and find strongly connected components |
340 init(); |
340 init(); |
341 findComponents(); |
341 findComponents(); |
342 |
342 |
343 // Find the minimum cycle mean in the components |
343 // Find the minimum cycle mean in the components |
388 /// functions.\n |
388 /// functions.\n |
389 /// The algorithm should be executed before using them. |
389 /// The algorithm should be executed before using them. |
390 |
390 |
391 /// @{ |
391 /// @{ |
392 |
392 |
393 /// \brief Return the total length of the found cycle. |
393 /// \brief Return the total cost of the found cycle. |
394 /// |
394 /// |
395 /// This function returns the total length of the found cycle. |
395 /// This function returns the total cost of the found cycle. |
396 /// |
396 /// |
397 /// \pre \ref run() or \ref findMinMean() must be called before |
397 /// \pre \ref run() or \ref findCycleMean() must be called before |
398 /// using this function. |
398 /// using this function. |
399 Value cycleLength() const { |
399 Cost cycleCost() const { |
400 return static_cast<Value>(_cycle_length); |
400 return static_cast<Cost>(_cycle_cost); |
401 } |
401 } |
402 |
402 |
403 /// \brief Return the number of arcs on the found cycle. |
403 /// \brief Return the number of arcs on the found cycle. |
404 /// |
404 /// |
405 /// This function returns the number of arcs on the found cycle. |
405 /// This function returns the number of arcs on the found cycle. |
406 /// |
406 /// |
407 /// \pre \ref run() or \ref findMinMean() must be called before |
407 /// \pre \ref run() or \ref findCycleMean() must be called before |
408 /// using this function. |
408 /// using this function. |
409 int cycleArcNum() const { |
409 int cycleSize() const { |
410 return _cycle_size; |
410 return _cycle_size; |
411 } |
411 } |
412 |
412 |
413 /// \brief Return the mean length of the found cycle. |
413 /// \brief Return the mean cost of the found cycle. |
414 /// |
414 /// |
415 /// This function returns the mean length of the found cycle. |
415 /// This function returns the mean cost of the found cycle. |
416 /// |
416 /// |
417 /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the |
417 /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the |
418 /// following code. |
418 /// following code. |
419 /// \code |
419 /// \code |
420 /// return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum(); |
420 /// return static_cast<double>(alg.cycleCost()) / alg.cycleSize(); |
421 /// \endcode |
421 /// \endcode |
422 /// |
422 /// |
423 /// \pre \ref run() or \ref findMinMean() must be called before |
423 /// \pre \ref run() or \ref findCycleMean() must be called before |
424 /// using this function. |
424 /// using this function. |
425 double cycleMean() const { |
425 double cycleMean() const { |
426 return static_cast<double>(_cycle_length) / _cycle_size; |
426 return static_cast<double>(_cycle_cost) / _cycle_size; |
427 } |
427 } |
428 |
428 |
429 /// \brief Return the found cycle. |
429 /// \brief Return the found cycle. |
430 /// |
430 /// |
431 /// This function returns a const reference to the path structure |
431 /// This function returns a const reference to the path structure |
557 void updateMinMean() { |
557 void updateMinMean() { |
558 int n = _nodes->size(); |
558 int n = _nodes->size(); |
559 for (int i = 0; i < n; ++i) { |
559 for (int i = 0; i < n; ++i) { |
560 Node u = (*_nodes)[i]; |
560 Node u = (*_nodes)[i]; |
561 if (_data[u][n].dist == INF) continue; |
561 if (_data[u][n].dist == INF) continue; |
562 LargeValue length, max_length = 0; |
562 LargeCost cost, max_cost = 0; |
563 int size, max_size = 1; |
563 int size, max_size = 1; |
564 bool found_curr = false; |
564 bool found_curr = false; |
565 for (int k = 0; k < n; ++k) { |
565 for (int k = 0; k < n; ++k) { |
566 if (_data[u][k].dist == INF) continue; |
566 if (_data[u][k].dist == INF) continue; |
567 length = _data[u][n].dist - _data[u][k].dist; |
567 cost = _data[u][n].dist - _data[u][k].dist; |
568 size = n - k; |
568 size = n - k; |
569 if (!found_curr || length * max_size > max_length * size) { |
569 if (!found_curr || cost * max_size > max_cost * size) { |
570 found_curr = true; |
570 found_curr = true; |
571 max_length = length; |
571 max_cost = cost; |
572 max_size = size; |
572 max_size = size; |
573 } |
573 } |
574 } |
574 } |
575 if ( found_curr && (_cycle_node == INVALID || |
575 if ( found_curr && (_cycle_node == INVALID || |
576 max_length * _cycle_size < _cycle_length * max_size) ) { |
576 max_cost * _cycle_size < _cycle_cost * max_size) ) { |
577 _cycle_length = max_length; |
577 _cycle_cost = max_cost; |
578 _cycle_size = max_size; |
578 _cycle_size = max_size; |
579 _cycle_node = u; |
579 _cycle_node = u; |
580 } |
580 } |
581 } |
581 } |
582 } |
582 } |
583 |
583 |
584 }; //class Karp |
584 }; //class KarpMmc |
585 |
585 |
586 ///@} |
586 ///@} |
587 |
587 |
588 } //namespace lemon |
588 } //namespace lemon |
589 |
589 |
590 #endif //LEMON_KARP_H |
590 #endif //LEMON_KARP_MMC_H |