| deba@948 |      1 | /* -*- mode: C++; indent-tabs-mode: nil; -*-
 | 
| deba@948 |      2 |  *
 | 
| deba@948 |      3 |  * This file is a part of LEMON, a generic C++ optimization library.
 | 
| deba@948 |      4 |  *
 | 
| alpar@1270 |      5 |  * Copyright (C) 2003-2013
 | 
| deba@948 |      6 |  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 | 
| deba@948 |      7 |  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 | 
| deba@948 |      8 |  *
 | 
| deba@948 |      9 |  * Permission to use, modify and distribute this software is granted
 | 
| deba@948 |     10 |  * provided that this copyright notice appears in all copies. For
 | 
| deba@948 |     11 |  * precise terms see the accompanying LICENSE file.
 | 
| deba@948 |     12 |  *
 | 
| deba@948 |     13 |  * This software is provided "AS IS" with no warranty of any kind,
 | 
| deba@948 |     14 |  * express or implied, and with no claim as to its suitability for any
 | 
| deba@948 |     15 |  * purpose.
 | 
| deba@948 |     16 |  *
 | 
| deba@948 |     17 |  */
 | 
| deba@948 |     18 | 
 | 
| deba@948 |     19 | #ifndef LEMON_FRACTIONAL_MATCHING_H
 | 
| deba@948 |     20 | #define LEMON_FRACTIONAL_MATCHING_H
 | 
| deba@948 |     21 | 
 | 
| deba@948 |     22 | #include <vector>
 | 
| deba@948 |     23 | #include <queue>
 | 
| deba@948 |     24 | #include <set>
 | 
| deba@948 |     25 | #include <limits>
 | 
| deba@948 |     26 | 
 | 
| deba@948 |     27 | #include <lemon/core.h>
 | 
| deba@948 |     28 | #include <lemon/unionfind.h>
 | 
| deba@948 |     29 | #include <lemon/bin_heap.h>
 | 
| deba@948 |     30 | #include <lemon/maps.h>
 | 
| deba@948 |     31 | #include <lemon/assert.h>
 | 
| deba@948 |     32 | #include <lemon/elevator.h>
 | 
| deba@948 |     33 | 
 | 
| deba@948 |     34 | ///\ingroup matching
 | 
| deba@948 |     35 | ///\file
 | 
| deba@948 |     36 | ///\brief Fractional matching algorithms in general graphs.
 | 
| deba@948 |     37 | 
 | 
| deba@948 |     38 | namespace lemon {
 | 
| deba@948 |     39 | 
 | 
| deba@948 |     40 |   /// \brief Default traits class of MaxFractionalMatching class.
 | 
| deba@948 |     41 |   ///
 | 
| deba@948 |     42 |   /// Default traits class of MaxFractionalMatching class.
 | 
| deba@948 |     43 |   /// \tparam GR Graph type.
 | 
| deba@948 |     44 |   template <typename GR>
 | 
| deba@948 |     45 |   struct MaxFractionalMatchingDefaultTraits {
 | 
| deba@948 |     46 | 
 | 
| deba@948 |     47 |     /// \brief The type of the graph the algorithm runs on.
 | 
| deba@948 |     48 |     typedef GR Graph;
 | 
| deba@948 |     49 | 
 | 
| deba@948 |     50 |     /// \brief The type of the map that stores the matching.
 | 
| deba@948 |     51 |     ///
 | 
| deba@948 |     52 |     /// The type of the map that stores the matching arcs.
 | 
| deba@948 |     53 |     /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
 | 
| deba@948 |     54 |     typedef typename Graph::template NodeMap<typename GR::Arc> MatchingMap;
 | 
| deba@948 |     55 | 
 | 
| deba@948 |     56 |     /// \brief Instantiates a MatchingMap.
 | 
| deba@948 |     57 |     ///
 | 
| deba@948 |     58 |     /// This function instantiates a \ref MatchingMap.
 | 
| deba@948 |     59 |     /// \param graph The graph for which we would like to define
 | 
| deba@948 |     60 |     /// the matching map.
 | 
| deba@948 |     61 |     static MatchingMap* createMatchingMap(const Graph& graph) {
 | 
| deba@948 |     62 |       return new MatchingMap(graph);
 | 
| deba@948 |     63 |     }
 | 
| deba@948 |     64 | 
 | 
| deba@948 |     65 |     /// \brief The elevator type used by MaxFractionalMatching algorithm.
 | 
| deba@948 |     66 |     ///
 | 
| deba@948 |     67 |     /// The elevator type used by MaxFractionalMatching algorithm.
 | 
| deba@948 |     68 |     ///
 | 
| deba@948 |     69 |     /// \sa Elevator
 | 
| deba@948 |     70 |     /// \sa LinkedElevator
 | 
| deba@948 |     71 |     typedef LinkedElevator<Graph, typename Graph::Node> Elevator;
 | 
| deba@948 |     72 | 
 | 
| deba@948 |     73 |     /// \brief Instantiates an Elevator.
 | 
| deba@948 |     74 |     ///
 | 
| deba@948 |     75 |     /// This function instantiates an \ref Elevator.
 | 
| deba@948 |     76 |     /// \param graph The graph for which we would like to define
 | 
| deba@948 |     77 |     /// the elevator.
 | 
| deba@948 |     78 |     /// \param max_level The maximum level of the elevator.
 | 
| deba@948 |     79 |     static Elevator* createElevator(const Graph& graph, int max_level) {
 | 
| deba@948 |     80 |       return new Elevator(graph, max_level);
 | 
| deba@948 |     81 |     }
 | 
| deba@948 |     82 |   };
 | 
| deba@948 |     83 | 
 | 
| deba@948 |     84 |   /// \ingroup matching
 | 
| deba@948 |     85 |   ///
 | 
| deba@948 |     86 |   /// \brief Max cardinality fractional matching
 | 
| deba@948 |     87 |   ///
 | 
| deba@948 |     88 |   /// This class provides an implementation of fractional matching
 | 
| deba@948 |     89 |   /// algorithm based on push-relabel principle.
 | 
| deba@948 |     90 |   ///
 | 
| deba@948 |     91 |   /// The maximum cardinality fractional matching is a relaxation of the
 | 
| deba@948 |     92 |   /// maximum cardinality matching problem where the odd set constraints
 | 
| deba@948 |     93 |   /// are omitted.
 | 
| deba@948 |     94 |   /// It can be formulated with the following linear program.
 | 
| deba@948 |     95 |   /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
 | 
| deba@948 |     96 |   /// \f[x_e \ge 0\quad \forall e\in E\f]
 | 
| deba@948 |     97 |   /// \f[\max \sum_{e\in E}x_e\f]
 | 
| deba@948 |     98 |   /// where \f$\delta(X)\f$ is the set of edges incident to a node in
 | 
| deba@948 |     99 |   /// \f$X\f$. The result can be represented as the union of a
 | 
| deba@948 |    100 |   /// matching with one value edges and a set of odd length cycles
 | 
| deba@948 |    101 |   /// with half value edges.
 | 
| deba@948 |    102 |   ///
 | 
| deba@948 |    103 |   /// The algorithm calculates an optimal fractional matching and a
 | 
| deba@948 |    104 |   /// barrier. The number of adjacents of any node set minus the size
 | 
| deba@948 |    105 |   /// of node set is a lower bound on the uncovered nodes in the
 | 
| deba@948 |    106 |   /// graph. For maximum matching a barrier is computed which
 | 
| deba@948 |    107 |   /// maximizes this difference.
 | 
| deba@948 |    108 |   ///
 | 
| deba@948 |    109 |   /// The algorithm can be executed with the run() function.  After it
 | 
| deba@948 |    110 |   /// the matching (the primal solution) and the barrier (the dual
 | 
| deba@948 |    111 |   /// solution) can be obtained using the query functions.
 | 
| deba@948 |    112 |   ///
 | 
| deba@948 |    113 |   /// The primal solution is multiplied by
 | 
| deba@950 |    114 |   /// \ref MaxFractionalMatching::primalScale "2".
 | 
| deba@948 |    115 |   ///
 | 
| deba@948 |    116 |   /// \tparam GR The undirected graph type the algorithm runs on.
 | 
| deba@948 |    117 | #ifdef DOXYGEN
 | 
| deba@948 |    118 |   template <typename GR, typename TR>
 | 
| deba@948 |    119 | #else
 | 
| deba@948 |    120 |   template <typename GR,
 | 
| deba@948 |    121 |             typename TR = MaxFractionalMatchingDefaultTraits<GR> >
 | 
| deba@948 |    122 | #endif
 | 
| deba@948 |    123 |   class MaxFractionalMatching {
 | 
| deba@948 |    124 |   public:
 | 
| deba@948 |    125 | 
 | 
| alpar@1250 |    126 |     /// \brief The \ref lemon::MaxFractionalMatchingDefaultTraits
 | 
| alpar@1250 |    127 |     /// "traits class" of the algorithm.
 | 
| deba@948 |    128 |     typedef TR Traits;
 | 
| deba@948 |    129 |     /// The type of the graph the algorithm runs on.
 | 
| deba@948 |    130 |     typedef typename TR::Graph Graph;
 | 
| deba@948 |    131 |     /// The type of the matching map.
 | 
| deba@948 |    132 |     typedef typename TR::MatchingMap MatchingMap;
 | 
| deba@948 |    133 |     /// The type of the elevator.
 | 
| deba@948 |    134 |     typedef typename TR::Elevator Elevator;
 | 
| deba@948 |    135 | 
 | 
| deba@948 |    136 |     /// \brief Scaling factor for primal solution
 | 
| deba@948 |    137 |     ///
 | 
| deba@948 |    138 |     /// Scaling factor for primal solution.
 | 
| deba@948 |    139 |     static const int primalScale = 2;
 | 
| deba@948 |    140 | 
 | 
| deba@948 |    141 |   private:
 | 
| deba@948 |    142 | 
 | 
| deba@948 |    143 |     const Graph &_graph;
 | 
| deba@948 |    144 |     int _node_num;
 | 
| deba@948 |    145 |     bool _allow_loops;
 | 
| deba@948 |    146 |     int _empty_level;
 | 
| deba@948 |    147 | 
 | 
| deba@948 |    148 |     TEMPLATE_GRAPH_TYPEDEFS(Graph);
 | 
| deba@948 |    149 | 
 | 
| deba@948 |    150 |     bool _local_matching;
 | 
| deba@948 |    151 |     MatchingMap *_matching;
 | 
| deba@948 |    152 | 
 | 
| deba@948 |    153 |     bool _local_level;
 | 
| deba@948 |    154 |     Elevator *_level;
 | 
| deba@948 |    155 | 
 | 
| deba@948 |    156 |     typedef typename Graph::template NodeMap<int> InDegMap;
 | 
| deba@948 |    157 |     InDegMap *_indeg;
 | 
| deba@948 |    158 | 
 | 
| deba@948 |    159 |     void createStructures() {
 | 
| deba@948 |    160 |       _node_num = countNodes(_graph);
 | 
| deba@948 |    161 | 
 | 
| deba@948 |    162 |       if (!_matching) {
 | 
| deba@948 |    163 |         _local_matching = true;
 | 
| deba@948 |    164 |         _matching = Traits::createMatchingMap(_graph);
 | 
| deba@948 |    165 |       }
 | 
| deba@948 |    166 |       if (!_level) {
 | 
| deba@948 |    167 |         _local_level = true;
 | 
| deba@948 |    168 |         _level = Traits::createElevator(_graph, _node_num);
 | 
| deba@948 |    169 |       }
 | 
| deba@948 |    170 |       if (!_indeg) {
 | 
| deba@948 |    171 |         _indeg = new InDegMap(_graph);
 | 
| deba@948 |    172 |       }
 | 
| deba@948 |    173 |     }
 | 
| deba@948 |    174 | 
 | 
| deba@948 |    175 |     void destroyStructures() {
 | 
| deba@948 |    176 |       if (_local_matching) {
 | 
| deba@948 |    177 |         delete _matching;
 | 
| deba@948 |    178 |       }
 | 
| deba@948 |    179 |       if (_local_level) {
 | 
| deba@948 |    180 |         delete _level;
 | 
| deba@948 |    181 |       }
 | 
| deba@948 |    182 |       if (_indeg) {
 | 
| deba@948 |    183 |         delete _indeg;
 | 
| deba@948 |    184 |       }
 | 
| deba@948 |    185 |     }
 | 
| deba@948 |    186 | 
 | 
| deba@948 |    187 |     void postprocessing() {
 | 
| deba@948 |    188 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |    189 |         if ((*_indeg)[n] != 0) continue;
 | 
| deba@948 |    190 |         _indeg->set(n, -1);
 | 
| deba@948 |    191 |         Node u = n;
 | 
| deba@948 |    192 |         while ((*_matching)[u] != INVALID) {
 | 
| deba@948 |    193 |           Node v = _graph.target((*_matching)[u]);
 | 
| deba@948 |    194 |           _indeg->set(v, -1);
 | 
| deba@948 |    195 |           Arc a = _graph.oppositeArc((*_matching)[u]);
 | 
| deba@948 |    196 |           u = _graph.target((*_matching)[v]);
 | 
| deba@948 |    197 |           _indeg->set(u, -1);
 | 
| deba@948 |    198 |           _matching->set(v, a);
 | 
| deba@948 |    199 |         }
 | 
| deba@948 |    200 |       }
 | 
| deba@948 |    201 | 
 | 
| deba@948 |    202 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |    203 |         if ((*_indeg)[n] != 1) continue;
 | 
| deba@948 |    204 |         _indeg->set(n, -1);
 | 
| deba@948 |    205 | 
 | 
| deba@948 |    206 |         int num = 1;
 | 
| deba@948 |    207 |         Node u = _graph.target((*_matching)[n]);
 | 
| deba@948 |    208 |         while (u != n) {
 | 
| deba@948 |    209 |           _indeg->set(u, -1);
 | 
| deba@948 |    210 |           u = _graph.target((*_matching)[u]);
 | 
| deba@948 |    211 |           ++num;
 | 
| deba@948 |    212 |         }
 | 
| deba@948 |    213 |         if (num % 2 == 0 && num > 2) {
 | 
| deba@948 |    214 |           Arc prev = _graph.oppositeArc((*_matching)[n]);
 | 
| deba@948 |    215 |           Node v = _graph.target((*_matching)[n]);
 | 
| deba@948 |    216 |           u = _graph.target((*_matching)[v]);
 | 
| deba@948 |    217 |           _matching->set(v, prev);
 | 
| deba@948 |    218 |           while (u != n) {
 | 
| deba@948 |    219 |             prev = _graph.oppositeArc((*_matching)[u]);
 | 
| deba@948 |    220 |             v = _graph.target((*_matching)[u]);
 | 
| deba@948 |    221 |             u = _graph.target((*_matching)[v]);
 | 
| deba@948 |    222 |             _matching->set(v, prev);
 | 
| deba@948 |    223 |           }
 | 
| deba@948 |    224 |         }
 | 
| deba@948 |    225 |       }
 | 
| deba@948 |    226 |     }
 | 
| deba@948 |    227 | 
 | 
| deba@948 |    228 |   public:
 | 
| deba@948 |    229 | 
 | 
| deba@948 |    230 |     typedef MaxFractionalMatching Create;
 | 
| deba@948 |    231 | 
 | 
| deba@948 |    232 |     ///\name Named Template Parameters
 | 
| deba@948 |    233 | 
 | 
| deba@948 |    234 |     ///@{
 | 
| deba@948 |    235 | 
 | 
| deba@948 |    236 |     template <typename T>
 | 
| deba@948 |    237 |     struct SetMatchingMapTraits : public Traits {
 | 
| deba@948 |    238 |       typedef T MatchingMap;
 | 
| deba@948 |    239 |       static MatchingMap *createMatchingMap(const Graph&) {
 | 
| deba@948 |    240 |         LEMON_ASSERT(false, "MatchingMap is not initialized");
 | 
| deba@948 |    241 |         return 0; // ignore warnings
 | 
| deba@948 |    242 |       }
 | 
| deba@948 |    243 |     };
 | 
| deba@948 |    244 | 
 | 
| deba@948 |    245 |     /// \brief \ref named-templ-param "Named parameter" for setting
 | 
| deba@948 |    246 |     /// MatchingMap type
 | 
| deba@948 |    247 |     ///
 | 
| deba@948 |    248 |     /// \ref named-templ-param "Named parameter" for setting MatchingMap
 | 
| deba@948 |    249 |     /// type.
 | 
| deba@948 |    250 |     template <typename T>
 | 
| deba@948 |    251 |     struct SetMatchingMap
 | 
| deba@948 |    252 |       : public MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > {
 | 
| deba@948 |    253 |       typedef MaxFractionalMatching<Graph, SetMatchingMapTraits<T> > Create;
 | 
| deba@948 |    254 |     };
 | 
| deba@948 |    255 | 
 | 
| deba@948 |    256 |     template <typename T>
 | 
| deba@948 |    257 |     struct SetElevatorTraits : public Traits {
 | 
| deba@948 |    258 |       typedef T Elevator;
 | 
| deba@948 |    259 |       static Elevator *createElevator(const Graph&, int) {
 | 
| deba@948 |    260 |         LEMON_ASSERT(false, "Elevator is not initialized");
 | 
| deba@948 |    261 |         return 0; // ignore warnings
 | 
| deba@948 |    262 |       }
 | 
| deba@948 |    263 |     };
 | 
| deba@948 |    264 | 
 | 
| deba@948 |    265 |     /// \brief \ref named-templ-param "Named parameter" for setting
 | 
| deba@948 |    266 |     /// Elevator type
 | 
| deba@948 |    267 |     ///
 | 
| deba@948 |    268 |     /// \ref named-templ-param "Named parameter" for setting Elevator
 | 
