| 1 | /* -*- C++ -*- | 
|---|
| 2 |  * | 
|---|
| 3 |  * This file is a part of LEMON, a generic C++ optimization library | 
|---|
| 4 |  * | 
|---|
| 5 |  * Copyright (C) 2003-2008 | 
|---|
| 6 |  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport | 
|---|
| 7 |  * (Egervary Research Group on Combinatorial Optimization, EGRES). | 
|---|
| 8 |  * | 
|---|
| 9 |  * Permission to use, modify and distribute this software is granted | 
|---|
| 10 |  * provided that this copyright notice appears in all copies. For | 
|---|
| 11 |  * precise terms see the accompanying LICENSE file. | 
|---|
| 12 |  * | 
|---|
| 13 |  * This software is provided "AS IS" with no warranty of any kind, | 
|---|
| 14 |  * express or implied, and with no claim as to its suitability for any | 
|---|
| 15 |  * purpose. | 
|---|
| 16 |  * | 
|---|
| 17 |  */ | 
|---|
| 18 |  | 
|---|
| 19 | #ifndef LEMON_KARP_H | 
|---|
| 20 | #define LEMON_KARP_H | 
|---|
| 21 |  | 
|---|
| 22 | /// \ingroup min_mean_cycle | 
|---|
| 23 | /// | 
|---|
| 24 | /// \file | 
|---|
| 25 | /// \brief Karp's algorithm for finding a minimum mean cycle. | 
|---|
| 26 |  | 
|---|
| 27 | #include <vector> | 
|---|
| 28 | #include <limits> | 
|---|
| 29 | #include <lemon/core.h> | 
|---|
| 30 | #include <lemon/path.h> | 
|---|
| 31 | #include <lemon/tolerance.h> | 
|---|
| 32 | #include <lemon/connectivity.h> | 
|---|
| 33 |  | 
|---|
| 34 | namespace lemon { | 
|---|
| 35 |  | 
|---|
| 36 |   /// \brief Default traits class of Karp algorithm. | 
|---|
| 37 |   /// | 
|---|
| 38 |   /// Default traits class of Karp algorithm. | 
|---|
| 39 |   /// \tparam GR The type of the digraph. | 
|---|
| 40 |   /// \tparam LEN The type of the length map. | 
|---|
| 41 |   /// It must conform to the \ref concepts::ReadMap "ReadMap" concept. | 
|---|
| 42 | #ifdef DOXYGEN | 
|---|
| 43 |   template <typename GR, typename LEN> | 
|---|
| 44 | #else | 
|---|
| 45 |   template <typename GR, typename LEN, | 
|---|
| 46 |     bool integer = std::numeric_limits<typename LEN::Value>::is_integer> | 
|---|
| 47 | #endif | 
|---|
| 48 |   struct KarpDefaultTraits | 
|---|
| 49 |   { | 
|---|
| 50 |     /// The type of the digraph | 
|---|
| 51 |     typedef GR Digraph; | 
|---|
| 52 |     /// The type of the length map | 
|---|
| 53 |     typedef LEN LengthMap; | 
|---|
| 54 |     /// The type of the arc lengths | 
|---|
| 55 |     typedef typename LengthMap::Value Value; | 
|---|
| 56 |  | 
|---|
| 57 |     /// \brief The large value type used for internal computations | 
|---|
| 58 |     /// | 
|---|
| 59 |     /// The large value type used for internal computations. | 
|---|
| 60 |     /// It is \c long \c long if the \c Value type is integer, | 
|---|
| 61 |     /// otherwise it is \c double. | 
|---|
| 62 |     /// \c Value must be convertible to \c LargeValue. | 
|---|
| 63 |     typedef double LargeValue; | 
|---|
| 64 |  | 
|---|
| 65 |     /// The tolerance type used for internal computations | 
|---|
| 66 |     typedef lemon::Tolerance<LargeValue> Tolerance; | 
|---|
| 67 |  | 
|---|
| 68 |     /// \brief The path type of the found cycles | 
|---|
| 69 |     /// | 
|---|
| 70 |     /// The path type of the found cycles. | 
|---|
| 71 |     /// It must conform to the \ref lemon::concepts::Path "Path" concept | 
|---|
| 72 |     /// and it must have an \c addFront() function. | 
|---|
| 73 |     typedef lemon::Path<Digraph> Path; | 
|---|
| 74 |   }; | 
|---|
| 75 |  | 
|---|
| 76 |   // Default traits class for integer value types | 
|---|
| 77 |   template <typename GR, typename LEN> | 
|---|
| 78 |   struct KarpDefaultTraits<GR, LEN, true> | 
|---|
| 79 |   { | 
|---|
| 80 |     typedef GR Digraph; | 
|---|
| 81 |     typedef LEN LengthMap; | 
|---|
| 82 |     typedef typename LengthMap::Value Value; | 
|---|
| 83 | #ifdef LEMON_HAVE_LONG_LONG | 
|---|
| 84 |     typedef long long LargeValue; | 
|---|
| 85 | #else | 
|---|
| 86 |     typedef long LargeValue; | 
|---|
| 87 | #endif | 
|---|
| 88 |     typedef lemon::Tolerance<LargeValue> Tolerance; | 
|---|
| 89 |     typedef lemon::Path<Digraph> Path; | 
|---|
| 90 |   }; | 
|---|
| 91 |  | 
|---|
| 92 |  | 
|---|
| 93 |   /// \addtogroup min_mean_cycle | 
|---|
| 94 |   /// @{ | 
|---|
| 95 |  | 
|---|
| 96 |   /// \brief Implementation of Karp's algorithm for finding a minimum | 
|---|
| 97 |   /// mean cycle. | 
|---|
| 98 |   /// | 
|---|
| 99 |   /// This class implements Karp's algorithm for finding a directed | 
|---|
| 100 |   /// cycle of minimum mean length (cost) in a digraph | 
|---|
| 101 |   /// \ref amo93networkflows, \ref dasdan98minmeancycle. | 
|---|
| 102 |   /// It runs in time O(ne) and uses space O(n<sup>2</sup>+e). | 
|---|
| 103 |   /// | 
|---|
| 104 |   /// \tparam GR The type of the digraph the algorithm runs on. | 
|---|
| 105 |   /// \tparam LEN The type of the length map. The default | 
|---|
| 106 |   /// map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>". | 
|---|
| 107 |   /// \tparam TR The traits class that defines various types used by the | 
|---|
| 108 |   /// algorithm. By default, it is \ref KarpDefaultTraits | 
|---|
| 109 |   /// "KarpDefaultTraits<GR, LEN>". | 
|---|
| 110 |   /// In most cases, this parameter should not be set directly, | 
|---|
| 111 |   /// consider to use the named template parameters instead. | 
|---|
| 112 | #ifdef DOXYGEN | 
|---|
| 113 |   template <typename GR, typename LEN, typename TR> | 
|---|
| 114 | #else | 
|---|
| 115 |   template < typename GR, | 
|---|
| 116 |              typename LEN = typename GR::template ArcMap<int>, | 
|---|
| 117 |              typename TR = KarpDefaultTraits<GR, LEN> > | 
|---|
| 118 | #endif | 
|---|
| 119 |   class Karp | 
|---|
| 120 |   { | 
|---|
| 121 |   public: | 
|---|
| 122 |  | 
|---|
| 123 |     /// The type of the digraph | 
|---|
| 124 |     typedef typename TR::Digraph Digraph; | 
|---|
| 125 |     /// The type of the length map | 
|---|
| 126 |     typedef typename TR::LengthMap LengthMap; | 
|---|
| 127 |     /// The type of the arc lengths | 
|---|
| 128 |     typedef typename TR::Value Value; | 
|---|
| 129 |  | 
|---|
| 130 |     /// \brief The large value type | 
|---|
| 131 |     /// | 
|---|
| 132 |     /// The large value type used for internal computations. | 
|---|
| 133 |     /// By default, it is \c long \c long if the \c Value type is integer, | 
|---|
| 134 |     /// otherwise it is \c double. | 
|---|
| 135 |     typedef typename TR::LargeValue LargeValue; | 
|---|
| 136 |  | 
|---|
| 137 |     /// The tolerance type | 
|---|
| 138 |     typedef typename TR::Tolerance Tolerance; | 
|---|
| 139 |  | 
|---|
| 140 |     /// \brief The path type of the found cycles | 
|---|
| 141 |     /// | 
|---|
| 142 |     /// The path type of the found cycles. | 
|---|
| 143 |     /// Using the \ref KarpDefaultTraits "default traits class", | 
|---|
| 144 |     /// it is \ref lemon::Path "Path<Digraph>". | 
|---|
| 145 |     typedef typename TR::Path Path; | 
|---|
| 146 |  | 
|---|
| 147 |     /// The \ref KarpDefaultTraits "traits class" of the algorithm | 
|---|
| 148 |     typedef TR Traits; | 
|---|
| 149 |  | 
|---|
| 150 |   private: | 
|---|
| 151 |  | 
|---|
| 152 |     TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); | 
|---|
| 153 |  | 
|---|
| 154 |     // Data sturcture for path data | 
|---|
| 155 |     struct PathData | 
|---|
| 156 |     { | 
|---|
| 157 |       LargeValue dist; | 
|---|
| 158 |       Arc pred; | 
|---|
| 159 |       PathData(LargeValue d, Arc p = INVALID) : | 
|---|
| 160 |         dist(d), pred(p) {} | 
|---|
| 161 |     }; | 
|---|
| 162 |  | 
|---|
| 163 |     typedef typename Digraph::template NodeMap<std::vector<PathData> > | 
|---|
| 164 |       PathDataNodeMap; | 
|---|
| 165 |  | 
|---|
| 166 |   private: | 
|---|
| 167 |  | 
|---|
| 168 |     // The digraph the algorithm runs on | 
|---|
| 169 |     const Digraph &_gr; | 
|---|
| 170 |     // The length of the arcs | 
|---|
| 171 |     const LengthMap &_length; | 
|---|
| 172 |  | 
|---|
| 173 |     // Data for storing the strongly connected components | 
|---|
| 174 |     int _comp_num; | 
|---|
| 175 |     typename Digraph::template NodeMap<int> _comp; | 
|---|
| 176 |     std::vector<std::vector<Node> > _comp_nodes; | 
|---|
| 177 |     std::vector<Node>* _nodes; | 
|---|
| 178 |     typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs; | 
|---|
| 179 |  | 
|---|
| 180 |     // Data for the found cycle | 
|---|
| 181 |     LargeValue _cycle_length; | 
|---|
| 182 |     int _cycle_size; | 
|---|
| 183 |     Node _cycle_node; | 
|---|
| 184 |  | 
|---|
| 185 |     Path *_cycle_path; | 
|---|
| 186 |     bool _local_path; | 
|---|
| 187 |  | 
|---|
| 188 |     // Node map for storing path data | 
|---|
| 189 |     PathDataNodeMap _data; | 
|---|
| 190 |     // The processed nodes in the last round | 
|---|
| 191 |     std::vector<Node> _process; | 
|---|
| 192 |  | 
|---|
| 193 |     Tolerance _tolerance; | 
|---|
| 194 |      | 
|---|
| 195 |     // Infinite constant | 
|---|
| 196 |     const LargeValue INF; | 
|---|
| 197 |  | 
|---|
| 198 |   public: | 
|---|
| 199 |  | 
|---|
| 200 |     /// \name Named Template Parameters | 
|---|
| 201 |     /// @{ | 
|---|
| 202 |  | 
|---|
| 203 |     template <typename T> | 
|---|
| 204 |     struct SetLargeValueTraits : public Traits { | 
|---|
| 205 |       typedef T LargeValue; | 
|---|
| 206 |       typedef lemon::Tolerance<T> Tolerance; | 
|---|
| 207 |     }; | 
|---|
| 208 |  | 
|---|
| 209 |     /// \brief \ref named-templ-param "Named parameter" for setting | 
|---|
| 210 |     /// \c LargeValue type. | 
|---|
| 211 |     /// | 
|---|
| 212 |     /// \ref named-templ-param "Named parameter" for setting \c LargeValue | 
|---|
| 213 |     /// type. It is used for internal computations in the algorithm. | 
|---|
| 214 |     template <typename T> | 
|---|
| 215 |     struct SetLargeValue | 
|---|
| 216 |       : public Karp<GR, LEN, SetLargeValueTraits<T> > { | 
|---|
| 217 |       typedef Karp<GR, LEN, SetLargeValueTraits<T> > Create; | 
|---|
| 218 |     }; | 
|---|
| 219 |  | 
|---|
| 220 |     template <typename T> | 
|---|
| 221 |     struct SetPathTraits : public Traits { | 
|---|
| 222 |       typedef T Path; | 
|---|
| 223 |     }; | 
|---|
| 224 |  | 
|---|
| 225 |     /// \brief \ref named-templ-param "Named parameter" for setting | 
|---|
| 226 |     /// \c %Path type. | 
|---|
| 227 |     /// | 
|---|
| 228 |     /// \ref named-templ-param "Named parameter" for setting the \c %Path | 
|---|
| 229 |     /// type of the found cycles. | 
|---|
| 230 |     /// It must conform to the \ref lemon::concepts::Path "Path" concept | 
|---|
| 231 |     /// and it must have an \c addFront() function. | 
|---|
| 232 |     template <typename T> | 
|---|
| 233 |     struct SetPath | 
|---|
| 234 |       : public Karp<GR, LEN, SetPathTraits<T> > { | 
|---|
| 235 |       typedef Karp<GR, LEN, SetPathTraits<T> > Create; | 
|---|
| 236 |     }; | 
|---|
| 237 |  | 
|---|
| 238 |     /// @} | 
|---|
| 239 |  | 
|---|
| 240 |   public: | 
|---|
| 241 |  | 
|---|
| 242 |     /// \brief Constructor. | 
|---|
| 243 |     /// | 
|---|
| 244 |     /// The constructor of the class. | 
|---|
| 245 |     /// | 
|---|
| 246 |     /// \param digraph The digraph the algorithm runs on. | 
|---|
| 247 |     /// \param length The lengths (costs) of the arcs. | 
|---|
| 248 |     Karp( const Digraph &digraph, | 
|---|
| 249 |           const LengthMap &length ) : | 
|---|
| 250 |       _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph), | 
|---|
| 251 |       _cycle_length(0), _cycle_size(1), _cycle_node(INVALID), | 
|---|
| 252 |       _cycle_path(NULL), _local_path(false), _data(digraph), | 
|---|
| 253 |       INF(std::numeric_limits<LargeValue>::has_infinity ? | 
|---|
| 254 |           std::numeric_limits<LargeValue>::infinity() : | 
|---|
| 255 |           std::numeric_limits<LargeValue>::max()) | 
|---|
| 256 |     {} | 
|---|
| 257 |  | 
|---|
| 258 |     /// Destructor. | 
|---|
| 259 |     ~Karp() { | 
|---|
| 260 |       if (_local_path) delete _cycle_path; | 
|---|
| 261 |     } | 
|---|
| 262 |  | 
|---|
| 263 |     /// \brief Set the path structure for storing the found cycle. | 
|---|
| 264 |     /// | 
|---|
| 265 |     /// This function sets an external path structure for storing the | 
|---|
| 266 |     /// found cycle. | 
|---|
| 267 |     /// | 
|---|
| 268 |     /// If you don't call this function before calling \ref run() or | 
|---|
| 269 |     /// \ref findMinMean(), it will allocate a local \ref Path "path" | 
|---|
| 270 |     /// structure. The destuctor deallocates this automatically | 
|---|
| 271 |     /// allocated object, of course. | 
|---|
| 272 |     /// | 
|---|
| 273 |     /// \note The algorithm calls only the \ref lemon::Path::addFront() | 
|---|
| 274 |     /// "addFront()" function of the given path structure. | 
|---|
| 275 |     /// | 
|---|
| 276 |     /// \return <tt>(*this)</tt> | 
|---|
| 277 |     Karp& cycle(Path &path) { | 
|---|
| 278 |       if (_local_path) { | 
|---|
| 279 |         delete _cycle_path; | 
|---|
| 280 |         _local_path = false; | 
|---|
| 281 |       } | 
|---|
| 282 |       _cycle_path = &path; | 
|---|
| 283 |       return *this; | 
|---|
| 284 |     } | 
|---|
| 285 |  | 
|---|
| 286 |     /// \brief Set the tolerance used by the algorithm. | 
|---|
| 287 |     /// | 
|---|
| 288 |     /// This function sets the tolerance object used by the algorithm. | 
|---|
| 289 |     /// | 
|---|
| 290 |     /// \return <tt>(*this)</tt> | 
|---|
| 291 |     Karp& tolerance(const Tolerance& tolerance) { | 
|---|
| 292 |       _tolerance = tolerance; | 
|---|
| 293 |       return *this; | 
|---|
| 294 |     } | 
|---|
| 295 |  | 
|---|
| 296 |     /// \brief Return a const reference to the tolerance. | 
|---|
| 297 |     /// | 
|---|
| 298 |     /// This function returns a const reference to the tolerance object | 
|---|
| 299 |     /// used by the algorithm. | 
|---|
| 300 |     const Tolerance& tolerance() const { | 
|---|
| 301 |       return _tolerance; | 
|---|
| 302 |     } | 
|---|
| 303 |  | 
|---|
| 304 |     /// \name Execution control | 
|---|
| 305 |     /// The simplest way to execute the algorithm is to call the \ref run() | 
|---|
| 306 |     /// function.\n | 
|---|
| 307 |     /// If you only need the minimum mean length, you may call | 
|---|
| 308 |     /// \ref findMinMean(). | 
|---|
| 309 |  | 
|---|
| 310 |     /// @{ | 
|---|
| 311 |  | 
|---|
| 312 |     /// \brief Run the algorithm. | 
|---|
| 313 |     /// | 
|---|
| 314 |     /// This function runs the algorithm. | 
|---|
| 315 |     /// It can be called more than once (e.g. if the underlying digraph | 
|---|
| 316 |     /// and/or the arc lengths have been modified). | 
|---|
| 317 |     /// | 
|---|
| 318 |     /// \return \c true if a directed cycle exists in the digraph. | 
|---|
| 319 |     /// | 
|---|
| 320 |     /// \note <tt>mmc.run()</tt> is just a shortcut of the following code. | 
|---|
| 321 |     /// \code | 
|---|
| 322 |     ///   return mmc.findMinMean() && mmc.findCycle(); | 
|---|
| 323 |     /// \endcode | 
|---|
| 324 |     bool run() { | 
|---|
| 325 |       return findMinMean() && findCycle(); | 
|---|
| 326 |     } | 
|---|
| 327 |  | 
|---|
| 328 |     /// \brief Find the minimum cycle mean. | 
|---|
| 329 |     /// | 
|---|
| 330 |     /// This function finds the minimum mean length of the directed | 
|---|
| 331 |     /// cycles in the digraph. | 
|---|
| 332 |     /// | 
|---|
| 333 |     /// \return \c true if a directed cycle exists in the digraph. | 
|---|
| 334 |     bool findMinMean() { | 
|---|
| 335 |       // Initialization and find strongly connected components | 
|---|
| 336 |       init(); | 
|---|
| 337 |       findComponents(); | 
|---|
| 338 |        | 
|---|
| 339 |       // Find the minimum cycle mean in the components | 
|---|
| 340 |       for (int comp = 0; comp < _comp_num; ++comp) { | 
|---|
| 341 |         if (!initComponent(comp)) continue; | 
|---|
| 342 |         processRounds(); | 
|---|
| 343 |         updateMinMean(); | 
|---|
| 344 |       } | 
|---|
| 345 |       return (_cycle_node != INVALID); | 
|---|
| 346 |     } | 
|---|
| 347 |  | 
|---|
| 348 |     /// \brief Find a minimum mean directed cycle. | 
|---|
| 349 |     /// | 
|---|
| 350 |     /// This function finds a directed cycle of minimum mean length | 
|---|
| 351 |     /// in the digraph using the data computed by findMinMean(). | 
|---|
| 352 |     /// | 
|---|
| 353 |     /// \return \c true if a directed cycle exists in the digraph. | 
|---|
| 354 |     /// | 
|---|
| 355 |     /// \pre \ref findMinMean() must be called before using this function. | 
|---|
| 356 |     bool findCycle() { | 
|---|
| 357 |       if (_cycle_node == INVALID) return false; | 
|---|
| 358 |       IntNodeMap reached(_gr, -1); | 
|---|
| 359 |       int r = _data[_cycle_node].size(); | 
|---|
| 360 |       Node u = _cycle_node; | 
|---|
| 361 |       while (reached[u] < 0) { | 
|---|
| 362 |         reached[u] = --r; | 
|---|
| 363 |         u = _gr.source(_data[u][r].pred); | 
|---|
| 364 |       } | 
|---|
| 365 |       r = reached[u]; | 
|---|
| 366 |       Arc e = _data[u][r].pred; | 
|---|
| 367 |       _cycle_path->addFront(e); | 
|---|
| 368 |       _cycle_length = _length[e]; | 
|---|
| 369 |       _cycle_size = 1; | 
|---|
| 370 |       Node v; | 
|---|
| 371 |       while ((v = _gr.source(e)) != u) { | 
|---|
| 372 |         e = _data[v][--r].pred; | 
|---|
| 373 |         _cycle_path->addFront(e); | 
|---|
| 374 |         _cycle_length += _length[e]; | 
|---|
| 375 |         ++_cycle_size; | 
|---|
| 376 |       } | 
|---|
| 377 |       return true; | 
|---|
| 378 |     } | 
|---|
| 379 |  | 
|---|
| 380 |     /// @} | 
|---|
| 381 |  | 
|---|
| 382 |     /// \name Query Functions | 
|---|
| 383 |     /// The results of the algorithm can be obtained using these | 
|---|
| 384 |     /// functions.\n | 
|---|
| 385 |     /// The algorithm should be executed before using them. | 
|---|
| 386 |  | 
|---|
| 387 |     /// @{ | 
|---|
| 388 |  | 
|---|
| 389 |     /// \brief Return the total length of the found cycle. | 
|---|
| 390 |     /// | 
|---|
| 391 |     /// This function returns the total length of the found cycle. | 
|---|
| 392 |     /// | 
|---|
| 393 |     /// \pre \ref run() or \ref findMinMean() must be called before | 
|---|
| 394 |     /// using this function. | 
|---|
| 395 |     Value cycleLength() const { | 
|---|
| 396 |       return static_cast<Value>(_cycle_length); | 
|---|
| 397 |     } | 
|---|
| 398 |  | 
|---|
| 399 |     /// \brief Return the number of arcs on the found cycle. | 
|---|
| 400 |     /// | 
|---|
| 401 |     /// This function returns the number of arcs on the found cycle. | 
|---|
| 402 |     /// | 
|---|
| 403 |     /// \pre \ref run() or \ref findMinMean() must be called before | 
|---|
| 404 |     /// using this function. | 
|---|
| 405 |     int cycleArcNum() const { | 
|---|
| 406 |       return _cycle_size; | 
|---|
| 407 |     } | 
|---|
| 408 |  | 
|---|
| 409 |     /// \brief Return the mean length of the found cycle. | 
|---|
| 410 |     /// | 
|---|
| 411 |     /// This function returns the mean length of the found cycle. | 
|---|
| 412 |     /// | 
|---|
| 413 |     /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the | 
|---|
| 414 |     /// following code. | 
|---|
| 415 |     /// \code | 
|---|
| 416 |     ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum(); | 
|---|
| 417 |     /// \endcode | 
|---|
| 418 |     /// | 
|---|
| 419 |     /// \pre \ref run() or \ref findMinMean() must be called before | 
|---|
| 420 |     /// using this function. | 
|---|
| 421 |     double cycleMean() const { | 
|---|
| 422 |       return static_cast<double>(_cycle_length) / _cycle_size; | 
|---|
| 423 |     } | 
|---|
| 424 |  | 
|---|
| 425 |     /// \brief Return the found cycle. | 
|---|
| 426 |     /// | 
|---|
| 427 |     /// This function returns a const reference to the path structure | 
|---|
| 428 |     /// storing the found cycle. | 
|---|
| 429 |     /// | 
|---|
| 430 |     /// \pre \ref run() or \ref findCycle() must be called before using | 
|---|
| 431 |     /// this function. | 
|---|
| 432 |     const Path& cycle() const { | 
|---|
| 433 |       return *_cycle_path; | 
|---|
| 434 |     } | 
|---|
| 435 |  | 
|---|
| 436 |     ///@} | 
|---|
| 437 |  | 
|---|
| 438 |   private: | 
|---|
| 439 |  | 
|---|
| 440 |     // Initialization | 
|---|
| 441 |     void init() { | 
|---|
| 442 |       if (!_cycle_path) { | 
|---|
| 443 |         _local_path = true; | 
|---|
| 444 |         _cycle_path = new Path; | 
|---|
| 445 |       } | 
|---|
| 446 |       _cycle_path->clear(); | 
|---|
| 447 |       _cycle_length = 0; | 
|---|
| 448 |       _cycle_size = 1; | 
|---|
| 449 |       _cycle_node = INVALID; | 
|---|
| 450 |       for (NodeIt u(_gr); u != INVALID; ++u) | 
|---|
| 451 |         _data[u].clear(); | 
|---|
| 452 |     } | 
|---|
| 453 |  | 
|---|
| 454 |     // Find strongly connected components and initialize _comp_nodes | 
|---|
| 455 |     // and _out_arcs | 
|---|
| 456 |     void findComponents() { | 
|---|
| 457 |       _comp_num = stronglyConnectedComponents(_gr, _comp); | 
|---|
| 458 |       _comp_nodes.resize(_comp_num); | 
|---|
| 459 |       if (_comp_num == 1) { | 
|---|
| 460 |         _comp_nodes[0].clear(); | 
|---|
| 461 |         for (NodeIt n(_gr); n != INVALID; ++n) { | 
|---|
| 462 |           _comp_nodes[0].push_back(n); | 
|---|
| 463 |           _out_arcs[n].clear(); | 
|---|
| 464 |           for (OutArcIt a(_gr, n); a != INVALID; ++a) { | 
|---|
| 465 |             _out_arcs[n].push_back(a); | 
|---|
| 466 |           } | 
|---|
| 467 |         } | 
|---|
| 468 |       } else { | 
|---|
| 469 |         for (int i = 0; i < _comp_num; ++i) | 
|---|
| 470 |           _comp_nodes[i].clear(); | 
|---|
| 471 |         for (NodeIt n(_gr); n != INVALID; ++n) { | 
|---|
| 472 |           int k = _comp[n]; | 
|---|
| 473 |           _comp_nodes[k].push_back(n); | 
|---|
| 474 |           _out_arcs[n].clear(); | 
|---|
| 475 |           for (OutArcIt a(_gr, n); a != INVALID; ++a) { | 
|---|
| 476 |             if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a); | 
|---|
| 477 |           } | 
|---|
| 478 |         } | 
|---|
| 479 |       } | 
|---|
| 480 |     } | 
|---|
| 481 |  | 
|---|
| 482 |     // Initialize path data for the current component | 
|---|
| 483 |     bool initComponent(int comp) { | 
|---|
| 484 |       _nodes = &(_comp_nodes[comp]); | 
|---|
| 485 |       int n = _nodes->size(); | 
|---|
| 486 |       if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) { | 
|---|
| 487 |         return false; | 
|---|
| 488 |       }       | 
|---|
| 489 |       for (int i = 0; i < n; ++i) { | 
|---|
| 490 |         _data[(*_nodes)[i]].resize(n + 1, PathData(INF)); | 
|---|
| 491 |       } | 
|---|
| 492 |       return true; | 
|---|
| 493 |     } | 
|---|
| 494 |  | 
|---|
| 495 |     // Process all rounds of computing path data for the current component. | 
|---|
| 496 |     // _data[v][k] is the length of a shortest directed walk from the root | 
|---|
| 497 |     // node to node v containing exactly k arcs. | 
|---|
| 498 |     void processRounds() { | 
|---|
| 499 |       Node start = (*_nodes)[0]; | 
|---|
| 500 |       _data[start][0] = PathData(0); | 
|---|
| 501 |       _process.clear(); | 
|---|
| 502 |       _process.push_back(start); | 
|---|
| 503 |  | 
|---|
| 504 |       int k, n = _nodes->size(); | 
|---|
| 505 |       for (k = 1; k <= n && int(_process.size()) < n; ++k) { | 
|---|
| 506 |         processNextBuildRound(k); | 
|---|
| 507 |       } | 
|---|
| 508 |       for ( ; k <= n; ++k) { | 
|---|
| 509 |         processNextFullRound(k); | 
|---|
| 510 |       } | 
|---|
| 511 |     } | 
|---|
| 512 |  | 
|---|
| 513 |     // Process one round and rebuild _process | 
|---|
| 514 |     void processNextBuildRound(int k) { | 
|---|
| 515 |       std::vector<Node> next; | 
|---|
| 516 |       Node u, v; | 
|---|
| 517 |       Arc e; | 
|---|
| 518 |       LargeValue d; | 
|---|
| 519 |       for (int i = 0; i < int(_process.size()); ++i) { | 
|---|
| 520 |         u = _process[i]; | 
|---|
| 521 |         for (int j = 0; j < int(_out_arcs[u].size()); ++j) { | 
|---|
| 522 |           e = _out_arcs[u][j]; | 
|---|
| 523 |           v = _gr.target(e); | 
|---|
| 524 |           d = _data[u][k-1].dist + _length[e]; | 
|---|
| 525 |           if (_tolerance.less(d, _data[v][k].dist)) { | 
|---|
| 526 |             if (_data[v][k].dist == INF) next.push_back(v); | 
|---|
| 527 |             _data[v][k] = PathData(d, e); | 
|---|
| 528 |           } | 
|---|
| 529 |         } | 
|---|
| 530 |       } | 
|---|
| 531 |       _process.swap(next); | 
|---|
| 532 |     } | 
|---|
| 533 |  | 
|---|
| 534 |     // Process one round using _nodes instead of _process | 
|---|
| 535 |     void processNextFullRound(int k) { | 
|---|
| 536 |       Node u, v; | 
|---|
| 537 |       Arc e; | 
|---|
| 538 |       LargeValue d; | 
|---|
| 539 |       for (int i = 0; i < int(_nodes->size()); ++i) { | 
|---|
| 540 |         u = (*_nodes)[i]; | 
|---|
| 541 |         for (int j = 0; j < int(_out_arcs[u].size()); ++j) { | 
|---|
| 542 |           e = _out_arcs[u][j]; | 
|---|
| 543 |           v = _gr.target(e); | 
|---|
| 544 |           d = _data[u][k-1].dist + _length[e]; | 
|---|
| 545 |           if (_tolerance.less(d, _data[v][k].dist)) { | 
|---|
| 546 |             _data[v][k] = PathData(d, e); | 
|---|
| 547 |           } | 
|---|
| 548 |         } | 
|---|
| 549 |       } | 
|---|
| 550 |     } | 
|---|
| 551 |  | 
|---|
| 552 |     // Update the minimum cycle mean | 
|---|
| 553 |     void updateMinMean() { | 
|---|
| 554 |       int n = _nodes->size(); | 
|---|
| 555 |       for (int i = 0; i < n; ++i) { | 
|---|
| 556 |         Node u = (*_nodes)[i]; | 
|---|
| 557 |         if (_data[u][n].dist == INF) continue; | 
|---|
| 558 |         LargeValue length, max_length = 0; | 
|---|
| 559 |         int size, max_size = 1; | 
|---|
| 560 |         bool found_curr = false; | 
|---|
| 561 |         for (int k = 0; k < n; ++k) { | 
|---|
| 562 |           if (_data[u][k].dist == INF) continue; | 
|---|
| 563 |           length = _data[u][n].dist - _data[u][k].dist; | 
|---|
| 564 |           size = n - k; | 
|---|
| 565 |           if (!found_curr || length * max_size > max_length * size) { | 
|---|
| 566 |             found_curr = true; | 
|---|
| 567 |             max_length = length; | 
|---|
| 568 |             max_size = size; | 
|---|
| 569 |           } | 
|---|
| 570 |         } | 
|---|
| 571 |         if ( found_curr && (_cycle_node == INVALID || | 
|---|
| 572 |              max_length * _cycle_size < _cycle_length * max_size) ) { | 
|---|
| 573 |           _cycle_length = max_length; | 
|---|
| 574 |           _cycle_size = max_size; | 
|---|
| 575 |           _cycle_node = u; | 
|---|
| 576 |         } | 
|---|
| 577 |       } | 
|---|
| 578 |     } | 
|---|
| 579 |  | 
|---|
| 580 |   }; //class Karp | 
|---|
| 581 |  | 
|---|
| 582 |   ///@} | 
|---|
| 583 |  | 
|---|
| 584 | } //namespace lemon | 
|---|
| 585 |  | 
|---|
| 586 | #endif //LEMON_KARP_H | 
|---|