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