| deba@948 |    269 |     /// type. If this named parameter is used, then an external
 | 
| deba@948 |    270 |     /// elevator object must be passed to the algorithm using the
 | 
| deba@948 |    271 |     /// \ref elevator(Elevator&) "elevator()" function before calling
 | 
| deba@948 |    272 |     /// \ref run() or \ref init().
 | 
| deba@948 |    273 |     /// \sa SetStandardElevator
 | 
| deba@948 |    274 |     template <typename T>
 | 
| deba@948 |    275 |     struct SetElevator
 | 
| deba@948 |    276 |       : public MaxFractionalMatching<Graph, SetElevatorTraits<T> > {
 | 
| deba@948 |    277 |       typedef MaxFractionalMatching<Graph, SetElevatorTraits<T> > Create;
 | 
| deba@948 |    278 |     };
 | 
| deba@948 |    279 | 
 | 
| deba@948 |    280 |     template <typename T>
 | 
| deba@948 |    281 |     struct SetStandardElevatorTraits : public Traits {
 | 
| deba@948 |    282 |       typedef T Elevator;
 | 
| deba@948 |    283 |       static Elevator *createElevator(const Graph& graph, int max_level) {
 | 
| deba@948 |    284 |         return new Elevator(graph, max_level);
 | 
| deba@948 |    285 |       }
 | 
| deba@948 |    286 |     };
 | 
| deba@948 |    287 | 
 | 
| deba@948 |    288 |     /// \brief \ref named-templ-param "Named parameter" for setting
 | 
| deba@948 |    289 |     /// Elevator type with automatic allocation
 | 
| deba@948 |    290 |     ///
 | 
| deba@948 |    291 |     /// \ref named-templ-param "Named parameter" for setting Elevator
 | 
| deba@948 |    292 |     /// type with automatic allocation.
 | 
| deba@948 |    293 |     /// The Elevator should have standard constructor interface to be
 | 
| deba@948 |    294 |     /// able to automatically created by the algorithm (i.e. the
 | 
| deba@948 |    295 |     /// graph and the maximum level should be passed to it).
 | 
| deba@948 |    296 |     /// However an external elevator object could also be passed to the
 | 
| deba@948 |    297 |     /// algorithm with the \ref elevator(Elevator&) "elevator()" function
 | 
| deba@948 |    298 |     /// before calling \ref run() or \ref init().
 | 
| deba@948 |    299 |     /// \sa SetElevator
 | 
| deba@948 |    300 |     template <typename T>
 | 
| deba@948 |    301 |     struct SetStandardElevator
 | 
| deba@948 |    302 |       : public MaxFractionalMatching<Graph, SetStandardElevatorTraits<T> > {
 | 
| deba@948 |    303 |       typedef MaxFractionalMatching<Graph,
 | 
| deba@948 |    304 |                                     SetStandardElevatorTraits<T> > Create;
 | 
| deba@948 |    305 |     };
 | 
| deba@948 |    306 | 
 | 
| deba@948 |    307 |     /// @}
 | 
| deba@948 |    308 | 
 | 
| deba@948 |    309 |   protected:
 | 
| deba@948 |    310 | 
 | 
| deba@948 |    311 |     MaxFractionalMatching() {}
 | 
| deba@948 |    312 | 
 | 
| deba@948 |    313 |   public:
 | 
| deba@948 |    314 | 
 | 
| deba@948 |    315 |     /// \brief Constructor
 | 
| deba@948 |    316 |     ///
 | 
| deba@948 |    317 |     /// Constructor.
 | 
| deba@948 |    318 |     ///
 | 
| deba@948 |    319 |     MaxFractionalMatching(const Graph &graph, bool allow_loops = true)
 | 
| deba@948 |    320 |       : _graph(graph), _allow_loops(allow_loops),
 | 
| deba@948 |    321 |         _local_matching(false), _matching(0),
 | 
| deba@948 |    322 |         _local_level(false), _level(0),  _indeg(0)
 | 
| deba@948 |    323 |     {}
 | 
| deba@948 |    324 | 
 | 
| deba@948 |    325 |     ~MaxFractionalMatching() {
 | 
| deba@948 |    326 |       destroyStructures();
 | 
| deba@948 |    327 |     }
 | 
| deba@948 |    328 | 
 | 
| deba@948 |    329 |     /// \brief Sets the matching map.
 | 
| deba@948 |    330 |     ///
 | 
| deba@948 |    331 |     /// Sets the matching map.
 | 
| deba@948 |    332 |     /// If you don't use this function before calling \ref run() or
 | 
| deba@948 |    333 |     /// \ref init(), an instance will be allocated automatically.
 | 
| deba@948 |    334 |     /// The destructor deallocates this automatically allocated map,
 | 
| deba@948 |    335 |     /// of course.
 | 
| deba@948 |    336 |     /// \return <tt>(*this)</tt>
 | 
| deba@948 |    337 |     MaxFractionalMatching& matchingMap(MatchingMap& map) {
 | 
| deba@948 |    338 |       if (_local_matching) {
 | 
| deba@948 |    339 |         delete _matching;
 | 
| deba@948 |    340 |         _local_matching = false;
 | 
| deba@948 |    341 |       }
 | 
| deba@948 |    342 |       _matching = ↦
 | 
| deba@948 |    343 |       return *this;
 | 
| deba@948 |    344 |     }
 | 
| deba@948 |    345 | 
 | 
| deba@948 |    346 |     /// \brief Sets the elevator used by algorithm.
 | 
| deba@948 |    347 |     ///
 | 
| deba@948 |    348 |     /// Sets the elevator used by algorithm.
 | 
| deba@948 |    349 |     /// If you don't use this function before calling \ref run() or
 | 
| deba@948 |    350 |     /// \ref init(), an instance will be allocated automatically.
 | 
| deba@948 |    351 |     /// The destructor deallocates this automatically allocated elevator,
 | 
| deba@948 |    352 |     /// of course.
 | 
| deba@948 |    353 |     /// \return <tt>(*this)</tt>
 | 
| deba@948 |    354 |     MaxFractionalMatching& elevator(Elevator& elevator) {
 | 
| deba@948 |    355 |       if (_local_level) {
 | 
| deba@948 |    356 |         delete _level;
 | 
| deba@948 |    357 |         _local_level = false;
 | 
| deba@948 |    358 |       }
 | 
| deba@948 |    359 |       _level = &elevator;
 | 
| deba@948 |    360 |       return *this;
 | 
| deba@948 |    361 |     }
 | 
| deba@948 |    362 | 
 | 
| deba@948 |    363 |     /// \brief Returns a const reference to the elevator.
 | 
| deba@948 |    364 |     ///
 | 
| deba@948 |    365 |     /// Returns a const reference to the elevator.
 | 
| deba@948 |    366 |     ///
 | 
| deba@948 |    367 |     /// \pre Either \ref run() or \ref init() must be called before
 | 
| deba@948 |    368 |     /// using this function.
 | 
| deba@948 |    369 |     const Elevator& elevator() const {
 | 
| deba@948 |    370 |       return *_level;
 | 
| deba@948 |    371 |     }
 | 
| deba@948 |    372 | 
 | 
| deba@948 |    373 |     /// \name Execution control
 | 
| deba@948 |    374 |     /// The simplest way to execute the algorithm is to use one of the
 | 
| deba@948 |    375 |     /// member functions called \c run(). \n
 | 
| deba@948 |    376 |     /// If you need more control on the execution, first
 | 
| deba@948 |    377 |     /// you must call \ref init() and then one variant of the start()
 | 
| deba@948 |    378 |     /// member.
 | 
| deba@948 |    379 | 
 | 
| deba@948 |    380 |     /// @{
 | 
| deba@948 |    381 | 
 | 
| deba@948 |    382 |     /// \brief Initializes the internal data structures.
 | 
| deba@948 |    383 |     ///
 | 
| deba@948 |    384 |     /// Initializes the internal data structures and sets the initial
 | 
| deba@948 |    385 |     /// matching.
 | 
| deba@948 |    386 |     void init() {
 | 
| deba@948 |    387 |       createStructures();
 | 
| deba@948 |    388 | 
 | 
| deba@948 |    389 |       _level->initStart();
 | 
| deba@948 |    390 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |    391 |         _indeg->set(n, 0);
 | 
| deba@948 |    392 |         _matching->set(n, INVALID);
 | 
| deba@948 |    393 |         _level->initAddItem(n);
 | 
| deba@948 |    394 |       }
 | 
| deba@948 |    395 |       _level->initFinish();
 | 
| deba@948 |    396 | 
 | 
| deba@948 |    397 |       _empty_level = _node_num;
 | 
| deba@948 |    398 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |    399 |         for (OutArcIt a(_graph, n); a != INVALID; ++a) {
 | 
| deba@948 |    400 |           if (_graph.target(a) == n && !_allow_loops) continue;
 | 
| deba@948 |    401 |           _matching->set(n, a);
 | 
| deba@948 |    402 |           Node v = _graph.target((*_matching)[n]);
 | 
| deba@948 |    403 |           _indeg->set(v, (*_indeg)[v] + 1);
 | 
| deba@948 |    404 |           break;
 | 
| deba@948 |    405 |         }
 | 
| deba@948 |    406 |       }
 | 
| deba@948 |    407 | 
 | 
| deba@948 |    408 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |    409 |         if ((*_indeg)[n] == 0) {
 | 
| deba@948 |    410 |           _level->activate(n);
 | 
| deba@948 |    411 |         }
 | 
| deba@948 |    412 |       }
 | 
| deba@948 |    413 |     }
 | 
| deba@948 |    414 | 
 | 
| deba@948 |    415 |     /// \brief Starts the algorithm and computes a fractional matching
 | 
| deba@948 |    416 |     ///
 | 
| deba@948 |    417 |     /// The algorithm computes a maximum fractional matching.
 | 
| deba@948 |    418 |     ///
 | 
| deba@948 |    419 |     /// \param postprocess The algorithm computes first a matching
 | 
| deba@948 |    420 |     /// which is a union of a matching with one value edges, cycles
 | 
| deba@948 |    421 |     /// with half value edges and even length paths with half value
 | 
| deba@948 |    422 |     /// edges. If the parameter is true, then after the push-relabel
 | 
| deba@948 |    423 |     /// algorithm it postprocesses the matching to contain only
 | 
| deba@948 |    424 |     /// matching edges and half value odd cycles.
 | 
| deba@948 |    425 |     void start(bool postprocess = true) {
 | 
| deba@948 |    426 |       Node n;
 | 
| deba@948 |    427 |       while ((n = _level->highestActive()) != INVALID) {
 | 
| deba@948 |    428 |         int level = _level->highestActiveLevel();
 | 
| deba@948 |    429 |         int new_level = _level->maxLevel();
 | 
| deba@948 |    430 |         for (InArcIt a(_graph, n); a != INVALID; ++a) {
 | 
| deba@948 |    431 |           Node u = _graph.source(a);
 | 
| deba@948 |    432 |           if (n == u && !_allow_loops) continue;
 | 
| deba@948 |    433 |           Node v = _graph.target((*_matching)[u]);
 | 
| deba@948 |    434 |           if ((*_level)[v] < level) {
 | 
| deba@948 |    435 |             _indeg->set(v, (*_indeg)[v] - 1);
 | 
| deba@948 |    436 |             if ((*_indeg)[v] == 0) {
 | 
| deba@948 |    437 |               _level->activate(v);
 | 
| deba@948 |    438 |             }
 | 
| deba@948 |    439 |             _matching->set(u, a);
 | 
| deba@948 |    440 |             _indeg->set(n, (*_indeg)[n] + 1);
 | 
| deba@948 |    441 |             _level->deactivate(n);
 | 
| deba@948 |    442 |             goto no_more_push;
 | 
| deba@948 |    443 |           } else if (new_level > (*_level)[v]) {
 | 
| deba@948 |    444 |             new_level = (*_level)[v];
 | 
| deba@948 |    445 |           }
 | 
| deba@948 |    446 |         }
 | 
| deba@948 |    447 | 
 | 
| deba@948 |    448 |         if (new_level + 1 < _level->maxLevel()) {
 | 
| deba@948 |    449 |           _level->liftHighestActive(new_level + 1);
 | 
| deba@948 |    450 |         } else {
 | 
| deba@948 |    451 |           _level->liftHighestActiveToTop();
 | 
| deba@948 |    452 |         }
 | 
| deba@948 |    453 |         if (_level->emptyLevel(level)) {
 | 
| deba@948 |    454 |           _level->liftToTop(level);
 | 
| deba@948 |    455 |         }
 | 
| deba@948 |    456 |       no_more_push:
 | 
| deba@948 |    457 |         ;
 | 
| deba@948 |    458 |       }
 | 
| deba@948 |    459 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |    460 |         if ((*_matching)[n] == INVALID) continue;
 | 
| deba@948 |    461 |         Node u = _graph.target((*_matching)[n]);
 | 
| deba@948 |    462 |         if ((*_indeg)[u] > 1) {
 | 
| deba@948 |    463 |           _indeg->set(u, (*_indeg)[u] - 1);
 | 
| deba@948 |    464 |           _matching->set(n, INVALID);
 | 
| deba@948 |    465 |         }
 | 
| deba@948 |    466 |       }
 | 
| deba@948 |    467 |       if (postprocess) {
 | 
| deba@948 |    468 |         postprocessing();
 | 
| deba@948 |    469 |       }
 | 
| deba@948 |    470 |     }
 | 
| deba@948 |    471 | 
 | 
| deba@948 |    472 |     /// \brief Starts the algorithm and computes a perfect fractional
 | 
| deba@948 |    473 |     /// matching
 | 
| deba@948 |    474 |     ///
 | 
| deba@948 |    475 |     /// The algorithm computes a perfect fractional matching. If it
 | 
| deba@948 |    476 |     /// does not exists, then the algorithm returns false and the
 | 
| deba@948 |    477 |     /// matching is undefined and the barrier.
 | 
| deba@948 |    478 |     ///
 | 
| deba@948 |    479 |     /// \param postprocess The algorithm computes first a matching
 | 
| deba@948 |    480 |     /// which is a union of a matching with one value edges, cycles
 | 
| deba@948 |    481 |     /// with half value edges and even length paths with half value
 | 
| deba@948 |    482 |     /// edges. If the parameter is true, then after the push-relabel
 | 
| deba@948 |    483 |     /// algorithm it postprocesses the matching to contain only
 | 
| deba@948 |    484 |     /// matching edges and half value odd cycles.
 | 
| deba@948 |    485 |     bool startPerfect(bool postprocess = true) {
 | 
| deba@948 |    486 |       Node n;
 | 
| deba@948 |    487 |       while ((n = _level->highestActive()) != INVALID) {
 | 
| deba@948 |    488 |         int level = _level->highestActiveLevel();
 | 
| deba@948 |    489 |         int new_level = _level->maxLevel();
 | 
| deba@948 |    490 |         for (InArcIt a(_graph, n); a != INVALID; ++a) {
 | 
| deba@948 |    491 |           Node u = _graph.source(a);
 | 
| deba@948 |    492 |           if (n == u && !_allow_loops) continue;
 | 
| deba@948 |    493 |           Node v = _graph.target((*_matching)[u]);
 | 
| deba@948 |    494 |           if ((*_level)[v] < level) {
 | 
| deba@948 |    495 |             _indeg->set(v, (*_indeg)[v] - 1);
 | 
| deba@948 |    496 |             if ((*_indeg)[v] == 0) {
 | 
| deba@948 |    497 |               _level->activate(v);
 | 
| deba@948 |    498 |             }
 | 
| deba@948 |    499 |             _matching->set(u, a);
 | 
| deba@948 |    500 |             _indeg->set(n, (*_indeg)[n] + 1);
 | 
| deba@948 |    501 |             _level->deactivate(n);
 | 
| deba@948 |    502 |             goto no_more_push;
 | 
| deba@948 |    503 |           } else if (new_level > (*_level)[v]) {
 | 
| deba@948 |    504 |             new_level = (*_level)[v];
 | 
| deba@948 |    505 |           }
 | 
| deba@948 |    506 |         }
 | 
| deba@948 |    507 | 
 | 
| deba@948 |    508 |         if (new_level + 1 < _level->maxLevel()) {
 | 
| deba@948 |    509 |           _level->liftHighestActive(new_level + 1);
 | 
| deba@948 |    510 |         } else {
 | 
| deba@948 |    511 |           _level->liftHighestActiveToTop();
 | 
| deba@948 |    512 |           _empty_level = _level->maxLevel() - 1;
 | 
| deba@948 |    513 |           return false;
 | 
| deba@948 |    514 |         }
 | 
| deba@948 |    515 |         if (_level->emptyLevel(level)) {
 | 
| deba@948 |    516 |           _level->liftToTop(level);
 | 
| deba@948 |    517 |           _empty_level = level;
 | 
| deba@948 |    518 |           return false;
 | 
| deba@948 |    519 |         }
 | 
| deba@948 |    520 |       no_more_push:
 | 
| deba@948 |    521 |         ;
 | 
| deba@948 |    522 |       }
 | 
| deba@948 |    523 |       if (postprocess) {
 | 
| deba@948 |    524 |         postprocessing();
 | 
| deba@948 |    525 |       }
 | 
| deba@948 |    526 |       return true;
 | 
| deba@948 |    527 |     }
 | 
| deba@948 |    528 | 
 | 
| deba@948 |    529 |     /// \brief Runs the algorithm
 | 
| deba@948 |    530 |     ///
 | 
| deba@948 |    531 |     /// Just a shortcut for the next code:
 | 
| deba@948 |    532 |     ///\code
 | 
| deba@948 |    533 |     /// init();
 | 
| deba@948 |    534 |     /// start();
 | 
