lemon/max_matching.h
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 24 Mar 2009 00:18:25 +0100
changeset 596 8c3112a66878
parent 425 cace3206223b
child 550 c5fd2d996909
permissions -rw-r--r--
Use XTI implementation instead of ATI in NetworkSimplex (#234)

XTI (eXtended Threaded Index) is an imporved version of the widely
known ATI (Augmented Threaded Index) method for storing and updating
the spanning tree structure in Network Simplex algorithms.

In the ATI data structure three indices are stored for each node:
predecessor, thread and depth. In the XTI data structure depth is
replaced by the number of successors and the last successor
(according to the thread index).
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library.
     4  *
     5  * Copyright (C) 2003-2009
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 #ifndef LEMON_MAX_MATCHING_H
    20 #define LEMON_MAX_MATCHING_H
    21 
    22 #include <vector>
    23 #include <queue>
    24 #include <set>
    25 #include <limits>
    26 
    27 #include <lemon/core.h>
    28 #include <lemon/unionfind.h>
    29 #include <lemon/bin_heap.h>
    30 #include <lemon/maps.h>
    31 
    32 ///\ingroup matching
    33 ///\file
    34 ///\brief Maximum matching algorithms in general graphs.
    35 
    36 namespace lemon {
    37 
    38   /// \ingroup matching
    39   ///
    40   /// \brief Edmonds' alternating forest maximum matching algorithm.
    41   ///
    42   /// This class implements Edmonds' alternating forest matching
    43   /// algorithm. The algorithm can be started from an arbitrary initial
    44   /// matching (the default is the empty one)
    45   ///
    46   /// The dual solution of the problem is a map of the nodes to
    47   /// MaxMatching::Status, having values \c EVEN/D, \c ODD/A and \c
    48   /// MATCHED/C showing the Gallai-Edmonds decomposition of the
    49   /// graph. The nodes in \c EVEN/D induce a graph with
    50   /// factor-critical components, the nodes in \c ODD/A form the
    51   /// barrier, and the nodes in \c MATCHED/C induce a graph having a
    52   /// perfect matching. The number of the factor-critical components
    53   /// minus the number of barrier nodes is a lower bound on the
    54   /// unmatched nodes, and the matching is optimal if and only if this bound is
    55   /// tight. This decomposition can be attained by calling \c
    56   /// decomposition() after running the algorithm.
    57   ///
    58   /// \param _Graph The graph type the algorithm runs on.
    59   template <typename _Graph>
    60   class MaxMatching {
    61   public:
    62 
    63     typedef _Graph Graph;
    64     typedef typename Graph::template NodeMap<typename Graph::Arc>
    65     MatchingMap;
    66 
    67     ///\brief Indicates the Gallai-Edmonds decomposition of the graph.
    68     ///
    69     ///Indicates the Gallai-Edmonds decomposition of the graph. The
    70     ///nodes with Status \c EVEN/D induce a graph with factor-critical
    71     ///components, the nodes in \c ODD/A form the canonical barrier,
    72     ///and the nodes in \c MATCHED/C induce a graph having a perfect
    73     ///matching.
    74     enum Status {
    75       EVEN = 1, D = 1, MATCHED = 0, C = 0, ODD = -1, A = -1, UNMATCHED = -2
    76     };
    77 
    78     typedef typename Graph::template NodeMap<Status> StatusMap;
    79 
    80   private:
    81 
    82     TEMPLATE_GRAPH_TYPEDEFS(Graph);
    83 
    84     typedef UnionFindEnum<IntNodeMap> BlossomSet;
    85     typedef ExtendFindEnum<IntNodeMap> TreeSet;
    86     typedef RangeMap<Node> NodeIntMap;
    87     typedef MatchingMap EarMap;
    88     typedef std::vector<Node> NodeQueue;
    89 
    90     const Graph& _graph;
    91     MatchingMap* _matching;
    92     StatusMap* _status;
    93 
    94     EarMap* _ear;
    95 
    96     IntNodeMap* _blossom_set_index;
    97     BlossomSet* _blossom_set;
    98     NodeIntMap* _blossom_rep;
    99 
   100     IntNodeMap* _tree_set_index;
   101     TreeSet* _tree_set;
   102 
   103     NodeQueue _node_queue;
   104     int _process, _postpone, _last;
   105 
   106     int _node_num;
   107 
   108   private:
   109 
   110     void createStructures() {
   111       _node_num = countNodes(_graph);
   112       if (!_matching) {
   113         _matching = new MatchingMap(_graph);
   114       }
   115       if (!_status) {
   116         _status = new StatusMap(_graph);
   117       }
   118       if (!_ear) {
   119         _ear = new EarMap(_graph);
   120       }
   121       if (!_blossom_set) {
   122         _blossom_set_index = new IntNodeMap(_graph);
   123         _blossom_set = new BlossomSet(*_blossom_set_index);
   124       }
   125       if (!_blossom_rep) {
   126         _blossom_rep = new NodeIntMap(_node_num);
   127       }
   128       if (!_tree_set) {
   129         _tree_set_index = new IntNodeMap(_graph);
   130         _tree_set = new TreeSet(*_tree_set_index);
   131       }
   132       _node_queue.resize(_node_num);
   133     }
   134 
   135     void destroyStructures() {
   136       if (_matching) {
   137         delete _matching;
   138       }
   139       if (_status) {
   140         delete _status;
   141       }
   142       if (_ear) {
   143         delete _ear;
   144       }
   145       if (_blossom_set) {
   146         delete _blossom_set;
   147         delete _blossom_set_index;
   148       }
   149       if (_blossom_rep) {
   150         delete _blossom_rep;
   151       }
   152       if (_tree_set) {
   153         delete _tree_set_index;
   154         delete _tree_set;
   155       }
   156     }
   157 
   158     void processDense(const Node& n) {
   159       _process = _postpone = _last = 0;
   160       _node_queue[_last++] = n;
   161 
   162       while (_process != _last) {
   163         Node u = _node_queue[_process++];
   164         for (OutArcIt a(_graph, u); a != INVALID; ++a) {
   165           Node v = _graph.target(a);
   166           if ((*_status)[v] == MATCHED) {
   167             extendOnArc(a);
   168           } else if ((*_status)[v] == UNMATCHED) {
   169             augmentOnArc(a);
   170             return;
   171           }
   172         }
   173       }
   174 
   175       while (_postpone != _last) {
   176         Node u = _node_queue[_postpone++];
   177 
   178         for (OutArcIt a(_graph, u); a != INVALID ; ++a) {
   179           Node v = _graph.target(a);
   180 
   181           if ((*_status)[v] == EVEN) {
   182             if (_blossom_set->find(u) != _blossom_set->find(v)) {
   183               shrinkOnEdge(a);
   184             }
   185           }
   186 
   187           while (_process != _last) {
   188             Node w = _node_queue[_process++];
   189             for (OutArcIt b(_graph, w); b != INVALID; ++b) {
   190               Node x = _graph.target(b);
   191               if ((*_status)[x] == MATCHED) {
   192                 extendOnArc(b);
   193               } else if ((*_status)[x] == UNMATCHED) {
   194                 augmentOnArc(b);
   195                 return;
   196               }
   197             }
   198           }
   199         }
   200       }
   201     }
   202 
   203     void processSparse(const Node& n) {
   204       _process = _last = 0;
   205       _node_queue[_last++] = n;
   206       while (_process != _last) {
   207         Node u = _node_queue[_process++];
   208         for (OutArcIt a(_graph, u); a != INVALID; ++a) {
   209           Node v = _graph.target(a);
   210 
   211           if ((*_status)[v] == EVEN) {
   212             if (_blossom_set->find(u) != _blossom_set->find(v)) {
   213               shrinkOnEdge(a);
   214             }
   215           } else if ((*_status)[v] == MATCHED) {
   216             extendOnArc(a);
   217           } else if ((*_status)[v] == UNMATCHED) {
   218             augmentOnArc(a);
   219             return;
   220           }
   221         }
   222       }
   223     }
   224 
   225     void shrinkOnEdge(const Edge& e) {
   226       Node nca = INVALID;
   227 
   228       {
   229         std::set<Node> left_set, right_set;
   230 
   231         Node left = (*_blossom_rep)[_blossom_set->find(_graph.u(e))];
   232         left_set.insert(left);
   233 
   234         Node right = (*_blossom_rep)[_blossom_set->find(_graph.v(e))];
   235         right_set.insert(right);
   236 
   237         while (true) {
   238           if ((*_matching)[left] == INVALID) break;
   239           left = _graph.target((*_matching)[left]);
   240           left = (*_blossom_rep)[_blossom_set->
   241                                  find(_graph.target((*_ear)[left]))];
   242           if (right_set.find(left) != right_set.end()) {
   243             nca = left;
   244             break;
   245           }
   246           left_set.insert(left);
   247 
   248           if ((*_matching)[right] == INVALID) break;
   249           right = _graph.target((*_matching)[right]);
   250           right = (*_blossom_rep)[_blossom_set->
   251                                   find(_graph.target((*_ear)[right]))];
   252           if (left_set.find(right) != left_set.end()) {
   253             nca = right;
   254             break;
   255           }
   256           right_set.insert(right);
   257         }
   258 
   259         if (nca == INVALID) {
   260           if ((*_matching)[left] == INVALID) {
   261             nca = right;
   262             while (left_set.find(nca) == left_set.end()) {
   263               nca = _graph.target((*_matching)[nca]);
   264               nca =(*_blossom_rep)[_blossom_set->
   265                                    find(_graph.target((*_ear)[nca]))];
   266             }
   267           } else {
   268             nca = left;
   269             while (right_set.find(nca) == right_set.end()) {
   270               nca = _graph.target((*_matching)[nca]);
   271               nca = (*_blossom_rep)[_blossom_set->
   272                                    find(_graph.target((*_ear)[nca]))];
   273             }
   274           }
   275         }
   276       }
   277 
   278       {
   279 
   280         Node node = _graph.u(e);
   281         Arc arc = _graph.direct(e, true);
   282         Node base = (*_blossom_rep)[_blossom_set->find(node)];
   283 
   284         while (base != nca) {
   285           _ear->set(node, arc);
   286 
   287           Node n = node;
   288           while (n != base) {
   289             n = _graph.target((*_matching)[n]);
   290             Arc a = (*_ear)[n];
   291             n = _graph.target(a);
   292             _ear->set(n, _graph.oppositeArc(a));
   293           }
   294           node = _graph.target((*_matching)[base]);
   295           _tree_set->erase(base);
   296           _tree_set->erase(node);
   297           _blossom_set->insert(node, _blossom_set->find(base));
   298           _status->set(node, EVEN);
   299           _node_queue[_last++] = node;
   300           arc = _graph.oppositeArc((*_ear)[node]);
   301           node = _graph.target((*_ear)[node]);
   302           base = (*_blossom_rep)[_blossom_set->find(node)];
   303           _blossom_set->join(_graph.target(arc), base);
   304         }
   305       }
   306 
   307       _blossom_rep->set(_blossom_set->find(nca), nca);
   308 
   309       {
   310 
   311         Node node = _graph.v(e);
   312         Arc arc = _graph.direct(e, false);
   313         Node base = (*_blossom_rep)[_blossom_set->find(node)];
   314 
   315         while (base != nca) {
   316           _ear->set(node, arc);
   317 
   318           Node n = node;
   319           while (n != base) {
   320             n = _graph.target((*_matching)[n]);
   321             Arc a = (*_ear)[n];
   322             n = _graph.target(a);
   323             _ear->set(n, _graph.oppositeArc(a));
   324           }
   325           node = _graph.target((*_matching)[base]);
   326           _tree_set->erase(base);
   327           _tree_set->erase(node);
   328           _blossom_set->insert(node, _blossom_set->find(base));
   329           _status->set(node, EVEN);
   330           _node_queue[_last++] = node;
   331           arc = _graph.oppositeArc((*_ear)[node]);
   332           node = _graph.target((*_ear)[node]);
   333           base = (*_blossom_rep)[_blossom_set->find(node)];
   334           _blossom_set->join(_graph.target(arc), base);
   335         }
   336       }
   337 
   338       _blossom_rep->set(_blossom_set->find(nca), nca);
   339     }
   340 
   341 
   342 
   343     void extendOnArc(const Arc& a) {
   344       Node base = _graph.source(a);
   345       Node odd = _graph.target(a);
   346 
   347       _ear->set(odd, _graph.oppositeArc(a));
   348       Node even = _graph.target((*_matching)[odd]);
   349       _blossom_rep->set(_blossom_set->insert(even), even);
   350       _status->set(odd, ODD);
   351       _status->set(even, EVEN);
   352       int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(base)]);
   353       _tree_set->insert(odd, tree);
   354       _tree_set->insert(even, tree);
   355       _node_queue[_last++] = even;
   356 
   357     }
   358 
   359     void augmentOnArc(const Arc& a) {
   360       Node even = _graph.source(a);
   361       Node odd = _graph.target(a);
   362 
   363       int tree = _tree_set->find((*_blossom_rep)[_blossom_set->find(even)]);
   364 
   365       _matching->set(odd, _graph.oppositeArc(a));
   366       _status->set(odd, MATCHED);
   367 
   368       Arc arc = (*_matching)[even];
   369       _matching->set(even, a);
   370 
   371       while (arc != INVALID) {
   372         odd = _graph.target(arc);
   373         arc = (*_ear)[odd];
   374         even = _graph.target(arc);
   375         _matching->set(odd, arc);
   376         arc = (*_matching)[even];
   377         _matching->set(even, _graph.oppositeArc((*_matching)[odd]));
   378       }
   379 
   380       for (typename TreeSet::ItemIt it(*_tree_set, tree);
   381            it != INVALID; ++it) {
   382         if ((*_status)[it] == ODD) {
   383           _status->set(it, MATCHED);
   384         } else {
   385           int blossom = _blossom_set->find(it);
   386           for (typename BlossomSet::ItemIt jt(*_blossom_set, blossom);
   387                jt != INVALID; ++jt) {
   388             _status->set(jt, MATCHED);
   389           }
   390           _blossom_set->eraseClass(blossom);
   391         }
   392       }
   393       _tree_set->eraseClass(tree);
   394 
   395     }
   396 
   397   public:
   398 
   399     /// \brief Constructor
   400     ///
   401     /// Constructor.
   402     MaxMatching(const Graph& graph)
   403       : _graph(graph), _matching(0), _status(0), _ear(0),
   404         _blossom_set_index(0), _blossom_set(0), _blossom_rep(0),
   405         _tree_set_index(0), _tree_set(0) {}
   406 
   407     ~MaxMatching() {
   408       destroyStructures();
   409     }
   410 
   411     /// \name Execution control
   412     /// The simplest way to execute the algorithm is to use the
   413     /// \c run() member function.
   414     /// \n
   415 
   416     /// If you need better control on the execution, you must call
   417     /// \ref init(), \ref greedyInit() or \ref matchingInit()
   418     /// functions first, then you can start the algorithm with the \ref
   419     /// startSparse() or startDense() functions.
   420 
   421     ///@{
   422 
   423     /// \brief Sets the actual matching to the empty matching.
   424     ///
   425     /// Sets the actual matching to the empty matching.
   426     ///
   427     void init() {
   428       createStructures();
   429       for(NodeIt n(_graph); n != INVALID; ++n) {
   430         _matching->set(n, INVALID);
   431         _status->set(n, UNMATCHED);
   432       }
   433     }
   434 
   435     ///\brief Finds an initial matching in a greedy way
   436     ///
   437     ///It finds an initial matching in a greedy way.
   438     void greedyInit() {
   439       createStructures();
   440       for (NodeIt n(_graph); n != INVALID; ++n) {
   441         _matching->set(n, INVALID);
   442         _status->set(n, UNMATCHED);
   443       }
   444       for (NodeIt n(_graph); n != INVALID; ++n) {
   445         if ((*_matching)[n] == INVALID) {
   446           for (OutArcIt a(_graph, n); a != INVALID ; ++a) {
   447             Node v = _graph.target(a);
   448             if ((*_matching)[v] == INVALID && v != n) {
   449               _matching->set(n, a);
   450               _status->set(n, MATCHED);
   451               _matching->set(v, _graph.oppositeArc(a));
   452               _status->set(v, MATCHED);
   453               break;
   454             }
   455           }
   456         }
   457       }
   458     }
   459 
   460 
   461     /// \brief Initialize the matching from a map containing.
   462     ///
   463     /// Initialize the matching from a \c bool valued \c Edge map. This
   464     /// map must have the property that there are no two incident edges
   465     /// with true value, ie. it contains a matching.
   466     /// \return %True if the map contains a matching.
   467     template <typename MatchingMap>
   468     bool matchingInit(const MatchingMap& matching) {
   469       createStructures();
   470 
   471       for (NodeIt n(_graph); n != INVALID; ++n) {
   472         _matching->set(n, INVALID);
   473         _status->set(n, UNMATCHED);
   474       }
   475       for(EdgeIt e(_graph); e!=INVALID; ++e) {
   476         if (matching[e]) {
   477 
   478           Node u = _graph.u(e);
   479           if ((*_matching)[u] != INVALID) return false;
   480           _matching->set(u, _graph.direct(e, true));
   481           _status->set(u, MATCHED);
   482 
   483           Node v = _graph.v(e);
   484           if ((*_matching)[v] != INVALID) return false;
   485           _matching->set(v, _graph.direct(e, false));
   486           _status->set(v, MATCHED);
   487         }
   488       }
   489       return true;
   490     }
   491 
   492     /// \brief Starts Edmonds' algorithm
   493     ///
   494     /// If runs the original Edmonds' algorithm.
   495     void startSparse() {
   496       for(NodeIt n(_graph); n != INVALID; ++n) {
   497         if ((*_status)[n] == UNMATCHED) {
   498           (*_blossom_rep)[_blossom_set->insert(n)] = n;
   499           _tree_set->insert(n);
   500           _status->set(n, EVEN);
   501           processSparse(n);
   502         }
   503       }
   504     }
   505 
   506     /// \brief Starts Edmonds' algorithm.
   507     ///
   508     /// It runs Edmonds' algorithm with a heuristic of postponing
   509     /// shrinks, therefore resulting in a faster algorithm for dense graphs.
   510     void startDense() {
   511       for(NodeIt n(_graph); n != INVALID; ++n) {
   512         if ((*_status)[n] == UNMATCHED) {
   513           (*_blossom_rep)[_blossom_set->insert(n)] = n;
   514           _tree_set->insert(n);
   515           _status->set(n, EVEN);
   516           processDense(n);
   517         }
   518       }
   519     }
   520 
   521 
   522     /// \brief Runs Edmonds' algorithm
   523     ///
   524     /// Runs Edmonds' algorithm for sparse graphs (<tt>m<2*n</tt>)
   525     /// or Edmonds' algorithm with a heuristic of
   526     /// postponing shrinks for dense graphs.
   527     void run() {
   528       if (countEdges(_graph) < 2 * countNodes(_graph)) {
   529         greedyInit();
   530         startSparse();
   531       } else {
   532         init();
   533         startDense();
   534       }
   535     }
   536 
   537     /// @}
   538 
   539     /// \name Primal solution
   540     /// Functions to get the primal solution, ie. the matching.
   541 
   542     /// @{
   543 
   544     ///\brief Returns the size of the current matching.
   545     ///
   546     ///Returns the size of the current matching. After \ref
   547     ///run() it returns the size of the maximum matching in the graph.
   548     int matchingSize() const {
   549       int size = 0;
   550       for (NodeIt n(_graph); n != INVALID; ++n) {
   551         if ((*_matching)[n] != INVALID) {
   552           ++size;
   553         }
   554       }
   555       return size / 2;
   556     }
   557 
   558     /// \brief Returns true when the edge is in the matching.
   559     ///
   560     /// Returns true when the edge is in the matching.
   561     bool matching(const Edge& edge) const {
   562       return edge == (*_matching)[_graph.u(edge)];
   563     }
   564 
   565     /// \brief Returns the matching edge incident to the given node.
   566     ///
   567     /// Returns the matching edge of a \c node in the actual matching or
   568     /// INVALID if the \c node is not covered by the actual matching.
   569     Arc matching(const Node& n) const {
   570       return (*_matching)[n];
   571     }
   572 
   573     ///\brief Returns the mate of a node in the actual matching.
   574     ///
   575     ///Returns the mate of a \c node in the actual matching or
   576     ///INVALID if the \c node is not covered by the actual matching.
   577     Node mate(const Node& n) const {
   578       return (*_matching)[n] != INVALID ?
   579         _graph.target((*_matching)[n]) : INVALID;
   580     }
   581 
   582     /// @}
   583 
   584     /// \name Dual solution
   585     /// Functions to get the dual solution, ie. the decomposition.
   586 
   587     /// @{
   588 
   589     /// \brief Returns the class of the node in the Edmonds-Gallai
   590     /// decomposition.
   591     ///
   592     /// Returns the class of the node in the Edmonds-Gallai
   593     /// decomposition.
   594     Status decomposition(const Node& n) const {
   595       return (*_status)[n];
   596     }
   597 
   598     /// \brief Returns true when the node is in the barrier.
   599     ///
   600     /// Returns true when the node is in the barrier.
   601     bool barrier(const Node& n) const {
   602       return (*_status)[n] == ODD;
   603     }
   604 
   605     /// @}
   606 
   607   };
   608 
   609   /// \ingroup matching
   610   ///
   611   /// \brief Weighted matching in general graphs
   612   ///
   613   /// This class provides an efficient implementation of Edmond's
   614   /// maximum weighted matching algorithm. The implementation is based
   615   /// on extensive use of priority queues and provides
   616   /// \f$O(nm\log(n))\f$ time complexity.
   617   ///
   618   /// The maximum weighted matching problem is to find undirected
   619   /// edges in the graph with maximum overall weight and no two of
   620   /// them shares their ends. The problem can be formulated with the
   621   /// following linear program.
   622   /// \f[ \sum_{e \in \delta(u)}x_e \le 1 \quad \forall u\in V\f]
   623   /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
   624       \quad \forall B\in\mathcal{O}\f] */
   625   /// \f[x_e \ge 0\quad \forall e\in E\f]
   626   /// \f[\max \sum_{e\in E}x_ew_e\f]
   627   /// where \f$\delta(X)\f$ is the set of edges incident to a node in
   628   /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
   629   /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
   630   /// subsets of the nodes.
   631   ///
   632   /// The algorithm calculates an optimal matching and a proof of the
   633   /// optimality. The solution of the dual problem can be used to check
   634   /// the result of the algorithm. The dual linear problem is the
   635   /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}
   636       z_B \ge w_{uv} \quad \forall uv\in E\f] */
   637   /// \f[y_u \ge 0 \quad \forall u \in V\f]
   638   /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
   639   /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
   640       \frac{\vert B \vert - 1}{2}z_B\f] */
   641   ///
   642   /// The algorithm can be executed with \c run() or the \c init() and
   643   /// then the \c start() member functions. After it the matching can
   644   /// be asked with \c matching() or mate() functions. The dual
   645   /// solution can be get with \c nodeValue(), \c blossomNum() and \c
   646   /// blossomValue() members and \ref MaxWeightedMatching::BlossomIt
   647   /// "BlossomIt" nested class, which is able to iterate on the nodes
   648   /// of a blossom. If the value type is integral then the dual
   649   /// solution is multiplied by \ref MaxWeightedMatching::dualScale "4".
   650   template <typename _Graph,
   651             typename _WeightMap = typename _Graph::template EdgeMap<int> >
   652   class MaxWeightedMatching {
   653   public:
   654 
   655     typedef _Graph Graph;
   656     typedef _WeightMap WeightMap;
   657     typedef typename WeightMap::Value Value;
   658 
   659     /// \brief Scaling factor for dual solution
   660     ///
   661     /// Scaling factor for dual solution, it is equal to 4 or 1
   662     /// according to the value type.
   663     static const int dualScale =
   664       std::numeric_limits<Value>::is_integer ? 4 : 1;
   665 
   666     typedef typename Graph::template NodeMap<typename Graph::Arc>
   667     MatchingMap;
   668 
   669   private:
   670 
   671     TEMPLATE_GRAPH_TYPEDEFS(Graph);
   672 
   673     typedef typename Graph::template NodeMap<Value> NodePotential;
   674     typedef std::vector<Node> BlossomNodeList;
   675 
   676     struct BlossomVariable {
   677       int begin, end;
   678       Value value;
   679 
   680       BlossomVariable(int _begin, int _end, Value _value)
   681         : begin(_begin), end(_end), value(_value) {}
   682 
   683     };
   684 
   685     typedef std::vector<BlossomVariable> BlossomPotential;
   686 
   687     const Graph& _graph;
   688     const WeightMap& _weight;
   689 
   690     MatchingMap* _matching;
   691 
   692     NodePotential* _node_potential;
   693 
   694     BlossomPotential _blossom_potential;
   695     BlossomNodeList _blossom_node_list;
   696 
   697     int _node_num;
   698     int _blossom_num;
   699 
   700     typedef RangeMap<int> IntIntMap;
   701 
   702     enum Status {
   703       EVEN = -1, MATCHED = 0, ODD = 1, UNMATCHED = -2
   704     };
   705 
   706     typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
   707     struct BlossomData {
   708       int tree;
   709       Status status;
   710       Arc pred, next;
   711       Value pot, offset;
   712       Node base;
   713     };
   714 
   715     IntNodeMap *_blossom_index;
   716     BlossomSet *_blossom_set;
   717     RangeMap<BlossomData>* _blossom_data;
   718 
   719     IntNodeMap *_node_index;
   720     IntArcMap *_node_heap_index;
   721 
   722     struct NodeData {
   723 
   724       NodeData(IntArcMap& node_heap_index)
   725         : heap(node_heap_index) {}
   726 
   727       int blossom;
   728       Value pot;
   729       BinHeap<Value, IntArcMap> heap;
   730       std::map<int, Arc> heap_index;
   731 
   732       int tree;
   733     };
   734 
   735     RangeMap<NodeData>* _node_data;
   736 
   737     typedef ExtendFindEnum<IntIntMap> TreeSet;
   738 
   739     IntIntMap *_tree_set_index;
   740     TreeSet *_tree_set;
   741 
   742     IntNodeMap *_delta1_index;
   743     BinHeap<Value, IntNodeMap> *_delta1;
   744 
   745     IntIntMap *_delta2_index;
   746     BinHeap<Value, IntIntMap> *_delta2;
   747 
   748     IntEdgeMap *_delta3_index;
   749     BinHeap<Value, IntEdgeMap> *_delta3;
   750 
   751     IntIntMap *_delta4_index;
   752     BinHeap<Value, IntIntMap> *_delta4;
   753 
   754     Value _delta_sum;
   755 
   756     void createStructures() {
   757       _node_num = countNodes(_graph);
   758       _blossom_num = _node_num * 3 / 2;
   759 
   760       if (!_matching) {
   761         _matching = new MatchingMap(_graph);
   762       }
   763       if (!_node_potential) {
   764         _node_potential = new NodePotential(_graph);
   765       }
   766       if (!_blossom_set) {
   767         _blossom_index = new IntNodeMap(_graph);
   768         _blossom_set = new BlossomSet(*_blossom_index);
   769         _blossom_data = new RangeMap<BlossomData>(_blossom_num);
   770       }
   771 
   772       if (!_node_index) {
   773         _node_index = new IntNodeMap(_graph);
   774         _node_heap_index = new IntArcMap(_graph);
   775         _node_data = new RangeMap<NodeData>(_node_num,
   776                                               NodeData(*_node_heap_index));
   777       }
   778 
   779       if (!_tree_set) {
   780         _tree_set_index = new IntIntMap(_blossom_num);
   781         _tree_set = new TreeSet(*_tree_set_index);
   782       }
   783       if (!_delta1) {
   784         _delta1_index = new IntNodeMap(_graph);
   785         _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
   786       }
   787       if (!_delta2) {
   788         _delta2_index = new IntIntMap(_blossom_num);
   789         _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
   790       }
   791       if (!_delta3) {
   792         _delta3_index = new IntEdgeMap(_graph);
   793         _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
   794       }
   795       if (!_delta4) {
   796         _delta4_index = new IntIntMap(_blossom_num);
   797         _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
   798       }
   799     }
   800 
   801     void destroyStructures() {
   802       _node_num = countNodes(_graph);
   803       _blossom_num = _node_num * 3 / 2;
   804 
   805       if (_matching) {
   806         delete _matching;
   807       }
   808       if (_node_potential) {
   809         delete _node_potential;
   810       }
   811       if (_blossom_set) {
   812         delete _blossom_index;
   813         delete _blossom_set;
   814         delete _blossom_data;
   815       }
   816 
   817       if (_node_index) {
   818         delete _node_index;
   819         delete _node_heap_index;
   820         delete _node_data;
   821       }
   822 
   823       if (_tree_set) {
   824         delete _tree_set_index;
   825         delete _tree_set;
   826       }
   827       if (_delta1) {
   828         delete _delta1_index;
   829         delete _delta1;
   830       }
   831       if (_delta2) {
   832         delete _delta2_index;
   833         delete _delta2;
   834       }
   835       if (_delta3) {
   836         delete _delta3_index;
   837         delete _delta3;
   838       }
   839       if (_delta4) {
   840         delete _delta4_index;
   841         delete _delta4;
   842       }
   843     }
   844 
   845     void matchedToEven(int blossom, int tree) {
   846       if (_delta2->state(blossom) == _delta2->IN_HEAP) {
   847         _delta2->erase(blossom);
   848       }
   849 
   850       if (!_blossom_set->trivial(blossom)) {
   851         (*_blossom_data)[blossom].pot -=
   852           2 * (_delta_sum - (*_blossom_data)[blossom].offset);
   853       }
   854 
   855       for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
   856            n != INVALID; ++n) {
   857 
   858         _blossom_set->increase(n, std::numeric_limits<Value>::max());
   859         int ni = (*_node_index)[n];
   860 
   861         (*_node_data)[ni].heap.clear();
   862         (*_node_data)[ni].heap_index.clear();
   863 
   864         (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
   865 
   866         _delta1->push(n, (*_node_data)[ni].pot);
   867 
   868         for (InArcIt e(_graph, n); e != INVALID; ++e) {
   869           Node v = _graph.source(e);
   870           int vb = _blossom_set->find(v);
   871           int vi = (*_node_index)[v];
   872 
   873           Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
   874             dualScale * _weight[e];
   875 
   876           if ((*_blossom_data)[vb].status == EVEN) {
   877             if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
   878               _delta3->push(e, rw / 2);
   879             }
   880           } else if ((*_blossom_data)[vb].status == UNMATCHED) {
   881             if (_delta3->state(e) != _delta3->IN_HEAP) {
   882               _delta3->push(e, rw);
   883             }
   884           } else {
   885             typename std::map<int, Arc>::iterator it =
   886               (*_node_data)[vi].heap_index.find(tree);
   887 
   888             if (it != (*_node_data)[vi].heap_index.end()) {
   889               if ((*_node_data)[vi].heap[it->second] > rw) {
   890                 (*_node_data)[vi].heap.replace(it->second, e);
   891                 (*_node_data)[vi].heap.decrease(e, rw);
   892                 it->second = e;
   893               }
   894             } else {
   895               (*_node_data)[vi].heap.push(e, rw);
   896               (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
   897             }
   898 
   899             if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
   900               _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
   901 
   902               if ((*_blossom_data)[vb].status == MATCHED) {
   903                 if (_delta2->state(vb) != _delta2->IN_HEAP) {
   904                   _delta2->push(vb, _blossom_set->classPrio(vb) -
   905                                (*_blossom_data)[vb].offset);
   906                 } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
   907                            (*_blossom_data)[vb].offset){
   908                   _delta2->decrease(vb, _blossom_set->classPrio(vb) -
   909                                    (*_blossom_data)[vb].offset);
   910                 }
   911               }
   912             }
   913           }
   914         }
   915       }
   916       (*_blossom_data)[blossom].offset = 0;
   917     }
   918 
   919     void matchedToOdd(int blossom) {
   920       if (_delta2->state(blossom) == _delta2->IN_HEAP) {
   921         _delta2->erase(blossom);
   922       }
   923       (*_blossom_data)[blossom].offset += _delta_sum;
   924       if (!_blossom_set->trivial(blossom)) {
   925         _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
   926                      (*_blossom_data)[blossom].offset);
   927       }
   928     }
   929 
   930     void evenToMatched(int blossom, int tree) {
   931       if (!_blossom_set->trivial(blossom)) {
   932         (*_blossom_data)[blossom].pot += 2 * _delta_sum;
   933       }
   934 
   935       for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
   936            n != INVALID; ++n) {
   937         int ni = (*_node_index)[n];
   938         (*_node_data)[ni].pot -= _delta_sum;
   939 
   940         _delta1->erase(n);
   941 
   942         for (InArcIt e(_graph, n); e != INVALID; ++e) {
   943           Node v = _graph.source(e);
   944           int vb = _blossom_set->find(v);
   945           int vi = (*_node_index)[v];
   946 
   947           Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
   948             dualScale * _weight[e];
   949 
   950           if (vb == blossom) {
   951             if (_delta3->state(e) == _delta3->IN_HEAP) {
   952               _delta3->erase(e);
   953             }
   954           } else if ((*_blossom_data)[vb].status == EVEN) {
   955 
   956             if (_delta3->state(e) == _delta3->IN_HEAP) {
   957               _delta3->erase(e);
   958             }
   959 
   960             int vt = _tree_set->find(vb);
   961 
   962             if (vt != tree) {
   963 
   964               Arc r = _graph.oppositeArc(e);
   965 
   966               typename std::map<int, Arc>::iterator it =
   967                 (*_node_data)[ni].heap_index.find(vt);
   968 
   969               if (it != (*_node_data)[ni].heap_index.end()) {
   970                 if ((*_node_data)[ni].heap[it->second] > rw) {
   971                   (*_node_data)[ni].heap.replace(it->second, r);
   972                   (*_node_data)[ni].heap.decrease(r, rw);
   973                   it->second = r;
   974                 }
   975               } else {
   976                 (*_node_data)[ni].heap.push(r, rw);
   977                 (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
   978               }
   979 
   980               if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
   981                 _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
   982 
   983                 if (_delta2->state(blossom) != _delta2->IN_HEAP) {
   984                   _delta2->push(blossom, _blossom_set->classPrio(blossom) -
   985                                (*_blossom_data)[blossom].offset);
   986                 } else if ((*_delta2)[blossom] >
   987                            _blossom_set->classPrio(blossom) -
   988                            (*_blossom_data)[blossom].offset){
   989                   _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
   990                                    (*_blossom_data)[blossom].offset);
   991                 }
   992               }
   993             }
   994 
   995           } else if ((*_blossom_data)[vb].status == UNMATCHED) {
   996             if (_delta3->state(e) == _delta3->IN_HEAP) {
   997               _delta3->erase(e);
   998             }
   999           } else {
  1000 
  1001             typename std::map<int, Arc>::iterator it =
  1002               (*_node_data)[vi].heap_index.find(tree);
  1003 
  1004             if (it != (*_node_data)[vi].heap_index.end()) {
  1005               (*_node_data)[vi].heap.erase(it->second);
  1006               (*_node_data)[vi].heap_index.erase(it);
  1007               if ((*_node_data)[vi].heap.empty()) {
  1008                 _blossom_set->increase(v, std::numeric_limits<Value>::max());
  1009               } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
  1010                 _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
  1011               }
  1012 
  1013               if ((*_blossom_data)[vb].status == MATCHED) {
  1014                 if (_blossom_set->classPrio(vb) ==
  1015                     std::numeric_limits<Value>::max()) {
  1016                   _delta2->erase(vb);
  1017                 } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
  1018                            (*_blossom_data)[vb].offset) {
  1019                   _delta2->increase(vb, _blossom_set->classPrio(vb) -
  1020                                    (*_blossom_data)[vb].offset);
  1021                 }
  1022               }
  1023             }
  1024           }
  1025         }
  1026       }
  1027     }
  1028 
  1029     void oddToMatched(int blossom) {
  1030       (*_blossom_data)[blossom].offset -= _delta_sum;
  1031 
  1032       if (_blossom_set->classPrio(blossom) !=
  1033           std::numeric_limits<Value>::max()) {
  1034         _delta2->push(blossom, _blossom_set->classPrio(blossom) -
  1035                        (*_blossom_data)[blossom].offset);
  1036       }
  1037 
  1038       if (!_blossom_set->trivial(blossom)) {
  1039         _delta4->erase(blossom);
  1040       }
  1041     }
  1042 
  1043     void oddToEven(int blossom, int tree) {
  1044       if (!_blossom_set->trivial(blossom)) {
  1045         _delta4->erase(blossom);
  1046         (*_blossom_data)[blossom].pot -=
  1047           2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
  1048       }
  1049 
  1050       for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
  1051            n != INVALID; ++n) {
  1052         int ni = (*_node_index)[n];
  1053 
  1054         _blossom_set->increase(n, std::numeric_limits<Value>::max());
  1055 
  1056         (*_node_data)[ni].heap.clear();
  1057         (*_node_data)[ni].heap_index.clear();
  1058         (*_node_data)[ni].pot +=
  1059           2 * _delta_sum - (*_blossom_data)[blossom].offset;
  1060 
  1061         _delta1->push(n, (*_node_data)[ni].pot);
  1062 
  1063         for (InArcIt e(_graph, n); e != INVALID; ++e) {
  1064           Node v = _graph.source(e);
  1065           int vb = _blossom_set->find(v);
  1066           int vi = (*_node_index)[v];
  1067 
  1068           Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
  1069             dualScale * _weight[e];
  1070 
  1071           if ((*_blossom_data)[vb].status == EVEN) {
  1072             if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
  1073               _delta3->push(e, rw / 2);
  1074             }
  1075           } else if ((*_blossom_data)[vb].status == UNMATCHED) {
  1076             if (_delta3->state(e) != _delta3->IN_HEAP) {
  1077               _delta3->push(e, rw);
  1078             }
  1079           } else {
  1080 
  1081             typename std::map<int, Arc>::iterator it =
  1082               (*_node_data)[vi].heap_index.find(tree);
  1083 
  1084             if (it != (*_node_data)[vi].heap_index.end()) {
  1085               if ((*_node_data)[vi].heap[it->second] > rw) {
  1086                 (*_node_data)[vi].heap.replace(it->second, e);
  1087                 (*_node_data)[vi].heap.decrease(e, rw);
  1088                 it->second = e;
  1089               }
  1090             } else {
  1091               (*_node_data)[vi].heap.push(e, rw);
  1092               (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
  1093             }
  1094 
  1095             if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
  1096               _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
  1097 
  1098               if ((*_blossom_data)[vb].status == MATCHED) {
  1099                 if (_delta2->state(vb) != _delta2->IN_HEAP) {
  1100                   _delta2->push(vb, _blossom_set->classPrio(vb) -
  1101                                (*_blossom_data)[vb].offset);
  1102                 } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
  1103                            (*_blossom_data)[vb].offset) {
  1104                   _delta2->decrease(vb, _blossom_set->classPrio(vb) -
  1105                                    (*_blossom_data)[vb].offset);
  1106                 }
  1107               }
  1108             }
  1109           }
  1110         }
  1111       }
  1112       (*_blossom_data)[blossom].offset = 0;
  1113     }
  1114 
  1115 
  1116     void matchedToUnmatched(int blossom) {
  1117       if (_delta2->state(blossom) == _delta2->IN_HEAP) {
  1118         _delta2->erase(blossom);
  1119       }
  1120 
  1121       for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
  1122            n != INVALID; ++n) {
  1123         int ni = (*_node_index)[n];
  1124 
  1125         _blossom_set->increase(n, std::numeric_limits<Value>::max());
  1126 
  1127         (*_node_data)[ni].heap.clear();
  1128         (*_node_data)[ni].heap_index.clear();
  1129 
  1130         for (OutArcIt e(_graph, n); e != INVALID; ++e) {
  1131           Node v = _graph.target(e);
  1132           int vb = _blossom_set->find(v);
  1133           int vi = (*_node_index)[v];
  1134 
  1135           Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
  1136             dualScale * _weight[e];
  1137 
  1138           if ((*_blossom_data)[vb].status == EVEN) {
  1139             if (_delta3->state(e) != _delta3->IN_HEAP) {
  1140               _delta3->push(e, rw);
  1141             }
  1142           }
  1143         }
  1144       }
  1145     }
  1146 
  1147     void unmatchedToMatched(int blossom) {
  1148       for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
  1149            n != INVALID; ++n) {
  1150         int ni = (*_node_index)[n];
  1151 
  1152         for (InArcIt e(_graph, n); e != INVALID; ++e) {
  1153           Node v = _graph.source(e);
  1154           int vb = _blossom_set->find(v);
  1155           int vi = (*_node_index)[v];
  1156 
  1157           Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
  1158             dualScale * _weight[e];
  1159 
  1160           if (vb == blossom) {
  1161             if (_delta3->state(e) == _delta3->IN_HEAP) {
  1162               _delta3->erase(e);
  1163             }
  1164           } else if ((*_blossom_data)[vb].status == EVEN) {
  1165 
  1166             if (_delta3->state(e) == _delta3->IN_HEAP) {
  1167               _delta3->erase(e);
  1168             }
  1169 
  1170             int vt = _tree_set->find(vb);
  1171 
  1172             Arc r = _graph.oppositeArc(e);
  1173 
  1174             typename std::map<int, Arc>::iterator it =
  1175               (*_node_data)[ni].heap_index.find(vt);
  1176 
  1177             if (it != (*_node_data)[ni].heap_index.end()) {
  1178               if ((*_node_data)[ni].heap[it->second] > rw) {
  1179                 (*_node_data)[ni].heap.replace(it->second, r);
  1180                 (*_node_data)[ni].heap.decrease(r, rw);
  1181                 it->second = r;
  1182               }
  1183             } else {
  1184               (*_node_data)[ni].heap.push(r, rw);
  1185               (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
  1186             }
  1187 
  1188             if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
  1189               _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
  1190 
  1191               if (_delta2->state(blossom) != _delta2->IN_HEAP) {
  1192                 _delta2->push(blossom, _blossom_set->classPrio(blossom) -
  1193                              (*_blossom_data)[blossom].offset);
  1194               } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-
  1195                          (*_blossom_data)[blossom].offset){
  1196                 _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
  1197                                  (*_blossom_data)[blossom].offset);
  1198               }
  1199             }
  1200 
  1201           } else if ((*_blossom_data)[vb].status == UNMATCHED) {
  1202             if (_delta3->state(e) == _delta3->IN_HEAP) {
  1203               _delta3->erase(e);
  1204             }
  1205           }
  1206         }
  1207       }
  1208     }
  1209 
  1210     void alternatePath(int even, int tree) {
  1211       int odd;
  1212 
  1213       evenToMatched(even, tree);
  1214       (*_blossom_data)[even].status = MATCHED;
  1215 
  1216       while ((*_blossom_data)[even].pred != INVALID) {
  1217         odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
  1218         (*_blossom_data)[odd].status = MATCHED;
  1219         oddToMatched(odd);
  1220         (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
  1221 
  1222         even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
  1223         (*_blossom_data)[even].status = MATCHED;
  1224         evenToMatched(even, tree);
  1225         (*_blossom_data)[even].next =
  1226           _graph.oppositeArc((*_blossom_data)[odd].pred);
  1227       }
  1228 
  1229     }
  1230 
  1231     void destroyTree(int tree) {
  1232       for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
  1233         if ((*_blossom_data)[b].status == EVEN) {
  1234           (*_blossom_data)[b].status = MATCHED;
  1235           evenToMatched(b, tree);
  1236         } else if ((*_blossom_data)[b].status == ODD) {
  1237           (*_blossom_data)[b].status = MATCHED;
  1238           oddToMatched(b);
  1239         }
  1240       }
  1241       _tree_set->eraseClass(tree);
  1242     }
  1243 
  1244 
  1245     void unmatchNode(const Node& node) {
  1246       int blossom = _blossom_set->find(node);
  1247       int tree = _tree_set->find(blossom);
  1248 
  1249       alternatePath(blossom, tree);
  1250       destroyTree(tree);
  1251 
  1252       (*_blossom_data)[blossom].status = UNMATCHED;
  1253       (*_blossom_data)[blossom].base = node;
  1254       matchedToUnmatched(blossom);
  1255     }
  1256 
  1257 
  1258     void augmentOnEdge(const Edge& edge) {
  1259 
  1260       int left = _blossom_set->find(_graph.u(edge));
  1261       int right = _blossom_set->find(_graph.v(edge));
  1262 
  1263       if ((*_blossom_data)[left].status == EVEN) {
  1264         int left_tree = _tree_set->find(left);
  1265         alternatePath(left, left_tree);
  1266         destroyTree(left_tree);
  1267       } else {
  1268         (*_blossom_data)[left].status = MATCHED;
  1269         unmatchedToMatched(left);
  1270       }
  1271 
  1272       if ((*_blossom_data)[right].status == EVEN) {
  1273         int right_tree = _tree_set->find(right);
  1274         alternatePath(right, right_tree);
  1275         destroyTree(right_tree);
  1276       } else {
  1277         (*_blossom_data)[right].status = MATCHED;
  1278         unmatchedToMatched(right);
  1279       }
  1280 
  1281       (*_blossom_data)[left].next = _graph.direct(edge, true);
  1282       (*_blossom_data)[right].next = _graph.direct(edge, false);
  1283     }
  1284 
  1285     void extendOnArc(const Arc& arc) {
  1286       int base = _blossom_set->find(_graph.target(arc));
  1287       int tree = _tree_set->find(base);
  1288 
  1289       int odd = _blossom_set->find(_graph.source(arc));
  1290       _tree_set->insert(odd, tree);
  1291       (*_blossom_data)[odd].status = ODD;
  1292       matchedToOdd(odd);
  1293       (*_blossom_data)[odd].pred = arc;
  1294 
  1295       int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
  1296       (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
  1297       _tree_set->insert(even, tree);
  1298       (*_blossom_data)[even].status = EVEN;
  1299       matchedToEven(even, tree);
  1300     }
  1301 
  1302     void shrinkOnEdge(const Edge& edge, int tree) {
  1303       int nca = -1;
  1304       std::vector<int> left_path, right_path;
  1305 
  1306       {
  1307         std::set<int> left_set, right_set;
  1308         int left = _blossom_set->find(_graph.u(edge));
  1309         left_path.push_back(left);
  1310         left_set.insert(left);
  1311 
  1312         int right = _blossom_set->find(_graph.v(edge));
  1313         right_path.push_back(right);
  1314         right_set.insert(right);
  1315 
  1316         while (true) {
  1317 
  1318           if ((*_blossom_data)[left].pred == INVALID) break;
  1319 
  1320           left =
  1321             _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
  1322           left_path.push_back(left);
  1323           left =
  1324             _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
  1325           left_path.push_back(left);
  1326 
  1327           left_set.insert(left);
  1328 
  1329           if (right_set.find(left) != right_set.end()) {
  1330             nca = left;
  1331             break;
  1332           }
  1333 
  1334           if ((*_blossom_data)[right].pred == INVALID) break;
  1335 
  1336           right =
  1337             _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
  1338           right_path.push_back(right);
  1339           right =
  1340             _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
  1341           right_path.push_back(right);
  1342 
  1343           right_set.insert(right);
  1344 
  1345           if (left_set.find(right) != left_set.end()) {
  1346             nca = right;
  1347             break;
  1348           }
  1349 
  1350         }
  1351 
  1352         if (nca == -1) {
  1353           if ((*_blossom_data)[left].pred == INVALID) {
  1354             nca = right;
  1355             while (left_set.find(nca) == left_set.end()) {
  1356               nca =
  1357                 _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
  1358               right_path.push_back(nca);
  1359               nca =
  1360                 _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
  1361               right_path.push_back(nca);
  1362             }
  1363           } else {
  1364             nca = left;
  1365             while (right_set.find(nca) == right_set.end()) {
  1366               nca =
  1367                 _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
  1368               left_path.push_back(nca);
  1369               nca =
  1370                 _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
  1371               left_path.push_back(nca);
  1372             }
  1373           }
  1374         }
  1375       }
  1376 
  1377       std::vector<int> subblossoms;
  1378       Arc prev;
  1379 
  1380       prev = _graph.direct(edge, true);
  1381       for (int i = 0; left_path[i] != nca; i += 2) {
  1382         subblossoms.push_back(left_path[i]);
  1383         (*_blossom_data)[left_path[i]].next = prev;
  1384         _tree_set->erase(left_path[i]);
  1385 
  1386         subblossoms.push_back(left_path[i + 1]);
  1387         (*_blossom_data)[left_path[i + 1]].status = EVEN;
  1388         oddToEven(left_path[i + 1], tree);
  1389         _tree_set->erase(left_path[i + 1]);
  1390         prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
  1391       }
  1392 
  1393       int k = 0;
  1394       while (right_path[k] != nca) ++k;
  1395 
  1396       subblossoms.push_back(nca);
  1397       (*_blossom_data)[nca].next = prev;
  1398 
  1399       for (int i = k - 2; i >= 0; i -= 2) {
  1400         subblossoms.push_back(right_path[i + 1]);
  1401         (*_blossom_data)[right_path[i + 1]].status = EVEN;
  1402         oddToEven(right_path[i + 1], tree);
  1403         _tree_set->erase(right_path[i + 1]);
  1404 
  1405         (*_blossom_data)[right_path[i + 1]].next =
  1406           (*_blossom_data)[right_path[i + 1]].pred;
  1407 
  1408         subblossoms.push_back(right_path[i]);
  1409         _tree_set->erase(right_path[i]);
  1410       }
  1411 
  1412       int surface =
  1413         _blossom_set->join(subblossoms.begin(), subblossoms.end());
  1414 
  1415       for (int i = 0; i < int(subblossoms.size()); ++i) {
  1416         if (!_blossom_set->trivial(subblossoms[i])) {
  1417           (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
  1418         }
  1419         (*_blossom_data)[subblossoms[i]].status = MATCHED;
  1420       }
  1421 
  1422       (*_blossom_data)[surface].pot = -2 * _delta_sum;
  1423       (*_blossom_data)[surface].offset = 0;
  1424       (*_blossom_data)[surface].status = EVEN;
  1425       (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
  1426       (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
  1427 
  1428       _tree_set->insert(surface, tree);
  1429       _tree_set->erase(nca);
  1430     }
  1431 
  1432     void splitBlossom(int blossom) {
  1433       Arc next = (*_blossom_data)[blossom].next;
  1434       Arc pred = (*_blossom_data)[blossom].pred;
  1435 
  1436       int tree = _tree_set->find(blossom);
  1437 
  1438       (*_blossom_data)[blossom].status = MATCHED;
  1439       oddToMatched(blossom);
  1440       if (_delta2->state(blossom) == _delta2->IN_HEAP) {
  1441         _delta2->erase(blossom);
  1442       }
  1443 
  1444       std::vector<int> subblossoms;
  1445       _blossom_set->split(blossom, std::back_inserter(subblossoms));
  1446 
  1447       Value offset = (*_blossom_data)[blossom].offset;
  1448       int b = _blossom_set->find(_graph.source(pred));
  1449       int d = _blossom_set->find(_graph.source(next));
  1450 
  1451       int ib = -1, id = -1;
  1452       for (int i = 0; i < int(subblossoms.size()); ++i) {
  1453         if (subblossoms[i] == b) ib = i;
  1454         if (subblossoms[i] == d) id = i;
  1455 
  1456         (*_blossom_data)[subblossoms[i]].offset = offset;
  1457         if (!_blossom_set->trivial(subblossoms[i])) {
  1458           (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
  1459         }
  1460         if (_blossom_set->classPrio(subblossoms[i]) !=
  1461             std::numeric_limits<Value>::max()) {
  1462           _delta2->push(subblossoms[i],
  1463                         _blossom_set->classPrio(subblossoms[i]) -
  1464                         (*_blossom_data)[subblossoms[i]].offset);
  1465         }
  1466       }
  1467 
  1468       if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
  1469         for (int i = (id + 1) % subblossoms.size();
  1470              i != ib; i = (i + 2) % subblossoms.size()) {
  1471           int sb = subblossoms[i];
  1472           int tb = subblossoms[(i + 1) % subblossoms.size()];
  1473           (*_blossom_data)[sb].next =
  1474             _graph.oppositeArc((*_blossom_data)[tb].next);
  1475         }
  1476 
  1477         for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
  1478           int sb = subblossoms[i];
  1479           int tb = subblossoms[(i + 1) % subblossoms.size()];
  1480           int ub = subblossoms[(i + 2) % subblossoms.size()];
  1481 
  1482           (*_blossom_data)[sb].status = ODD;
  1483           matchedToOdd(sb);
  1484           _tree_set->insert(sb, tree);
  1485           (*_blossom_data)[sb].pred = pred;
  1486           (*_blossom_data)[sb].next =
  1487                            _graph.oppositeArc((*_blossom_data)[tb].next);
  1488 
  1489           pred = (*_blossom_data)[ub].next;
  1490 
  1491           (*_blossom_data)[tb].status = EVEN;
  1492           matchedToEven(tb, tree);
  1493           _tree_set->insert(tb, tree);
  1494           (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
  1495         }
  1496 
  1497         (*_blossom_data)[subblossoms[id]].status = ODD;
  1498         matchedToOdd(subblossoms[id]);
  1499         _tree_set->insert(subblossoms[id], tree);
  1500         (*_blossom_data)[subblossoms[id]].next = next;
  1501         (*_blossom_data)[subblossoms[id]].pred = pred;
  1502 
  1503       } else {
  1504 
  1505         for (int i = (ib + 1) % subblossoms.size();
  1506              i != id; i = (i + 2) % subblossoms.size()) {
  1507           int sb = subblossoms[i];
  1508           int tb = subblossoms[(i + 1) % subblossoms.size()];
  1509           (*_blossom_data)[sb].next =
  1510             _graph.oppositeArc((*_blossom_data)[tb].next);
  1511         }
  1512 
  1513         for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
  1514           int sb = subblossoms[i];
  1515           int tb = subblossoms[(i + 1) % subblossoms.size()];
  1516           int ub = subblossoms[(i + 2) % subblossoms.size()];
  1517 
  1518           (*_blossom_data)[sb].status = ODD;
  1519           matchedToOdd(sb);
  1520           _tree_set->insert(sb, tree);
  1521           (*_blossom_data)[sb].next = next;
  1522           (*_blossom_data)[sb].pred =
  1523             _graph.oppositeArc((*_blossom_data)[tb].next);
  1524 
  1525           (*_blossom_data)[tb].status = EVEN;
  1526           matchedToEven(tb, tree);
  1527           _tree_set->insert(tb, tree);
  1528           (*_blossom_data)[tb].pred =
  1529             (*_blossom_data)[tb].next =
  1530             _graph.oppositeArc((*_blossom_data)[ub].next);
  1531           next = (*_blossom_data)[ub].next;
  1532         }
  1533 
  1534         (*_blossom_data)[subblossoms[ib]].status = ODD;
  1535         matchedToOdd(subblossoms[ib]);
  1536         _tree_set->insert(subblossoms[ib], tree);
  1537         (*_blossom_data)[subblossoms[ib]].next = next;
  1538         (*_blossom_data)[subblossoms[ib]].pred = pred;
  1539       }
  1540       _tree_set->erase(blossom);
  1541     }
  1542 
  1543     void extractBlossom(int blossom, const Node& base, const Arc& matching) {
  1544       if (_blossom_set->trivial(blossom)) {
  1545         int bi = (*_node_index)[base];
  1546         Value pot = (*_node_data)[bi].pot;
  1547 
  1548         _matching->set(base, matching);
  1549         _blossom_node_list.push_back(base);
  1550         _node_potential->set(base, pot);
  1551       } else {
  1552 
  1553         Value pot = (*_blossom_data)[blossom].pot;
  1554         int bn = _blossom_node_list.size();
  1555 
  1556         std::vector<int> subblossoms;
  1557         _blossom_set->split(blossom, std::back_inserter(subblossoms));
  1558         int b = _blossom_set->find(base);
  1559         int ib = -1;
  1560         for (int i = 0; i < int(subblossoms.size()); ++i) {
  1561           if (subblossoms[i] == b) { ib = i; break; }
  1562         }
  1563 
  1564         for (int i = 1; i < int(subblossoms.size()); i += 2) {
  1565           int sb = subblossoms[(ib + i) % subblossoms.size()];
  1566           int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
  1567 
  1568           Arc m = (*_blossom_data)[tb].next;
  1569           extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
  1570           extractBlossom(tb, _graph.source(m), m);
  1571         }
  1572         extractBlossom(subblossoms[ib], base, matching);
  1573 
  1574         int en = _blossom_node_list.size();
  1575 
  1576         _blossom_potential.push_back(BlossomVariable(bn, en, pot));
  1577       }
  1578     }
  1579 
  1580     void extractMatching() {
  1581       std::vector<int> blossoms;
  1582       for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
  1583         blossoms.push_back(c);
  1584       }
  1585 
  1586       for (int i = 0; i < int(blossoms.size()); ++i) {
  1587         if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
  1588 
  1589           Value offset = (*_blossom_data)[blossoms[i]].offset;
  1590           (*_blossom_data)[blossoms[i]].pot += 2 * offset;
  1591           for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
  1592                n != INVALID; ++n) {
  1593             (*_node_data)[(*_node_index)[n]].pot -= offset;
  1594           }
  1595 
  1596           Arc matching = (*_blossom_data)[blossoms[i]].next;
  1597           Node base = _graph.source(matching);
  1598           extractBlossom(blossoms[i], base, matching);
  1599         } else {
  1600           Node base = (*_blossom_data)[blossoms[i]].base;
  1601           extractBlossom(blossoms[i], base, INVALID);
  1602         }
  1603       }
  1604     }
  1605 
  1606   public:
  1607 
  1608     /// \brief Constructor
  1609     ///
  1610     /// Constructor.
  1611     MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
  1612       : _graph(graph), _weight(weight), _matching(0),
  1613         _node_potential(0), _blossom_potential(), _blossom_node_list(),
  1614         _node_num(0), _blossom_num(0),
  1615 
  1616         _blossom_index(0), _blossom_set(0), _blossom_data(0),
  1617         _node_index(0), _node_heap_index(0), _node_data(0),
  1618         _tree_set_index(0), _tree_set(0),
  1619 
  1620         _delta1_index(0), _delta1(0),
  1621         _delta2_index(0), _delta2(0),
  1622         _delta3_index(0), _delta3(0),
  1623         _delta4_index(0), _delta4(0),
  1624 
  1625         _delta_sum() {}
  1626 
  1627     ~MaxWeightedMatching() {
  1628       destroyStructures();
  1629     }
  1630 
  1631     /// \name Execution control
  1632     /// The simplest way to execute the algorithm is to use the
  1633     /// \c run() member function.
  1634 
  1635     ///@{
  1636 
  1637     /// \brief Initialize the algorithm
  1638     ///
  1639     /// Initialize the algorithm
  1640     void init() {
  1641       createStructures();
  1642 
  1643       for (ArcIt e(_graph); e != INVALID; ++e) {
  1644         _node_heap_index->set(e, BinHeap<Value, IntArcMap>::PRE_HEAP);
  1645       }
  1646       for (NodeIt n(_graph); n != INVALID; ++n) {
  1647         _delta1_index->set(n, _delta1->PRE_HEAP);
  1648       }
  1649       for (EdgeIt e(_graph); e != INVALID; ++e) {
  1650         _delta3_index->set(e, _delta3->PRE_HEAP);
  1651       }
  1652       for (int i = 0; i < _blossom_num; ++i) {
  1653         _delta2_index->set(i, _delta2->PRE_HEAP);
  1654         _delta4_index->set(i, _delta4->PRE_HEAP);
  1655       }
  1656 
  1657       int index = 0;
  1658       for (NodeIt n(_graph); n != INVALID; ++n) {
  1659         Value max = 0;
  1660         for (OutArcIt e(_graph, n); e != INVALID; ++e) {
  1661           if (_graph.target(e) == n) continue;
  1662           if ((dualScale * _weight[e]) / 2 > max) {
  1663             max = (dualScale * _weight[e]) / 2;
  1664           }
  1665         }
  1666         _node_index->set(n, index);
  1667         (*_node_data)[index].pot = max;
  1668         _delta1->push(n, max);
  1669         int blossom =
  1670           _blossom_set->insert(n, std::numeric_limits<Value>::max());
  1671 
  1672         _tree_set->insert(blossom);
  1673 
  1674         (*_blossom_data)[blossom].status = EVEN;
  1675         (*_blossom_data)[blossom].pred = INVALID;
  1676         (*_blossom_data)[blossom].next = INVALID;
  1677         (*_blossom_data)[blossom].pot = 0;
  1678         (*_blossom_data)[blossom].offset = 0;
  1679         ++index;
  1680       }
  1681       for (EdgeIt e(_graph); e != INVALID; ++e) {
  1682         int si = (*_node_index)[_graph.u(e)];
  1683         int ti = (*_node_index)[_graph.v(e)];
  1684         if (_graph.u(e) != _graph.v(e)) {
  1685           _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
  1686                             dualScale * _weight[e]) / 2);
  1687         }
  1688       }
  1689     }
  1690 
  1691     /// \brief Starts the algorithm
  1692     ///
  1693     /// Starts the algorithm
  1694     void start() {
  1695       enum OpType {
  1696         D1, D2, D3, D4
  1697       };
  1698 
  1699       int unmatched = _node_num;
  1700       while (unmatched > 0) {
  1701         Value d1 = !_delta1->empty() ?
  1702           _delta1->prio() : std::numeric_limits<Value>::max();
  1703 
  1704         Value d2 = !_delta2->empty() ?
  1705           _delta2->prio() : std::numeric_limits<Value>::max();
  1706 
  1707         Value d3 = !_delta3->empty() ?
  1708           _delta3->prio() : std::numeric_limits<Value>::max();
  1709 
  1710         Value d4 = !_delta4->empty() ?
  1711           _delta4->prio() : std::numeric_limits<Value>::max();
  1712 
  1713         _delta_sum = d1; OpType ot = D1;
  1714         if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
  1715         if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
  1716         if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
  1717 
  1718 
  1719         switch (ot) {
  1720         case D1:
  1721           {
  1722             Node n = _delta1->top();
  1723             unmatchNode(n);
  1724             --unmatched;
  1725           }
  1726           break;
  1727         case D2:
  1728           {
  1729             int blossom = _delta2->top();
  1730             Node n = _blossom_set->classTop(blossom);
  1731             Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
  1732             extendOnArc(e);
  1733           }
  1734           break;
  1735         case D3:
  1736           {
  1737             Edge e = _delta3->top();
  1738 
  1739             int left_blossom = _blossom_set->find(_graph.u(e));
  1740             int right_blossom = _blossom_set->find(_graph.v(e));
  1741 
  1742             if (left_blossom == right_blossom) {
  1743               _delta3->pop();
  1744             } else {
  1745               int left_tree;
  1746               if ((*_blossom_data)[left_blossom].status == EVEN) {
  1747                 left_tree = _tree_set->find(left_blossom);
  1748               } else {
  1749                 left_tree = -1;
  1750                 ++unmatched;
  1751               }
  1752               int right_tree;
  1753               if ((*_blossom_data)[right_blossom].status == EVEN) {
  1754                 right_tree = _tree_set->find(right_blossom);
  1755               } else {
  1756                 right_tree = -1;
  1757                 ++unmatched;
  1758               }
  1759 
  1760               if (left_tree == right_tree) {
  1761                 shrinkOnEdge(e, left_tree);
  1762               } else {
  1763                 augmentOnEdge(e);
  1764                 unmatched -= 2;
  1765               }
  1766             }
  1767           } break;
  1768         case D4:
  1769           splitBlossom(_delta4->top());
  1770           break;
  1771         }
  1772       }
  1773       extractMatching();
  1774     }
  1775 
  1776     /// \brief Runs %MaxWeightedMatching algorithm.
  1777     ///
  1778     /// This method runs the %MaxWeightedMatching algorithm.
  1779     ///
  1780     /// \note mwm.run() is just a shortcut of the following code.
  1781     /// \code
  1782     ///   mwm.init();
  1783     ///   mwm.start();
  1784     /// \endcode
  1785     void run() {
  1786       init();
  1787       start();
  1788     }
  1789 
  1790     /// @}
  1791 
  1792     /// \name Primal solution
  1793     /// Functions to get the primal solution, ie. the matching.
  1794 
  1795     /// @{
  1796 
  1797     /// \brief Returns the weight of the matching.
  1798     ///
  1799     /// Returns the weight of the matching.
  1800     Value matchingValue() const {
  1801       Value sum = 0;
  1802       for (NodeIt n(_graph); n != INVALID; ++n) {
  1803         if ((*_matching)[n] != INVALID) {
  1804           sum += _weight[(*_matching)[n]];
  1805         }
  1806       }
  1807       return sum /= 2;
  1808     }
  1809 
  1810     /// \brief Returns the cardinality of the matching.
  1811     ///
  1812     /// Returns the cardinality of the matching.
  1813     int matchingSize() const {
  1814       int num = 0;
  1815       for (NodeIt n(_graph); n != INVALID; ++n) {
  1816         if ((*_matching)[n] != INVALID) {
  1817           ++num;
  1818         }
  1819       }
  1820       return num /= 2;
  1821     }
  1822 
  1823     /// \brief Returns true when the edge is in the matching.
  1824     ///
  1825     /// Returns true when the edge is in the matching.
  1826     bool matching(const Edge& edge) const {
  1827       return edge == (*_matching)[_graph.u(edge)];
  1828     }
  1829 
  1830     /// \brief Returns the incident matching arc.
  1831     ///
  1832     /// Returns the incident matching arc from given node. If the
  1833     /// node is not matched then it gives back \c INVALID.
  1834     Arc matching(const Node& node) const {
  1835       return (*_matching)[node];
  1836     }
  1837 
  1838     /// \brief Returns the mate of the node.
  1839     ///
  1840     /// Returns the adjancent node in a mathcing arc. If the node is
  1841     /// not matched then it gives back \c INVALID.
  1842     Node mate(const Node& node) const {
  1843       return (*_matching)[node] != INVALID ?
  1844         _graph.target((*_matching)[node]) : INVALID;
  1845     }
  1846 
  1847     /// @}
  1848 
  1849     /// \name Dual solution
  1850     /// Functions to get the dual solution.
  1851 
  1852     /// @{
  1853 
  1854     /// \brief Returns the value of the dual solution.
  1855     ///
  1856     /// Returns the value of the dual solution. It should be equal to
  1857     /// the primal value scaled by \ref dualScale "dual scale".
  1858     Value dualValue() const {
  1859       Value sum = 0;
  1860       for (NodeIt n(_graph); n != INVALID; ++n) {
  1861         sum += nodeValue(n);
  1862       }
  1863       for (int i = 0; i < blossomNum(); ++i) {
  1864         sum += blossomValue(i) * (blossomSize(i) / 2);
  1865       }
  1866       return sum;
  1867     }
  1868 
  1869     /// \brief Returns the value of the node.
  1870     ///
  1871     /// Returns the the value of the node.
  1872     Value nodeValue(const Node& n) const {
  1873       return (*_node_potential)[n];
  1874     }
  1875 
  1876     /// \brief Returns the number of the blossoms in the basis.
  1877     ///
  1878     /// Returns the number of the blossoms in the basis.
  1879     /// \see BlossomIt
  1880     int blossomNum() const {
  1881       return _blossom_potential.size();
  1882     }
  1883 
  1884 
  1885     /// \brief Returns the number of the nodes in the blossom.
  1886     ///
  1887     /// Returns the number of the nodes in the blossom.
  1888     int blossomSize(int k) const {
  1889       return _blossom_potential[k].end - _blossom_potential[k].begin;
  1890     }
  1891 
  1892     /// \brief Returns the value of the blossom.
  1893     ///
  1894     /// Returns the the value of the blossom.
  1895     /// \see BlossomIt
  1896     Value blossomValue(int k) const {
  1897       return _blossom_potential[k].value;
  1898     }
  1899 
  1900     /// \brief Iterator for obtaining the nodes of the blossom.
  1901     ///
  1902     /// Iterator for obtaining the nodes of the blossom. This class
  1903     /// provides a common lemon style iterator for listing a
  1904     /// subset of the nodes.
  1905     class BlossomIt {
  1906     public:
  1907 
  1908       /// \brief Constructor.
  1909       ///
  1910       /// Constructor to get the nodes of the variable.
  1911       BlossomIt(const MaxWeightedMatching& algorithm, int variable)
  1912         : _algorithm(&algorithm)
  1913       {
  1914         _index = _algorithm->_blossom_potential[variable].begin;
  1915         _last = _algorithm->_blossom_potential[variable].end;
  1916       }
  1917 
  1918       /// \brief Conversion to node.
  1919       ///
  1920       /// Conversion to node.
  1921       operator Node() const {
  1922         return _algorithm->_blossom_node_list[_index];
  1923       }
  1924 
  1925       /// \brief Increment operator.
  1926       ///
  1927       /// Increment operator.
  1928       BlossomIt& operator++() {
  1929         ++_index;
  1930         return *this;
  1931       }
  1932 
  1933       /// \brief Validity checking
  1934       ///
  1935       /// Checks whether the iterator is invalid.
  1936       bool operator==(Invalid) const { return _index == _last; }
  1937 
  1938       /// \brief Validity checking
  1939       ///
  1940       /// Checks whether the iterator is valid.
  1941       bool operator!=(Invalid) const { return _index != _last; }
  1942 
  1943     private:
  1944       const MaxWeightedMatching* _algorithm;
  1945       int _last;
  1946       int _index;
  1947     };
  1948 
  1949     /// @}
  1950 
  1951   };
  1952 
  1953   /// \ingroup matching
  1954   ///
  1955   /// \brief Weighted perfect matching in general graphs
  1956   ///
  1957   /// This class provides an efficient implementation of Edmond's
  1958   /// maximum weighted perfect matching algorithm. The implementation
  1959   /// is based on extensive use of priority queues and provides
  1960   /// \f$O(nm\log(n))\f$ time complexity.
  1961   ///
  1962   /// The maximum weighted matching problem is to find undirected
  1963   /// edges in the graph with maximum overall weight and no two of
  1964   /// them shares their ends and covers all nodes. The problem can be
  1965   /// formulated with the following linear program.
  1966   /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
  1967   /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
  1968       \quad \forall B\in\mathcal{O}\f] */
  1969   /// \f[x_e \ge 0\quad \forall e\in E\f]
  1970   /// \f[\max \sum_{e\in E}x_ew_e\f]
  1971   /// where \f$\delta(X)\f$ is the set of edges incident to a node in
  1972   /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
  1973   /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
  1974   /// subsets of the nodes.
  1975   ///
  1976   /// The algorithm calculates an optimal matching and a proof of the
  1977   /// optimality. The solution of the dual problem can be used to check
  1978   /// the result of the algorithm. The dual linear problem is the
  1979   /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
  1980       w_{uv} \quad \forall uv\in E\f] */
  1981   /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
  1982   /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
  1983       \frac{\vert B \vert - 1}{2}z_B\f] */
  1984   ///
  1985   /// The algorithm can be executed with \c run() or the \c init() and
  1986   /// then the \c start() member functions. After it the matching can
  1987   /// be asked with \c matching() or mate() functions. The dual
  1988   /// solution can be get with \c nodeValue(), \c blossomNum() and \c
  1989   /// blossomValue() members and \ref MaxWeightedMatching::BlossomIt
  1990   /// "BlossomIt" nested class which is able to iterate on the nodes
  1991   /// of a blossom. If the value type is integral then the dual
  1992   /// solution is multiplied by \ref MaxWeightedMatching::dualScale "4".
  1993   template <typename _Graph,
  1994             typename _WeightMap = typename _Graph::template EdgeMap<int> >
  1995   class MaxWeightedPerfectMatching {
  1996   public:
  1997 
  1998     typedef _Graph Graph;
  1999     typedef _WeightMap WeightMap;
  2000     typedef typename WeightMap::Value Value;
  2001 
  2002     /// \brief Scaling factor for dual solution
  2003     ///
  2004     /// Scaling factor for dual solution, it is equal to 4 or 1
  2005     /// according to the value type.
  2006     static const int dualScale =
  2007       std::numeric_limits<Value>::is_integer ? 4 : 1;
  2008 
  2009     typedef typename Graph::template NodeMap<typename Graph::Arc>
  2010     MatchingMap;
  2011 
  2012   private:
  2013 
  2014     TEMPLATE_GRAPH_TYPEDEFS(Graph);
  2015 
  2016     typedef typename Graph::template NodeMap<Value> NodePotential;
  2017     typedef std::vector<Node> BlossomNodeList;
  2018 
  2019     struct BlossomVariable {
  2020       int begin, end;
  2021       Value value;
  2022 
  2023       BlossomVariable(int _begin, int _end, Value _value)
  2024         : begin(_begin), end(_end), value(_value) {}
  2025 
  2026     };
  2027 
  2028     typedef std::vector<BlossomVariable> BlossomPotential;
  2029 
  2030     const Graph& _graph;
  2031     const WeightMap& _weight;
  2032 
  2033     MatchingMap* _matching;
  2034 
  2035     NodePotential* _node_potential;
  2036 
  2037     BlossomPotential _blossom_potential;
  2038     BlossomNodeList _blossom_node_list;
  2039 
  2040     int _node_num;
  2041     int _blossom_num;
  2042 
  2043     typedef RangeMap<int> IntIntMap;
  2044 
  2045     enum Status {
  2046       EVEN = -1, MATCHED = 0, ODD = 1
  2047     };
  2048 
  2049     typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
  2050     struct BlossomData {
  2051       int tree;
  2052       Status status;
  2053       Arc pred, next;
  2054       Value pot, offset;
  2055     };
  2056 
  2057     IntNodeMap *_blossom_index;
  2058     BlossomSet *_blossom_set;
  2059     RangeMap<BlossomData>* _blossom_data;
  2060 
  2061     IntNodeMap *_node_index;
  2062     IntArcMap *_node_heap_index;
  2063 
  2064     struct NodeData {
  2065 
  2066       NodeData(IntArcMap& node_heap_index)
  2067         : heap(node_heap_index) {}
  2068 
  2069       int blossom;
  2070       Value pot;
  2071       BinHeap<Value, IntArcMap> heap;
  2072       std::map<int, Arc> heap_index;
  2073 
  2074       int tree;
  2075     };
  2076 
  2077     RangeMap<NodeData>* _node_data;
  2078 
  2079     typedef ExtendFindEnum<IntIntMap> TreeSet;
  2080 
  2081     IntIntMap *_tree_set_index;
  2082     TreeSet *_tree_set;
  2083 
  2084     IntIntMap *_delta2_index;
  2085     BinHeap<Value, IntIntMap> *_delta2;
  2086 
  2087     IntEdgeMap *_delta3_index;
  2088     BinHeap<Value, IntEdgeMap> *_delta3;
  2089 
  2090     IntIntMap *_delta4_index;
  2091     BinHeap<Value, IntIntMap> *_delta4;
  2092 
  2093     Value _delta_sum;
  2094 
  2095     void createStructures() {
  2096       _node_num = countNodes(_graph);
  2097       _blossom_num = _node_num * 3 / 2;
  2098 
  2099       if (!_matching) {
  2100         _matching = new MatchingMap(_graph);
  2101       }
  2102       if (!_node_potential) {
  2103         _node_potential = new NodePotential(_graph);
  2104       }
  2105       if (!_blossom_set) {
  2106         _blossom_index = new IntNodeMap(_graph);
  2107         _blossom_set = new BlossomSet(*_blossom_index);
  2108         _blossom_data = new RangeMap<BlossomData>(_blossom_num);
  2109       }
  2110 
  2111       if (!_node_index) {
  2112         _node_index = new IntNodeMap(_graph);
  2113         _node_heap_index = new IntArcMap(_graph);
  2114         _node_data = new RangeMap<NodeData>(_node_num,
  2115                                             NodeData(*_node_heap_index));
  2116       }
  2117 
  2118       if (!_tree_set) {
  2119         _tree_set_index = new IntIntMap(_blossom_num);
  2120         _tree_set = new TreeSet(*_tree_set_index);
  2121       }
  2122       if (!_delta2) {
  2123         _delta2_index = new IntIntMap(_blossom_num);
  2124         _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
  2125       }
  2126       if (!_delta3) {
  2127         _delta3_index = new IntEdgeMap(_graph);
  2128         _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
  2129       }
  2130       if (!_delta4) {
  2131         _delta4_index = new IntIntMap(_blossom_num);
  2132         _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
  2133       }
  2134     }
  2135 
  2136     void destroyStructures() {
  2137       _node_num = countNodes(_graph);
  2138       _blossom_num = _node_num * 3 / 2;
  2139 
  2140       if (_matching) {
  2141         delete _matching;
  2142       }
  2143       if (_node_potential) {
  2144         delete _node_potential;
  2145       }
  2146       if (_blossom_set) {
  2147         delete _blossom_index;
  2148         delete _blossom_set;
  2149         delete _blossom_data;
  2150       }
  2151 
  2152       if (_node_index) {
  2153         delete _node_index;
  2154         delete _node_heap_index;
  2155         delete _node_data;
  2156       }
  2157 
  2158       if (_tree_set) {
  2159         delete _tree_set_index;
  2160         delete _tree_set;
  2161       }
  2162       if (_delta2) {
  2163         delete _delta2_index;
  2164         delete _delta2;
  2165       }
  2166       if (_delta3) {
  2167         delete _delta3_index;
  2168         delete _delta3;
  2169       }
  2170       if (_delta4) {
  2171         delete _delta4_index;
  2172         delete _delta4;
  2173       }
  2174     }
  2175 
  2176     void matchedToEven(int blossom, int tree) {
  2177       if (_delta2->state(blossom) == _delta2->IN_HEAP) {
  2178         _delta2->erase(blossom);
  2179       }
  2180 
  2181       if (!_blossom_set->trivial(blossom)) {
  2182         (*_blossom_data)[blossom].pot -=
  2183           2 * (_delta_sum - (*_blossom_data)[blossom].offset);
  2184       }
  2185 
  2186       for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
  2187            n != INVALID; ++n) {
  2188 
  2189         _blossom_set->increase(n, std::numeric_limits<Value>::max());
  2190         int ni = (*_node_index)[n];
  2191 
  2192         (*_node_data)[ni].heap.clear();
  2193         (*_node_data)[ni].heap_index.clear();
  2194 
  2195         (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
  2196 
  2197         for (InArcIt e(_graph, n); e != INVALID; ++e) {
  2198           Node v = _graph.source(e);
  2199           int vb = _blossom_set->find(v);
  2200           int vi = (*_node_index)[v];
  2201 
  2202           Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
  2203             dualScale * _weight[e];
  2204 
  2205           if ((*_blossom_data)[vb].status == EVEN) {
  2206             if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
  2207               _delta3->push(e, rw / 2);
  2208             }
  2209           } else {
  2210             typename std::map<int, Arc>::iterator it =
  2211               (*_node_data)[vi].heap_index.find(tree);
  2212 
  2213             if (it != (*_node_data)[vi].heap_index.end()) {
  2214               if ((*_node_data)[vi].heap[it->second] > rw) {
  2215                 (*_node_data)[vi].heap.replace(it->second, e);
  2216                 (*_node_data)[vi].heap.decrease(e, rw);
  2217                 it->second = e;
  2218               }
  2219             } else {
  2220               (*_node_data)[vi].heap.push(e, rw);
  2221               (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
  2222             }
  2223 
  2224             if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
  2225               _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
  2226 
  2227               if ((*_blossom_data)[vb].status == MATCHED) {
  2228                 if (_delta2->state(vb) != _delta2->IN_HEAP) {
  2229                   _delta2->push(vb, _blossom_set->classPrio(vb) -
  2230                                (*_blossom_data)[vb].offset);
  2231                 } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
  2232                            (*_blossom_data)[vb].offset){
  2233                   _delta2->decrease(vb, _blossom_set->classPrio(vb) -
  2234                                    (*_blossom_data)[vb].offset);
  2235                 }
  2236               }
  2237             }
  2238           }
  2239         }
  2240       }
  2241       (*_blossom_data)[blossom].offset = 0;
  2242     }
  2243 
  2244     void matchedToOdd(int blossom) {
  2245       if (_delta2->state(blossom) == _delta2->IN_HEAP) {
  2246         _delta2->erase(blossom);
  2247       }
  2248       (*_blossom_data)[blossom].offset += _delta_sum;
  2249       if (!_blossom_set->trivial(blossom)) {
  2250         _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
  2251                      (*_blossom_data)[blossom].offset);
  2252       }
  2253     }
  2254 
  2255     void evenToMatched(int blossom, int tree) {
  2256       if (!_blossom_set->trivial(blossom)) {
  2257         (*_blossom_data)[blossom].pot += 2 * _delta_sum;
  2258       }
  2259 
  2260       for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
  2261            n != INVALID; ++n) {
  2262         int ni = (*_node_index)[n];
  2263         (*_node_data)[ni].pot -= _delta_sum;
  2264 
  2265         for (InArcIt e(_graph, n); e != INVALID; ++e) {
  2266           Node v = _graph.source(e);
  2267           int vb = _blossom_set->find(v);
  2268           int vi = (*_node_index)[v];
  2269 
  2270           Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
  2271             dualScale * _weight[e];
  2272 
  2273           if (vb == blossom) {
  2274             if (_delta3->state(e) == _delta3->IN_HEAP) {
  2275               _delta3->erase(e);
  2276             }
  2277           } else if ((*_blossom_data)[vb].status == EVEN) {
  2278 
  2279             if (_delta3->state(e) == _delta3->IN_HEAP) {
  2280               _delta3->erase(e);
  2281             }
  2282 
  2283             int vt = _tree_set->find(vb);
  2284 
  2285             if (vt != tree) {
  2286 
  2287               Arc r = _graph.oppositeArc(e);
  2288 
  2289               typename std::map<int, Arc>::iterator it =
  2290                 (*_node_data)[ni].heap_index.find(vt);
  2291 
  2292               if (it != (*_node_data)[ni].heap_index.end()) {
  2293                 if ((*_node_data)[ni].heap[it->second] > rw) {
  2294                   (*_node_data)[ni].heap.replace(it->second, r);
  2295                   (*_node_data)[ni].heap.decrease(r, rw);
  2296                   it->second = r;
  2297                 }
  2298               } else {
  2299                 (*_node_data)[ni].heap.push(r, rw);
  2300                 (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
  2301               }
  2302 
  2303               if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
  2304                 _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
  2305 
  2306                 if (_delta2->state(blossom) != _delta2->IN_HEAP) {
  2307                   _delta2->push(blossom, _blossom_set->classPrio(blossom) -
  2308                                (*_blossom_data)[blossom].offset);
  2309                 } else if ((*_delta2)[blossom] >
  2310                            _blossom_set->classPrio(blossom) -
  2311                            (*_blossom_data)[blossom].offset){
  2312                   _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
  2313                                    (*_blossom_data)[blossom].offset);
  2314                 }
  2315               }
  2316             }
  2317           } else {
  2318 
  2319             typename std::map<int, Arc>::iterator it =
  2320               (*_node_data)[vi].heap_index.find(tree);
  2321 
  2322             if (it != (*_node_data)[vi].heap_index.end()) {
  2323               (*_node_data)[vi].heap.erase(it->second);
  2324               (*_node_data)[vi].heap_index.erase(it);
  2325               if ((*_node_data)[vi].heap.empty()) {
  2326                 _blossom_set->increase(v, std::numeric_limits<Value>::max());
  2327               } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
  2328                 _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
  2329               }
  2330 
  2331               if ((*_blossom_data)[vb].status == MATCHED) {
  2332                 if (_blossom_set->classPrio(vb) ==
  2333                     std::numeric_limits<Value>::max()) {
  2334                   _delta2->erase(vb);
  2335                 } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
  2336                            (*_blossom_data)[vb].offset) {
  2337                   _delta2->increase(vb, _blossom_set->classPrio(vb) -
  2338                                    (*_blossom_data)[vb].offset);
  2339                 }
  2340               }
  2341             }
  2342           }
  2343         }
  2344       }
  2345     }
  2346 
  2347     void oddToMatched(int blossom) {
  2348       (*_blossom_data)[blossom].offset -= _delta_sum;
  2349 
  2350       if (_blossom_set->classPrio(blossom) !=
  2351           std::numeric_limits<Value>::max()) {
  2352         _delta2->push(blossom, _blossom_set->classPrio(blossom) -
  2353                        (*_blossom_data)[blossom].offset);
  2354       }
  2355 
  2356       if (!_blossom_set->trivial(blossom)) {
  2357         _delta4->erase(blossom);
  2358       }
  2359     }
  2360 
  2361     void oddToEven(int blossom, int tree) {
  2362       if (!_blossom_set->trivial(blossom)) {
  2363         _delta4->erase(blossom);
  2364         (*_blossom_data)[blossom].pot -=
  2365           2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
  2366       }
  2367 
  2368       for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
  2369            n != INVALID; ++n) {
  2370         int ni = (*_node_index)[n];
  2371 
  2372         _blossom_set->increase(n, std::numeric_limits<Value>::max());
  2373 
  2374         (*_node_data)[ni].heap.clear();
  2375         (*_node_data)[ni].heap_index.clear();
  2376         (*_node_data)[ni].pot +=
  2377           2 * _delta_sum - (*_blossom_data)[blossom].offset;
  2378 
  2379         for (InArcIt e(_graph, n); e != INVALID; ++e) {
  2380           Node v = _graph.source(e);
  2381           int vb = _blossom_set->find(v);
  2382           int vi = (*_node_index)[v];
  2383 
  2384           Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
  2385             dualScale * _weight[e];
  2386 
  2387           if ((*_blossom_data)[vb].status == EVEN) {
  2388             if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
  2389               _delta3->push(e, rw / 2);
  2390             }
  2391           } else {
  2392 
  2393             typename std::map<int, Arc>::iterator it =
  2394               (*_node_data)[vi].heap_index.find(tree);
  2395 
  2396             if (it != (*_node_data)[vi].heap_index.end()) {
  2397               if ((*_node_data)[vi].heap[it->second] > rw) {
  2398                 (*_node_data)[vi].heap.replace(it->second, e);
  2399                 (*_node_data)[vi].heap.decrease(e, rw);
  2400                 it->second = e;
  2401               }
  2402             } else {
  2403               (*_node_data)[vi].heap.push(e, rw);
  2404               (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
  2405             }
  2406 
  2407             if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
  2408               _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
  2409 
  2410               if ((*_blossom_data)[vb].status == MATCHED) {
  2411                 if (_delta2->state(vb) != _delta2->IN_HEAP) {
  2412                   _delta2->push(vb, _blossom_set->classPrio(vb) -
  2413                                (*_blossom_data)[vb].offset);
  2414                 } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
  2415                            (*_blossom_data)[vb].offset) {
  2416                   _delta2->decrease(vb, _blossom_set->classPrio(vb) -
  2417                                    (*_blossom_data)[vb].offset);
  2418                 }
  2419               }
  2420             }
  2421           }
  2422         }
  2423       }
  2424       (*_blossom_data)[blossom].offset = 0;
  2425     }
  2426 
  2427     void alternatePath(int even, int tree) {
  2428       int odd;
  2429 
  2430       evenToMatched(even, tree);
  2431       (*_blossom_data)[even].status = MATCHED;
  2432 
  2433       while ((*_blossom_data)[even].pred != INVALID) {
  2434         odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
  2435         (*_blossom_data)[odd].status = MATCHED;
  2436         oddToMatched(odd);
  2437         (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
  2438 
  2439         even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
  2440         (*_blossom_data)[even].status = MATCHED;
  2441         evenToMatched(even, tree);
  2442         (*_blossom_data)[even].next =
  2443           _graph.oppositeArc((*_blossom_data)[odd].pred);
  2444       }
  2445 
  2446     }
  2447 
  2448     void destroyTree(int tree) {
  2449       for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
  2450         if ((*_blossom_data)[b].status == EVEN) {
  2451           (*_blossom_data)[b].status = MATCHED;
  2452           evenToMatched(b, tree);
  2453         } else if ((*_blossom_data)[b].status == ODD) {
  2454           (*_blossom_data)[b].status = MATCHED;
  2455           oddToMatched(b);
  2456         }
  2457       }
  2458       _tree_set->eraseClass(tree);
  2459     }
  2460 
  2461     void augmentOnEdge(const Edge& edge) {
  2462 
  2463       int left = _blossom_set->find(_graph.u(edge));
  2464       int right = _blossom_set->find(_graph.v(edge));
  2465 
  2466       int left_tree = _tree_set->find(left);
  2467       alternatePath(left, left_tree);
  2468       destroyTree(left_tree);
  2469 
  2470       int right_tree = _tree_set->find(right);
  2471       alternatePath(right, right_tree);
  2472       destroyTree(right_tree);
  2473 
  2474       (*_blossom_data)[left].next = _graph.direct(edge, true);
  2475       (*_blossom_data)[right].next = _graph.direct(edge, false);
  2476     }
  2477 
  2478     void extendOnArc(const Arc& arc) {
  2479       int base = _blossom_set->find(_graph.target(arc));
  2480       int tree = _tree_set->find(base);
  2481 
  2482       int odd = _blossom_set->find(_graph.source(arc));
  2483       _tree_set->insert(odd, tree);
  2484       (*_blossom_data)[odd].status = ODD;
  2485       matchedToOdd(odd);
  2486       (*_blossom_data)[odd].pred = arc;
  2487 
  2488       int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
  2489       (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
  2490       _tree_set->insert(even, tree);
  2491       (*_blossom_data)[even].status = EVEN;
  2492       matchedToEven(even, tree);
  2493     }
  2494 
  2495     void shrinkOnEdge(const Edge& edge, int tree) {
  2496       int nca = -1;
  2497       std::vector<int> left_path, right_path;
  2498 
  2499       {
  2500         std::set<int> left_set, right_set;
  2501         int left = _blossom_set->find(_graph.u(edge));
  2502         left_path.push_back(left);
  2503         left_set.insert(left);
  2504 
  2505         int right = _blossom_set->find(_graph.v(edge));
  2506         right_path.push_back(right);
  2507         right_set.insert(right);
  2508 
  2509         while (true) {
  2510 
  2511           if ((*_blossom_data)[left].pred == INVALID) break;
  2512 
  2513           left =
  2514             _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
  2515           left_path.push_back(left);
  2516           left =
  2517             _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
  2518           left_path.push_back(left);
  2519 
  2520           left_set.insert(left);
  2521 
  2522           if (right_set.find(left) != right_set.end()) {
  2523             nca = left;
  2524             break;
  2525           }
  2526 
  2527           if ((*_blossom_data)[right].pred == INVALID) break;
  2528 
  2529           right =
  2530             _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
  2531           right_path.push_back(right);
  2532           right =
  2533             _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
  2534           right_path.push_back(right);
  2535 
  2536           right_set.insert(right);
  2537 
  2538           if (left_set.find(right) != left_set.end()) {
  2539             nca = right;
  2540             break;
  2541           }
  2542 
  2543         }
  2544 
  2545         if (nca == -1) {
  2546           if ((*_blossom_data)[left].pred == INVALID) {
  2547             nca = right;
  2548             while (left_set.find(nca) == left_set.end()) {
  2549               nca =
  2550                 _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
  2551               right_path.push_back(nca);
  2552               nca =
  2553                 _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
  2554               right_path.push_back(nca);
  2555             }
  2556           } else {
  2557             nca = left;
  2558             while (right_set.find(nca) == right_set.end()) {
  2559               nca =
  2560                 _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
  2561               left_path.push_back(nca);
  2562               nca =
  2563                 _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
  2564               left_path.push_back(nca);
  2565             }
  2566           }
  2567         }
  2568       }
  2569 
  2570       std::vector<int> subblossoms;
  2571       Arc prev;
  2572 
  2573       prev = _graph.direct(edge, true);
  2574       for (int i = 0; left_path[i] != nca; i += 2) {
  2575         subblossoms.push_back(left_path[i]);
  2576         (*_blossom_data)[left_path[i]].next = prev;
  2577         _tree_set->erase(left_path[i]);
  2578 
  2579         subblossoms.push_back(left_path[i + 1]);
  2580         (*_blossom_data)[left_path[i + 1]].status = EVEN;
  2581         oddToEven(left_path[i + 1], tree);
  2582         _tree_set->erase(left_path[i + 1]);
  2583         prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
  2584       }
  2585 
  2586       int k = 0;
  2587       while (right_path[k] != nca) ++k;
  2588 
  2589       subblossoms.push_back(nca);
  2590       (*_blossom_data)[nca].next = prev;
  2591 
  2592       for (int i = k - 2; i >= 0; i -= 2) {
  2593         subblossoms.push_back(right_path[i + 1]);
  2594         (*_blossom_data)[right_path[i + 1]].status = EVEN;
  2595         oddToEven(right_path[i + 1], tree);
  2596         _tree_set->erase(right_path[i + 1]);
  2597 
  2598         (*_blossom_data)[right_path[i + 1]].next =
  2599           (*_blossom_data)[right_path[i + 1]].pred;
  2600 
  2601         subblossoms.push_back(right_path[i]);
  2602         _tree_set->erase(right_path[i]);
  2603       }
  2604 
  2605       int surface =
  2606         _blossom_set->join(subblossoms.begin(), subblossoms.end());
  2607 
  2608       for (int i = 0; i < int(subblossoms.size()); ++i) {
  2609         if (!_blossom_set->trivial(subblossoms[i])) {
  2610           (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
  2611         }
  2612         (*_blossom_data)[subblossoms[i]].status = MATCHED;
  2613       }
  2614 
  2615       (*_blossom_data)[surface].pot = -2 * _delta_sum;
  2616       (*_blossom_data)[surface].offset = 0;
  2617       (*_blossom_data)[surface].status = EVEN;
  2618       (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
  2619       (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
  2620 
  2621       _tree_set->insert(surface, tree);
  2622       _tree_set->erase(nca);
  2623     }
  2624 
  2625     void splitBlossom(int blossom) {
  2626       Arc next = (*_blossom_data)[blossom].next;
  2627       Arc pred = (*_blossom_data)[blossom].pred;
  2628 
  2629       int tree = _tree_set->find(blossom);
  2630 
  2631       (*_blossom_data)[blossom].status = MATCHED;
  2632       oddToMatched(blossom);
  2633       if (_delta2->state(blossom) == _delta2->IN_HEAP) {
  2634         _delta2->erase(blossom);
  2635       }
  2636 
  2637       std::vector<int> subblossoms;
  2638       _blossom_set->split(blossom, std::back_inserter(subblossoms));
  2639 
  2640       Value offset = (*_blossom_data)[blossom].offset;
  2641       int b = _blossom_set->find(_graph.source(pred));
  2642       int d = _blossom_set->find(_graph.source(next));
  2643 
  2644       int ib = -1, id = -1;
  2645       for (int i = 0; i < int(subblossoms.size()); ++i) {
  2646         if (subblossoms[i] == b) ib = i;
  2647         if (subblossoms[i] == d) id = i;
  2648 
  2649         (*_blossom_data)[subblossoms[i]].offset = offset;
  2650         if (!_blossom_set->trivial(subblossoms[i])) {
  2651           (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
  2652         }
  2653         if (_blossom_set->classPrio(subblossoms[i]) !=
  2654             std::numeric_limits<Value>::max()) {
  2655           _delta2->push(subblossoms[i],
  2656                         _blossom_set->classPrio(subblossoms[i]) -
  2657                         (*_blossom_data)[subblossoms[i]].offset);
  2658         }
  2659       }
  2660 
  2661       if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
  2662         for (int i = (id + 1) % subblossoms.size();
  2663              i != ib; i = (i + 2) % subblossoms.size()) {
  2664           int sb = subblossoms[i];
  2665           int tb = subblossoms[(i + 1) % subblossoms.size()];
  2666           (*_blossom_data)[sb].next =
  2667             _graph.oppositeArc((*_blossom_data)[tb].next);
  2668         }
  2669 
  2670         for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
  2671           int sb = subblossoms[i];
  2672           int tb = subblossoms[(i + 1) % subblossoms.size()];
  2673           int ub = subblossoms[(i + 2) % subblossoms.size()];
  2674 
  2675           (*_blossom_data)[sb].status = ODD;
  2676           matchedToOdd(sb);
  2677           _tree_set->insert(sb, tree);
  2678           (*_blossom_data)[sb].pred = pred;
  2679           (*_blossom_data)[sb].next =
  2680                            _graph.oppositeArc((*_blossom_data)[tb].next);
  2681 
  2682           pred = (*_blossom_data)[ub].next;
  2683 
  2684           (*_blossom_data)[tb].status = EVEN;
  2685           matchedToEven(tb, tree);
  2686           _tree_set->insert(tb, tree);
  2687           (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
  2688         }
  2689 
  2690         (*_blossom_data)[subblossoms[id]].status = ODD;
  2691         matchedToOdd(subblossoms[id]);
  2692         _tree_set->insert(subblossoms[id], tree);
  2693         (*_blossom_data)[subblossoms[id]].next = next;
  2694         (*_blossom_data)[subblossoms[id]].pred = pred;
  2695 
  2696       } else {
  2697 
  2698         for (int i = (ib + 1) % subblossoms.size();
  2699              i != id; i = (i + 2) % subblossoms.size()) {
  2700           int sb = subblossoms[i];
  2701           int tb = subblossoms[(i + 1) % subblossoms.size()];
  2702           (*_blossom_data)[sb].next =
  2703             _graph.oppositeArc((*_blossom_data)[tb].next);
  2704         }
  2705 
  2706         for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
  2707           int sb = subblossoms[i];
  2708           int tb = subblossoms[(i + 1) % subblossoms.size()];
  2709           int ub = subblossoms[(i + 2) % subblossoms.size()];
  2710 
  2711           (*_blossom_data)[sb].status = ODD;
  2712           matchedToOdd(sb);
  2713           _tree_set->insert(sb, tree);
  2714           (*_blossom_data)[sb].next = next;
  2715           (*_blossom_data)[sb].pred =
  2716             _graph.oppositeArc((*_blossom_data)[tb].next);
  2717 
  2718           (*_blossom_data)[tb].status = EVEN;
  2719           matchedToEven(tb, tree);
  2720           _tree_set->insert(tb, tree);
  2721           (*_blossom_data)[tb].pred =
  2722             (*_blossom_data)[tb].next =
  2723             _graph.oppositeArc((*_blossom_data)[ub].next);
  2724           next = (*_blossom_data)[ub].next;
  2725         }
  2726 
  2727         (*_blossom_data)[subblossoms[ib]].status = ODD;
  2728         matchedToOdd(subblossoms[ib]);
  2729         _tree_set->insert(subblossoms[ib], tree);
  2730         (*_blossom_data)[subblossoms[ib]].next = next;
  2731         (*_blossom_data)[subblossoms[ib]].pred = pred;
  2732       }
  2733       _tree_set->erase(blossom);
  2734     }
  2735 
  2736     void extractBlossom(int blossom, const Node& base, const Arc& matching) {
  2737       if (_blossom_set->trivial(blossom)) {
  2738         int bi = (*_node_index)[base];
  2739         Value pot = (*_node_data)[bi].pot;
  2740 
  2741         _matching->set(base, matching);
  2742         _blossom_node_list.push_back(base);
  2743         _node_potential->set(base, pot);
  2744       } else {
  2745 
  2746         Value pot = (*_blossom_data)[blossom].pot;
  2747         int bn = _blossom_node_list.size();
  2748 
  2749         std::vector<int> subblossoms;
  2750         _blossom_set->split(blossom, std::back_inserter(subblossoms));
  2751         int b = _blossom_set->find(base);
  2752         int ib = -1;
  2753         for (int i = 0; i < int(subblossoms.size()); ++i) {
  2754           if (subblossoms[i] == b) { ib = i; break; }
  2755         }
  2756 
  2757         for (int i = 1; i < int(subblossoms.size()); i += 2) {
  2758           int sb = subblossoms[(ib + i) % subblossoms.size()];
  2759           int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
  2760 
  2761           Arc m = (*_blossom_data)[tb].next;
  2762           extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
  2763           extractBlossom(tb, _graph.source(m), m);
  2764         }
  2765         extractBlossom(subblossoms[ib], base, matching);
  2766 
  2767         int en = _blossom_node_list.size();
  2768 
  2769         _blossom_potential.push_back(BlossomVariable(bn, en, pot));
  2770       }
  2771     }
  2772 
  2773     void extractMatching() {
  2774       std::vector<int> blossoms;
  2775       for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
  2776         blossoms.push_back(c);
  2777       }
  2778 
  2779       for (int i = 0; i < int(blossoms.size()); ++i) {
  2780 
  2781         Value offset = (*_blossom_data)[blossoms[i]].offset;
  2782         (*_blossom_data)[blossoms[i]].pot += 2 * offset;
  2783         for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
  2784              n != INVALID; ++n) {
  2785           (*_node_data)[(*_node_index)[n]].pot -= offset;
  2786         }
  2787 
  2788         Arc matching = (*_blossom_data)[blossoms[i]].next;
  2789         Node base = _graph.source(matching);
  2790         extractBlossom(blossoms[i], base, matching);
  2791       }
  2792     }
  2793 
  2794   public:
  2795 
  2796     /// \brief Constructor
  2797     ///
  2798     /// Constructor.
  2799     MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight)
  2800       : _graph(graph), _weight(weight), _matching(0),
  2801         _node_potential(0), _blossom_potential(), _blossom_node_list(),
  2802         _node_num(0), _blossom_num(0),
  2803 
  2804         _blossom_index(0), _blossom_set(0), _blossom_data(0),
  2805         _node_index(0), _node_heap_index(0), _node_data(0),
  2806         _tree_set_index(0), _tree_set(0),
  2807 
  2808         _delta2_index(0), _delta2(0),
  2809         _delta3_index(0), _delta3(0),
  2810         _delta4_index(0), _delta4(0),
  2811 
  2812         _delta_sum() {}
  2813 
  2814     ~MaxWeightedPerfectMatching() {
  2815       destroyStructures();
  2816     }
  2817 
  2818     /// \name Execution control
  2819     /// The simplest way to execute the algorithm is to use the
  2820     /// \c run() member function.
  2821 
  2822     ///@{
  2823 
  2824     /// \brief Initialize the algorithm
  2825     ///
  2826     /// Initialize the algorithm
  2827     void init() {
  2828       createStructures();
  2829 
  2830       for (ArcIt e(_graph); e != INVALID; ++e) {
  2831         _node_heap_index->set(e, BinHeap<Value, IntArcMap>::PRE_HEAP);
  2832       }
  2833       for (EdgeIt e(_graph); e != INVALID; ++e) {
  2834         _delta3_index->set(e, _delta3->PRE_HEAP);
  2835       }
  2836       for (int i = 0; i < _blossom_num; ++i) {
  2837         _delta2_index->set(i, _delta2->PRE_HEAP);
  2838         _delta4_index->set(i, _delta4->PRE_HEAP);
  2839       }
  2840 
  2841       int index = 0;
  2842       for (NodeIt n(_graph); n != INVALID; ++n) {
  2843         Value max = - std::numeric_limits<Value>::max();
  2844         for (OutArcIt e(_graph, n); e != INVALID; ++e) {
  2845           if (_graph.target(e) == n) continue;
  2846           if ((dualScale * _weight[e]) / 2 > max) {
  2847             max = (dualScale * _weight[e]) / 2;
  2848           }
  2849         }
  2850         _node_index->set(n, index);
  2851         (*_node_data)[index].pot = max;
  2852         int blossom =
  2853           _blossom_set->insert(n, std::numeric_limits<Value>::max());
  2854 
  2855         _tree_set->insert(blossom);
  2856 
  2857         (*_blossom_data)[blossom].status = EVEN;
  2858         (*_blossom_data)[blossom].pred = INVALID;
  2859         (*_blossom_data)[blossom].next = INVALID;
  2860         (*_blossom_data)[blossom].pot = 0;
  2861         (*_blossom_data)[blossom].offset = 0;
  2862         ++index;
  2863       }
  2864       for (EdgeIt e(_graph); e != INVALID; ++e) {
  2865         int si = (*_node_index)[_graph.u(e)];
  2866         int ti = (*_node_index)[_graph.v(e)];
  2867         if (_graph.u(e) != _graph.v(e)) {
  2868           _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
  2869                             dualScale * _weight[e]) / 2);
  2870         }
  2871       }
  2872     }
  2873 
  2874     /// \brief Starts the algorithm
  2875     ///
  2876     /// Starts the algorithm
  2877     bool start() {
  2878       enum OpType {
  2879         D2, D3, D4
  2880       };
  2881 
  2882       int unmatched = _node_num;
  2883       while (unmatched > 0) {
  2884         Value d2 = !_delta2->empty() ?
  2885           _delta2->prio() : std::numeric_limits<Value>::max();
  2886 
  2887         Value d3 = !_delta3->empty() ?
  2888           _delta3->prio() : std::numeric_limits<Value>::max();
  2889 
  2890         Value d4 = !_delta4->empty() ?
  2891           _delta4->prio() : std::numeric_limits<Value>::max();
  2892 
  2893         _delta_sum = d2; OpType ot = D2;
  2894         if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
  2895         if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
  2896 
  2897         if (_delta_sum == std::numeric_limits<Value>::max()) {
  2898           return false;
  2899         }
  2900 
  2901         switch (ot) {
  2902         case D2:
  2903           {
  2904             int blossom = _delta2->top();
  2905             Node n = _blossom_set->classTop(blossom);
  2906             Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
  2907             extendOnArc(e);
  2908           }
  2909           break;
  2910         case D3:
  2911           {
  2912             Edge e = _delta3->top();
  2913 
  2914             int left_blossom = _blossom_set->find(_graph.u(e));
  2915             int right_blossom = _blossom_set->find(_graph.v(e));
  2916 
  2917             if (left_blossom == right_blossom) {
  2918               _delta3->pop();
  2919             } else {
  2920               int left_tree = _tree_set->find(left_blossom);
  2921               int right_tree = _tree_set->find(right_blossom);
  2922 
  2923               if (left_tree == right_tree) {
  2924                 shrinkOnEdge(e, left_tree);
  2925               } else {
  2926                 augmentOnEdge(e);
  2927                 unmatched -= 2;
  2928               }
  2929             }
  2930           } break;
  2931         case D4:
  2932           splitBlossom(_delta4->top());
  2933           break;
  2934         }
  2935       }
  2936       extractMatching();
  2937       return true;
  2938     }
  2939 
  2940     /// \brief Runs %MaxWeightedPerfectMatching algorithm.
  2941     ///
  2942     /// This method runs the %MaxWeightedPerfectMatching algorithm.
  2943     ///
  2944     /// \note mwm.run() is just a shortcut of the following code.
  2945     /// \code
  2946     ///   mwm.init();
  2947     ///   mwm.start();
  2948     /// \endcode
  2949     bool run() {
  2950       init();
  2951       return start();
  2952     }
  2953 
  2954     /// @}
  2955 
  2956     /// \name Primal solution
  2957     /// Functions to get the primal solution, ie. the matching.
  2958 
  2959     /// @{
  2960 
  2961     /// \brief Returns the matching value.
  2962     ///
  2963     /// Returns the matching value.
  2964     Value matchingValue() const {
  2965       Value sum = 0;
  2966       for (NodeIt n(_graph); n != INVALID; ++n) {
  2967         if ((*_matching)[n] != INVALID) {
  2968           sum += _weight[(*_matching)[n]];
  2969         }
  2970       }
  2971       return sum /= 2;
  2972     }
  2973 
  2974     /// \brief Returns true when the edge is in the matching.
  2975     ///
  2976     /// Returns true when the edge is in the matching.
  2977     bool matching(const Edge& edge) const {
  2978       return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
  2979     }
  2980 
  2981     /// \brief Returns the incident matching edge.
  2982     ///
  2983     /// Returns the incident matching arc from given edge.
  2984     Arc matching(const Node& node) const {
  2985       return (*_matching)[node];
  2986     }
  2987 
  2988     /// \brief Returns the mate of the node.
  2989     ///
  2990     /// Returns the adjancent node in a mathcing arc.
  2991     Node mate(const Node& node) const {
  2992       return _graph.target((*_matching)[node]);
  2993     }
  2994 
  2995     /// @}
  2996 
  2997     /// \name Dual solution
  2998     /// Functions to get the dual solution.
  2999 
  3000     /// @{
  3001 
  3002     /// \brief Returns the value of the dual solution.
  3003     ///
  3004     /// Returns the value of the dual solution. It should be equal to
  3005     /// the primal value scaled by \ref dualScale "dual scale".
  3006     Value dualValue() const {
  3007       Value sum = 0;
  3008       for (NodeIt n(_graph); n != INVALID; ++n) {
  3009         sum += nodeValue(n);
  3010       }
  3011       for (int i = 0; i < blossomNum(); ++i) {
  3012         sum += blossomValue(i) * (blossomSize(i) / 2);
  3013       }
  3014       return sum;
  3015     }
  3016 
  3017     /// \brief Returns the value of the node.
  3018     ///
  3019     /// Returns the the value of the node.
  3020     Value nodeValue(const Node& n) const {
  3021       return (*_node_potential)[n];
  3022     }
  3023 
  3024     /// \brief Returns the number of the blossoms in the basis.
  3025     ///
  3026     /// Returns the number of the blossoms in the basis.
  3027     /// \see BlossomIt
  3028     int blossomNum() const {
  3029       return _blossom_potential.size();
  3030     }
  3031 
  3032 
  3033     /// \brief Returns the number of the nodes in the blossom.
  3034     ///
  3035     /// Returns the number of the nodes in the blossom.
  3036     int blossomSize(int k) const {
  3037       return _blossom_potential[k].end - _blossom_potential[k].begin;
  3038     }
  3039 
  3040     /// \brief Returns the value of the blossom.
  3041     ///
  3042     /// Returns the the value of the blossom.
  3043     /// \see BlossomIt
  3044     Value blossomValue(int k) const {
  3045       return _blossom_potential[k].value;
  3046     }
  3047 
  3048     /// \brief Iterator for obtaining the nodes of the blossom.
  3049     ///
  3050     /// Iterator for obtaining the nodes of the blossom. This class
  3051     /// provides a common lemon style iterator for listing a
  3052     /// subset of the nodes.
  3053     class BlossomIt {
  3054     public:
  3055 
  3056       /// \brief Constructor.
  3057       ///
  3058       /// Constructor to get the nodes of the variable.
  3059       BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
  3060         : _algorithm(&algorithm)
  3061       {
  3062         _index = _algorithm->_blossom_potential[variable].begin;
  3063         _last = _algorithm->_blossom_potential[variable].end;
  3064       }
  3065 
  3066       /// \brief Conversion to node.
  3067       ///
  3068       /// Conversion to node.
  3069       operator Node() const {
  3070         return _algorithm->_blossom_node_list[_index];
  3071       }
  3072 
  3073       /// \brief Increment operator.
  3074       ///
  3075       /// Increment operator.
  3076       BlossomIt& operator++() {
  3077         ++_index;
  3078         return *this;
  3079       }
  3080 
  3081       /// \brief Validity checking
  3082       ///
  3083       /// Checks whether the iterator is invalid.
  3084       bool operator==(Invalid) const { return _index == _last; }
  3085 
  3086       /// \brief Validity checking
  3087       ///
  3088       /// Checks whether the iterator is valid.
  3089       bool operator!=(Invalid) const { return _index != _last; }
  3090 
  3091     private:
  3092       const MaxWeightedPerfectMatching* _algorithm;
  3093       int _last;
  3094       int _index;
  3095     };
  3096 
  3097     /// @}
  3098 
  3099   };
  3100 
  3101 
  3102 } //END OF NAMESPACE LEMON
  3103 
  3104 #endif //LEMON_MAX_MATCHING_H