lemon/karp.h
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 806 fa6f37d7a25b
parent 771 8452ca46e29a
child 825 75e6020b19b1
permissions -rw-r--r--
Entirely rework CapacityScaling (#180)

- Use the new interface similarly to NetworkSimplex.
- Rework the implementation using an efficient internal structure
for handling the residual network. This improvement made the
code much faster (up to 2-5 times faster on large graphs).
- Handle GEQ supply type (LEQ is not supported).
- Handle negative costs for arcs of finite capacity.
(Note that this algorithm cannot handle arcs of negative cost
and infinite upper bound, thus it returns UNBOUNDED if such
an arc exists.)
- Extend the documentation.
     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 #ifdef DOXYGEN
   108   template <typename GR, typename LEN, typename TR>
   109 #else
   110   template < typename GR,
   111              typename LEN = typename GR::template ArcMap<int>,
   112              typename TR = KarpDefaultTraits<GR, LEN> >
   113 #endif
   114   class Karp
   115   {
   116   public:
   117 
   118     /// The type of the digraph
   119     typedef typename TR::Digraph Digraph;
   120     /// The type of the length map
   121     typedef typename TR::LengthMap LengthMap;
   122     /// The type of the arc lengths
   123     typedef typename TR::Value Value;
   124 
   125     /// \brief The large value type
   126     ///
   127     /// The large value type used for internal computations.
   128     /// Using the \ref KarpDefaultTraits "default traits class",
   129     /// it is \c long \c long if the \c Value type is integer,
   130     /// otherwise it is \c double.
   131     typedef typename TR::LargeValue LargeValue;
   132 
   133     /// The tolerance type
   134     typedef typename TR::Tolerance Tolerance;
   135 
   136     /// \brief The path type of the found cycles
   137     ///
   138     /// The path type of the found cycles.
   139     /// Using the \ref KarpDefaultTraits "default traits class",
   140     /// it is \ref lemon::Path "Path<Digraph>".
   141     typedef typename TR::Path Path;
   142 
   143     /// The \ref KarpDefaultTraits "traits class" of the algorithm
   144     typedef TR Traits;
   145 
   146   private:
   147 
   148     TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
   149 
   150     // Data sturcture for path data
   151     struct PathData
   152     {
   153       LargeValue dist;
   154       Arc pred;
   155       PathData(LargeValue d, Arc p = INVALID) :
   156         dist(d), pred(p) {}
   157     };
   158 
   159     typedef typename Digraph::template NodeMap<std::vector<PathData> >
   160       PathDataNodeMap;
   161 
   162   private:
   163 
   164     // The digraph the algorithm runs on
   165     const Digraph &_gr;
   166     // The length of the arcs
   167     const LengthMap &_length;
   168 
   169     // Data for storing the strongly connected components
   170     int _comp_num;
   171     typename Digraph::template NodeMap<int> _comp;
   172     std::vector<std::vector<Node> > _comp_nodes;
   173     std::vector<Node>* _nodes;
   174     typename Digraph::template NodeMap<std::vector<Arc> > _out_arcs;
   175 
   176     // Data for the found cycle
   177     LargeValue _cycle_length;
   178     int _cycle_size;
   179     Node _cycle_node;
   180 
   181     Path *_cycle_path;
   182     bool _local_path;
   183 
   184     // Node map for storing path data
   185     PathDataNodeMap _data;
   186     // The processed nodes in the last round
   187     std::vector<Node> _process;
   188 
   189     Tolerance _tolerance;
   190     
   191     // Infinite constant
   192     const LargeValue INF;
   193 
   194   public:
   195 
   196     /// \name Named Template Parameters
   197     /// @{
   198 
   199     template <typename T>
   200     struct SetLargeValueTraits : public Traits {
   201       typedef T LargeValue;
   202       typedef lemon::Tolerance<T> Tolerance;
   203     };
   204 
   205     /// \brief \ref named-templ-param "Named parameter" for setting
   206     /// \c LargeValue type.
   207     ///
   208     /// \ref named-templ-param "Named parameter" for setting \c LargeValue
   209     /// type. It is used for internal computations in the algorithm.
   210     template <typename T>
   211     struct SetLargeValue
   212       : public Karp<GR, LEN, SetLargeValueTraits<T> > {
   213       typedef Karp<GR, LEN, SetLargeValueTraits<T> > Create;
   214     };
   215 
   216     template <typename T>
   217     struct SetPathTraits : public Traits {
   218       typedef T Path;
   219     };
   220 
   221     /// \brief \ref named-templ-param "Named parameter" for setting
   222     /// \c %Path type.
   223     ///
   224     /// \ref named-templ-param "Named parameter" for setting the \c %Path
   225     /// type of the found cycles.
   226     /// It must conform to the \ref lemon::concepts::Path "Path" concept
   227     /// and it must have an \c addFront() function.
   228     template <typename T>
   229     struct SetPath
   230       : public Karp<GR, LEN, SetPathTraits<T> > {
   231       typedef Karp<GR, LEN, SetPathTraits<T> > Create;
   232     };
   233 
   234     /// @}
   235 
   236   public:
   237 
   238     /// \brief Constructor.
   239     ///
   240     /// The constructor of the class.
   241     ///
   242     /// \param digraph The digraph the algorithm runs on.
   243     /// \param length The lengths (costs) of the arcs.
   244     Karp( const Digraph &digraph,
   245           const LengthMap &length ) :
   246       _gr(digraph), _length(length), _comp(digraph), _out_arcs(digraph),
   247       _cycle_length(0), _cycle_size(1), _cycle_node(INVALID),
   248       _cycle_path(NULL), _local_path(false), _data(digraph),
   249       INF(std::numeric_limits<LargeValue>::has_infinity ?
   250           std::numeric_limits<LargeValue>::infinity() :
   251           std::numeric_limits<LargeValue>::max())
   252     {}
   253 
   254     /// Destructor.
   255     ~Karp() {
   256       if (_local_path) delete _cycle_path;
   257     }
   258 
   259     /// \brief Set the path structure for storing the found cycle.
   260     ///
   261     /// This function sets an external path structure for storing the
   262     /// found cycle.
   263     ///
   264     /// If you don't call this function before calling \ref run() or
   265     /// \ref findMinMean(), it will allocate a local \ref Path "path"
   266     /// structure. The destuctor deallocates this automatically
   267     /// allocated object, of course.
   268     ///
   269     /// \note The algorithm calls only the \ref lemon::Path::addFront()
   270     /// "addFront()" function of the given path structure.
   271     ///
   272     /// \return <tt>(*this)</tt>
   273     Karp& cycle(Path &path) {
   274       if (_local_path) {
   275         delete _cycle_path;
   276         _local_path = false;
   277       }
   278       _cycle_path = &path;
   279       return *this;
   280     }
   281 
   282     /// \brief Set the tolerance used by the algorithm.
   283     ///
   284     /// This function sets the tolerance object used by the algorithm.
   285     ///
   286     /// \return <tt>(*this)</tt>
   287     Karp& tolerance(const Tolerance& tolerance) {
   288       _tolerance = tolerance;
   289       return *this;
   290     }
   291 
   292     /// \brief Return a const reference to the tolerance.
   293     ///
   294     /// This function returns a const reference to the tolerance object
   295     /// used by the algorithm.
   296     const Tolerance& tolerance() const {
   297       return _tolerance;
   298     }
   299 
   300     /// \name Execution control
   301     /// The simplest way to execute the algorithm is to call the \ref run()
   302     /// function.\n
   303     /// If you only need the minimum mean length, you may call
   304     /// \ref findMinMean().
   305 
   306     /// @{
   307 
   308     /// \brief Run the algorithm.
   309     ///
   310     /// This function runs the algorithm.
   311     /// It can be called more than once (e.g. if the underlying digraph
   312     /// and/or the arc lengths have been modified).
   313     ///
   314     /// \return \c true if a directed cycle exists in the digraph.
   315     ///
   316     /// \note <tt>mmc.run()</tt> is just a shortcut of the following code.
   317     /// \code
   318     ///   return mmc.findMinMean() && mmc.findCycle();
   319     /// \endcode
   320     bool run() {
   321       return findMinMean() && findCycle();
   322     }
   323 
   324     /// \brief Find the minimum cycle mean.
   325     ///
   326     /// This function finds the minimum mean length of the directed
   327     /// cycles in the digraph.
   328     ///
   329     /// \return \c true if a directed cycle exists in the digraph.
   330     bool findMinMean() {
   331       // Initialization and find strongly connected components
   332       init();
   333       findComponents();
   334       
   335       // Find the minimum cycle mean in the components
   336       for (int comp = 0; comp < _comp_num; ++comp) {
   337         if (!initComponent(comp)) continue;
   338         processRounds();
   339         updateMinMean();
   340       }
   341       return (_cycle_node != INVALID);
   342     }
   343 
   344     /// \brief Find a minimum mean directed cycle.
   345     ///
   346     /// This function finds a directed cycle of minimum mean length
   347     /// in the digraph using the data computed by findMinMean().
   348     ///
   349     /// \return \c true if a directed cycle exists in the digraph.
   350     ///
   351     /// \pre \ref findMinMean() must be called before using this function.
   352     bool findCycle() {
   353       if (_cycle_node == INVALID) return false;
   354       IntNodeMap reached(_gr, -1);
   355       int r = _data[_cycle_node].size();
   356       Node u = _cycle_node;
   357       while (reached[u] < 0) {
   358         reached[u] = --r;
   359         u = _gr.source(_data[u][r].pred);
   360       }
   361       r = reached[u];
   362       Arc e = _data[u][r].pred;
   363       _cycle_path->addFront(e);
   364       _cycle_length = _length[e];
   365       _cycle_size = 1;
   366       Node v;
   367       while ((v = _gr.source(e)) != u) {
   368         e = _data[v][--r].pred;
   369         _cycle_path->addFront(e);
   370         _cycle_length += _length[e];
   371         ++_cycle_size;
   372       }
   373       return true;
   374     }
   375 
   376     /// @}
   377 
   378     /// \name Query Functions
   379     /// The results of the algorithm can be obtained using these
   380     /// functions.\n
   381     /// The algorithm should be executed before using them.
   382 
   383     /// @{
   384 
   385     /// \brief Return the total length of the found cycle.
   386     ///
   387     /// This function returns the total length of the found cycle.
   388     ///
   389     /// \pre \ref run() or \ref findMinMean() must be called before
   390     /// using this function.
   391     LargeValue cycleLength() const {
   392       return _cycle_length;
   393     }
   394 
   395     /// \brief Return the number of arcs on the found cycle.
   396     ///
   397     /// This function returns the number of arcs on the found cycle.
   398     ///
   399     /// \pre \ref run() or \ref findMinMean() must be called before
   400     /// using this function.
   401     int cycleArcNum() const {
   402       return _cycle_size;
   403     }
   404 
   405     /// \brief Return the mean length of the found cycle.
   406     ///
   407     /// This function returns the mean length of the found cycle.
   408     ///
   409     /// \note <tt>alg.cycleMean()</tt> is just a shortcut of the
   410     /// following code.
   411     /// \code
   412     ///   return static_cast<double>(alg.cycleLength()) / alg.cycleArcNum();
   413     /// \endcode
   414     ///
   415     /// \pre \ref run() or \ref findMinMean() must be called before
   416     /// using this function.
   417     double cycleMean() const {
   418       return static_cast<double>(_cycle_length) / _cycle_size;
   419     }
   420 
   421     /// \brief Return the found cycle.
   422     ///
   423     /// This function returns a const reference to the path structure
   424     /// storing the found cycle.
   425     ///
   426     /// \pre \ref run() or \ref findCycle() must be called before using
   427     /// this function.
   428     const Path& cycle() const {
   429       return *_cycle_path;
   430     }
   431 
   432     ///@}
   433 
   434   private:
   435 
   436     // Initialization
   437     void init() {
   438       if (!_cycle_path) {
   439         _local_path = true;
   440         _cycle_path = new Path;
   441       }
   442       _cycle_path->clear();
   443       _cycle_length = 0;
   444       _cycle_size = 1;
   445       _cycle_node = INVALID;
   446       for (NodeIt u(_gr); u != INVALID; ++u)
   447         _data[u].clear();
   448     }
   449 
   450     // Find strongly connected components and initialize _comp_nodes
   451     // and _out_arcs
   452     void findComponents() {
   453       _comp_num = stronglyConnectedComponents(_gr, _comp);
   454       _comp_nodes.resize(_comp_num);
   455       if (_comp_num == 1) {
   456         _comp_nodes[0].clear();
   457         for (NodeIt n(_gr); n != INVALID; ++n) {
   458           _comp_nodes[0].push_back(n);
   459           _out_arcs[n].clear();
   460           for (OutArcIt a(_gr, n); a != INVALID; ++a) {
   461             _out_arcs[n].push_back(a);
   462           }
   463         }
   464       } else {
   465         for (int i = 0; i < _comp_num; ++i)
   466           _comp_nodes[i].clear();
   467         for (NodeIt n(_gr); n != INVALID; ++n) {
   468           int k = _comp[n];
   469           _comp_nodes[k].push_back(n);
   470           _out_arcs[n].clear();
   471           for (OutArcIt a(_gr, n); a != INVALID; ++a) {
   472             if (_comp[_gr.target(a)] == k) _out_arcs[n].push_back(a);
   473           }
   474         }
   475       }
   476     }
   477 
   478     // Initialize path data for the current component
   479     bool initComponent(int comp) {
   480       _nodes = &(_comp_nodes[comp]);
   481       int n = _nodes->size();
   482       if (n < 1 || (n == 1 && _out_arcs[(*_nodes)[0]].size() == 0)) {
   483         return false;
   484       }      
   485       for (int i = 0; i < n; ++i) {
   486         _data[(*_nodes)[i]].resize(n + 1, PathData(INF));
   487       }
   488       return true;
   489     }
   490 
   491     // Process all rounds of computing path data for the current component.
   492     // _data[v][k] is the length of a shortest directed walk from the root
   493     // node to node v containing exactly k arcs.
   494     void processRounds() {
   495       Node start = (*_nodes)[0];
   496       _data[start][0] = PathData(0);
   497       _process.clear();
   498       _process.push_back(start);
   499 
   500       int k, n = _nodes->size();
   501       for (k = 1; k <= n && int(_process.size()) < n; ++k) {
   502         processNextBuildRound(k);
   503       }
   504       for ( ; k <= n; ++k) {
   505         processNextFullRound(k);
   506       }
   507     }
   508 
   509     // Process one round and rebuild _process
   510     void processNextBuildRound(int k) {
   511       std::vector<Node> next;
   512       Node u, v;
   513       Arc e;
   514       LargeValue d;
   515       for (int i = 0; i < int(_process.size()); ++i) {
   516         u = _process[i];
   517         for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
   518           e = _out_arcs[u][j];
   519           v = _gr.target(e);
   520           d = _data[u][k-1].dist + _length[e];
   521           if (_tolerance.less(d, _data[v][k].dist)) {
   522             if (_data[v][k].dist == INF) next.push_back(v);
   523             _data[v][k] = PathData(d, e);
   524           }
   525         }
   526       }
   527       _process.swap(next);
   528     }
   529 
   530     // Process one round using _nodes instead of _process
   531     void processNextFullRound(int k) {
   532       Node u, v;
   533       Arc e;
   534       LargeValue d;
   535       for (int i = 0; i < int(_nodes->size()); ++i) {
   536         u = (*_nodes)[i];
   537         for (int j = 0; j < int(_out_arcs[u].size()); ++j) {
   538           e = _out_arcs[u][j];
   539           v = _gr.target(e);
   540           d = _data[u][k-1].dist + _length[e];
   541           if (_tolerance.less(d, _data[v][k].dist)) {
   542             _data[v][k] = PathData(d, e);
   543           }
   544         }
   545       }
   546     }
   547 
   548     // Update the minimum cycle mean
   549     void updateMinMean() {
   550       int n = _nodes->size();
   551       for (int i = 0; i < n; ++i) {
   552         Node u = (*_nodes)[i];
   553         if (_data[u][n].dist == INF) continue;
   554         LargeValue length, max_length = 0;
   555         int size, max_size = 1;
   556         bool found_curr = false;
   557         for (int k = 0; k < n; ++k) {
   558           if (_data[u][k].dist == INF) continue;
   559           length = _data[u][n].dist - _data[u][k].dist;
   560           size = n - k;
   561           if (!found_curr || length * max_size > max_length * size) {
   562             found_curr = true;
   563             max_length = length;
   564             max_size = size;
   565           }
   566         }
   567         if ( found_curr && (_cycle_node == INVALID ||
   568              max_length * _cycle_size < _cycle_length * max_size) ) {
   569           _cycle_length = max_length;
   570           _cycle_size = max_size;
   571           _cycle_node = u;
   572         }
   573       }
   574     }
   575 
   576   }; //class Karp
   577 
   578   ///@}
   579 
   580 } //namespace lemon
   581 
   582 #endif //LEMON_KARP_H