| deba@948 |    535 |     ///\endcode
 | 
| deba@948 |    536 |     void run(bool postprocess = true) {
 | 
| deba@948 |    537 |       init();
 | 
| deba@948 |    538 |       start(postprocess);
 | 
| deba@948 |    539 |     }
 | 
| deba@948 |    540 | 
 | 
| deba@948 |    541 |     /// \brief Runs the algorithm to find a perfect fractional matching
 | 
| deba@948 |    542 |     ///
 | 
| deba@948 |    543 |     /// Just a shortcut for the next code:
 | 
| deba@948 |    544 |     ///\code
 | 
| deba@948 |    545 |     /// init();
 | 
| deba@948 |    546 |     /// startPerfect();
 | 
| deba@948 |    547 |     ///\endcode
 | 
| deba@948 |    548 |     bool runPerfect(bool postprocess = true) {
 | 
| deba@948 |    549 |       init();
 | 
| deba@948 |    550 |       return startPerfect(postprocess);
 | 
| deba@948 |    551 |     }
 | 
| deba@948 |    552 | 
 | 
| deba@948 |    553 |     ///@}
 | 
| deba@948 |    554 | 
 | 
| deba@948 |    555 |     /// \name Query Functions
 | 
| deba@948 |    556 |     /// The result of the %Matching algorithm can be obtained using these
 | 
| deba@948 |    557 |     /// functions.\n
 | 
| deba@948 |    558 |     /// Before the use of these functions,
 | 
| deba@948 |    559 |     /// either run() or start() must be called.
 | 
| deba@948 |    560 |     ///@{
 | 
| deba@948 |    561 | 
 | 
| deba@948 |    562 | 
 | 
| deba@948 |    563 |     /// \brief Return the number of covered nodes in the matching.
 | 
| deba@948 |    564 |     ///
 | 
| deba@948 |    565 |     /// This function returns the number of covered nodes in the matching.
 | 
| deba@948 |    566 |     ///
 | 
| deba@948 |    567 |     /// \pre Either run() or start() must be called before using this function.
 | 
| deba@948 |    568 |     int matchingSize() const {
 | 
| deba@948 |    569 |       int num = 0;
 | 
| deba@948 |    570 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |    571 |         if ((*_matching)[n] != INVALID) {
 | 
| deba@948 |    572 |           ++num;
 | 
| deba@948 |    573 |         }
 | 
| deba@948 |    574 |       }
 | 
| deba@948 |    575 |       return num;
 | 
| deba@948 |    576 |     }
 | 
| deba@948 |    577 | 
 | 
| deba@948 |    578 |     /// \brief Returns a const reference to the matching map.
 | 
| deba@948 |    579 |     ///
 | 
| deba@948 |    580 |     /// Returns a const reference to the node map storing the found
 | 
| deba@948 |    581 |     /// fractional matching. This method can be called after
 | 
| deba@948 |    582 |     /// running the algorithm.
 | 
| deba@948 |    583 |     ///
 | 
| deba@948 |    584 |     /// \pre Either \ref run() or \ref init() must be called before
 | 
| deba@948 |    585 |     /// using this function.
 | 
| deba@948 |    586 |     const MatchingMap& matchingMap() const {
 | 
| deba@948 |    587 |       return *_matching;
 | 
| deba@948 |    588 |     }
 | 
| deba@948 |    589 | 
 | 
| deba@948 |    590 |     /// \brief Return \c true if the given edge is in the matching.
 | 
| deba@948 |    591 |     ///
 | 
| deba@948 |    592 |     /// This function returns \c true if the given edge is in the
 | 
| deba@948 |    593 |     /// found matching. The result is scaled by \ref primalScale
 | 
| deba@948 |    594 |     /// "primal scale".
 | 
| deba@948 |    595 |     ///
 | 
| deba@948 |    596 |     /// \pre Either run() or start() must be called before using this function.
 | 
| deba@948 |    597 |     int matching(const Edge& edge) const {
 | 
| deba@948 |    598 |       return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0) +
 | 
| deba@948 |    599 |         (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
 | 
| deba@948 |    600 |     }
 | 
| deba@948 |    601 | 
 | 
| deba@948 |    602 |     /// \brief Return the fractional matching arc (or edge) incident
 | 
| deba@948 |    603 |     /// to the given node.
 | 
| deba@948 |    604 |     ///
 | 
| deba@948 |    605 |     /// This function returns one of the fractional matching arc (or
 | 
| deba@948 |    606 |     /// edge) incident to the given node in the found matching or \c
 | 
| deba@948 |    607 |     /// INVALID if the node is not covered by the matching or if the
 | 
| deba@948 |    608 |     /// node is on an odd length cycle then it is the successor edge
 | 
| deba@948 |    609 |     /// on the cycle.
 | 
| deba@948 |    610 |     ///
 | 
| deba@948 |    611 |     /// \pre Either run() or start() must be called before using this function.
 | 
| deba@948 |    612 |     Arc matching(const Node& node) const {
 | 
| deba@948 |    613 |       return (*_matching)[node];
 | 
| deba@948 |    614 |     }
 | 
| deba@948 |    615 | 
 | 
| deba@948 |    616 |     /// \brief Returns true if the node is in the barrier
 | 
| deba@948 |    617 |     ///
 | 
| deba@948 |    618 |     /// The barrier is a subset of the nodes. If the nodes in the
 | 
| deba@948 |    619 |     /// barrier have less adjacent nodes than the size of the barrier,
 | 
| deba@948 |    620 |     /// then at least as much nodes cannot be covered as the
 | 
| deba@948 |    621 |     /// difference of the two subsets.
 | 
| deba@948 |    622 |     bool barrier(const Node& node) const {
 | 
| deba@948 |    623 |       return (*_level)[node] >= _empty_level;
 | 
| deba@948 |    624 |     }
 | 
| deba@948 |    625 | 
 | 
| deba@948 |    626 |     /// @}
 | 
| deba@948 |    627 | 
 | 
| deba@948 |    628 |   };
 | 
| deba@948 |    629 | 
 | 
| deba@948 |    630 |   /// \ingroup matching
 | 
| deba@948 |    631 |   ///
 | 
| deba@948 |    632 |   /// \brief Weighted fractional matching in general graphs
 | 
| deba@948 |    633 |   ///
 | 
| deba@948 |    634 |   /// This class provides an efficient implementation of fractional
 | 
| deba@950 |    635 |   /// matching algorithm. The implementation uses priority queues and
 | 
| deba@950 |    636 |   /// provides \f$O(nm\log n)\f$ time complexity.
 | 
| deba@948 |    637 |   ///
 | 
| deba@948 |    638 |   /// The maximum weighted fractional matching is a relaxation of the
 | 
| deba@948 |    639 |   /// maximum weighted matching problem where the odd set constraints
 | 
| deba@948 |    640 |   /// are omitted.
 | 
| deba@948 |    641 |   /// It can be formulated with the following linear program.
 | 
| deba@948 |    642 |   /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
 | 
| deba@948 |    643 |   /// \f[x_e \ge 0\quad \forall e\in E\f]
 | 
| deba@948 |    644 |   /// \f[\max \sum_{e\in E}x_ew_e\f]
 | 
| deba@948 |    645 |   /// where \f$\delta(X)\f$ is the set of edges incident to a node in
 | 
| deba@948 |    646 |   /// \f$X\f$. The result must be the union of a matching with one
 | 
| deba@948 |    647 |   /// value edges and a set of odd length cycles with half value edges.
 | 
| deba@948 |    648 |   ///
 | 
| deba@948 |    649 |   /// The algorithm calculates an optimal fractional matching and a
 | 
| deba@948 |    650 |   /// proof of the optimality. The solution of the dual problem can be
 | 
| deba@948 |    651 |   /// used to check the result of the algorithm. The dual linear
 | 
| deba@948 |    652 |   /// problem is the following.
 | 
| deba@948 |    653 |   /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
 | 
| deba@948 |    654 |   /// \f[y_u \ge 0 \quad \forall u \in V\f]
 | 
| deba@950 |    655 |   /// \f[\min \sum_{u \in V}y_u \f]
 | 
| deba@948 |    656 |   ///
 | 
| deba@948 |    657 |   /// The algorithm can be executed with the run() function.
 | 
| deba@948 |    658 |   /// After it the matching (the primal solution) and the dual solution
 | 
| deba@948 |    659 |   /// can be obtained using the query functions.
 | 
| deba@948 |    660 |   ///
 | 
| deba@951 |    661 |   /// The primal solution is multiplied by
 | 
| deba@951 |    662 |   /// \ref MaxWeightedFractionalMatching::primalScale "2".
 | 
| deba@951 |    663 |   /// If the value type is integer, then the dual
 | 
| deba@951 |    664 |   /// solution is scaled by
 | 
| deba@951 |    665 |   /// \ref MaxWeightedFractionalMatching::dualScale "4".
 | 
| deba@948 |    666 |   ///
 | 
| deba@948 |    667 |   /// \tparam GR The undirected graph type the algorithm runs on.
 | 
| deba@948 |    668 |   /// \tparam WM The type edge weight map. The default type is
 | 
| deba@948 |    669 |   /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
 | 
| deba@948 |    670 | #ifdef DOXYGEN
 | 
| deba@948 |    671 |   template <typename GR, typename WM>
 | 
| deba@948 |    672 | #else
 | 
| deba@948 |    673 |   template <typename GR,
 | 
| deba@948 |    674 |             typename WM = typename GR::template EdgeMap<int> >
 | 
| deba@948 |    675 | #endif
 | 
| deba@948 |    676 |   class MaxWeightedFractionalMatching {
 | 
| deba@948 |    677 |   public:
 | 
| deba@948 |    678 | 
 | 
| deba@948 |    679 |     /// The graph type of the algorithm
 | 
| deba@948 |    680 |     typedef GR Graph;
 | 
| deba@948 |    681 |     /// The type of the edge weight map
 | 
| deba@948 |    682 |     typedef WM WeightMap;
 | 
| deba@948 |    683 |     /// The value type of the edge weights
 | 
| deba@948 |    684 |     typedef typename WeightMap::Value Value;
 | 
| deba@948 |    685 | 
 | 
| deba@948 |    686 |     /// The type of the matching map
 | 
| deba@948 |    687 |     typedef typename Graph::template NodeMap<typename Graph::Arc>
 | 
| deba@948 |    688 |     MatchingMap;
 | 
| deba@948 |    689 | 
 | 
| deba@948 |    690 |     /// \brief Scaling factor for primal solution
 | 
| deba@948 |    691 |     ///
 | 
| deba@951 |    692 |     /// Scaling factor for primal solution.
 | 
| deba@951 |    693 |     static const int primalScale = 2;
 | 
| deba@948 |    694 | 
 | 
| deba@948 |    695 |     /// \brief Scaling factor for dual solution
 | 
| deba@948 |    696 |     ///
 | 
| deba@948 |    697 |     /// Scaling factor for dual solution. It is equal to 4 or 1
 | 
| deba@948 |    698 |     /// according to the value type.
 | 
| deba@948 |    699 |     static const int dualScale =
 | 
| deba@948 |    700 |       std::numeric_limits<Value>::is_integer ? 4 : 1;
 | 
| deba@948 |    701 | 
 | 
| deba@948 |    702 |   private:
 | 
| deba@948 |    703 | 
 | 
| deba@948 |    704 |     TEMPLATE_GRAPH_TYPEDEFS(Graph);
 | 
| deba@948 |    705 | 
 | 
| deba@948 |    706 |     typedef typename Graph::template NodeMap<Value> NodePotential;
 | 
| deba@948 |    707 | 
 | 
| deba@948 |    708 |     const Graph& _graph;
 | 
| deba@948 |    709 |     const WeightMap& _weight;
 | 
| deba@948 |    710 | 
 | 
| deba@948 |    711 |     MatchingMap* _matching;
 | 
| deba@948 |    712 |     NodePotential* _node_potential;
 | 
| deba@948 |    713 | 
 | 
| deba@948 |    714 |     int _node_num;
 | 
| deba@948 |    715 |     bool _allow_loops;
 | 
| deba@948 |    716 | 
 | 
| deba@948 |    717 |     enum Status {
 | 
| deba@948 |    718 |       EVEN = -1, MATCHED = 0, ODD = 1
 | 
| deba@948 |    719 |     };
 | 
| deba@948 |    720 | 
 | 
| deba@948 |    721 |     typedef typename Graph::template NodeMap<Status> StatusMap;
 | 
| deba@948 |    722 |     StatusMap* _status;
 | 
| deba@948 |    723 | 
 | 
| deba@948 |    724 |     typedef typename Graph::template NodeMap<Arc> PredMap;
 | 
| deba@948 |    725 |     PredMap* _pred;
 | 
| deba@948 |    726 | 
 | 
| deba@948 |    727 |     typedef ExtendFindEnum<IntNodeMap> TreeSet;
 | 
| deba@948 |    728 | 
 | 
| deba@948 |    729 |     IntNodeMap *_tree_set_index;
 | 
| deba@948 |    730 |     TreeSet *_tree_set;
 | 
| deba@948 |    731 | 
 | 
| deba@948 |    732 |     IntNodeMap *_delta1_index;
 | 
| deba@948 |    733 |     BinHeap<Value, IntNodeMap> *_delta1;
 | 
| deba@948 |    734 | 
 | 
| deba@948 |    735 |     IntNodeMap *_delta2_index;
 | 
| deba@948 |    736 |     BinHeap<Value, IntNodeMap> *_delta2;
 | 
| deba@948 |    737 | 
 | 
| deba@948 |    738 |     IntEdgeMap *_delta3_index;
 | 
| deba@948 |    739 |     BinHeap<Value, IntEdgeMap> *_delta3;
 | 
| deba@948 |    740 | 
 | 
| deba@948 |    741 |     Value _delta_sum;
 | 
| deba@948 |    742 | 
 | 
| deba@948 |    743 |     void createStructures() {
 | 
| deba@948 |    744 |       _node_num = countNodes(_graph);
 | 
| deba@948 |    745 | 
 | 
| deba@948 |    746 |       if (!_matching) {
 | 
| deba@948 |    747 |         _matching = new MatchingMap(_graph);
 | 
| deba@948 |    748 |       }
 | 
| deba@948 |    749 |       if (!_node_potential) {
 | 
| deba@948 |    750 |         _node_potential = new NodePotential(_graph);
 | 
| deba@948 |    751 |       }
 | 
| deba@948 |    752 |       if (!_status) {
 | 
| deba@948 |    753 |         _status = new StatusMap(_graph);
 | 
| deba@948 |    754 |       }
 | 
| deba@948 |    755 |       if (!_pred) {
 | 
| deba@948 |    756 |         _pred = new PredMap(_graph);
 | 
| deba@948 |    757 |       }
 | 
| deba@948 |    758 |       if (!_tree_set) {
 | 
| deba@948 |    759 |         _tree_set_index = new IntNodeMap(_graph);
 | 
| deba@948 |    760 |         _tree_set = new TreeSet(*_tree_set_index);
 | 
| deba@948 |    761 |       }
 | 
| deba@948 |    762 |       if (!_delta1) {
 | 
| deba@948 |    763 |         _delta1_index = new IntNodeMap(_graph);
 | 
| deba@948 |    764 |         _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
 | 
| deba@948 |    765 |       }
 | 
| deba@948 |    766 |       if (!_delta2) {
 | 
| deba@948 |    767 |         _delta2_index = new IntNodeMap(_graph);
 | 
| deba@948 |    768 |         _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
 | 
| deba@948 |    769 |       }
 | 
| deba@948 |    770 |       if (!_delta3) {
 | 
| deba@948 |    771 |         _delta3_index = new IntEdgeMap(_graph);
 | 
| deba@948 |    772 |         _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
 | 
| deba@948 |    773 |       }
 | 
| deba@948 |    774 |     }
 | 
| deba@948 |    775 | 
 | 
| deba@948 |    776 |     void destroyStructures() {
 | 
| deba@948 |    777 |       if (_matching) {
 | 
| deba@948 |    778 |         delete _matching;
 | 
| deba@948 |    779 |       }
 | 
| deba@948 |    780 |       if (_node_potential) {
 | 
| deba@948 |    781 |         delete _node_potential;
 | 
| deba@948 |    782 |       }
 | 
| deba@948 |    783 |       if (_status) {
 | 
| deba@948 |    784 |         delete _status;
 | 
| deba@948 |    785 |       }
 | 
| deba@948 |    786 |       if (_pred) {
 | 
| deba@948 |    787 |         delete _pred;
 | 
| deba@948 |    788 |       }
 | 
| deba@948 |    789 |       if (_tree_set) {
 | 
| deba@948 |    790 |         delete _tree_set_index;
 | 
| deba@948 |    791 |         delete _tree_set;
 | 
| deba@948 |    792 |       }
 | 
| deba@948 |    793 |       if (_delta1) {
 | 
| deba@948 |    794 |         delete _delta1_index;
 | 
| deba@948 |    795 |         delete _delta1;
 | 
| deba@948 |    796 |       }
 | 
| deba@948 |    797 |       if (_delta2) {
 | 
| deba@948 |    798 |         delete _delta2_index;
 | 
| deba@948 |    799 |         delete _delta2;
 | 
| deba@948 |    800 |       }
 | 
| deba@948 |    801 |       if (_delta3) {
 | 
| deba@948 |    802 |         delete _delta3_index;
 | 
| deba@948 |    803 |         delete _delta3;
 | 
| deba@948 |    804 |       }
 | 
| deba@948 |    805 |     }
 | 
| deba@948 |    806 | 
 | 
| deba@948 |    807 |     void matchedToEven(Node node, int tree) {
 | 
| deba@948 |    808 |       _tree_set->insert(node, tree);
 | 
| deba@948 |    809 |       _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
 | 
| deba@948 |    810 |       _delta1->push(node, (*_node_potential)[node]);
 | 
| deba@948 |    811 | 
 | 
| deba@948 |    812 |       if (_delta2->state(node) == _delta2->IN_HEAP) {
 | 
| deba@948 |    813 |         _delta2->erase(node);
 | 
| deba@948 |    814 |       }
 | 
| deba@948 |    815 | 
 | 
| deba@948 |    816 |       for (InArcIt a(_graph, node); a != INVALID; ++a) {
 | 
| deba@948 |    817 |         Node v = _graph.source(a);
 | 
| deba@948 |    818 |         Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
 | 
| deba@948 |    819 |           dualScale * _weight[a];
 | 
| deba@948 |    820 |         if (node == v) {
 | 
| deba@948 |    821 |           if (_allow_loops && _graph.direction(a)) {
 | 
| deba@948 |    822 |             _delta3->push(a, rw / 2);
 | 
| deba@948 |    823 |           }
 | 
| deba@948 |    824 |         } else if ((*_status)[v] == EVEN) {
 | 
| deba@948 |    825 |           _delta3->push(a, rw / 2);
 | 
| deba@948 |    826 |         } else if ((*_status)[v] == MATCHED) {
 | 
| deba@948 |    827 |           if (_delta2->state(v) != _delta2->IN_HEAP) {
 | 
| deba@948 |    828 |             _pred->set(v, a);
 | 
| deba@948 |    829 |             _delta2->push(v, rw);
 | 
| deba@948 |    830 |           } else if ((*_delta2)[v] > rw) {
 | 
| deba@948 |    831 |             _pred->set(v, a);
 | 
| deba@948 |    832 |             _delta2->decrease(v, rw);
 | 
| deba@948 |    833 |           }
 | 
| deba@948 |    834 |         }
 | 
| deba@948 |    835 |       }
 | 
| deba@948 |    836 |     }
 | 
| deba@948 |    837 | 
 | 
| deba@948 |    838 |     void matchedToOdd(Node node, int tree) {
 | 
| deba@948 |    839 |       _tree_set->insert(node, tree);
 | 
| deba@948 |    840 |       _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
 | 
| deba@948 |    841 | 
 | 
| deba@948 |    842 |       if (_delta2->state(node) == _delta2->IN_HEAP) {
 | 
| deba@948 |    843 |         _delta2->erase(node);
 | 
| deba@948 |    844 |       }
 | 
| deba@948 |    845 |     }
 | 
| deba@948 |    846 | 
 | 
| deba@948 |    847 |     void evenToMatched(Node node, int tree) {
 | 
| deba@948 |    848 |       _delta1->erase(node);
 | 
| deba@948 |    849 |       _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
 | 
| deba@948 |    850 |       Arc min = INVALID;
 | 
| deba@948 |    851 |       Value minrw = std::numeric_limits<Value>::max();
 | 
| deba@948 |    852 |       for (InArcIt a(_graph, node); a != INVALID; ++a) {
 | 
| deba@948 |    853 |         Node v = _graph.source(a);
 | 
| deba@948 |    854 |         Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
 | 
| deba@948 |    855 |           dualScale * _weight[a];
 | 
| deba@948 |    856 | 
 | 
| deba@948 |    857 |         if (node == v) {
 | 
| deba@948 |    858 |           if (_allow_loops && _graph.direction(a)) {
 | 
| deba@948 |    859 |             _delta3->erase(a);
 | 
| deba@948 |    860 |           }
 | 
| deba@948 |    861 |         } else if ((*_status)[v] == EVEN) {
 | 
| deba@948 |    862 |           _delta3->erase(a);
 | 
| deba@948 |    863 |           if (minrw > rw) {
 | 
| deba@948 |    864 |             min = _graph.oppositeArc(a);
 | 
| deba@948 |    865 |             minrw = rw;
 | 
| deba@948 |    866 |           }
 | 
| deba@948 |    867 |         } else if ((*_status)[v]  == MATCHED) {
 | 
| deba@948 |    868 |           if ((*_pred)[v] == a) {
 | 
| deba@948 |    869 |             Arc mina = INVALID;
 | 
| deba@948 |    870 |             Value minrwa = std::numeric_limits<Value>::max();
 | 
| deba@948 |    871 |             for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
 | 
| deba@948 |    872 |               Node va = _graph.target(aa);
 | 
| deba@948 |    873 |               if ((*_status)[va] != EVEN ||
 | 
| deba@948 |    874 |                   _tree_set->find(va) == tree) continue;
 | 
| deba@948 |    875 |               Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
 | 
| deba@948 |    876 |                 dualScale * _weight[aa];
 | 
| deba@948 |    877 |               if (minrwa > rwa) {
 | 
| deba@948 |    878 |                 minrwa = rwa;
 | 
| deba@948 |    879 |                 mina = aa;
 | 
| deba@948 |    880 |               }
 | 
| deba@948 |    881 |             }
 | 
| deba@948 |    882 |             if (mina != INVALID) {
 | 
| deba@948 |    883 |               _pred->set(v, mina);
 | 
| deba@948 |    884 |               _delta2->increase(v, minrwa);
 | 
| deba@948 |    885 |             } else {
 | 
| deba@948 |    886 |               _pred->set(v, INVALID);
 | 
| deba@948 |    887 |               _delta2->erase(v);
 | 
| deba@948 |    888 |             }
 | 
| deba@948 |    889 |           }
 | 
| deba@948 |    890 |         }
 | 
| deba@948 |    891 |       }
 | 
| deba@948 |    892 |       if (min != INVALID) {
 | 
| deba@948 |    893 |         _pred->set(node, min);
 | 
| deba@948 |    894 |         _delta2->push(node, minrw);
 | 
| deba@948 |    895 |       } else {
 | 
| deba@948 |    896 |         _pred->set(node, INVALID);
 | 
| deba@948 |    897 |       }
 | 
| deba@948 |    898 |     }
 | 
