lemon/matching.h
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 806 fa6f37d7a25b
parent 594 d657c71db7db
child 867 5b926cc36a4b
child 868 0513ccfea967
permissions -rw-r--r--
Entirely rework CapacityScaling (#180)

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