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