| deba@948 |    899 | 
 | 
| deba@948 |    900 |     void oddToMatched(Node node) {
 | 
| deba@948 |    901 |       _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
 | 
| deba@948 |    902 |       Arc min = INVALID;
 | 
| deba@948 |    903 |       Value minrw = std::numeric_limits<Value>::max();
 | 
| deba@948 |    904 |       for (InArcIt a(_graph, node); a != INVALID; ++a) {
 | 
| deba@948 |    905 |         Node v = _graph.source(a);
 | 
| deba@948 |    906 |         if ((*_status)[v] != EVEN) continue;
 | 
| deba@948 |    907 |         Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
 | 
| deba@948 |    908 |           dualScale * _weight[a];
 | 
| deba@948 |    909 | 
 | 
| deba@948 |    910 |         if (minrw > rw) {
 | 
| deba@948 |    911 |           min = _graph.oppositeArc(a);
 | 
| deba@948 |    912 |           minrw = rw;
 | 
| deba@948 |    913 |         }
 | 
| deba@948 |    914 |       }
 | 
| deba@948 |    915 |       if (min != INVALID) {
 | 
| deba@948 |    916 |         _pred->set(node, min);
 | 
| deba@948 |    917 |         _delta2->push(node, minrw);
 | 
| deba@948 |    918 |       } else {
 | 
| deba@948 |    919 |         _pred->set(node, INVALID);
 | 
| deba@948 |    920 |       }
 | 
| deba@948 |    921 |     }
 | 
| deba@948 |    922 | 
 | 
| deba@948 |    923 |     void alternatePath(Node even, int tree) {
 | 
| deba@948 |    924 |       Node odd;
 | 
| deba@948 |    925 | 
 | 
| deba@948 |    926 |       _status->set(even, MATCHED);
 | 
| deba@948 |    927 |       evenToMatched(even, tree);
 | 
| deba@948 |    928 | 
 | 
| deba@948 |    929 |       Arc prev = (*_matching)[even];
 | 
| deba@948 |    930 |       while (prev != INVALID) {
 | 
| deba@948 |    931 |         odd = _graph.target(prev);
 | 
| deba@948 |    932 |         even = _graph.target((*_pred)[odd]);
 | 
| deba@948 |    933 |         _matching->set(odd, (*_pred)[odd]);
 | 
| deba@948 |    934 |         _status->set(odd, MATCHED);
 | 
| deba@948 |    935 |         oddToMatched(odd);
 | 
| deba@948 |    936 | 
 | 
| deba@948 |    937 |         prev = (*_matching)[even];
 | 
| deba@948 |    938 |         _status->set(even, MATCHED);
 | 
| deba@948 |    939 |         _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
 | 
| deba@948 |    940 |         evenToMatched(even, tree);
 | 
| deba@948 |    941 |       }
 | 
| deba@948 |    942 |     }
 | 
| deba@948 |    943 | 
 | 
| deba@948 |    944 |     void destroyTree(int tree) {
 | 
| deba@948 |    945 |       for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
 | 
| deba@948 |    946 |         if ((*_status)[n] == EVEN) {
 | 
| deba@948 |    947 |           _status->set(n, MATCHED);
 | 
| deba@948 |    948 |           evenToMatched(n, tree);
 | 
| deba@948 |    949 |         } else if ((*_status)[n] == ODD) {
 | 
| deba@948 |    950 |           _status->set(n, MATCHED);
 | 
| deba@948 |    951 |           oddToMatched(n);
 | 
| deba@948 |    952 |         }
 | 
| deba@948 |    953 |       }
 | 
| deba@948 |    954 |       _tree_set->eraseClass(tree);
 | 
| deba@948 |    955 |     }
 | 
| deba@948 |    956 | 
 | 
| deba@948 |    957 | 
 | 
| deba@948 |    958 |     void unmatchNode(const Node& node) {
 | 
| deba@948 |    959 |       int tree = _tree_set->find(node);
 | 
| deba@948 |    960 | 
 | 
| deba@948 |    961 |       alternatePath(node, tree);
 | 
| deba@948 |    962 |       destroyTree(tree);
 | 
| deba@948 |    963 | 
 | 
| deba@948 |    964 |       _matching->set(node, INVALID);
 | 
| deba@948 |    965 |     }
 | 
| deba@948 |    966 | 
 | 
| deba@948 |    967 | 
 | 
| deba@948 |    968 |     void augmentOnEdge(const Edge& edge) {
 | 
| deba@948 |    969 |       Node left = _graph.u(edge);
 | 
| deba@948 |    970 |       int left_tree = _tree_set->find(left);
 | 
| deba@948 |    971 | 
 | 
| deba@948 |    972 |       alternatePath(left, left_tree);
 | 
| deba@948 |    973 |       destroyTree(left_tree);
 | 
| deba@948 |    974 |       _matching->set(left, _graph.direct(edge, true));
 | 
| deba@948 |    975 | 
 | 
| deba@948 |    976 |       Node right = _graph.v(edge);
 | 
| deba@948 |    977 |       int right_tree = _tree_set->find(right);
 | 
| deba@948 |    978 | 
 | 
| deba@948 |    979 |       alternatePath(right, right_tree);
 | 
| deba@948 |    980 |       destroyTree(right_tree);
 | 
| deba@948 |    981 |       _matching->set(right, _graph.direct(edge, false));
 | 
| deba@948 |    982 |     }
 | 
| deba@948 |    983 | 
 | 
| deba@948 |    984 |     void augmentOnArc(const Arc& arc) {
 | 
| deba@948 |    985 |       Node left = _graph.source(arc);
 | 
| deba@948 |    986 |       _status->set(left, MATCHED);
 | 
| deba@948 |    987 |       _matching->set(left, arc);
 | 
| deba@948 |    988 |       _pred->set(left, arc);
 | 
| deba@948 |    989 | 
 | 
| deba@948 |    990 |       Node right = _graph.target(arc);
 | 
| deba@948 |    991 |       int right_tree = _tree_set->find(right);
 | 
| deba@948 |    992 | 
 | 
| deba@948 |    993 |       alternatePath(right, right_tree);
 | 
| deba@948 |    994 |       destroyTree(right_tree);
 | 
| deba@948 |    995 |       _matching->set(right, _graph.oppositeArc(arc));
 | 
| deba@948 |    996 |     }
 | 
| deba@948 |    997 | 
 | 
| deba@948 |    998 |     void extendOnArc(const Arc& arc) {
 | 
| deba@948 |    999 |       Node base = _graph.target(arc);
 | 
| deba@948 |   1000 |       int tree = _tree_set->find(base);
 | 
| deba@948 |   1001 | 
 | 
| deba@948 |   1002 |       Node odd = _graph.source(arc);
 | 
| deba@948 |   1003 |       _tree_set->insert(odd, tree);
 | 
| deba@948 |   1004 |       _status->set(odd, ODD);
 | 
| deba@948 |   1005 |       matchedToOdd(odd, tree);
 | 
| deba@948 |   1006 |       _pred->set(odd, arc);
 | 
| deba@948 |   1007 | 
 | 
| deba@948 |   1008 |       Node even = _graph.target((*_matching)[odd]);
 | 
| deba@948 |   1009 |       _tree_set->insert(even, tree);
 | 
| deba@948 |   1010 |       _status->set(even, EVEN);
 | 
| deba@948 |   1011 |       matchedToEven(even, tree);
 | 
| deba@948 |   1012 |     }
 | 
| deba@948 |   1013 | 
 | 
| deba@948 |   1014 |     void cycleOnEdge(const Edge& edge, int tree) {
 | 
| deba@948 |   1015 |       Node nca = INVALID;
 | 
| deba@948 |   1016 |       std::vector<Node> left_path, right_path;
 | 
| deba@948 |   1017 | 
 | 
| deba@948 |   1018 |       {
 | 
| deba@948 |   1019 |         std::set<Node> left_set, right_set;
 | 
| deba@948 |   1020 |         Node left = _graph.u(edge);
 | 
| deba@948 |   1021 |         left_path.push_back(left);
 | 
| deba@948 |   1022 |         left_set.insert(left);
 | 
| deba@948 |   1023 | 
 | 
| deba@948 |   1024 |         Node right = _graph.v(edge);
 | 
| deba@948 |   1025 |         right_path.push_back(right);
 | 
| deba@948 |   1026 |         right_set.insert(right);
 | 
| deba@948 |   1027 | 
 | 
| deba@948 |   1028 |         while (true) {
 | 
| deba@948 |   1029 | 
 | 
| deba@948 |   1030 |           if (left_set.find(right) != left_set.end()) {
 | 
| deba@948 |   1031 |             nca = right;
 | 
| deba@948 |   1032 |             break;
 | 
| deba@948 |   1033 |           }
 | 
| deba@948 |   1034 | 
 | 
| deba@948 |   1035 |           if ((*_matching)[left] == INVALID) break;
 | 
| deba@948 |   1036 | 
 | 
| deba@948 |   1037 |           left = _graph.target((*_matching)[left]);
 | 
| deba@948 |   1038 |           left_path.push_back(left);
 | 
| deba@948 |   1039 |           left = _graph.target((*_pred)[left]);
 | 
| deba@948 |   1040 |           left_path.push_back(left);
 | 
| deba@948 |   1041 | 
 | 
| deba@948 |   1042 |           left_set.insert(left);
 | 
| deba@948 |   1043 | 
 | 
| deba@948 |   1044 |           if (right_set.find(left) != right_set.end()) {
 | 
| deba@948 |   1045 |             nca = left;
 | 
| deba@948 |   1046 |             break;
 | 
| deba@948 |   1047 |           }
 | 
| deba@948 |   1048 | 
 | 
| deba@948 |   1049 |           if ((*_matching)[right] == INVALID) break;
 | 
| deba@948 |   1050 | 
 | 
| deba@948 |   1051 |           right = _graph.target((*_matching)[right]);
 | 
| deba@948 |   1052 |           right_path.push_back(right);
 | 
| deba@948 |   1053 |           right = _graph.target((*_pred)[right]);
 | 
| deba@948 |   1054 |           right_path.push_back(right);
 | 
| deba@948 |   1055 | 
 | 
| deba@948 |   1056 |           right_set.insert(right);
 | 
| deba@948 |   1057 | 
 | 
| deba@948 |   1058 |         }
 | 
| deba@948 |   1059 | 
 | 
| deba@948 |   1060 |         if (nca == INVALID) {
 | 
| deba@948 |   1061 |           if ((*_matching)[left] == INVALID) {
 | 
| deba@948 |   1062 |             nca = right;
 | 
| deba@948 |   1063 |             while (left_set.find(nca) == left_set.end()) {
 | 
| deba@948 |   1064 |               nca = _graph.target((*_matching)[nca]);
 | 
| deba@948 |   1065 |               right_path.push_back(nca);
 | 
| deba@948 |   1066 |               nca = _graph.target((*_pred)[nca]);
 | 
| deba@948 |   1067 |               right_path.push_back(nca);
 | 
| deba@948 |   1068 |             }
 | 
| deba@948 |   1069 |           } else {
 | 
| deba@948 |   1070 |             nca = left;
 | 
| deba@948 |   1071 |             while (right_set.find(nca) == right_set.end()) {
 | 
| deba@948 |   1072 |               nca = _graph.target((*_matching)[nca]);
 | 
| deba@948 |   1073 |               left_path.push_back(nca);
 | 
| deba@948 |   1074 |               nca = _graph.target((*_pred)[nca]);
 | 
| deba@948 |   1075 |               left_path.push_back(nca);
 | 
| deba@948 |   1076 |             }
 | 
| deba@948 |   1077 |           }
 | 
| deba@948 |   1078 |         }
 | 
| deba@948 |   1079 |       }
 | 
| deba@948 |   1080 | 
 | 
| deba@948 |   1081 |       alternatePath(nca, tree);
 | 
| deba@948 |   1082 |       Arc prev;
 | 
| deba@948 |   1083 | 
 | 
| deba@948 |   1084 |       prev = _graph.direct(edge, true);
 | 
| deba@948 |   1085 |       for (int i = 0; left_path[i] != nca; i += 2) {
 | 
| deba@948 |   1086 |         _matching->set(left_path[i], prev);
 | 
| deba@948 |   1087 |         _status->set(left_path[i], MATCHED);
 | 
| deba@948 |   1088 |         evenToMatched(left_path[i], tree);
 | 
| deba@948 |   1089 | 
 | 
| deba@948 |   1090 |         prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
 | 
| deba@948 |   1091 |         _status->set(left_path[i + 1], MATCHED);
 | 
| deba@948 |   1092 |         oddToMatched(left_path[i + 1]);
 | 
| deba@948 |   1093 |       }
 | 
| deba@948 |   1094 |       _matching->set(nca, prev);
 | 
| deba@948 |   1095 | 
 | 
| deba@948 |   1096 |       for (int i = 0; right_path[i] != nca; i += 2) {
 | 
| deba@948 |   1097 |         _status->set(right_path[i], MATCHED);
 | 
| deba@948 |   1098 |         evenToMatched(right_path[i], tree);
 | 
| deba@948 |   1099 | 
 | 
| deba@948 |   1100 |         _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
 | 
| deba@948 |   1101 |         _status->set(right_path[i + 1], MATCHED);
 | 
| deba@948 |   1102 |         oddToMatched(right_path[i + 1]);
 | 
| deba@948 |   1103 |       }
 | 
| deba@948 |   1104 | 
 | 
| deba@948 |   1105 |       destroyTree(tree);
 | 
| deba@948 |   1106 |     }
 | 
