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