| deba@948 |   1107 | 
 | 
| deba@948 |   1108 |     void extractCycle(const Arc &arc) {
 | 
| deba@948 |   1109 |       Node left = _graph.source(arc);
 | 
| deba@948 |   1110 |       Node odd = _graph.target((*_matching)[left]);
 | 
| deba@948 |   1111 |       Arc prev;
 | 
| deba@948 |   1112 |       while (odd != left) {
 | 
| deba@948 |   1113 |         Node even = _graph.target((*_matching)[odd]);
 | 
| deba@948 |   1114 |         prev = (*_matching)[odd];
 | 
| deba@948 |   1115 |         odd = _graph.target((*_matching)[even]);
 | 
| deba@948 |   1116 |         _matching->set(even, _graph.oppositeArc(prev));
 | 
| deba@948 |   1117 |       }
 | 
| deba@948 |   1118 |       _matching->set(left, arc);
 | 
| deba@948 |   1119 | 
 | 
| deba@948 |   1120 |       Node right = _graph.target(arc);
 | 
| deba@948 |   1121 |       int right_tree = _tree_set->find(right);
 | 
| deba@948 |   1122 |       alternatePath(right, right_tree);
 | 
| deba@948 |   1123 |       destroyTree(right_tree);
 | 
| deba@948 |   1124 |       _matching->set(right, _graph.oppositeArc(arc));
 | 
| deba@948 |   1125 |     }
 | 
| deba@948 |   1126 | 
 | 
| deba@948 |   1127 |   public:
 | 
| deba@948 |   1128 | 
 | 
| deba@948 |   1129 |     /// \brief Constructor
 | 
| deba@948 |   1130 |     ///
 | 
| deba@948 |   1131 |     /// Constructor.
 | 
| deba@948 |   1132 |     MaxWeightedFractionalMatching(const Graph& graph, const WeightMap& weight,
 | 
| deba@948 |   1133 |                                   bool allow_loops = true)
 | 
| deba@948 |   1134 |       : _graph(graph), _weight(weight), _matching(0),
 | 
| deba@948 |   1135 |       _node_potential(0), _node_num(0), _allow_loops(allow_loops),
 | 
| deba@948 |   1136 |       _status(0),  _pred(0),
 | 
| deba@948 |   1137 |       _tree_set_index(0), _tree_set(0),
 | 
| deba@948 |   1138 | 
 | 
| deba@948 |   1139 |       _delta1_index(0), _delta1(0),
 | 
| deba@948 |   1140 |       _delta2_index(0), _delta2(0),
 | 
| deba@948 |   1141 |       _delta3_index(0), _delta3(0),
 | 
| deba@948 |   1142 | 
 | 
| deba@948 |   1143 |       _delta_sum() {}
 | 
| deba@948 |   1144 | 
 | 
| deba@948 |   1145 |     ~MaxWeightedFractionalMatching() {
 | 
| deba@948 |   1146 |       destroyStructures();
 | 
| deba@948 |   1147 |     }
 | 
| deba@948 |   1148 | 
 | 
| deba@948 |   1149 |     /// \name Execution Control
 | 
| deba@948 |   1150 |     /// The simplest way to execute the algorithm is to use the
 | 
| deba@948 |   1151 |     /// \ref run() member function.
 | 
| deba@948 |   1152 | 
 | 
| deba@948 |   1153 |     ///@{
 | 
| deba@948 |   1154 | 
 | 
| deba@948 |   1155 |     /// \brief Initialize the algorithm
 | 
| deba@948 |   1156 |     ///
 | 
| deba@948 |   1157 |     /// This function initializes the algorithm.
 | 
| deba@948 |   1158 |     void init() {
 | 
| deba@948 |   1159 |       createStructures();
 | 
| deba@948 |   1160 | 
 | 
| deba@948 |   1161 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |   1162 |         (*_delta1_index)[n] = _delta1->PRE_HEAP;
 | 
| deba@948 |   1163 |         (*_delta2_index)[n] = _delta2->PRE_HEAP;
 | 
| deba@948 |   1164 |       }
 | 
| deba@948 |   1165 |       for (EdgeIt e(_graph); e != INVALID; ++e) {
 | 
| deba@948 |   1166 |         (*_delta3_index)[e] = _delta3->PRE_HEAP;
 | 
| deba@948 |   1167 |       }
 | 
| deba@948 |   1168 | 
 | 
| deba@955 |   1169 |       _delta1->clear();
 | 
| deba@955 |   1170 |       _delta2->clear();
 | 
| deba@955 |   1171 |       _delta3->clear();
 | 
| deba@955 |   1172 |       _tree_set->clear();
 | 
| deba@955 |   1173 | 
 | 
| deba@948 |   1174 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |   1175 |         Value max = 0;
 | 
| deba@948 |   1176 |         for (OutArcIt e(_graph, n); e != INVALID; ++e) {
 | 
| deba@948 |   1177 |           if (_graph.target(e) == n && !_allow_loops) continue;
 | 
| deba@948 |   1178 |           if ((dualScale * _weight[e]) / 2 > max) {
 | 
| deba@948 |   1179 |             max = (dualScale * _weight[e]) / 2;
 | 
| deba@948 |   1180 |           }
 | 
| deba@948 |   1181 |         }
 | 
| deba@948 |   1182 |         _node_potential->set(n, max);
 | 
| deba@948 |   1183 |         _delta1->push(n, max);
 | 
| deba@948 |   1184 | 
 | 
| deba@948 |   1185 |         _tree_set->insert(n);
 | 
| deba@948 |   1186 | 
 | 
| deba@948 |   1187 |         _matching->set(n, INVALID);
 | 
| deba@948 |   1188 |         _status->set(n, EVEN);
 | 
| deba@948 |   1189 |       }
 | 
| deba@948 |   1190 | 
 | 
| deba@948 |   1191 |       for (EdgeIt e(_graph); e != INVALID; ++e) {
 | 
| deba@948 |   1192 |         Node left = _graph.u(e);
 | 
| deba@948 |   1193 |         Node right = _graph.v(e);
 | 
| deba@948 |   1194 |         if (left == right && !_allow_loops) continue;
 | 
| deba@948 |   1195 |         _delta3->push(e, ((*_node_potential)[left] +
 | 
| deba@948 |   1196 |                           (*_node_potential)[right] -
 | 
| deba@948 |   1197 |                           dualScale * _weight[e]) / 2);
 | 
| deba@948 |   1198 |       }
 | 
| deba@948 |   1199 |     }
 | 
| deba@948 |   1200 | 
 | 
| deba@948 |   1201 |     /// \brief Start the algorithm
 | 
| deba@948 |   1202 |     ///
 | 
| deba@948 |   1203 |     /// This function starts the algorithm.
 | 
| deba@948 |   1204 |     ///
 | 
| deba@948 |   1205 |     /// \pre \ref init() must be called before using this function.
 | 
| deba@948 |   1206 |     void start() {
 | 
| deba@948 |   1207 |       enum OpType {
 | 
| deba@948 |   1208 |         D1, D2, D3
 | 
| deba@948 |   1209 |       };
 | 
| deba@948 |   1210 | 
 | 
| deba@948 |   1211 |       int unmatched = _node_num;
 | 
| deba@948 |   1212 |       while (unmatched > 0) {
 | 
| deba@948 |   1213 |         Value d1 = !_delta1->empty() ?
 | 
| deba@948 |   1214 |           _delta1->prio() : std::numeric_limits<Value>::max();
 | 
| deba@948 |   1215 | 
 | 
| deba@948 |   1216 |         Value d2 = !_delta2->empty() ?
 | 
| deba@948 |   1217 |           _delta2->prio() : std::numeric_limits<Value>::max();
 | 
| deba@948 |   1218 | 
 | 
| deba@948 |   1219 |         Value d3 = !_delta3->empty() ?
 | 
| deba@948 |   1220 |           _delta3->prio() : std::numeric_limits<Value>::max();
 | 
| deba@948 |   1221 | 
 | 
| deba@948 |   1222 |         _delta_sum = d3; OpType ot = D3;
 | 
| deba@948 |   1223 |         if (d1 < _delta_sum) { _delta_sum = d1; ot = D1; }
 | 
| deba@948 |   1224 |         if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
 | 
| deba@948 |   1225 | 
 | 
| deba@948 |   1226 |         switch (ot) {
 | 
| deba@948 |   1227 |         case D1:
 | 
| deba@948 |   1228 |           {
 | 
| deba@948 |   1229 |             Node n = _delta1->top();
 | 
| deba@948 |   1230 |             unmatchNode(n);
 | 
| deba@948 |   1231 |             --unmatched;
 | 
| deba@948 |   1232 |           }
 | 
| deba@948 |   1233 |           break;
 | 
| deba@948 |   1234 |         case D2:
 | 
| deba@948 |   1235 |           {
 | 
| deba@948 |   1236 |             Node n = _delta2->top();
 | 
| deba@948 |   1237 |             Arc a = (*_pred)[n];
 | 
| deba@948 |   1238 |             if ((*_matching)[n] == INVALID) {
 | 
| deba@948 |   1239 |               augmentOnArc(a);
 | 
| deba@948 |   1240 |               --unmatched;
 | 
| deba@948 |   1241 |             } else {
 | 
| deba@948 |   1242 |               Node v = _graph.target((*_matching)[n]);
 | 
| deba@948 |   1243 |               if ((*_matching)[n] !=
 | 
| deba@948 |   1244 |                   _graph.oppositeArc((*_matching)[v])) {
 | 
| deba@948 |   1245 |                 extractCycle(a);
 | 
| deba@948 |   1246 |                 --unmatched;
 | 
| deba@948 |   1247 |               } else {
 | 
| deba@948 |   1248 |                 extendOnArc(a);
 | 
| deba@948 |   1249 |               }
 | 
| deba@948 |   1250 |             }
 | 
| deba@948 |   1251 |           } break;
 | 
| deba@948 |   1252 |         case D3:
 | 
| deba@948 |   1253 |           {
 | 
| deba@948 |   1254 |             Edge e = _delta3->top();
 | 
| deba@948 |   1255 | 
 | 
| deba@948 |   1256 |             Node left = _graph.u(e);
 | 
| deba@948 |   1257 |             Node right = _graph.v(e);
 | 
| deba@948 |   1258 | 
 | 
| deba@948 |   1259 |             int left_tree = _tree_set->find(left);
 | 
| deba@948 |   1260 |             int right_tree = _tree_set->find(right);
 | 
| deba@948 |   1261 | 
 | 
| deba@948 |   1262 |             if (left_tree == right_tree) {
 | 
| deba@948 |   1263 |               cycleOnEdge(e, left_tree);
 | 
| deba@948 |   1264 |               --unmatched;
 | 
| deba@948 |   1265 |             } else {
 | 
| deba@948 |   1266 |               augmentOnEdge(e);
 | 
| deba@948 |   1267 |               unmatched -= 2;
 | 
| deba@948 |   1268 |             }
 | 
| deba@948 |   1269 |           } break;
 | 
| deba@948 |   1270 |         }
 | 
| deba@948 |   1271 |       }
 | 
| deba@948 |   1272 |     }
 | 
| deba@948 |   1273 | 
 | 
| deba@948 |   1274 |     /// \brief Run the algorithm.
 | 
| deba@948 |   1275 |     ///
 | 
| deba@950 |   1276 |     /// This method runs the \c %MaxWeightedFractionalMatching algorithm.
 | 
| deba@948 |   1277 |     ///
 | 
| deba@948 |   1278 |     /// \note mwfm.run() is just a shortcut of the following code.
 | 
| deba@948 |   1279 |     /// \code
 | 
| deba@948 |   1280 |     ///   mwfm.init();
 | 
| deba@948 |   1281 |     ///   mwfm.start();
 | 
| deba@948 |   1282 |     /// \endcode
 | 
| deba@948 |   1283 |     void run() {
 | 
| deba@948 |   1284 |       init();
 | 
| deba@948 |   1285 |       start();
 | 
| deba@948 |   1286 |     }
 | 
| deba@948 |   1287 | 
 | 
| deba@948 |   1288 |     /// @}
 | 
| deba@948 |   1289 | 
 | 
| deba@948 |   1290 |     /// \name Primal Solution
 | 
| deba@948 |   1291 |     /// Functions to get the primal solution, i.e. the maximum weighted
 | 
| deba@948 |   1292 |     /// matching.\n
 | 
| deba@948 |   1293 |     /// Either \ref run() or \ref start() function should be called before
 | 
| deba@948 |   1294 |     /// using them.
 | 
| deba@948 |   1295 | 
 | 
| deba@948 |   1296 |     /// @{
 | 
| deba@948 |   1297 | 
 | 
| deba@948 |   1298 |     /// \brief Return the weight of the matching.
 | 
| deba@948 |   1299 |     ///
 | 
| deba@948 |   1300 |     /// This function returns the weight of the found matching. This
 | 
| deba@948 |   1301 |     /// value is scaled by \ref primalScale "primal scale".
 | 
| deba@948 |   1302 |     ///
 | 
| deba@948 |   1303 |     /// \pre Either run() or start() must be called before using this function.
 | 
| deba@948 |   1304 |     Value matchingWeight() const {
 | 
| deba@948 |   1305 |       Value sum = 0;
 | 
| deba@948 |   1306 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |   1307 |         if ((*_matching)[n] != INVALID) {
 | 
| deba@948 |   1308 |           sum += _weight[(*_matching)[n]];
 | 
| deba@948 |   1309 |         }
 | 
| deba@948 |   1310 |       }
 | 
| deba@948 |   1311 |       return sum * primalScale / 2;
 | 
| deba@948 |   1312 |     }
 | 
| deba@948 |   1313 | 
 | 
| deba@948 |   1314 |     /// \brief Return the number of covered nodes in the matching.
 | 
| deba@948 |   1315 |     ///
 | 
| deba@948 |   1316 |     /// This function returns the number of covered nodes in the matching.
 | 
| deba@948 |   1317 |     ///
 | 
| deba@948 |   1318 |     /// \pre Either run() or start() must be called before using this function.
 | 
| deba@948 |   1319 |     int matchingSize() const {
 | 
| deba@948 |   1320 |       int num = 0;
 | 
| deba@948 |   1321 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |   1322 |         if ((*_matching)[n] != INVALID) {
 | 
| deba@948 |   1323 |           ++num;
 | 
| deba@948 |   1324 |         }
 | 
| deba@948 |   1325 |       }
 | 
| deba@948 |   1326 |       return num;
 | 
| deba@948 |   1327 |     }
 | 
| deba@948 |   1328 | 
 | 
| deba@948 |   1329 |     /// \brief Return \c true if the given edge is in the matching.
 | 
| deba@948 |   1330 |     ///
 | 
| deba@948 |   1331 |     /// This function returns \c true if the given edge is in the
 | 
| deba@948 |   1332 |     /// found matching. The result is scaled by \ref primalScale
 | 
| deba@948 |   1333 |     /// "primal scale".
 | 
| deba@948 |   1334 |     ///
 | 
| deba@948 |   1335 |     /// \pre Either run() or start() must be called before using this function.
 | 
| deba@951 |   1336 |     int matching(const Edge& edge) const {
 | 
| deba@951 |   1337 |       return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
 | 
| deba@951 |   1338 |         + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
 | 
| deba@948 |   1339 |     }
 | 
| deba@948 |   1340 | 
 | 
| deba@948 |   1341 |     /// \brief Return the fractional matching arc (or edge) incident
 | 
| deba@948 |   1342 |     /// to the given node.
 | 
| deba@948 |   1343 |     ///
 | 
| deba@948 |   1344 |     /// This function returns one of the fractional matching arc (or
 | 
| deba@948 |   1345 |     /// edge) incident to the given node in the found matching or \c
 | 
| deba@948 |   1346 |     /// INVALID if the node is not covered by the matching or if the
 | 
| deba@948 |   1347 |     /// node is on an odd length cycle then it is the successor edge
 | 
| deba@948 |   1348 |     /// on the cycle.
 | 
| deba@948 |   1349 |     ///
 | 
| deba@948 |   1350 |     /// \pre Either run() or start() must be called before using this function.
 | 
| deba@948 |   1351 |     Arc matching(const Node& node) const {
 | 
| deba@948 |   1352 |       return (*_matching)[node];
 | 
| deba@948 |   1353 |     }
 | 
| deba@948 |   1354 | 
 | 
| deba@948 |   1355 |     /// \brief Return a const reference to the matching map.
 | 
| deba@948 |   1356 |     ///
 | 
| deba@948 |   1357 |     /// This function returns a const reference to a node map that stores
 | 
| deba@948 |   1358 |     /// the matching arc (or edge) incident to each node.
 | 
| deba@948 |   1359 |     const MatchingMap& matchingMap() const {
 | 
| deba@948 |   1360 |       return *_matching;
 | 
| deba@948 |   1361 |     }
 | 
| deba@948 |   1362 | 
 | 
| deba@948 |   1363 |     /// @}
 | 
| deba@948 |   1364 | 
 | 
| deba@948 |   1365 |     /// \name Dual Solution
 | 
| deba@948 |   1366 |     /// Functions to get the dual solution.\n
 | 
| deba@948 |   1367 |     /// Either \ref run() or \ref start() function should be called before
 | 
| deba@948 |   1368 |     /// using them.
 | 
| deba@948 |   1369 | 
 | 
| deba@948 |   1370 |     /// @{
 | 
| deba@948 |   1371 | 
 | 
| deba@948 |   1372 |     /// \brief Return the value of the dual solution.
 | 
| deba@948 |   1373 |     ///
 | 
| deba@948 |   1374 |     /// This function returns the value of the dual solution.
 | 
| deba@948 |   1375 |     /// It should be equal to the primal value scaled by \ref dualScale
 | 
| deba@948 |   1376 |     /// "dual scale".
 | 
| deba@948 |   1377 |     ///
 | 
| deba@948 |   1378 |     /// \pre Either run() or start() must be called before using this function.
 | 
| deba@948 |   1379 |     Value dualValue() const {
 | 
| deba@948 |   1380 |       Value sum = 0;
 | 
| deba@948 |   1381 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |   1382 |         sum += nodeValue(n);
 | 
| deba@948 |   1383 |       }
 | 
| deba@948 |   1384 |       return sum;
 | 
| deba@948 |   1385 |     }
 | 
| deba@948 |   1386 | 
 | 
| deba@948 |   1387 |     /// \brief Return the dual value (potential) of the given node.
 | 
| deba@948 |   1388 |     ///
 | 
| deba@948 |   1389 |     /// This function returns the dual value (potential) of the given node.
 | 
| deba@948 |   1390 |     ///
 | 
| deba@948 |   1391 |     /// \pre Either run() or start() must be called before using this function.
 | 
| deba@948 |   1392 |     Value nodeValue(const Node& n) const {
 | 
| deba@948 |   1393 |       return (*_node_potential)[n];
 | 
| deba@948 |   1394 |     }
 | 
| deba@948 |   1395 | 
 | 
| deba@948 |   1396 |     /// @}
 | 
| deba@948 |   1397 | 
 | 
| deba@948 |   1398 |   };
 | 
| deba@948 |   1399 | 
 | 
| deba@948 |   1400 |   /// \ingroup matching
 | 
| deba@948 |   1401 |   ///
 | 
| deba@948 |   1402 |   /// \brief Weighted fractional perfect matching in general graphs
 | 
| deba@948 |   1403 |   ///
 | 
| deba@948 |   1404 |   /// This class provides an efficient implementation of fractional
 | 
| deba@950 |   1405 |   /// matching algorithm. The implementation uses priority queues and
 | 
| deba@950 |   1406 |   /// provides \f$O(nm\log n)\f$ time complexity.
 | 
| deba@948 |   1407 |   ///
 | 
| deba@948 |   1408 |   /// The maximum weighted fractional perfect matching is a relaxation
 | 
| deba@948 |   1409 |   /// of the maximum weighted perfect matching problem where the odd
 | 
| deba@948 |   1410 |   /// set constraints are omitted.
 | 
| deba@948 |   1411 |   /// It can be formulated with the following linear program.
 | 
| deba@948 |   1412 |   /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
 | 
| deba@948 |   1413 |   /// \f[x_e \ge 0\quad \forall e\in E\f]
 | 
| deba@948 |   1414 |   /// \f[\max \sum_{e\in E}x_ew_e\f]
 | 
| deba@948 |   1415 |   /// where \f$\delta(X)\f$ is the set of edges incident to a node in
 | 
| deba@948 |   1416 |   /// \f$X\f$. The result must be the union of a matching with one
 | 
| deba@948 |   1417 |   /// value edges and a set of odd length cycles with half value edges.
 | 
| deba@948 |   1418 |   ///
 | 
| deba@948 |   1419 |   /// The algorithm calculates an optimal fractional matching and a
 | 
| deba@948 |   1420 |   /// proof of the optimality. The solution of the dual problem can be
 | 
| deba@948 |   1421 |   /// used to check the result of the algorithm. The dual linear
 | 
| deba@948 |   1422 |   /// problem is the following.
 | 
| deba@948 |   1423 |   /// \f[ y_u + y_v \ge w_{uv} \quad \forall uv\in E\f]
 | 
| deba@950 |   1424 |   /// \f[\min \sum_{u \in V}y_u \f]
 | 
| deba@948 |   1425 |   ///
 | 
| deba@948 |   1426 |   /// The algorithm can be executed with the run() function.
 | 
| deba@948 |   1427 |   /// After it the matching (the primal solution) and the dual solution
 | 
| deba@948 |   1428 |   /// can be obtained using the query functions.
 | 
| deba@951 |   1429 |   ///
 | 
| deba@951 |   1430 |   /// The primal solution is multiplied by
 | 
| deba@951 |   1431 |   /// \ref MaxWeightedPerfectFractionalMatching::primalScale "2".
 | 
| deba@951 |   1432 |   /// If the value type is integer, then the dual
 | 
| deba@951 |   1433 |   /// solution is scaled by
 | 
| deba@951 |   1434 |   /// \ref MaxWeightedPerfectFractionalMatching::dualScale "4".
 | 
| deba@948 |   1435 |   ///
 | 
| deba@948 |   1436 |   /// \tparam GR The undirected graph type the algorithm runs on.
 | 
| deba@948 |   1437 |   /// \tparam WM The type edge weight map. The default type is
 | 
| deba@948 |   1438 |   /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
 | 
| deba@948 |   1439 | #ifdef DOXYGEN
 | 
| deba@948 |   1440 |   template <typename GR, typename WM>
 | 
| deba@948 |   1441 | #else
 | 
| deba@948 |   1442 |   template <typename GR,
 | 
| deba@948 |   1443 |             typename WM = typename GR::template EdgeMap<int> >
 | 
| deba@948 |   1444 | #endif
 | 
| deba@948 |   1445 |   class MaxWeightedPerfectFractionalMatching {
 | 
| deba@948 |   1446 |   public:
 | 
| deba@948 |   1447 | 
 | 
| deba@948 |   1448 |     /// The graph type of the algorithm
 | 
| deba@948 |   1449 |     typedef GR Graph;
 | 
| deba@948 |   1450 |     /// The type of the edge weight map
 | 
| deba@948 |   1451 |     typedef WM WeightMap;
 | 
| deba@948 |   1452 |     /// The value type of the edge weights
 | 
| deba@948 |   1453 |     typedef typename WeightMap::Value Value;
 | 
| deba@948 |   1454 | 
 | 
| deba@948 |   1455 |     /// The type of the matching map
 | 
| deba@948 |   1456 |     typedef typename Graph::template NodeMap<typename Graph::Arc>
 | 
| deba@948 |   1457 |     MatchingMap;
 | 
| deba@948 |   1458 | 
 | 
| deba@948 |   1459 |     /// \brief Scaling factor for primal solution
 | 
| deba@948 |   1460 |     ///
 | 
| deba@951 |   1461 |     /// Scaling factor for primal solution.
 | 
| deba@951 |   1462 |     static const int primalScale = 2;
 | 
| deba@948 |   1463 | 
 | 
| deba@948 |   1464 |     /// \brief Scaling factor for dual solution
 | 
| deba@948 |   1465 |     ///
 | 
| deba@948 |   1466 |     /// Scaling factor for dual solution. It is equal to 4 or 1
 | 
| deba@948 |   1467 |     /// according to the value type.
 | 
| deba@948 |   1468 |     static const int dualScale =
 | 
| deba@948 |   1469 |       std::numeric_limits<Value>::is_integer ? 4 : 1;
 | 
| deba@948 |   1470 | 
 | 
| deba@948 |   1471 |   private:
 | 
| deba@948 |   1472 | 
 | 
| deba@948 |   1473 |     TEMPLATE_GRAPH_TYPEDEFS(Graph);
 | 
| deba@948 |   1474 | 
 | 
| deba@948 |   1475 |     typedef typename Graph::template NodeMap<Value> NodePotential;
 | 
| deba@948 |   1476 | 
 | 
| deba@948 |   1477 |     const Graph& _graph;
 | 
| deba@948 |   1478 |     const WeightMap& _weight;
 | 
| deba@948 |   1479 | 
 | 
| deba@948 |   1480 |     MatchingMap* _matching;
 | 
| deba@948 |   1481 |     NodePotential* _node_potential;
 | 
| deba@948 |   1482 | 
 | 
| deba@948 |   1483 |     int _node_num;
 | 
| deba@948 |   1484 |     bool _allow_loops;
 | 
| deba@948 |   1485 | 
 | 
| deba@948 |   1486 |     enum Status {
 | 
| deba@948 |   1487 |       EVEN = -1, MATCHED = 0, ODD = 1
 | 
| deba@948 |   1488 |     };
 | 
| deba@948 |   1489 | 
 | 
| deba@948 |   1490 |     typedef typename Graph::template NodeMap<Status> StatusMap;
 | 
| deba@948 |   1491 |     StatusMap* _status;
 | 
| deba@948 |   1492 | 
 | 
| deba@948 |   1493 |     typedef typename Graph::template NodeMap<Arc> PredMap;
 | 
| deba@948 |   1494 |     PredMap* _pred;
 | 
| deba@948 |   1495 | 
 | 
| deba@948 |   1496 |     typedef ExtendFindEnum<IntNodeMap> TreeSet;
 | 
| deba@948 |   1497 | 
 | 
| deba@948 |   1498 |     IntNodeMap *_tree_set_index;
 | 
| deba@948 |   1499 |     TreeSet *_tree_set;
 | 
| deba@948 |   1500 | 
 | 
| deba@948 |   1501 |     IntNodeMap *_delta2_index;
 | 
| deba@948 |   1502 |     BinHeap<Value, IntNodeMap> *_delta2;
 | 
| deba@948 |   1503 | 
 | 
| deba@948 |   1504 |     IntEdgeMap *_delta3_index;
 | 
| deba@948 |   1505 |     BinHeap<Value, IntEdgeMap> *_delta3;
 | 
| deba@948 |   1506 | 
 | 
| deba@948 |   1507 |     Value _delta_sum;
 | 
| deba@948 |   1508 | 
 | 
| deba@948 |   1509 |     void createStructures() {
 | 
| deba@948 |   1510 |       _node_num = countNodes(_graph);
 | 
| deba@948 |   1511 | 
 | 
| deba@948 |   1512 |       if (!_matching) {
 | 
| deba@948 |   1513 |         _matching = new MatchingMap(_graph);
 | 
| deba@948 |   1514 |       }
 | 
| deba@948 |   1515 |       if (!_node_potential) {
 | 
| deba@948 |   1516 |         _node_potential = new NodePotential(_graph);
 | 
| deba@948 |   1517 |       }
 | 
| deba@948 |   1518 |       if (!_status) {
 | 
| deba@948 |   1519 |         _status = new StatusMap(_graph);
 | 
| deba@948 |   1520 |       }
 | 
| deba@948 |   1521 |       if (!_pred) {
 | 
| deba@948 |   1522 |         _pred = new PredMap(_graph);
 | 
| deba@948 |   1523 |       }
 | 
| deba@948 |   1524 |       if (!_tree_set) {
 | 
| deba@948 |   1525 |         _tree_set_index = new IntNodeMap(_graph);
 | 
| deba@948 |   1526 |         _tree_set = new TreeSet(*_tree_set_index);
 | 
| deba@948 |   1527 |       }
 | 
| deba@948 |   1528 |       if (!_delta2) {
 | 
| deba@948 |   1529 |         _delta2_index = new IntNodeMap(_graph);
 | 
| deba@948 |   1530 |         _delta2 = new BinHeap<Value, IntNodeMap>(*_delta2_index);
 | 
| deba@948 |   1531 |       }
 | 
| deba@948 |   1532 |       if (!_delta3) {
 | 
| deba@948 |   1533 |         _delta3_index = new IntEdgeMap(_graph);
 | 
| deba@948 |   1534 |         _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
 | 
| deba@948 |   1535 |       }
 | 
| deba@948 |   1536 |     }
 | 
| deba@948 |   1537 | 
 | 
| deba@948 |   1538 |     void destroyStructures() {
 | 
| deba@948 |   1539 |       if (_matching) {
 | 
| deba@948 |   1540 |         delete _matching;
 | 
| deba@948 |   1541 |       }
 | 
| deba@948 |   1542 |       if (_node_potential) {
 | 
| deba@948 |   1543 |         delete _node_potential;
 | 
| deba@948 |   1544 |       }
 | 
| deba@948 |   1545 |       if (_status) {
 | 
| deba@948 |   1546 |         delete _status;
 | 
| deba@948 |   1547 |       }
 | 
| deba@948 |   1548 |       if (_pred) {
 | 
| deba@948 |   1549 |         delete _pred;
 | 
| deba@948 |   1550 |       }
 | 
| deba@948 |   1551 |       if (_tree_set) {
 | 
| deba@948 |   1552 |         delete _tree_set_index;
 | 
| deba@948 |   1553 |         delete _tree_set;
 | 
| deba@948 |   1554 |       }
 | 
| deba@948 |   1555 |       if (_delta2) {
 | 
| deba@948 |   1556 |         delete _delta2_index;
 | 
| deba@948 |   1557 |         delete _delta2;
 | 
| deba@948 |   1558 |       }
 | 
| deba@948 |   1559 |       if (_delta3) {
 | 
| deba@948 |   1560 |         delete _delta3_index;
 | 
| deba@948 |   1561 |         delete _delta3;
 | 
| deba@948 |   1562 |       }
 | 
| deba@948 |   1563 |     }
 | 
| deba@948 |   1564 | 
 | 
| deba@948 |   1565 |     void matchedToEven(Node node, int tree) {
 | 
| deba@948 |   1566 |       _tree_set->insert(node, tree);
 | 
| deba@948 |   1567 |       _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
 | 
| deba@948 |   1568 | 
 | 
| deba@948 |   1569 |       if (_delta2->state(node) == _delta2->IN_HEAP) {
 | 
| deba@948 |   1570 |         _delta2->erase(node);
 | 
| deba@948 |   1571 |       }
 | 
| deba@948 |   1572 | 
 | 
| deba@948 |   1573 |       for (InArcIt a(_graph, node); a != INVALID; ++a) {
 | 
| deba@948 |   1574 |         Node v = _graph.source(a);
 | 
| deba@948 |   1575 |         Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
 | 
| deba@948 |   1576 |           dualScale * _weight[a];
 | 
| deba@948 |   1577 |         if (node == v) {
 | 
| deba@948 |   1578 |           if (_allow_loops && _graph.direction(a)) {
 | 
| deba@948 |   1579 |             _delta3->push(a, rw / 2);
 | 
| deba@948 |   1580 |           }
 | 
| deba@948 |   1581 |         } else if ((*_status)[v] == EVEN) {
 | 
| deba@948 |   1582 |           _delta3->push(a, rw / 2);
 | 
| deba@948 |   1583 |         } else if ((*_status)[v] == MATCHED) {
 | 
| deba@948 |   1584 |           if (_delta2->state(v) != _delta2->IN_HEAP) {
 | 
| deba@948 |   1585 |             _pred->set(v, a);
 | 
| deba@948 |   1586 |             _delta2->push(v, rw);
 | 
| deba@948 |   1587 |           } else if ((*_delta2)[v] > rw) {
 | 
| deba@948 |   1588 |             _pred->set(v, a);
 | 
| deba@948 |   1589 |             _delta2->decrease(v, rw);
 | 
| deba@948 |   1590 |           }
 | 
| deba@948 |   1591 |         }
 | 
| deba@948 |   1592 |       }
 | 
| deba@948 |   1593 |     }
 | 
| deba@948 |   1594 | 
 | 
| deba@948 |   1595 |     void matchedToOdd(Node node, int tree) {
 | 
| deba@948 |   1596 |       _tree_set->insert(node, tree);
 | 
| deba@948 |   1597 |       _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
 | 
| deba@948 |   1598 | 
 | 
| deba@948 |   1599 |       if (_delta2->state(node) == _delta2->IN_HEAP) {
 | 
| deba@948 |   1600 |         _delta2->erase(node);
 | 
| deba@948 |   1601 |       }
 | 
| deba@948 |   1602 |     }
 | 
| deba@948 |   1603 | 
 | 
| deba@948 |   1604 |     void evenToMatched(Node node, int tree) {
 | 
| deba@948 |   1605 |       _node_potential->set(node, (*_node_potential)[node] - _delta_sum);
 | 
| deba@948 |   1606 |       Arc min = INVALID;
 | 
| deba@948 |   1607 |       Value minrw = std::numeric_limits<Value>::max();
 | 
| deba@948 |   1608 |       for (InArcIt a(_graph, node); a != INVALID; ++a) {
 | 
| deba@948 |   1609 |         Node v = _graph.source(a);
 | 
| deba@948 |   1610 |         Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
 | 
| deba@948 |   1611 |           dualScale * _weight[a];
 | 
| deba@948 |   1612 | 
 | 
| deba@948 |   1613 |         if (node == v) {
 | 
| deba@948 |   1614 |           if (_allow_loops && _graph.direction(a)) {
 | 
| deba@948 |   1615 |             _delta3->erase(a);
 | 
| deba@948 |   1616 |           }
 | 
| deba@948 |   1617 |         } else if ((*_status)[v] == EVEN) {
 | 
| deba@948 |   1618 |           _delta3->erase(a);
 | 
| deba@948 |   1619 |           if (minrw > rw) {
 | 
| deba@948 |   1620 |             min = _graph.oppositeArc(a);
 | 
| deba@948 |   1621 |             minrw = rw;
 | 
| deba@948 |   1622 |           }
 | 
| deba@948 |   1623 |         } else if ((*_status)[v]  == MATCHED) {
 | 
| deba@948 |   1624 |           if ((*_pred)[v] == a) {
 | 
| deba@948 |   1625 |             Arc mina = INVALID;
 | 
| deba@948 |   1626 |             Value minrwa = std::numeric_limits<Value>::max();
 | 
| deba@948 |   1627 |             for (OutArcIt aa(_graph, v); aa != INVALID; ++aa) {
 | 
| deba@948 |   1628 |               Node va = _graph.target(aa);
 | 
| deba@948 |   1629 |               if ((*_status)[va] != EVEN ||
 | 
| deba@948 |   1630 |                   _tree_set->find(va) == tree) continue;
 | 
| deba@948 |   1631 |               Value rwa = (*_node_potential)[v] + (*_node_potential)[va] -
 | 
| deba@948 |   1632 |                 dualScale * _weight[aa];
 | 
| deba@948 |   1633 |               if (minrwa > rwa) {
 | 
| deba@948 |   1634 |                 minrwa = rwa;
 | 
| deba@948 |   1635 |                 mina = aa;
 | 
| deba@948 |   1636 |               }
 | 
| deba@948 |   1637 |             }
 | 
| deba@948 |   1638 |             if (mina != INVALID) {
 | 
| deba@948 |   1639 |               _pred->set(v, mina);
 | 
| deba@948 |   1640 |               _delta2->increase(v, minrwa);
 | 
| deba@948 |   1641 |             } else {
 | 
| deba@948 |   1642 |               _pred->set(v, INVALID);
 | 
| deba@948 |   1643 |               _delta2->erase(v);
 | 
| deba@948 |   1644 |             }
 | 
| deba@948 |   1645 |           }
 | 
| deba@948 |   1646 |         }
 | 
| deba@948 |   1647 |       }
 | 
| deba@948 |   1648 |       if (min != INVALID) {
 | 
| deba@948 |   1649 |         _pred->set(node, min);
 | 
| deba@948 |   1650 |         _delta2->push(node, minrw);
 | 
| deba@948 |   1651 |       } else {
 | 
| deba@948 |   1652 |         _pred->set(node, INVALID);
 | 
| deba@948 |   1653 |       }
 | 
| deba@948 |   1654 |     }
 | 
| deba@948 |   1655 | 
 | 
| deba@948 |   1656 |     void oddToMatched(Node node) {
 | 
| deba@948 |   1657 |       _node_potential->set(node, (*_node_potential)[node] + _delta_sum);
 | 
| deba@948 |   1658 |       Arc min = INVALID;
 | 
| deba@948 |   1659 |       Value minrw = std::numeric_limits<Value>::max();
 | 
| deba@948 |   1660 |       for (InArcIt a(_graph, node); a != INVALID; ++a) {
 | 
| deba@948 |   1661 |         Node v = _graph.source(a);
 | 
| deba@948 |   1662 |         if ((*_status)[v] != EVEN) continue;
 | 
| deba@948 |   1663 |         Value rw = (*_node_potential)[node] + (*_node_potential)[v] -
 | 
| deba@948 |   1664 |           dualScale * _weight[a];
 | 
| deba@948 |   1665 | 
 | 
| deba@948 |   1666 |         if (minrw > rw) {
 | 
| deba@948 |   1667 |           min = _graph.oppositeArc(a);
 | 
| deba@948 |   1668 |           minrw = rw;
 | 
| deba@948 |   1669 |         }
 | 
| deba@948 |   1670 |       }
 | 
| deba@948 |   1671 |       if (min != INVALID) {
 | 
| deba@948 |   1672 |         _pred->set(node, min);
 | 
| deba@948 |   1673 |         _delta2->push(node, minrw);
 | 
| deba@948 |   1674 |       } else {
 | 
| deba@948 |   1675 |         _pred->set(node, INVALID);
 | 
| deba@948 |   1676 |       }
 | 
| deba@948 |   1677 |     }
 | 
| deba@948 |   1678 | 
 | 
| deba@948 |   1679 |     void alternatePath(Node even, int tree) {
 | 
| deba@948 |   1680 |       Node odd;
 | 
| deba@948 |   1681 | 
 | 
| deba@948 |   1682 |       _status->set(even, MATCHED);
 | 
| deba@948 |   1683 |       evenToMatched(even, tree);
 | 
| deba@948 |   1684 | 
 | 
| deba@948 |   1685 |       Arc prev = (*_matching)[even];
 | 
| deba@948 |   1686 |       while (prev != INVALID) {
 | 
| deba@948 |   1687 |         odd = _graph.target(prev);
 | 
| deba@948 |   1688 |         even = _graph.target((*_pred)[odd]);
 | 
| deba@948 |   1689 |         _matching->set(odd, (*_pred)[odd]);
 | 
| deba@948 |   1690 |         _status->set(odd, MATCHED);
 | 
| deba@948 |   1691 |         oddToMatched(odd);
 | 
| deba@948 |   1692 | 
 | 
| deba@948 |   1693 |         prev = (*_matching)[even];
 | 
| deba@948 |   1694 |         _status->set(even, MATCHED);
 | 
| deba@948 |   1695 |         _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
 | 
| deba@948 |   1696 |         evenToMatched(even, tree);
 | 
| deba@948 |   1697 |       }
 | 
| deba@948 |   1698 |     }
 | 
| deba@948 |   1699 | 
 | 
| deba@948 |   1700 |     void destroyTree(int tree) {
 | 
| deba@948 |   1701 |       for (typename TreeSet::ItemIt n(*_tree_set, tree); n != INVALID; ++n) {
 | 
| deba@948 |   1702 |         if ((*_status)[n] == EVEN) {
 | 
| deba@948 |   1703 |           _status->set(n, MATCHED);
 | 
| deba@948 |   1704 |           evenToMatched(n, tree);
 | 
| deba@948 |   1705 |         } else if ((*_status)[n] == ODD) {
 | 
| deba@948 |   1706 |           _status->set(n, MATCHED);
 | 
| deba@948 |   1707 |           oddToMatched(n);
 | 
| deba@948 |   1708 |         }
 | 
| deba@948 |   1709 |       }
 | 
| deba@948 |   1710 |       _tree_set->eraseClass(tree);
 | 
| deba@948 |   1711 |     }
 | 
| deba@948 |   1712 | 
 | 
| deba@948 |   1713 |     void augmentOnEdge(const Edge& edge) {
 | 
| deba@948 |   1714 |       Node left = _graph.u(edge);
 | 
| deba@948 |   1715 |       int left_tree = _tree_set->find(left);
 | 
| deba@948 |   1716 | 
 | 
| deba@948 |   1717 |       alternatePath(left, left_tree);
 | 
| deba@948 |   1718 |       destroyTree(left_tree);
 | 
| deba@948 |   1719 |       _matching->set(left, _graph.direct(edge, true));
 | 
| deba@948 |   1720 | 
 | 
| deba@948 |   1721 |       Node right = _graph.v(edge);
 | 
| deba@948 |   1722 |       int right_tree = _tree_set->find(right);
 | 
| deba@948 |   1723 | 
 | 
| deba@948 |   1724 |       alternatePath(right, right_tree);
 | 
| deba@948 |   1725 |       destroyTree(right_tree);
 | 
| deba@948 |   1726 |       _matching->set(right, _graph.direct(edge, false));
 | 
| deba@948 |   1727 |     }
 | 
| deba@948 |   1728 | 
 | 
| deba@948 |   1729 |     void augmentOnArc(const Arc& arc) {
 | 
| deba@948 |   1730 |       Node left = _graph.source(arc);
 | 
| deba@948 |   1731 |       _status->set(left, MATCHED);
 | 
| deba@948 |   1732 |       _matching->set(left, arc);
 | 
| deba@948 |   1733 |       _pred->set(left, arc);
 | 
| deba@948 |   1734 | 
 | 
| deba@948 |   1735 |       Node right = _graph.target(arc);
 | 
| deba@948 |   1736 |       int right_tree = _tree_set->find(right);
 | 
| deba@948 |   1737 | 
 | 
| deba@948 |   1738 |       alternatePath(right, right_tree);
 | 
| deba@948 |   1739 |       destroyTree(right_tree);
 | 
| deba@948 |   1740 |       _matching->set(right, _graph.oppositeArc(arc));
 | 
| deba@948 |   1741 |     }
 | 
| deba@948 |   1742 | 
 | 
| deba@948 |   1743 |     void extendOnArc(const Arc& arc) {
 | 
| deba@948 |   1744 |       Node base = _graph.target(arc);
 | 
| deba@948 |   1745 |       int tree = _tree_set->find(base);
 | 
| deba@948 |   1746 | 
 | 
| deba@948 |   1747 |       Node odd = _graph.source(arc);
 | 
| deba@948 |   1748 |       _tree_set->insert(odd, tree);
 | 
| deba@948 |   1749 |       _status->set(odd, ODD);
 | 
| deba@948 |   1750 |       matchedToOdd(odd, tree);
 | 
| deba@948 |   1751 |       _pred->set(odd, arc);
 | 
| deba@948 |   1752 | 
 | 
| deba@948 |   1753 |       Node even = _graph.target((*_matching)[odd]);
 | 
| deba@948 |   1754 |       _tree_set->insert(even, tree);
 | 
| deba@948 |   1755 |       _status->set(even, EVEN);
 | 
| deba@948 |   1756 |       matchedToEven(even, tree);
 | 
| deba@948 |   1757 |     }
 | 
| deba@948 |   1758 | 
 | 
| deba@948 |   1759 |     void cycleOnEdge(const Edge& edge, int tree) {
 | 
| deba@948 |   1760 |       Node nca = INVALID;
 | 
| deba@948 |   1761 |       std::vector<Node> left_path, right_path;
 | 
| deba@948 |   1762 | 
 | 
| deba@948 |   1763 |       {
 | 
| deba@948 |   1764 |         std::set<Node> left_set, right_set;
 | 
| deba@948 |   1765 |         Node left = _graph.u(edge);
 | 
| deba@948 |   1766 |         left_path.push_back(left);
 | 
| deba@948 |   1767 |         left_set.insert(left);
 | 
| deba@948 |   1768 | 
 | 
| deba@948 |   1769 |         Node right = _graph.v(edge);
 | 
| deba@948 |   1770 |         right_path.push_back(right);
 | 
| deba@948 |   1771 |         right_set.insert(right);
 | 
| deba@948 |   1772 | 
 | 
| deba@948 |   1773 |         while (true) {
 | 
| deba@948 |   1774 | 
 | 
| deba@948 |   1775 |           if (left_set.find(right) != left_set.end()) {
 | 
| deba@948 |   1776 |             nca = right;
 | 
| deba@948 |   1777 |             break;
 | 
| deba@948 |   1778 |           }
 | 
| deba@948 |   1779 | 
 | 
| deba@948 |   1780 |           if ((*_matching)[left] == INVALID) break;
 | 
| deba@948 |   1781 | 
 | 
| deba@948 |   1782 |           left = _graph.target((*_matching)[left]);
 | 
| deba@948 |   1783 |           left_path.push_back(left);
 | 
| deba@948 |   1784 |           left = _graph.target((*_pred)[left]);
 | 
| deba@948 |   1785 |           left_path.push_back(left);
 | 
| deba@948 |   1786 | 
 | 
| deba@948 |   1787 |           left_set.insert(left);
 | 
| deba@948 |   1788 | 
 | 
| deba@948 |   1789 |           if (right_set.find(left) != right_set.end()) {
 | 
| deba@948 |   1790 |             nca = left;
 | 
| deba@948 |   1791 |             break;
 | 
| deba@948 |   1792 |           }
 | 
| deba@948 |   1793 | 
 | 
| deba@948 |   1794 |           if ((*_matching)[right] == INVALID) break;
 | 
| deba@948 |   1795 | 
 | 
| deba@948 |   1796 |           right = _graph.target((*_matching)[right]);
 | 
| deba@948 |   1797 |           right_path.push_back(right);
 | 
| deba@948 |   1798 |           right = _graph.target((*_pred)[right]);
 | 
| deba@948 |   1799 |           right_path.push_back(right);
 | 
| deba@948 |   1800 | 
 | 
| deba@948 |   1801 |           right_set.insert(right);
 | 
| deba@948 |   1802 | 
 | 
| deba@948 |   1803 |         }
 | 
| deba@948 |   1804 | 
 | 
| deba@948 |   1805 |         if (nca == INVALID) {
 | 
| deba@948 |   1806 |           if ((*_matching)[left] == INVALID) {
 | 
| deba@948 |   1807 |             nca = right;
 | 
| deba@948 |   1808 |             while (left_set.find(nca) == left_set.end()) {
 | 
| deba@948 |   1809 |               nca = _graph.target((*_matching)[nca]);
 | 
| deba@948 |   1810 |               right_path.push_back(nca);
 | 
| deba@948 |   1811 |               nca = _graph.target((*_pred)[nca]);
 | 
| deba@948 |   1812 |               right_path.push_back(nca);
 | 
| deba@948 |   1813 |             }
 | 
| deba@948 |   1814 |           } else {
 | 
| deba@948 |   1815 |             nca = left;
 | 
| deba@948 |   1816 |             while (right_set.find(nca) == right_set.end()) {
 | 
| deba@948 |   1817 |               nca = _graph.target((*_matching)[nca]);
 | 
| deba@948 |   1818 |               left_path.push_back(nca);
 | 
| deba@948 |   1819 |               nca = _graph.target((*_pred)[nca]);
 | 
| deba@948 |   1820 |               left_path.push_back(nca);
 | 
| deba@948 |   1821 |             }
 | 
| deba@948 |   1822 |           }
 | 
| deba@948 |   1823 |         }
 | 
| deba@948 |   1824 |       }
 | 
| deba@948 |   1825 | 
 | 
| deba@948 |   1826 |       alternatePath(nca, tree);
 | 
| deba@948 |   1827 |       Arc prev;
 | 
| deba@948 |   1828 | 
 | 
| deba@948 |   1829 |       prev = _graph.direct(edge, true);
 | 
| deba@948 |   1830 |       for (int i = 0; left_path[i] != nca; i += 2) {
 | 
| deba@948 |   1831 |         _matching->set(left_path[i], prev);
 | 
| deba@948 |   1832 |         _status->set(left_path[i], MATCHED);
 | 
| deba@948 |   1833 |         evenToMatched(left_path[i], tree);
 | 
| deba@948 |   1834 | 
 | 
| deba@948 |   1835 |         prev = _graph.oppositeArc((*_pred)[left_path[i + 1]]);
 | 
| deba@948 |   1836 |         _status->set(left_path[i + 1], MATCHED);
 | 
| deba@948 |   1837 |         oddToMatched(left_path[i + 1]);
 | 
| deba@948 |   1838 |       }
 | 
| deba@948 |   1839 |       _matching->set(nca, prev);
 | 
| deba@948 |   1840 | 
 | 
| deba@948 |   1841 |       for (int i = 0; right_path[i] != nca; i += 2) {
 | 
| deba@948 |   1842 |         _status->set(right_path[i], MATCHED);
 | 
| deba@948 |   1843 |         evenToMatched(right_path[i], tree);
 | 
| deba@948 |   1844 | 
 | 
| deba@948 |   1845 |         _matching->set(right_path[i + 1], (*_pred)[right_path[i + 1]]);
 | 
| deba@948 |   1846 |         _status->set(right_path[i + 1], MATCHED);
 | 
| deba@948 |   1847 |         oddToMatched(right_path[i + 1]);
 | 
| deba@948 |   1848 |       }
 | 
| deba@948 |   1849 | 
 | 
| deba@948 |   1850 |       destroyTree(tree);
 | 
| deba@948 |   1851 |     }
 | 
| deba@948 |   1852 | 
 | 
| deba@948 |   1853 |     void extractCycle(const Arc &arc) {
 | 
| deba@948 |   1854 |       Node left = _graph.source(arc);
 | 
| deba@948 |   1855 |       Node odd = _graph.target((*_matching)[left]);
 | 
| deba@948 |   1856 |       Arc prev;
 | 
| deba@948 |   1857 |       while (odd != left) {
 | 
| deba@948 |   1858 |         Node even = _graph.target((*_matching)[odd]);
 | 
| deba@948 |   1859 |         prev = (*_matching)[odd];
 | 
| deba@948 |   1860 |         odd = _graph.target((*_matching)[even]);
 | 
| deba@948 |   1861 |         _matching->set(even, _graph.oppositeArc(prev));
 | 
| deba@948 |   1862 |       }
 | 
| deba@948 |   1863 |       _matching->set(left, arc);
 | 
| deba@948 |   1864 | 
 | 
| deba@948 |   1865 |       Node right = _graph.target(arc);
 | 
| deba@948 |   1866 |       int right_tree = _tree_set->find(right);
 | 
| deba@948 |   1867 |       alternatePath(right, right_tree);
 | 
| deba@948 |   1868 |       destroyTree(right_tree);
 | 
| deba@948 |   1869 |       _matching->set(right, _graph.oppositeArc(arc));
 | 
| deba@948 |   1870 |     }
 | 
| deba@948 |   1871 | 
 | 
| deba@948 |   1872 |   public:
 | 
| deba@948 |   1873 | 
 | 
| deba@948 |   1874 |     /// \brief Constructor
 | 
| deba@948 |   1875 |     ///
 | 
| deba@948 |   1876 |     /// Constructor.
 | 
| deba@948 |   1877 |     MaxWeightedPerfectFractionalMatching(const Graph& graph,
 | 
| deba@948 |   1878 |                                          const WeightMap& weight,
 | 
| deba@948 |   1879 |                                          bool allow_loops = true)
 | 
| deba@948 |   1880 |       : _graph(graph), _weight(weight), _matching(0),
 | 
| deba@948 |   1881 |       _node_potential(0), _node_num(0), _allow_loops(allow_loops),
 | 
| deba@948 |   1882 |       _status(0),  _pred(0),
 | 
| deba@948 |   1883 |       _tree_set_index(0), _tree_set(0),
 | 
| deba@948 |   1884 | 
 | 
| deba@948 |   1885 |       _delta2_index(0), _delta2(0),
 | 
| deba@948 |   1886 |       _delta3_index(0), _delta3(0),
 | 
| deba@948 |   1887 | 
 | 
| deba@948 |   1888 |       _delta_sum() {}
 | 
| deba@948 |   1889 | 
 | 
| deba@948 |   1890 |     ~MaxWeightedPerfectFractionalMatching() {
 | 
| deba@948 |   1891 |       destroyStructures();
 | 
| deba@948 |   1892 |     }
 | 
| deba@948 |   1893 | 
 | 
| deba@948 |   1894 |     /// \name Execution Control
 | 
| deba@948 |   1895 |     /// The simplest way to execute the algorithm is to use the
 | 
| deba@948 |   1896 |     /// \ref run() member function.
 | 
| deba@948 |   1897 | 
 | 
| deba@948 |   1898 |     ///@{
 | 
| deba@948 |   1899 | 
 | 
| deba@948 |   1900 |     /// \brief Initialize the algorithm
 | 
| deba@948 |   1901 |     ///
 | 
| deba@948 |   1902 |     /// This function initializes the algorithm.
 | 
| deba@948 |   1903 |     void init() {
 | 
| deba@948 |   1904 |       createStructures();
 | 
| deba@948 |   1905 | 
 | 
| deba@948 |   1906 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |   1907 |         (*_delta2_index)[n] = _delta2->PRE_HEAP;
 | 
| deba@948 |   1908 |       }
 | 
| deba@948 |   1909 |       for (EdgeIt e(_graph); e != INVALID; ++e) {
 | 
| deba@948 |   1910 |         (*_delta3_index)[e] = _delta3->PRE_HEAP;
 | 
| deba@948 |   1911 |       }
 | 
| deba@948 |   1912 | 
 | 
| deba@955 |   1913 |       _delta2->clear();
 | 
| deba@955 |   1914 |       _delta3->clear();
 | 
| deba@955 |   1915 |       _tree_set->clear();
 | 
| deba@955 |   1916 | 
 | 
| deba@948 |   1917 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |   1918 |         Value max = - std::numeric_limits<Value>::max();
 | 
| deba@948 |   1919 |         for (OutArcIt e(_graph, n); e != INVALID; ++e) {
 | 
| deba@948 |   1920 |           if (_graph.target(e) == n && !_allow_loops) continue;
 | 
| deba@948 |   1921 |           if ((dualScale * _weight[e]) / 2 > max) {
 | 
| deba@948 |   1922 |             max = (dualScale * _weight[e]) / 2;
 | 
| deba@948 |   1923 |           }
 | 
| deba@948 |   1924 |         }
 | 
| deba@948 |   1925 |         _node_potential->set(n, max);
 | 
| deba@948 |   1926 | 
 | 
| deba@948 |   1927 |         _tree_set->insert(n);
 | 
| deba@948 |   1928 | 
 | 
| deba@948 |   1929 |         _matching->set(n, INVALID);
 | 
| deba@948 |   1930 |         _status->set(n, EVEN);
 | 
| deba@948 |   1931 |       }
 | 
| deba@948 |   1932 | 
 | 
| deba@948 |   1933 |       for (EdgeIt e(_graph); e != INVALID; ++e) {
 | 
| deba@948 |   1934 |         Node left = _graph.u(e);
 | 
| deba@948 |   1935 |         Node right = _graph.v(e);
 | 
| deba@948 |   1936 |         if (left == right && !_allow_loops) continue;
 | 
| deba@948 |   1937 |         _delta3->push(e, ((*_node_potential)[left] +
 | 
| deba@948 |   1938 |                           (*_node_potential)[right] -
 | 
| deba@948 |   1939 |                           dualScale * _weight[e]) / 2);
 | 
| deba@948 |   1940 |       }
 | 
| deba@948 |   1941 |     }
 | 
| deba@948 |   1942 | 
 | 
| deba@948 |   1943 |     /// \brief Start the algorithm
 | 
| deba@948 |   1944 |     ///
 | 
| deba@948 |   1945 |     /// This function starts the algorithm.
 | 
| deba@948 |   1946 |     ///
 | 
| deba@948 |   1947 |     /// \pre \ref init() must be called before using this function.
 | 
| deba@948 |   1948 |     bool start() {
 | 
| deba@948 |   1949 |       enum OpType {
 | 
| deba@948 |   1950 |         D2, D3
 | 
| deba@948 |   1951 |       };
 | 
| deba@948 |   1952 | 
 | 
| deba@948 |   1953 |       int unmatched = _node_num;
 | 
| deba@948 |   1954 |       while (unmatched > 0) {
 | 
| deba@948 |   1955 |         Value d2 = !_delta2->empty() ?
 | 
| deba@948 |   1956 |           _delta2->prio() : std::numeric_limits<Value>::max();
 | 
| deba@948 |   1957 | 
 | 
| deba@948 |   1958 |         Value d3 = !_delta3->empty() ?
 | 
| deba@948 |   1959 |           _delta3->prio() : std::numeric_limits<Value>::max();
 | 
| deba@948 |   1960 | 
 | 
| deba@948 |   1961 |         _delta_sum = d3; OpType ot = D3;
 | 
| deba@948 |   1962 |         if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
 | 
| deba@948 |   1963 | 
 | 
| deba@948 |   1964 |         if (_delta_sum == std::numeric_limits<Value>::max()) {
 | 
| deba@948 |   1965 |           return false;
 | 
| deba@948 |   1966 |         }
 | 
| deba@948 |   1967 | 
 | 
| deba@948 |   1968 |         switch (ot) {
 | 
| deba@948 |   1969 |         case D2:
 | 
| deba@948 |   1970 |           {
 | 
| deba@948 |   1971 |             Node n = _delta2->top();
 | 
| deba@948 |   1972 |             Arc a = (*_pred)[n];
 | 
| deba@948 |   1973 |             if ((*_matching)[n] == INVALID) {
 | 
| deba@948 |   1974 |               augmentOnArc(a);
 | 
| deba@948 |   1975 |               --unmatched;
 | 
| deba@948 |   1976 |             } else {
 | 
| deba@948 |   1977 |               Node v = _graph.target((*_matching)[n]);
 | 
| deba@948 |   1978 |               if ((*_matching)[n] !=
 | 
| deba@948 |   1979 |                   _graph.oppositeArc((*_matching)[v])) {
 | 
| deba@948 |   1980 |                 extractCycle(a);
 | 
| deba@948 |   1981 |                 --unmatched;
 | 
| deba@948 |   1982 |               } else {
 | 
| deba@948 |   1983 |                 extendOnArc(a);
 | 
| deba@948 |   1984 |               }
 | 
| deba@948 |   1985 |             }
 | 
| deba@948 |   1986 |           } break;
 | 
| deba@948 |   1987 |         case D3:
 | 
| deba@948 |   1988 |           {
 | 
| deba@948 |   1989 |             Edge e = _delta3->top();
 | 
| deba@948 |   1990 | 
 | 
| deba@948 |   1991 |             Node left = _graph.u(e);
 | 
| deba@948 |   1992 |             Node right = _graph.v(e);
 | 
| deba@948 |   1993 | 
 | 
| deba@948 |   1994 |             int left_tree = _tree_set->find(left);
 | 
| deba@948 |   1995 |             int right_tree = _tree_set->find(right);
 | 
| deba@948 |   1996 | 
 | 
| deba@948 |   1997 |             if (left_tree == right_tree) {
 | 
| deba@948 |   1998 |               cycleOnEdge(e, left_tree);
 | 
| deba@948 |   1999 |               --unmatched;
 | 
| deba@948 |   2000 |             } else {
 | 
| deba@948 |   2001 |               augmentOnEdge(e);
 | 
| deba@948 |   2002 |               unmatched -= 2;
 | 
| deba@948 |   2003 |             }
 | 
| deba@948 |   2004 |           } break;
 | 
| deba@948 |   2005 |         }
 | 
| deba@948 |   2006 |       }
 | 
| deba@948 |   2007 |       return true;
 | 
| deba@948 |   2008 |     }
 | 
| deba@948 |   2009 | 
 | 
| deba@948 |   2010 |     /// \brief Run the algorithm.
 | 
| deba@948 |   2011 |     ///
 | 
| alpar@956 |   2012 |     /// This method runs the \c %MaxWeightedPerfectFractionalMatching
 | 
| deba@950 |   2013 |     /// algorithm.
 | 
| deba@948 |   2014 |     ///
 | 
| deba@948 |   2015 |     /// \note mwfm.run() is just a shortcut of the following code.
 | 
| deba@948 |   2016 |     /// \code
 | 
| deba@948 |   2017 |     ///   mwpfm.init();
 | 
| deba@948 |   2018 |     ///   mwpfm.start();
 | 
| deba@948 |   2019 |     /// \endcode
 | 
| deba@948 |   2020 |     bool run() {
 | 
| deba@948 |   2021 |       init();
 | 
| deba@948 |   2022 |       return start();
 | 
| deba@948 |   2023 |     }
 | 
| deba@948 |   2024 | 
 | 
| deba@948 |   2025 |     /// @}
 | 
| deba@948 |   2026 | 
 | 
| deba@948 |   2027 |     /// \name Primal Solution
 | 
| deba@948 |   2028 |     /// Functions to get the primal solution, i.e. the maximum weighted
 | 
| deba@948 |   2029 |     /// matching.\n
 | 
| deba@948 |   2030 |     /// Either \ref run() or \ref start() function should be called before
 | 
| deba@948 |   2031 |     /// using them.
 | 
| deba@948 |   2032 | 
 | 
| deba@948 |   2033 |     /// @{
 | 
| deba@948 |   2034 | 
 | 
| deba@948 |   2035 |     /// \brief Return the weight of the matching.
 | 
| deba@948 |   2036 |     ///
 | 
| deba@948 |   2037 |     /// This function returns the weight of the found matching. This
 | 
| deba@948 |   2038 |     /// value is scaled by \ref primalScale "primal scale".
 | 
| deba@948 |   2039 |     ///
 | 
| deba@948 |   2040 |     /// \pre Either run() or start() must be called before using this function.
 | 
| deba@948 |   2041 |     Value matchingWeight() const {
 | 
| deba@948 |   2042 |       Value sum = 0;
 | 
| deba@948 |   2043 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |   2044 |         if ((*_matching)[n] != INVALID) {
 | 
| deba@948 |   2045 |           sum += _weight[(*_matching)[n]];
 | 
| deba@948 |   2046 |         }
 | 
| deba@948 |   2047 |       }
 | 
| deba@948 |   2048 |       return sum * primalScale / 2;
 | 
| deba@948 |   2049 |     }
 | 
| deba@948 |   2050 | 
 | 
| deba@948 |   2051 |     /// \brief Return the number of covered nodes in the matching.
 | 
| deba@948 |   2052 |     ///
 | 
| deba@948 |   2053 |     /// This function returns the number of covered nodes in the matching.
 | 
| deba@948 |   2054 |     ///
 | 
| deba@948 |   2055 |     /// \pre Either run() or start() must be called before using this function.
 | 
| deba@948 |   2056 |     int matchingSize() const {
 | 
| deba@948 |   2057 |       int num = 0;
 | 
| deba@948 |   2058 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |   2059 |         if ((*_matching)[n] != INVALID) {
 | 
| deba@948 |   2060 |           ++num;
 | 
| deba@948 |   2061 |         }
 | 
| deba@948 |   2062 |       }
 | 
| deba@948 |   2063 |       return num;
 | 
| deba@948 |   2064 |     }
 | 
| deba@948 |   2065 | 
 | 
| deba@948 |   2066 |     /// \brief Return \c true if the given edge is in the matching.
 | 
| deba@948 |   2067 |     ///
 | 
| deba@948 |   2068 |     /// This function returns \c true if the given edge is in the
 | 
| deba@948 |   2069 |     /// found matching. The result is scaled by \ref primalScale
 | 
| deba@948 |   2070 |     /// "primal scale".
 | 
| deba@948 |   2071 |     ///
 | 
| deba@948 |   2072 |     /// \pre Either run() or start() must be called before using this function.
 | 
| deba@951 |   2073 |     int matching(const Edge& edge) const {
 | 
| deba@951 |   2074 |       return (edge == (*_matching)[_graph.u(edge)] ? 1 : 0)
 | 
| deba@951 |   2075 |         + (edge == (*_matching)[_graph.v(edge)] ? 1 : 0);
 | 
| deba@948 |   2076 |     }
 | 
| deba@948 |   2077 | 
 | 
| deba@948 |   2078 |     /// \brief Return the fractional matching arc (or edge) incident
 | 
| deba@948 |   2079 |     /// to the given node.
 | 
| deba@948 |   2080 |     ///
 | 
| deba@948 |   2081 |     /// This function returns one of the fractional matching arc (or
 | 
| deba@948 |   2082 |     /// edge) incident to the given node in the found matching or \c
 | 
| deba@948 |   2083 |     /// INVALID if the node is not covered by the matching or if the
 | 
| deba@948 |   2084 |     /// node is on an odd length cycle then it is the successor edge
 | 
| deba@948 |   2085 |     /// on the cycle.
 | 
| deba@948 |   2086 |     ///
 | 
| deba@948 |   2087 |     /// \pre Either run() or start() must be called before using this function.
 | 
| deba@948 |   2088 |     Arc matching(const Node& node) const {
 | 
| deba@948 |   2089 |       return (*_matching)[node];
 | 
| deba@948 |   2090 |     }
 | 
| deba@948 |   2091 | 
 | 
| deba@948 |   2092 |     /// \brief Return a const reference to the matching map.
 | 
| deba@948 |   2093 |     ///
 | 
| deba@948 |   2094 |     /// This function returns a const reference to a node map that stores
 | 
| deba@948 |   2095 |     /// the matching arc (or edge) incident to each node.
 | 
| deba@948 |   2096 |     const MatchingMap& matchingMap() const {
 | 
| deba@948 |   2097 |       return *_matching;
 | 
| deba@948 |   2098 |     }
 | 
| deba@948 |   2099 | 
 | 
| deba@948 |   2100 |     /// @}
 | 
| deba@948 |   2101 | 
 | 
| deba@948 |   2102 |     /// \name Dual Solution
 | 
| deba@948 |   2103 |     /// Functions to get the dual solution.\n
 | 
| deba@948 |   2104 |     /// Either \ref run() or \ref start() function should be called before
 | 
| deba@948 |   2105 |     /// using them.
 | 
| deba@948 |   2106 | 
 | 
| deba@948 |   2107 |     /// @{
 | 
| deba@948 |   2108 | 
 | 
| deba@948 |   2109 |     /// \brief Return the value of the dual solution.
 | 
| deba@948 |   2110 |     ///
 | 
| deba@948 |   2111 |     /// This function returns the value of the dual solution.
 | 
| deba@948 |   2112 |     /// It should be equal to the primal value scaled by \ref dualScale
 | 
| deba@948 |   2113 |     /// "dual scale".
 | 
| deba@948 |   2114 |     ///
 | 
| deba@948 |   2115 |     /// \pre Either run() or start() must be called before using this function.
 | 
| deba@948 |   2116 |     Value dualValue() const {
 | 
| deba@948 |   2117 |       Value sum = 0;
 | 
| deba@948 |   2118 |       for (NodeIt n(_graph); n != INVALID; ++n) {
 | 
| deba@948 |   2119 |         sum += nodeValue(n);
 | 
| deba@948 |   2120 |       }
 | 
| deba@948 |   2121 |       return sum;
 | 
| deba@948 |   2122 |     }
 | 
| deba@948 |   2123 | 
 | 
| deba@948 |   2124 |     /// \brief Return the dual value (potential) of the given node.
 | 
| deba@948 |   2125 |     ///
 | 
| deba@948 |   2126 |     /// This function returns the dual value (potential) of the given node.
 | 
| deba@948 |   2127 |     ///
 | 
| deba@948 |   2128 |     /// \pre Either run() or start() must be called before using this function.
 | 
| deba@948 |   2129 |     Value nodeValue(const Node& n) const {
 | 
| deba@948 |   2130 |       return (*_node_potential)[n];
 | 
| deba@948 |   2131 |     }
 | 
| deba@948 |   2132 | 
 | 
| deba@948 |   2133 |     /// @}
 | 
| deba@948 |   2134 | 
 | 
| deba@948 |   2135 |   };
 | 
| deba@948 |   2136 | 
 | 
| deba@948 |   2137 | } //END OF NAMESPACE LEMON
 | 
| deba@948 |   2138 | 
 | 
| deba@948 |   2139 | #endif //LEMON_FRACTIONAL_MATCHING_H
 |