lemon/matching.h
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 982 bb70ad62c95f
parent 698 3adf5e2d1e62
child 954 07ec2b52e53d
child 1081 f1398882a928
permissions -rw-r--r--
Fix critical bug in preflow (#372)

The wrong transition between the bound decrease and highest active
heuristics caused the bug. The last node chosen in bound decrease mode
is used in the first iteration in highest active mode.
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@945
   808
deba@338
   809
      if (!_node_potential) {
deba@338
   810
        _node_potential = new NodePotential(_graph);
deba@338
   811
      }
deba@945
   812
deba@338
   813
      if (!_blossom_set) {
deba@339
   814
        _blossom_index = new IntNodeMap(_graph);
deba@338
   815
        _blossom_set = new BlossomSet(*_blossom_index);
deba@338
   816
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
deba@945
   817
      } else if (_blossom_data->size() != _blossom_num) {
deba@945
   818
        delete _blossom_data;
deba@945
   819
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
deba@338
   820
      }
deba@338
   821
deba@338
   822
      if (!_node_index) {
deba@339
   823
        _node_index = new IntNodeMap(_graph);
deba@339
   824
        _node_heap_index = new IntArcMap(_graph);
deba@338
   825
        _node_data = new RangeMap<NodeData>(_node_num,
deba@945
   826
                                            NodeData(*_node_heap_index));
deba@945
   827
      } else {
deba@945
   828
        delete _node_data;
deba@945
   829
        _node_data = new RangeMap<NodeData>(_node_num,
deba@945
   830
                                            NodeData(*_node_heap_index));
deba@338
   831
      }
deba@338
   832
deba@338
   833
      if (!_tree_set) {
deba@338
   834
        _tree_set_index = new IntIntMap(_blossom_num);
deba@338
   835
        _tree_set = new TreeSet(*_tree_set_index);
deba@945
   836
      } else {
deba@945
   837
        _tree_set_index->resize(_blossom_num);
deba@338
   838
      }
deba@945
   839
deba@338
   840
      if (!_delta1) {
deba@339
   841
        _delta1_index = new IntNodeMap(_graph);
deba@339
   842
        _delta1 = new BinHeap<Value, IntNodeMap>(*_delta1_index);
deba@338
   843
      }
deba@945
   844
deba@338
   845
      if (!_delta2) {
deba@338
   846
        _delta2_index = new IntIntMap(_blossom_num);
deba@338
   847
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
deba@945
   848
      } else {
deba@945
   849
        _delta2_index->resize(_blossom_num);
deba@338
   850
      }
deba@945
   851
deba@338
   852
      if (!_delta3) {
deba@339
   853
        _delta3_index = new IntEdgeMap(_graph);
deba@339
   854
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
deba@338
   855
      }
deba@945
   856
deba@338
   857
      if (!_delta4) {
deba@338
   858
        _delta4_index = new IntIntMap(_blossom_num);
deba@338
   859
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
deba@945
   860
      } else {
deba@945
   861
        _delta4_index->resize(_blossom_num);
deba@338
   862
      }
deba@338
   863
    }
deba@338
   864
deba@338
   865
    void destroyStructures() {
deba@338
   866
      _node_num = countNodes(_graph);
deba@338
   867
      _blossom_num = _node_num * 3 / 2;
deba@338
   868
deba@338
   869
      if (_matching) {
deba@338
   870
        delete _matching;
deba@338
   871
      }
deba@338
   872
      if (_node_potential) {
deba@338
   873
        delete _node_potential;
deba@338
   874
      }
deba@338
   875
      if (_blossom_set) {
deba@338
   876
        delete _blossom_index;
deba@338
   877
        delete _blossom_set;
deba@338
   878
        delete _blossom_data;
deba@338
   879
      }
deba@338
   880
deba@338
   881
      if (_node_index) {
deba@338
   882
        delete _node_index;
deba@338
   883
        delete _node_heap_index;
deba@338
   884
        delete _node_data;
deba@338
   885
      }
deba@338
   886
deba@338
   887
      if (_tree_set) {
deba@338
   888
        delete _tree_set_index;
deba@338
   889
        delete _tree_set;
deba@338
   890
      }
deba@338
   891
      if (_delta1) {
deba@338
   892
        delete _delta1_index;
deba@338
   893
        delete _delta1;
deba@338
   894
      }
deba@338
   895
      if (_delta2) {
deba@338
   896
        delete _delta2_index;
deba@338
   897
        delete _delta2;
deba@338
   898
      }
deba@338
   899
      if (_delta3) {
deba@338
   900
        delete _delta3_index;
deba@338
   901
        delete _delta3;
deba@338
   902
      }
deba@338
   903
      if (_delta4) {
deba@338
   904
        delete _delta4_index;
deba@338
   905
        delete _delta4;
deba@338
   906
      }
deba@338
   907
    }
deba@338
   908
deba@338
   909
    void matchedToEven(int blossom, int tree) {
deba@338
   910
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
deba@338
   911
        _delta2->erase(blossom);
deba@338
   912
      }
deba@338
   913
deba@338
   914
      if (!_blossom_set->trivial(blossom)) {
deba@338
   915
        (*_blossom_data)[blossom].pot -=
deba@338
   916
          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
deba@338
   917
      }
deba@338
   918
deba@338
   919
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
deba@338
   920
           n != INVALID; ++n) {
deba@338
   921
deba@338
   922
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
deba@338
   923
        int ni = (*_node_index)[n];
deba@338
   924
deba@338
   925
        (*_node_data)[ni].heap.clear();
deba@338
   926
        (*_node_data)[ni].heap_index.clear();
deba@338
   927
deba@338
   928
        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
deba@338
   929
deba@338
   930
        _delta1->push(n, (*_node_data)[ni].pot);
deba@338
   931
deba@338
   932
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
deba@338
   933
          Node v = _graph.source(e);
deba@338
   934
          int vb = _blossom_set->find(v);
deba@338
   935
          int vi = (*_node_index)[v];
deba@338
   936
deba@338
   937
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
deba@338
   938
            dualScale * _weight[e];
deba@338
   939
deba@338
   940
          if ((*_blossom_data)[vb].status == EVEN) {
deba@338
   941
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
deba@338
   942
              _delta3->push(e, rw / 2);
deba@338
   943
            }
deba@338
   944
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
deba@338
   945
            if (_delta3->state(e) != _delta3->IN_HEAP) {
deba@338
   946
              _delta3->push(e, rw);
deba@338
   947
            }
deba@338
   948
          } else {
deba@338
   949
            typename std::map<int, Arc>::iterator it =
deba@338
   950
              (*_node_data)[vi].heap_index.find(tree);
deba@338
   951
deba@338
   952
            if (it != (*_node_data)[vi].heap_index.end()) {
deba@338
   953
              if ((*_node_data)[vi].heap[it->second] > rw) {
deba@338
   954
                (*_node_data)[vi].heap.replace(it->second, e);
deba@338
   955
                (*_node_data)[vi].heap.decrease(e, rw);
deba@338
   956
                it->second = e;
deba@338
   957
              }
deba@338
   958
            } else {
deba@338
   959
              (*_node_data)[vi].heap.push(e, rw);
deba@338
   960
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
deba@338
   961
            }
deba@338
   962
deba@338
   963
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
deba@338
   964
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
deba@338
   965
deba@338
   966
              if ((*_blossom_data)[vb].status == MATCHED) {
deba@338
   967
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
deba@338
   968
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
deba@338
   969
                               (*_blossom_data)[vb].offset);
deba@338
   970
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
deba@338
   971
                           (*_blossom_data)[vb].offset){
deba@338
   972
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
deba@338
   973
                                   (*_blossom_data)[vb].offset);
deba@338
   974
                }
deba@338
   975
              }
deba@338
   976
            }
deba@338
   977
          }
deba@338
   978
        }
deba@338
   979
      }
deba@338
   980
      (*_blossom_data)[blossom].offset = 0;
deba@338
   981
    }
deba@338
   982
deba@338
   983
    void matchedToOdd(int blossom) {
deba@338
   984
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
deba@338
   985
        _delta2->erase(blossom);
deba@338
   986
      }
deba@338
   987
      (*_blossom_data)[blossom].offset += _delta_sum;
deba@338
   988
      if (!_blossom_set->trivial(blossom)) {
deba@338
   989
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
deba@338
   990
                     (*_blossom_data)[blossom].offset);
deba@338
   991
      }
deba@338
   992
    }
deba@338
   993
deba@338
   994
    void evenToMatched(int blossom, int tree) {
deba@338
   995
      if (!_blossom_set->trivial(blossom)) {
deba@338
   996
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
deba@338
   997
      }
deba@338
   998
deba@338
   999
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
deba@338
  1000
           n != INVALID; ++n) {
deba@338
  1001
        int ni = (*_node_index)[n];
deba@338
  1002
        (*_node_data)[ni].pot -= _delta_sum;
deba@338
  1003
deba@338
  1004
        _delta1->erase(n);
deba@338
  1005
deba@338
  1006
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
deba@338
  1007
          Node v = _graph.source(e);
deba@338
  1008
          int vb = _blossom_set->find(v);
deba@338
  1009
          int vi = (*_node_index)[v];
deba@338
  1010
deba@338
  1011
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
deba@338
  1012
            dualScale * _weight[e];
deba@338
  1013
deba@338
  1014
          if (vb == blossom) {
deba@338
  1015
            if (_delta3->state(e) == _delta3->IN_HEAP) {
deba@338
  1016
              _delta3->erase(e);
deba@338
  1017
            }
deba@338
  1018
          } else if ((*_blossom_data)[vb].status == EVEN) {
deba@338
  1019
deba@338
  1020
            if (_delta3->state(e) == _delta3->IN_HEAP) {
deba@338
  1021
              _delta3->erase(e);
deba@338
  1022
            }
deba@338
  1023
deba@338
  1024
            int vt = _tree_set->find(vb);
deba@338
  1025
deba@338
  1026
            if (vt != tree) {
deba@338
  1027
deba@338
  1028
              Arc r = _graph.oppositeArc(e);
deba@338
  1029
deba@338
  1030
              typename std::map<int, Arc>::iterator it =
deba@338
  1031
                (*_node_data)[ni].heap_index.find(vt);
deba@338
  1032
deba@338
  1033
              if (it != (*_node_data)[ni].heap_index.end()) {
deba@338
  1034
                if ((*_node_data)[ni].heap[it->second] > rw) {
deba@338
  1035
                  (*_node_data)[ni].heap.replace(it->second, r);
deba@338
  1036
                  (*_node_data)[ni].heap.decrease(r, rw);
deba@338
  1037
                  it->second = r;
deba@338
  1038
                }
deba@338
  1039
              } else {
deba@338
  1040
                (*_node_data)[ni].heap.push(r, rw);
deba@338
  1041
                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
deba@338
  1042
              }
deba@338
  1043
deba@338
  1044
              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
deba@338
  1045
                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
deba@338
  1046
deba@338
  1047
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
deba@338
  1048
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
deba@338
  1049
                               (*_blossom_data)[blossom].offset);
deba@338
  1050
                } else if ((*_delta2)[blossom] >
deba@338
  1051
                           _blossom_set->classPrio(blossom) -
deba@338
  1052
                           (*_blossom_data)[blossom].offset){
deba@338
  1053
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
deba@338
  1054
                                   (*_blossom_data)[blossom].offset);
deba@338
  1055
                }
deba@338
  1056
              }
deba@338
  1057
            }
deba@338
  1058
deba@338
  1059
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
deba@338
  1060
            if (_delta3->state(e) == _delta3->IN_HEAP) {
deba@338
  1061
              _delta3->erase(e);
deba@338
  1062
            }
deba@338
  1063
          } else {
deba@338
  1064
deba@338
  1065
            typename std::map<int, Arc>::iterator it =
deba@338
  1066
              (*_node_data)[vi].heap_index.find(tree);
deba@338
  1067
deba@338
  1068
            if (it != (*_node_data)[vi].heap_index.end()) {
deba@338
  1069
              (*_node_data)[vi].heap.erase(it->second);
deba@338
  1070
              (*_node_data)[vi].heap_index.erase(it);
deba@338
  1071
              if ((*_node_data)[vi].heap.empty()) {
deba@338
  1072
                _blossom_set->increase(v, std::numeric_limits<Value>::max());
deba@338
  1073
              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
deba@338
  1074
                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
deba@338
  1075
              }
deba@338
  1076
deba@338
  1077
              if ((*_blossom_data)[vb].status == MATCHED) {
deba@338
  1078
                if (_blossom_set->classPrio(vb) ==
deba@338
  1079
                    std::numeric_limits<Value>::max()) {
deba@338
  1080
                  _delta2->erase(vb);
deba@338
  1081
                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
deba@338
  1082
                           (*_blossom_data)[vb].offset) {
deba@338
  1083
                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
deba@338
  1084
                                   (*_blossom_data)[vb].offset);
deba@338
  1085
                }
deba@338
  1086
              }
deba@338
  1087
            }
deba@338
  1088
          }
deba@338
  1089
        }
deba@338
  1090
      }
deba@338
  1091
    }
deba@338
  1092
deba@338
  1093
    void oddToMatched(int blossom) {
deba@338
  1094
      (*_blossom_data)[blossom].offset -= _delta_sum;
deba@338
  1095
deba@338
  1096
      if (_blossom_set->classPrio(blossom) !=
deba@338
  1097
          std::numeric_limits<Value>::max()) {
deba@338
  1098
        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
deba@338
  1099
                       (*_blossom_data)[blossom].offset);
deba@338
  1100
      }
deba@338
  1101
deba@338
  1102
      if (!_blossom_set->trivial(blossom)) {
deba@338
  1103
        _delta4->erase(blossom);
deba@338
  1104
      }
deba@338
  1105
    }
deba@338
  1106
deba@338
  1107
    void oddToEven(int blossom, int tree) {
deba@338
  1108
      if (!_blossom_set->trivial(blossom)) {
deba@338
  1109
        _delta4->erase(blossom);
deba@338
  1110
        (*_blossom_data)[blossom].pot -=
deba@338
  1111
          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
deba@338
  1112
      }
deba@338
  1113
deba@338
  1114
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
deba@338
  1115
           n != INVALID; ++n) {
deba@338
  1116
        int ni = (*_node_index)[n];
deba@338
  1117
deba@338
  1118
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
deba@338
  1119
deba@338
  1120
        (*_node_data)[ni].heap.clear();
deba@338
  1121
        (*_node_data)[ni].heap_index.clear();
deba@338
  1122
        (*_node_data)[ni].pot +=
deba@338
  1123
          2 * _delta_sum - (*_blossom_data)[blossom].offset;
deba@338
  1124
deba@338
  1125
        _delta1->push(n, (*_node_data)[ni].pot);
deba@338
  1126
deba@338
  1127
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
deba@338
  1128
          Node v = _graph.source(e);
deba@338
  1129
          int vb = _blossom_set->find(v);
deba@338
  1130
          int vi = (*_node_index)[v];
deba@338
  1131
deba@338
  1132
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
deba@338
  1133
            dualScale * _weight[e];
deba@338
  1134
deba@338
  1135
          if ((*_blossom_data)[vb].status == EVEN) {
deba@338
  1136
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
deba@338
  1137
              _delta3->push(e, rw / 2);
deba@338
  1138
            }
deba@338
  1139
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
deba@338
  1140
            if (_delta3->state(e) != _delta3->IN_HEAP) {
deba@338
  1141
              _delta3->push(e, rw);
deba@338
  1142
            }
deba@338
  1143
          } else {
deba@338
  1144
deba@338
  1145
            typename std::map<int, Arc>::iterator it =
deba@338
  1146
              (*_node_data)[vi].heap_index.find(tree);
deba@338
  1147
deba@338
  1148
            if (it != (*_node_data)[vi].heap_index.end()) {
deba@338
  1149
              if ((*_node_data)[vi].heap[it->second] > rw) {
deba@338
  1150
                (*_node_data)[vi].heap.replace(it->second, e);
deba@338
  1151
                (*_node_data)[vi].heap.decrease(e, rw);
deba@338
  1152
                it->second = e;
deba@338
  1153
              }
deba@338
  1154
            } else {
deba@338
  1155
              (*_node_data)[vi].heap.push(e, rw);
deba@338
  1156
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
deba@338
  1157
            }
deba@338
  1158
deba@338
  1159
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
deba@338
  1160
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
deba@338
  1161
deba@338
  1162
              if ((*_blossom_data)[vb].status == MATCHED) {
deba@338
  1163
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
deba@338
  1164
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
deba@338
  1165
                               (*_blossom_data)[vb].offset);
deba@338
  1166
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
deba@338
  1167
                           (*_blossom_data)[vb].offset) {
deba@338
  1168
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
deba@338
  1169
                                   (*_blossom_data)[vb].offset);
deba@338
  1170
                }
deba@338
  1171
              }
deba@338
  1172
            }
deba@338
  1173
          }
deba@338
  1174
        }
deba@338
  1175
      }
deba@338
  1176
      (*_blossom_data)[blossom].offset = 0;
deba@338
  1177
    }
deba@338
  1178
deba@338
  1179
deba@338
  1180
    void matchedToUnmatched(int blossom) {
deba@338
  1181
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
deba@338
  1182
        _delta2->erase(blossom);
deba@338
  1183
      }
deba@338
  1184
deba@338
  1185
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
deba@338
  1186
           n != INVALID; ++n) {
deba@338
  1187
        int ni = (*_node_index)[n];
deba@338
  1188
deba@338
  1189
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
deba@338
  1190
deba@338
  1191
        (*_node_data)[ni].heap.clear();
deba@338
  1192
        (*_node_data)[ni].heap_index.clear();
deba@338
  1193
deba@338
  1194
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
deba@338
  1195
          Node v = _graph.target(e);
deba@338
  1196
          int vb = _blossom_set->find(v);
deba@338
  1197
          int vi = (*_node_index)[v];
deba@338
  1198
deba@338
  1199
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
deba@338
  1200
            dualScale * _weight[e];
deba@338
  1201
deba@338
  1202
          if ((*_blossom_data)[vb].status == EVEN) {
deba@338
  1203
            if (_delta3->state(e) != _delta3->IN_HEAP) {
deba@338
  1204
              _delta3->push(e, rw);
deba@338
  1205
            }
deba@338
  1206
          }
deba@338
  1207
        }
deba@338
  1208
      }
deba@338
  1209
    }
deba@338
  1210
deba@338
  1211
    void unmatchedToMatched(int blossom) {
deba@338
  1212
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
deba@338
  1213
           n != INVALID; ++n) {
deba@338
  1214
        int ni = (*_node_index)[n];
deba@338
  1215
deba@338
  1216
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
deba@338
  1217
          Node v = _graph.source(e);
deba@338
  1218
          int vb = _blossom_set->find(v);
deba@338
  1219
          int vi = (*_node_index)[v];
deba@338
  1220
deba@338
  1221
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
deba@338
  1222
            dualScale * _weight[e];
deba@338
  1223
deba@338
  1224
          if (vb == blossom) {
deba@338
  1225
            if (_delta3->state(e) == _delta3->IN_HEAP) {
deba@338
  1226
              _delta3->erase(e);
deba@338
  1227
            }
deba@338
  1228
          } else if ((*_blossom_data)[vb].status == EVEN) {
deba@338
  1229
deba@338
  1230
            if (_delta3->state(e) == _delta3->IN_HEAP) {
deba@338
  1231
              _delta3->erase(e);
deba@338
  1232
            }
deba@338
  1233
deba@338
  1234
            int vt = _tree_set->find(vb);
deba@338
  1235
deba@338
  1236
            Arc r = _graph.oppositeArc(e);
deba@338
  1237
deba@338
  1238
            typename std::map<int, Arc>::iterator it =
deba@338
  1239
              (*_node_data)[ni].heap_index.find(vt);
deba@338
  1240
deba@338
  1241
            if (it != (*_node_data)[ni].heap_index.end()) {
deba@338
  1242
              if ((*_node_data)[ni].heap[it->second] > rw) {
deba@338
  1243
                (*_node_data)[ni].heap.replace(it->second, r);
deba@338
  1244
                (*_node_data)[ni].heap.decrease(r, rw);
deba@338
  1245
                it->second = r;
deba@338
  1246
              }
deba@338
  1247
            } else {
deba@338
  1248
              (*_node_data)[ni].heap.push(r, rw);
deba@338
  1249
              (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
deba@338
  1250
            }
deba@338
  1251
deba@338
  1252
            if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
deba@338
  1253
              _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
deba@338
  1254
deba@338
  1255
              if (_delta2->state(blossom) != _delta2->IN_HEAP) {
deba@338
  1256
                _delta2->push(blossom, _blossom_set->classPrio(blossom) -
deba@338
  1257
                             (*_blossom_data)[blossom].offset);
deba@338
  1258
              } else if ((*_delta2)[blossom] > _blossom_set->classPrio(blossom)-
deba@338
  1259
                         (*_blossom_data)[blossom].offset){
deba@338
  1260
                _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
deba@338
  1261
                                 (*_blossom_data)[blossom].offset);
deba@338
  1262
              }
deba@338
  1263
            }
deba@338
  1264
deba@338
  1265
          } else if ((*_blossom_data)[vb].status == UNMATCHED) {
deba@338
  1266
            if (_delta3->state(e) == _delta3->IN_HEAP) {
deba@338
  1267
              _delta3->erase(e);
deba@338
  1268
            }
deba@338
  1269
          }
deba@338
  1270
        }
deba@338
  1271
      }
deba@338
  1272
    }
deba@338
  1273
deba@338
  1274
    void alternatePath(int even, int tree) {
deba@338
  1275
      int odd;
deba@338
  1276
deba@338
  1277
      evenToMatched(even, tree);
deba@338
  1278
      (*_blossom_data)[even].status = MATCHED;
deba@338
  1279
deba@338
  1280
      while ((*_blossom_data)[even].pred != INVALID) {
deba@338
  1281
        odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
deba@338
  1282
        (*_blossom_data)[odd].status = MATCHED;
deba@338
  1283
        oddToMatched(odd);
deba@338
  1284
        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
deba@338
  1285
deba@338
  1286
        even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
deba@338
  1287
        (*_blossom_data)[even].status = MATCHED;
deba@338
  1288
        evenToMatched(even, tree);
deba@338
  1289
        (*_blossom_data)[even].next =
deba@338
  1290
          _graph.oppositeArc((*_blossom_data)[odd].pred);
deba@338
  1291
      }
deba@338
  1292
deba@338
  1293
    }
deba@338
  1294
deba@338
  1295
    void destroyTree(int tree) {
deba@338
  1296
      for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
deba@338
  1297
        if ((*_blossom_data)[b].status == EVEN) {
deba@338
  1298
          (*_blossom_data)[b].status = MATCHED;
deba@338
  1299
          evenToMatched(b, tree);
deba@338
  1300
        } else if ((*_blossom_data)[b].status == ODD) {
deba@338
  1301
          (*_blossom_data)[b].status = MATCHED;
deba@338
  1302
          oddToMatched(b);
deba@338
  1303
        }
deba@338
  1304
      }
deba@338
  1305
      _tree_set->eraseClass(tree);
deba@338
  1306
    }
deba@338
  1307
deba@338
  1308
deba@338
  1309
    void unmatchNode(const Node& node) {
deba@338
  1310
      int blossom = _blossom_set->find(node);
deba@338
  1311
      int tree = _tree_set->find(blossom);
deba@338
  1312
deba@338
  1313
      alternatePath(blossom, tree);
deba@338
  1314
      destroyTree(tree);
deba@338
  1315
deba@338
  1316
      (*_blossom_data)[blossom].status = UNMATCHED;
deba@338
  1317
      (*_blossom_data)[blossom].base = node;
deba@338
  1318
      matchedToUnmatched(blossom);
deba@338
  1319
    }
deba@338
  1320
deba@338
  1321
deba@339
  1322
    void augmentOnEdge(const Edge& edge) {
deba@339
  1323
deba@339
  1324
      int left = _blossom_set->find(_graph.u(edge));
deba@339
  1325
      int right = _blossom_set->find(_graph.v(edge));
deba@338
  1326
deba@338
  1327
      if ((*_blossom_data)[left].status == EVEN) {
deba@338
  1328
        int left_tree = _tree_set->find(left);
deba@338
  1329
        alternatePath(left, left_tree);
deba@338
  1330
        destroyTree(left_tree);
deba@338
  1331
      } else {
deba@338
  1332
        (*_blossom_data)[left].status = MATCHED;
deba@338
  1333
        unmatchedToMatched(left);
deba@338
  1334
      }
deba@338
  1335
deba@338
  1336
      if ((*_blossom_data)[right].status == EVEN) {
deba@338
  1337
        int right_tree = _tree_set->find(right);
deba@338
  1338
        alternatePath(right, right_tree);
deba@338
  1339
        destroyTree(right_tree);
deba@338
  1340
      } else {
deba@338
  1341
        (*_blossom_data)[right].status = MATCHED;
deba@338
  1342
        unmatchedToMatched(right);
deba@338
  1343
      }
deba@338
  1344
deba@339
  1345
      (*_blossom_data)[left].next = _graph.direct(edge, true);
deba@339
  1346
      (*_blossom_data)[right].next = _graph.direct(edge, false);
deba@338
  1347
    }
deba@338
  1348
deba@338
  1349
    void extendOnArc(const Arc& arc) {
deba@338
  1350
      int base = _blossom_set->find(_graph.target(arc));
deba@338
  1351
      int tree = _tree_set->find(base);
deba@338
  1352
deba@338
  1353
      int odd = _blossom_set->find(_graph.source(arc));
deba@338
  1354
      _tree_set->insert(odd, tree);
deba@338
  1355
      (*_blossom_data)[odd].status = ODD;
deba@338
  1356
      matchedToOdd(odd);
deba@338
  1357
      (*_blossom_data)[odd].pred = arc;
deba@338
  1358
deba@338
  1359
      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
deba@338
  1360
      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
deba@338
  1361
      _tree_set->insert(even, tree);
deba@338
  1362
      (*_blossom_data)[even].status = EVEN;
deba@338
  1363
      matchedToEven(even, tree);
deba@338
  1364
    }
deba@338
  1365
deba@339
  1366
    void shrinkOnEdge(const Edge& edge, int tree) {
deba@338
  1367
      int nca = -1;
deba@338
  1368
      std::vector<int> left_path, right_path;
deba@338
  1369
deba@338
  1370
      {
deba@338
  1371
        std::set<int> left_set, right_set;
deba@338
  1372
        int left = _blossom_set->find(_graph.u(edge));
deba@338
  1373
        left_path.push_back(left);
deba@338
  1374
        left_set.insert(left);
deba@338
  1375
deba@338
  1376
        int right = _blossom_set->find(_graph.v(edge));
deba@338
  1377
        right_path.push_back(right);
deba@338
  1378
        right_set.insert(right);
deba@338
  1379
deba@338
  1380
        while (true) {
deba@338
  1381
deba@338
  1382
          if ((*_blossom_data)[left].pred == INVALID) break;
deba@338
  1383
deba@338
  1384
          left =
deba@338
  1385
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
deba@338
  1386
          left_path.push_back(left);
deba@338
  1387
          left =
deba@338
  1388
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
deba@338
  1389
          left_path.push_back(left);
deba@338
  1390
deba@338
  1391
          left_set.insert(left);
deba@338
  1392
deba@338
  1393
          if (right_set.find(left) != right_set.end()) {
deba@338
  1394
            nca = left;
deba@338
  1395
            break;
deba@338
  1396
          }
deba@338
  1397
deba@338
  1398
          if ((*_blossom_data)[right].pred == INVALID) break;
deba@338
  1399
deba@338
  1400
          right =
deba@338
  1401
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
deba@338
  1402
          right_path.push_back(right);
deba@338
  1403
          right =
deba@338
  1404
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
deba@338
  1405
          right_path.push_back(right);
deba@338
  1406
deba@338
  1407
          right_set.insert(right);
deba@338
  1408
deba@338
  1409
          if (left_set.find(right) != left_set.end()) {
deba@338
  1410
            nca = right;
deba@338
  1411
            break;
deba@338
  1412
          }
deba@338
  1413
deba@338
  1414
        }
deba@338
  1415
deba@338
  1416
        if (nca == -1) {
deba@338
  1417
          if ((*_blossom_data)[left].pred == INVALID) {
deba@338
  1418
            nca = right;
deba@338
  1419
            while (left_set.find(nca) == left_set.end()) {
deba@338
  1420
              nca =
deba@338
  1421
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
deba@338
  1422
              right_path.push_back(nca);
deba@338
  1423
              nca =
deba@338
  1424
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
deba@338
  1425
              right_path.push_back(nca);
deba@338
  1426
            }
deba@338
  1427
          } else {
deba@338
  1428
            nca = left;
deba@338
  1429
            while (right_set.find(nca) == right_set.end()) {
deba@338
  1430
              nca =
deba@338
  1431
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
deba@338
  1432
              left_path.push_back(nca);
deba@338
  1433
              nca =
deba@338
  1434
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
deba@338
  1435
              left_path.push_back(nca);
deba@338
  1436
            }
deba@338
  1437
          }
deba@338
  1438
        }
deba@338
  1439
      }
deba@338
  1440
deba@338
  1441
      std::vector<int> subblossoms;
deba@338
  1442
      Arc prev;
deba@338
  1443
deba@338
  1444
      prev = _graph.direct(edge, true);
deba@338
  1445
      for (int i = 0; left_path[i] != nca; i += 2) {
deba@338
  1446
        subblossoms.push_back(left_path[i]);
deba@338
  1447
        (*_blossom_data)[left_path[i]].next = prev;
deba@338
  1448
        _tree_set->erase(left_path[i]);
deba@338
  1449
deba@338
  1450
        subblossoms.push_back(left_path[i + 1]);
deba@338
  1451
        (*_blossom_data)[left_path[i + 1]].status = EVEN;
deba@338
  1452
        oddToEven(left_path[i + 1], tree);
deba@338
  1453
        _tree_set->erase(left_path[i + 1]);
deba@338
  1454
        prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
deba@338
  1455
      }
deba@338
  1456
deba@338
  1457
      int k = 0;
deba@338
  1458
      while (right_path[k] != nca) ++k;
deba@338
  1459
deba@338
  1460
      subblossoms.push_back(nca);
deba@338
  1461
      (*_blossom_data)[nca].next = prev;
deba@338
  1462
deba@338
  1463
      for (int i = k - 2; i >= 0; i -= 2) {
deba@338
  1464
        subblossoms.push_back(right_path[i + 1]);
deba@338
  1465
        (*_blossom_data)[right_path[i + 1]].status = EVEN;
deba@338
  1466
        oddToEven(right_path[i + 1], tree);
deba@338
  1467
        _tree_set->erase(right_path[i + 1]);
deba@338
  1468
deba@338
  1469
        (*_blossom_data)[right_path[i + 1]].next =
deba@338
  1470
          (*_blossom_data)[right_path[i + 1]].pred;
deba@338
  1471
deba@338
  1472
        subblossoms.push_back(right_path[i]);
deba@338
  1473
        _tree_set->erase(right_path[i]);
deba@338
  1474
      }
deba@338
  1475
deba@338
  1476
      int surface =
deba@338
  1477
        _blossom_set->join(subblossoms.begin(), subblossoms.end());
deba@338
  1478
deba@338
  1479
      for (int i = 0; i < int(subblossoms.size()); ++i) {
deba@338
  1480
        if (!_blossom_set->trivial(subblossoms[i])) {
deba@338
  1481
          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
deba@338
  1482
        }
deba@338
  1483
        (*_blossom_data)[subblossoms[i]].status = MATCHED;
deba@338
  1484
      }
deba@338
  1485
deba@338
  1486
      (*_blossom_data)[surface].pot = -2 * _delta_sum;
deba@338
  1487
      (*_blossom_data)[surface].offset = 0;
deba@338
  1488
      (*_blossom_data)[surface].status = EVEN;
deba@338
  1489
      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
deba@338
  1490
      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
deba@338
  1491
deba@338
  1492
      _tree_set->insert(surface, tree);
deba@338
  1493
      _tree_set->erase(nca);
deba@338
  1494
    }
deba@338
  1495
deba@338
  1496
    void splitBlossom(int blossom) {
deba@338
  1497
      Arc next = (*_blossom_data)[blossom].next;
deba@338
  1498
      Arc pred = (*_blossom_data)[blossom].pred;
deba@338
  1499
deba@338
  1500
      int tree = _tree_set->find(blossom);
deba@338
  1501
deba@338
  1502
      (*_blossom_data)[blossom].status = MATCHED;
deba@338
  1503
      oddToMatched(blossom);
deba@338
  1504
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
deba@338
  1505
        _delta2->erase(blossom);
deba@338
  1506
      }
deba@338
  1507
deba@338
  1508
      std::vector<int> subblossoms;
deba@338
  1509
      _blossom_set->split(blossom, std::back_inserter(subblossoms));
deba@338
  1510
deba@338
  1511
      Value offset = (*_blossom_data)[blossom].offset;
deba@338
  1512
      int b = _blossom_set->find(_graph.source(pred));
deba@338
  1513
      int d = _blossom_set->find(_graph.source(next));
deba@338
  1514
deba@338
  1515
      int ib = -1, id = -1;
deba@338
  1516
      for (int i = 0; i < int(subblossoms.size()); ++i) {
deba@338
  1517
        if (subblossoms[i] == b) ib = i;
deba@338
  1518
        if (subblossoms[i] == d) id = i;
deba@338
  1519
deba@338
  1520
        (*_blossom_data)[subblossoms[i]].offset = offset;
deba@338
  1521
        if (!_blossom_set->trivial(subblossoms[i])) {
deba@338
  1522
          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
deba@338
  1523
        }
deba@338
  1524
        if (_blossom_set->classPrio(subblossoms[i]) !=
deba@338
  1525
            std::numeric_limits<Value>::max()) {
deba@338
  1526
          _delta2->push(subblossoms[i],
deba@338
  1527
                        _blossom_set->classPrio(subblossoms[i]) -
deba@338
  1528
                        (*_blossom_data)[subblossoms[i]].offset);
deba@338
  1529
        }
deba@338
  1530
      }
deba@338
  1531
deba@338
  1532
      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
deba@338
  1533
        for (int i = (id + 1) % subblossoms.size();
deba@338
  1534
             i != ib; i = (i + 2) % subblossoms.size()) {
deba@338
  1535
          int sb = subblossoms[i];
deba@338
  1536
          int tb = subblossoms[(i + 1) % subblossoms.size()];
deba@338
  1537
          (*_blossom_data)[sb].next =
deba@338
  1538
            _graph.oppositeArc((*_blossom_data)[tb].next);
deba@338
  1539
        }
deba@338
  1540
deba@338
  1541
        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
deba@338
  1542
          int sb = subblossoms[i];
deba@338
  1543
          int tb = subblossoms[(i + 1) % subblossoms.size()];
deba@338
  1544
          int ub = subblossoms[(i + 2) % subblossoms.size()];
deba@338
  1545
deba@338
  1546
          (*_blossom_data)[sb].status = ODD;
deba@338
  1547
          matchedToOdd(sb);
deba@338
  1548
          _tree_set->insert(sb, tree);
deba@338
  1549
          (*_blossom_data)[sb].pred = pred;
deba@338
  1550
          (*_blossom_data)[sb].next =
deba@338
  1551
                           _graph.oppositeArc((*_blossom_data)[tb].next);
deba@338
  1552
deba@338
  1553
          pred = (*_blossom_data)[ub].next;
deba@338
  1554
deba@338
  1555
          (*_blossom_data)[tb].status = EVEN;
deba@338
  1556
          matchedToEven(tb, tree);
deba@338
  1557
          _tree_set->insert(tb, tree);
deba@338
  1558
          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
deba@338
  1559
        }
deba@338
  1560
deba@338
  1561
        (*_blossom_data)[subblossoms[id]].status = ODD;
deba@338
  1562
        matchedToOdd(subblossoms[id]);
deba@338
  1563
        _tree_set->insert(subblossoms[id], tree);
deba@338
  1564
        (*_blossom_data)[subblossoms[id]].next = next;
deba@338
  1565
        (*_blossom_data)[subblossoms[id]].pred = pred;
deba@338
  1566
deba@338
  1567
      } else {
deba@338
  1568
deba@338
  1569
        for (int i = (ib + 1) % subblossoms.size();
deba@338
  1570
             i != id; i = (i + 2) % subblossoms.size()) {
deba@338
  1571
          int sb = subblossoms[i];
deba@338
  1572
          int tb = subblossoms[(i + 1) % subblossoms.size()];
deba@338
  1573
          (*_blossom_data)[sb].next =
deba@338
  1574
            _graph.oppositeArc((*_blossom_data)[tb].next);
deba@338
  1575
        }
deba@338
  1576
deba@338
  1577
        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
deba@338
  1578
          int sb = subblossoms[i];
deba@338
  1579
          int tb = subblossoms[(i + 1) % subblossoms.size()];
deba@338
  1580
          int ub = subblossoms[(i + 2) % subblossoms.size()];
deba@338
  1581
deba@338
  1582
          (*_blossom_data)[sb].status = ODD;
deba@338
  1583
          matchedToOdd(sb);
deba@338
  1584
          _tree_set->insert(sb, tree);
deba@338
  1585
          (*_blossom_data)[sb].next = next;
deba@338
  1586
          (*_blossom_data)[sb].pred =
deba@338
  1587
            _graph.oppositeArc((*_blossom_data)[tb].next);
deba@338
  1588
deba@338
  1589
          (*_blossom_data)[tb].status = EVEN;
deba@338
  1590
          matchedToEven(tb, tree);
deba@338
  1591
          _tree_set->insert(tb, tree);
deba@338
  1592
          (*_blossom_data)[tb].pred =
deba@338
  1593
            (*_blossom_data)[tb].next =
deba@338
  1594
            _graph.oppositeArc((*_blossom_data)[ub].next);
deba@338
  1595
          next = (*_blossom_data)[ub].next;
deba@338
  1596
        }
deba@338
  1597
deba@338
  1598
        (*_blossom_data)[subblossoms[ib]].status = ODD;
deba@338
  1599
        matchedToOdd(subblossoms[ib]);
deba@338
  1600
        _tree_set->insert(subblossoms[ib], tree);
deba@338
  1601
        (*_blossom_data)[subblossoms[ib]].next = next;
deba@338
  1602
        (*_blossom_data)[subblossoms[ib]].pred = pred;
deba@338
  1603
      }
deba@338
  1604
      _tree_set->erase(blossom);
deba@338
  1605
    }
deba@338
  1606
deba@338
  1607
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
deba@338
  1608
      if (_blossom_set->trivial(blossom)) {
deba@338
  1609
        int bi = (*_node_index)[base];
deba@338
  1610
        Value pot = (*_node_data)[bi].pot;
deba@338
  1611
kpeter@628
  1612
        (*_matching)[base] = matching;
deba@338
  1613
        _blossom_node_list.push_back(base);
kpeter@628
  1614
        (*_node_potential)[base] = pot;
deba@338
  1615
      } else {
deba@338
  1616
deba@338
  1617
        Value pot = (*_blossom_data)[blossom].pot;
deba@338
  1618
        int bn = _blossom_node_list.size();
deba@338
  1619
deba@338
  1620
        std::vector<int> subblossoms;
deba@338
  1621
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
deba@338
  1622
        int b = _blossom_set->find(base);
deba@338
  1623
        int ib = -1;
deba@338
  1624
        for (int i = 0; i < int(subblossoms.size()); ++i) {
deba@338
  1625
          if (subblossoms[i] == b) { ib = i; break; }
deba@338
  1626
        }
deba@338
  1627
deba@338
  1628
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
deba@338
  1629
          int sb = subblossoms[(ib + i) % subblossoms.size()];
deba@338
  1630
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
deba@338
  1631
deba@338
  1632
          Arc m = (*_blossom_data)[tb].next;
deba@338
  1633
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
deba@338
  1634
          extractBlossom(tb, _graph.source(m), m);
deba@338
  1635
        }
deba@338
  1636
        extractBlossom(subblossoms[ib], base, matching);
deba@338
  1637
deba@338
  1638
        int en = _blossom_node_list.size();
deba@338
  1639
deba@338
  1640
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
deba@338
  1641
      }
deba@338
  1642
    }
deba@338
  1643
deba@338
  1644
    void extractMatching() {
deba@338
  1645
      std::vector<int> blossoms;
deba@338
  1646
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
deba@338
  1647
        blossoms.push_back(c);
deba@338
  1648
      }
deba@338
  1649
deba@338
  1650
      for (int i = 0; i < int(blossoms.size()); ++i) {
deba@338
  1651
        if ((*_blossom_data)[blossoms[i]].status == MATCHED) {
deba@338
  1652
deba@338
  1653
          Value offset = (*_blossom_data)[blossoms[i]].offset;
deba@338
  1654
          (*_blossom_data)[blossoms[i]].pot += 2 * offset;
deba@338
  1655
          for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
deba@338
  1656
               n != INVALID; ++n) {
deba@338
  1657
            (*_node_data)[(*_node_index)[n]].pot -= offset;
deba@338
  1658
          }
deba@338
  1659
deba@338
  1660
          Arc matching = (*_blossom_data)[blossoms[i]].next;
deba@338
  1661
          Node base = _graph.source(matching);
deba@338
  1662
          extractBlossom(blossoms[i], base, matching);
deba@338
  1663
        } else {
deba@338
  1664
          Node base = (*_blossom_data)[blossoms[i]].base;
deba@338
  1665
          extractBlossom(blossoms[i], base, INVALID);
deba@338
  1666
        }
deba@338
  1667
      }
deba@338
  1668
    }
deba@338
  1669
deba@338
  1670
  public:
deba@338
  1671
deba@338
  1672
    /// \brief Constructor
deba@338
  1673
    ///
deba@338
  1674
    /// Constructor.
deba@338
  1675
    MaxWeightedMatching(const Graph& graph, const WeightMap& weight)
deba@338
  1676
      : _graph(graph), _weight(weight), _matching(0),
deba@338
  1677
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
deba@338
  1678
        _node_num(0), _blossom_num(0),
deba@338
  1679
deba@338
  1680
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
deba@338
  1681
        _node_index(0), _node_heap_index(0), _node_data(0),
deba@338
  1682
        _tree_set_index(0), _tree_set(0),
deba@338
  1683
deba@338
  1684
        _delta1_index(0), _delta1(0),
deba@338
  1685
        _delta2_index(0), _delta2(0),
deba@338
  1686
        _delta3_index(0), _delta3(0),
deba@338
  1687
        _delta4_index(0), _delta4(0),
deba@338
  1688
deba@338
  1689
        _delta_sum() {}
deba@338
  1690
deba@338
  1691
    ~MaxWeightedMatching() {
deba@338
  1692
      destroyStructures();
deba@338
  1693
    }
deba@338
  1694
kpeter@637
  1695
    /// \name Execution Control
alpar@342
  1696
    /// The simplest way to execute the algorithm is to use the
kpeter@637
  1697
    /// \ref run() member function.
deba@338
  1698
deba@338
  1699
    ///@{
deba@338
  1700
deba@338
  1701
    /// \brief Initialize the algorithm
deba@338
  1702
    ///
kpeter@637
  1703
    /// This function initializes the algorithm.
deba@338
  1704
    void init() {
deba@338
  1705
      createStructures();
deba@338
  1706
deba@945
  1707
      _blossom_node_list.clear();
deba@945
  1708
      _blossom_potential.clear();
deba@945
  1709
deba@338
  1710
      for (ArcIt e(_graph); e != INVALID; ++e) {
kpeter@628
  1711
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
deba@338
  1712
      }
deba@338
  1713
      for (NodeIt n(_graph); n != INVALID; ++n) {
kpeter@628
  1714
        (*_delta1_index)[n] = _delta1->PRE_HEAP;
deba@338
  1715
      }
deba@338
  1716
      for (EdgeIt e(_graph); e != INVALID; ++e) {
kpeter@628
  1717
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
deba@338
  1718
      }
deba@338
  1719
      for (int i = 0; i < _blossom_num; ++i) {
kpeter@628
  1720
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
kpeter@628
  1721
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
deba@338
  1722
      }
deba@945
  1723
      
deba@945
  1724
      _delta1->clear();
deba@945
  1725
      _delta2->clear();
deba@945
  1726
      _delta3->clear();
deba@945
  1727
      _delta4->clear();
deba@945
  1728
      _blossom_set->clear();
deba@945
  1729
      _tree_set->clear();
deba@338
  1730
deba@338
  1731
      int index = 0;
deba@338
  1732
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@338
  1733
        Value max = 0;
deba@338
  1734
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
deba@338
  1735
          if (_graph.target(e) == n) continue;
deba@338
  1736
          if ((dualScale * _weight[e]) / 2 > max) {
deba@338
  1737
            max = (dualScale * _weight[e]) / 2;
deba@338
  1738
          }
deba@338
  1739
        }
kpeter@628
  1740
        (*_node_index)[n] = index;
deba@945
  1741
        (*_node_data)[index].heap_index.clear();
deba@945
  1742
        (*_node_data)[index].heap.clear();
deba@338
  1743
        (*_node_data)[index].pot = max;
deba@338
  1744
        _delta1->push(n, max);
deba@338
  1745
        int blossom =
deba@338
  1746
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
deba@338
  1747
deba@338
  1748
        _tree_set->insert(blossom);
deba@338
  1749
deba@338
  1750
        (*_blossom_data)[blossom].status = EVEN;
deba@338
  1751
        (*_blossom_data)[blossom].pred = INVALID;
deba@338
  1752
        (*_blossom_data)[blossom].next = INVALID;
deba@338
  1753
        (*_blossom_data)[blossom].pot = 0;
deba@338
  1754
        (*_blossom_data)[blossom].offset = 0;
deba@338
  1755
        ++index;
deba@338
  1756
      }
deba@338
  1757
      for (EdgeIt e(_graph); e != INVALID; ++e) {
deba@338
  1758
        int si = (*_node_index)[_graph.u(e)];
deba@338
  1759
        int ti = (*_node_index)[_graph.v(e)];
deba@338
  1760
        if (_graph.u(e) != _graph.v(e)) {
deba@338
  1761
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
deba@338
  1762
                            dualScale * _weight[e]) / 2);
deba@338
  1763
        }
deba@338
  1764
      }
deba@338
  1765
    }
deba@338
  1766
kpeter@637
  1767
    /// \brief Start the algorithm
deba@338
  1768
    ///
kpeter@637
  1769
    /// This function starts the algorithm.
kpeter@637
  1770
    ///
kpeter@637
  1771
    /// \pre \ref init() must be called before using this function.
deba@338
  1772
    void start() {
deba@338
  1773
      enum OpType {
deba@338
  1774
        D1, D2, D3, D4
deba@338
  1775
      };
deba@338
  1776
deba@338
  1777
      int unmatched = _node_num;
deba@338
  1778
      while (unmatched > 0) {
deba@338
  1779
        Value d1 = !_delta1->empty() ?
deba@338
  1780
          _delta1->prio() : std::numeric_limits<Value>::max();
deba@338
  1781
deba@338
  1782
        Value d2 = !_delta2->empty() ?
deba@338
  1783
          _delta2->prio() : std::numeric_limits<Value>::max();
deba@338
  1784
deba@338
  1785
        Value d3 = !_delta3->empty() ?
deba@338
  1786
          _delta3->prio() : std::numeric_limits<Value>::max();
deba@338
  1787
deba@338
  1788
        Value d4 = !_delta4->empty() ?
deba@338
  1789
          _delta4->prio() : std::numeric_limits<Value>::max();
deba@338
  1790
deba@338
  1791
        _delta_sum = d1; OpType ot = D1;
deba@338
  1792
        if (d2 < _delta_sum) { _delta_sum = d2; ot = D2; }
deba@338
  1793
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
deba@338
  1794
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
deba@338
  1795
deba@338
  1796
deba@338
  1797
        switch (ot) {
deba@338
  1798
        case D1:
deba@338
  1799
          {
deba@338
  1800
            Node n = _delta1->top();
deba@338
  1801
            unmatchNode(n);
deba@338
  1802
            --unmatched;
deba@338
  1803
          }
deba@338
  1804
          break;
deba@338
  1805
        case D2:
deba@338
  1806
          {
deba@338
  1807
            int blossom = _delta2->top();
deba@338
  1808
            Node n = _blossom_set->classTop(blossom);
deba@338
  1809
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
deba@338
  1810
            extendOnArc(e);
deba@338
  1811
          }
deba@338
  1812
          break;
deba@338
  1813
        case D3:
deba@338
  1814
          {
deba@338
  1815
            Edge e = _delta3->top();
deba@338
  1816
deba@338
  1817
            int left_blossom = _blossom_set->find(_graph.u(e));
deba@338
  1818
            int right_blossom = _blossom_set->find(_graph.v(e));
deba@338
  1819
deba@338
  1820
            if (left_blossom == right_blossom) {
deba@338
  1821
              _delta3->pop();
deba@338
  1822
            } else {
deba@338
  1823
              int left_tree;
deba@338
  1824
              if ((*_blossom_data)[left_blossom].status == EVEN) {
deba@338
  1825
                left_tree = _tree_set->find(left_blossom);
deba@338
  1826
              } else {
deba@338
  1827
                left_tree = -1;
deba@338
  1828
                ++unmatched;
deba@338
  1829
              }
deba@338
  1830
              int right_tree;
deba@338
  1831
              if ((*_blossom_data)[right_blossom].status == EVEN) {
deba@338
  1832
                right_tree = _tree_set->find(right_blossom);
deba@338
  1833
              } else {
deba@338
  1834
                right_tree = -1;
deba@338
  1835
                ++unmatched;
deba@338
  1836
              }
deba@338
  1837
deba@338
  1838
              if (left_tree == right_tree) {
deba@339
  1839
                shrinkOnEdge(e, left_tree);
deba@338
  1840
              } else {
deba@339
  1841
                augmentOnEdge(e);
deba@338
  1842
                unmatched -= 2;
deba@338
  1843
              }
deba@338
  1844
            }
deba@338
  1845
          } break;
deba@338
  1846
        case D4:
deba@338
  1847
          splitBlossom(_delta4->top());
deba@338
  1848
          break;
deba@338
  1849
        }
deba@338
  1850
      }
deba@338
  1851
      extractMatching();
deba@338
  1852
    }
deba@338
  1853
kpeter@637
  1854
    /// \brief Run the algorithm.
deba@338
  1855
    ///
kpeter@637
  1856
    /// This method runs the \c %MaxWeightedMatching algorithm.
deba@338
  1857
    ///
deba@338
  1858
    /// \note mwm.run() is just a shortcut of the following code.
deba@338
  1859
    /// \code
deba@338
  1860
    ///   mwm.init();
deba@338
  1861
    ///   mwm.start();
deba@338
  1862
    /// \endcode
deba@338
  1863
    void run() {
deba@338
  1864
      init();
deba@338
  1865
      start();
deba@338
  1866
    }
deba@338
  1867
deba@338
  1868
    /// @}
deba@338
  1869
kpeter@637
  1870
    /// \name Primal Solution
kpeter@637
  1871
    /// Functions to get the primal solution, i.e. the maximum weighted 
kpeter@637
  1872
    /// matching.\n
kpeter@637
  1873
    /// Either \ref run() or \ref start() function should be called before
kpeter@637
  1874
    /// using them.
deba@338
  1875
deba@338
  1876
    /// @{
deba@338
  1877
kpeter@637
  1878
    /// \brief Return the weight of the matching.
deba@338
  1879
    ///
kpeter@637
  1880
    /// This function returns the weight of the found matching.
kpeter@637
  1881
    ///
kpeter@637
  1882
    /// \pre Either run() or start() must be called before using this function.
kpeter@640
  1883
    Value matchingWeight() const {
deba@338
  1884
      Value sum = 0;
deba@338
  1885
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@338
  1886
        if ((*_matching)[n] != INVALID) {
deba@338
  1887
          sum += _weight[(*_matching)[n]];
deba@338
  1888
        }
deba@338
  1889
      }
deba@338
  1890
      return sum /= 2;
deba@338
  1891
    }
deba@338
  1892
kpeter@637
  1893
    /// \brief Return the size (cardinality) of the matching.
deba@338
  1894
    ///
kpeter@637
  1895
    /// This function returns the size (cardinality) of the found matching.
kpeter@637
  1896
    ///
kpeter@637
  1897
    /// \pre Either run() or start() must be called before using this function.
deba@339
  1898
    int matchingSize() const {
deba@339
  1899
      int num = 0;
deba@339
  1900
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@339
  1901
        if ((*_matching)[n] != INVALID) {
deba@339
  1902
          ++num;
deba@339
  1903
        }
deba@339
  1904
      }
deba@339
  1905
      return num /= 2;
deba@339
  1906
    }
deba@339
  1907
kpeter@637
  1908
    /// \brief Return \c true if the given edge is in the matching.
deba@339
  1909
    ///
kpeter@637
  1910
    /// This function returns \c true if the given edge is in the found 
kpeter@637
  1911
    /// matching.
kpeter@637
  1912
    ///
kpeter@637
  1913
    /// \pre Either run() or start() must be called before using this function.
deba@339
  1914
    bool matching(const Edge& edge) const {
deba@339
  1915
      return edge == (*_matching)[_graph.u(edge)];
deba@338
  1916
    }
deba@338
  1917
kpeter@637
  1918
    /// \brief Return the matching arc (or edge) incident to the given node.
deba@338
  1919
    ///
kpeter@637
  1920
    /// This function returns the matching arc (or edge) incident to the
kpeter@637
  1921
    /// given node in the found matching or \c INVALID if the node is 
kpeter@637
  1922
    /// not covered by the matching.
kpeter@637
  1923
    ///
kpeter@637
  1924
    /// \pre Either run() or start() must be called before using this function.
deba@338
  1925
    Arc matching(const Node& node) const {
deba@338
  1926
      return (*_matching)[node];
deba@338
  1927
    }
deba@338
  1928
kpeter@640
  1929
    /// \brief Return a const reference to the matching map.
kpeter@640
  1930
    ///
kpeter@640
  1931
    /// This function returns a const reference to a node map that stores
kpeter@640
  1932
    /// the matching arc (or edge) incident to each node.
kpeter@640
  1933
    const MatchingMap& matchingMap() const {
kpeter@640
  1934
      return *_matching;
kpeter@640
  1935
    }
kpeter@640
  1936
kpeter@637
  1937
    /// \brief Return the mate of the given node.
deba@338
  1938
    ///
kpeter@637
  1939
    /// This function returns the mate of the given node in the found 
kpeter@637
  1940
    /// matching or \c INVALID if the node is not covered by the matching.
kpeter@637
  1941
    ///
kpeter@637
  1942
    /// \pre Either run() or start() must be called before using this function.
deba@338
  1943
    Node mate(const Node& node) const {
deba@338
  1944
      return (*_matching)[node] != INVALID ?
deba@338
  1945
        _graph.target((*_matching)[node]) : INVALID;
deba@338
  1946
    }
deba@338
  1947
deba@338
  1948
    /// @}
deba@338
  1949
kpeter@637
  1950
    /// \name Dual Solution
kpeter@637
  1951
    /// Functions to get the dual solution.\n
kpeter@637
  1952
    /// Either \ref run() or \ref start() function should be called before
kpeter@637
  1953
    /// using them.
deba@338
  1954
deba@338
  1955
    /// @{
deba@338
  1956
kpeter@637
  1957
    /// \brief Return the value of the dual solution.
deba@338
  1958
    ///
kpeter@637
  1959
    /// This function returns the value of the dual solution. 
kpeter@637
  1960
    /// It should be equal to the primal value scaled by \ref dualScale 
kpeter@637
  1961
    /// "dual scale".
kpeter@637
  1962
    ///
kpeter@637
  1963
    /// \pre Either run() or start() must be called before using this function.
deba@338
  1964
    Value dualValue() const {
deba@338
  1965
      Value sum = 0;
deba@338
  1966
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@338
  1967
        sum += nodeValue(n);
deba@338
  1968
      }
deba@338
  1969
      for (int i = 0; i < blossomNum(); ++i) {
deba@338
  1970
        sum += blossomValue(i) * (blossomSize(i) / 2);
deba@338
  1971
      }
deba@338
  1972
      return sum;
deba@338
  1973
    }
deba@338
  1974
kpeter@637
  1975
    /// \brief Return the dual value (potential) of the given node.
deba@338
  1976
    ///
kpeter@637
  1977
    /// This function returns the dual value (potential) of the given node.
kpeter@637
  1978
    ///
kpeter@637
  1979
    /// \pre Either run() or start() must be called before using this function.
deba@338
  1980
    Value nodeValue(const Node& n) const {
deba@338
  1981
      return (*_node_potential)[n];
deba@338
  1982
    }
deba@338
  1983
kpeter@637
  1984
    /// \brief Return the number of the blossoms in the basis.
deba@338
  1985
    ///
kpeter@637
  1986
    /// This function returns the number of the blossoms in the basis.
kpeter@637
  1987
    ///
kpeter@637
  1988
    /// \pre Either run() or start() must be called before using this function.
deba@338
  1989
    /// \see BlossomIt
deba@338
  1990
    int blossomNum() const {
deba@338
  1991
      return _blossom_potential.size();
deba@338
  1992
    }
deba@338
  1993
kpeter@637
  1994
    /// \brief Return the number of the nodes in the given blossom.
deba@338
  1995
    ///
kpeter@637
  1996
    /// This function returns the number of the nodes in the given blossom.
kpeter@637
  1997
    ///
kpeter@637
  1998
    /// \pre Either run() or start() must be called before using this function.
kpeter@637
  1999
    /// \see BlossomIt
deba@338
  2000
    int blossomSize(int k) const {
deba@338
  2001
      return _blossom_potential[k].end - _blossom_potential[k].begin;
deba@338
  2002
    }
deba@338
  2003
kpeter@637
  2004
    /// \brief Return the dual value (ptential) of the given blossom.
deba@338
  2005
    ///
kpeter@637
  2006
    /// This function returns the dual value (ptential) of the given blossom.
kpeter@637
  2007
    ///
kpeter@637
  2008
    /// \pre Either run() or start() must be called before using this function.
deba@338
  2009
    Value blossomValue(int k) const {
deba@338
  2010
      return _blossom_potential[k].value;
deba@338
  2011
    }
deba@338
  2012
kpeter@637
  2013
    /// \brief Iterator for obtaining the nodes of a blossom.
deba@338
  2014
    ///
kpeter@637
  2015
    /// This class provides an iterator for obtaining the nodes of the 
kpeter@637
  2016
    /// given blossom. It lists a subset of the nodes.
kpeter@637
  2017
    /// Before using this iterator, you must allocate a 
kpeter@637
  2018
    /// MaxWeightedMatching class and execute it.
deba@338
  2019
    class BlossomIt {
deba@338
  2020
    public:
deba@338
  2021
deba@338
  2022
      /// \brief Constructor.
deba@338
  2023
      ///
kpeter@637
  2024
      /// Constructor to get the nodes of the given variable.
kpeter@637
  2025
      ///
kpeter@637
  2026
      /// \pre Either \ref MaxWeightedMatching::run() "algorithm.run()" or 
kpeter@637
  2027
      /// \ref MaxWeightedMatching::start() "algorithm.start()" must be 
kpeter@637
  2028
      /// called before initializing this iterator.
deba@338
  2029
      BlossomIt(const MaxWeightedMatching& algorithm, int variable)
deba@338
  2030
        : _algorithm(&algorithm)
deba@338
  2031
      {
deba@338
  2032
        _index = _algorithm->_blossom_potential[variable].begin;
deba@338
  2033
        _last = _algorithm->_blossom_potential[variable].end;
deba@338
  2034
      }
deba@338
  2035
kpeter@637
  2036
      /// \brief Conversion to \c Node.
deba@338
  2037
      ///
kpeter@637
  2038
      /// Conversion to \c Node.
deba@338
  2039
      operator Node() const {
deba@339
  2040
        return _algorithm->_blossom_node_list[_index];
deba@338
  2041
      }
deba@338
  2042
deba@338
  2043
      /// \brief Increment operator.
deba@338
  2044
      ///
deba@338
  2045
      /// Increment operator.
deba@338
  2046
      BlossomIt& operator++() {
deba@338
  2047
        ++_index;
deba@338
  2048
        return *this;
deba@338
  2049
      }
deba@338
  2050
deba@339
  2051
      /// \brief Validity checking
deba@339
  2052
      ///
deba@339
  2053
      /// Checks whether the iterator is invalid.
deba@339
  2054
      bool operator==(Invalid) const { return _index == _last; }
deba@339
  2055
deba@339
  2056
      /// \brief Validity checking
deba@339
  2057
      ///
deba@339
  2058
      /// Checks whether the iterator is valid.
deba@339
  2059
      bool operator!=(Invalid) const { return _index != _last; }
deba@338
  2060
deba@338
  2061
    private:
deba@338
  2062
      const MaxWeightedMatching* _algorithm;
deba@338
  2063
      int _last;
deba@338
  2064
      int _index;
deba@338
  2065
    };
deba@338
  2066
deba@338
  2067
    /// @}
deba@338
  2068
deba@338
  2069
  };
deba@338
  2070
deba@338
  2071
  /// \ingroup matching
deba@338
  2072
  ///
deba@338
  2073
  /// \brief Weighted perfect matching in general graphs
deba@338
  2074
  ///
deba@338
  2075
  /// This class provides an efficient implementation of Edmond's
deba@339
  2076
  /// maximum weighted perfect matching algorithm. The implementation
deba@338
  2077
  /// is based on extensive use of priority queues and provides
kpeter@606
  2078
  /// \f$O(nm\log n)\f$ time complexity.
deba@338
  2079
  ///
kpeter@637
  2080
  /// The maximum weighted perfect matching problem is to find a subset of 
kpeter@637
  2081
  /// the edges in an undirected graph with maximum overall weight for which 
kpeter@637
  2082
  /// each node has exactly one incident edge.
kpeter@637
  2083
  /// It can be formulated with the following linear program.
deba@338
  2084
  /// \f[ \sum_{e \in \delta(u)}x_e = 1 \quad \forall u\in V\f]
deba@339
  2085
  /** \f[ \sum_{e \in \gamma(B)}x_e \le \frac{\vert B \vert - 1}{2}
deba@339
  2086
      \quad \forall B\in\mathcal{O}\f] */
deba@338
  2087
  /// \f[x_e \ge 0\quad \forall e\in E\f]
deba@338
  2088
  /// \f[\max \sum_{e\in E}x_ew_e\f]
deba@339
  2089
  /// where \f$\delta(X)\f$ is the set of edges incident to a node in
deba@339
  2090
  /// \f$X\f$, \f$\gamma(X)\f$ is the set of edges with both ends in
deba@339
  2091
  /// \f$X\f$ and \f$\mathcal{O}\f$ is the set of odd cardinality
deba@339
  2092
  /// subsets of the nodes.
deba@338
  2093
  ///
deba@338
  2094
  /// The algorithm calculates an optimal matching and a proof of the
deba@338
  2095
  /// optimality. The solution of the dual problem can be used to check
deba@339
  2096
  /// the result of the algorithm. The dual linear problem is the
kpeter@637
  2097
  /// following.
deba@339
  2098
  /** \f[ y_u + y_v + \sum_{B \in \mathcal{O}, uv \in \gamma(B)}z_B \ge
deba@339
  2099
      w_{uv} \quad \forall uv\in E\f] */
deba@338
  2100
  /// \f[z_B \ge 0 \quad \forall B \in \mathcal{O}\f]
deba@339
  2101
  /** \f[\min \sum_{u \in V}y_u + \sum_{B \in \mathcal{O}}
deba@339
  2102
      \frac{\vert B \vert - 1}{2}z_B\f] */
deba@338
  2103
  ///
kpeter@637
  2104
  /// The algorithm can be executed with the run() function. 
kpeter@637
  2105
  /// After it the matching (the primal solution) and the dual solution
kpeter@637
  2106
  /// can be obtained using the query functions and the 
kpeter@637
  2107
  /// \ref MaxWeightedPerfectMatching::BlossomIt "BlossomIt" nested class, 
kpeter@637
  2108
  /// which is able to iterate on the nodes of a blossom. 
kpeter@637
  2109
  /// If the value type is integer, then the dual solution is multiplied
kpeter@637
  2110
  /// by \ref MaxWeightedMatching::dualScale "4".
kpeter@637
  2111
  ///
kpeter@640
  2112
  /// \tparam GR The undirected graph type the algorithm runs on.
kpeter@637
  2113
  /// \tparam WM The type edge weight map. The default type is 
kpeter@637
  2114
  /// \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>".
kpeter@637
  2115
#ifdef DOXYGEN
kpeter@637
  2116
  template <typename GR, typename WM>
kpeter@637
  2117
#else
kpeter@606
  2118
  template <typename GR,
kpeter@606
  2119
            typename WM = typename GR::template EdgeMap<int> >
kpeter@637
  2120
#endif
deba@338
  2121
  class MaxWeightedPerfectMatching {
deba@338
  2122
  public:
deba@338
  2123
kpeter@637
  2124
    /// The graph type of the algorithm
kpeter@606
  2125
    typedef GR Graph;
kpeter@637
  2126
    /// The type of the edge weight map
kpeter@606
  2127
    typedef WM WeightMap;
kpeter@637
  2128
    /// The value type of the edge weights
deba@338
  2129
    typedef typename WeightMap::Value Value;
deba@338
  2130
deba@338
  2131
    /// \brief Scaling factor for dual solution
deba@338
  2132
    ///
deba@338
  2133
    /// Scaling factor for dual solution, it is equal to 4 or 1
deba@338
  2134
    /// according to the value type.
deba@338
  2135
    static const int dualScale =
deba@338
  2136
      std::numeric_limits<Value>::is_integer ? 4 : 1;
deba@338
  2137
kpeter@640
  2138
    /// The type of the matching map
deba@338
  2139
    typedef typename Graph::template NodeMap<typename Graph::Arc>
deba@338
  2140
    MatchingMap;
deba@338
  2141
deba@338
  2142
  private:
deba@338
  2143
deba@338
  2144
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
deba@338
  2145
deba@338
  2146
    typedef typename Graph::template NodeMap<Value> NodePotential;
deba@338
  2147
    typedef std::vector<Node> BlossomNodeList;
deba@338
  2148
deba@338
  2149
    struct BlossomVariable {
deba@338
  2150
      int begin, end;
deba@338
  2151
      Value value;
deba@338
  2152
deba@338
  2153
      BlossomVariable(int _begin, int _end, Value _value)
deba@338
  2154
        : begin(_begin), end(_end), value(_value) {}
deba@338
  2155
deba@338
  2156
    };
deba@338
  2157
deba@338
  2158
    typedef std::vector<BlossomVariable> BlossomPotential;
deba@338
  2159
deba@338
  2160
    const Graph& _graph;
deba@338
  2161
    const WeightMap& _weight;
deba@338
  2162
deba@338
  2163
    MatchingMap* _matching;
deba@338
  2164
deba@338
  2165
    NodePotential* _node_potential;
deba@338
  2166
deba@338
  2167
    BlossomPotential _blossom_potential;
deba@338
  2168
    BlossomNodeList _blossom_node_list;
deba@338
  2169
deba@338
  2170
    int _node_num;
deba@338
  2171
    int _blossom_num;
deba@338
  2172
deba@338
  2173
    typedef RangeMap<int> IntIntMap;
deba@338
  2174
deba@338
  2175
    enum Status {
deba@338
  2176
      EVEN = -1, MATCHED = 0, ODD = 1
deba@338
  2177
    };
deba@338
  2178
deba@339
  2179
    typedef HeapUnionFind<Value, IntNodeMap> BlossomSet;
deba@338
  2180
    struct BlossomData {
deba@338
  2181
      int tree;
deba@338
  2182
      Status status;
deba@338
  2183
      Arc pred, next;
deba@338
  2184
      Value pot, offset;
deba@338
  2185
    };
deba@338
  2186
deba@339
  2187
    IntNodeMap *_blossom_index;
deba@338
  2188
    BlossomSet *_blossom_set;
deba@338
  2189
    RangeMap<BlossomData>* _blossom_data;
deba@338
  2190
deba@339
  2191
    IntNodeMap *_node_index;
deba@339
  2192
    IntArcMap *_node_heap_index;
deba@338
  2193
deba@338
  2194
    struct NodeData {
deba@338
  2195
deba@339
  2196
      NodeData(IntArcMap& node_heap_index)
deba@338
  2197
        : heap(node_heap_index) {}
deba@338
  2198
deba@338
  2199
      int blossom;
deba@338
  2200
      Value pot;
deba@339
  2201
      BinHeap<Value, IntArcMap> heap;
deba@338
  2202
      std::map<int, Arc> heap_index;
deba@338
  2203
deba@338
  2204
      int tree;
deba@338
  2205
    };
deba@338
  2206
deba@338
  2207
    RangeMap<NodeData>* _node_data;
deba@338
  2208
deba@338
  2209
    typedef ExtendFindEnum<IntIntMap> TreeSet;
deba@338
  2210
deba@338
  2211
    IntIntMap *_tree_set_index;
deba@338
  2212
    TreeSet *_tree_set;
deba@338
  2213
deba@338
  2214
    IntIntMap *_delta2_index;
deba@338
  2215
    BinHeap<Value, IntIntMap> *_delta2;
deba@338
  2216
deba@339
  2217
    IntEdgeMap *_delta3_index;
deba@339
  2218
    BinHeap<Value, IntEdgeMap> *_delta3;
deba@338
  2219
deba@338
  2220
    IntIntMap *_delta4_index;
deba@338
  2221
    BinHeap<Value, IntIntMap> *_delta4;
deba@338
  2222
deba@338
  2223
    Value _delta_sum;
deba@338
  2224
deba@338
  2225
    void createStructures() {
deba@338
  2226
      _node_num = countNodes(_graph);
deba@338
  2227
      _blossom_num = _node_num * 3 / 2;
deba@338
  2228
deba@338
  2229
      if (!_matching) {
deba@338
  2230
        _matching = new MatchingMap(_graph);
deba@338
  2231
      }
deba@945
  2232
deba@338
  2233
      if (!_node_potential) {
deba@338
  2234
        _node_potential = new NodePotential(_graph);
deba@338
  2235
      }
deba@945
  2236
deba@338
  2237
      if (!_blossom_set) {
deba@339
  2238
        _blossom_index = new IntNodeMap(_graph);
deba@338
  2239
        _blossom_set = new BlossomSet(*_blossom_index);
deba@338
  2240
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
deba@945
  2241
      } else if (_blossom_data->size() != _blossom_num) {
deba@945
  2242
        delete _blossom_data;
deba@945
  2243
        _blossom_data = new RangeMap<BlossomData>(_blossom_num);
deba@338
  2244
      }
deba@338
  2245
deba@338
  2246
      if (!_node_index) {
deba@339
  2247
        _node_index = new IntNodeMap(_graph);
deba@339
  2248
        _node_heap_index = new IntArcMap(_graph);
deba@338
  2249
        _node_data = new RangeMap<NodeData>(_node_num,
deba@339
  2250
                                            NodeData(*_node_heap_index));
deba@945
  2251
      } else if (_node_data->size() != _node_num) {
deba@945
  2252
        delete _node_data;
deba@945
  2253
        _node_data = new RangeMap<NodeData>(_node_num,
deba@945
  2254
                                            NodeData(*_node_heap_index));
deba@338
  2255
      }
deba@338
  2256
deba@338
  2257
      if (!_tree_set) {
deba@338
  2258
        _tree_set_index = new IntIntMap(_blossom_num);
deba@338
  2259
        _tree_set = new TreeSet(*_tree_set_index);
deba@945
  2260
      } else {
deba@945
  2261
        _tree_set_index->resize(_blossom_num);
deba@338
  2262
      }
deba@945
  2263
deba@338
  2264
      if (!_delta2) {
deba@338
  2265
        _delta2_index = new IntIntMap(_blossom_num);
deba@338
  2266
        _delta2 = new BinHeap<Value, IntIntMap>(*_delta2_index);
deba@945
  2267
      } else {
deba@945
  2268
        _delta2_index->resize(_blossom_num);
deba@338
  2269
      }
deba@945
  2270
deba@338
  2271
      if (!_delta3) {
deba@339
  2272
        _delta3_index = new IntEdgeMap(_graph);
deba@339
  2273
        _delta3 = new BinHeap<Value, IntEdgeMap>(*_delta3_index);
deba@338
  2274
      }
deba@945
  2275
deba@338
  2276
      if (!_delta4) {
deba@338
  2277
        _delta4_index = new IntIntMap(_blossom_num);
deba@338
  2278
        _delta4 = new BinHeap<Value, IntIntMap>(*_delta4_index);
deba@945
  2279
      } else {
deba@945
  2280
        _delta4_index->resize(_blossom_num);
deba@338
  2281
      }
deba@338
  2282
    }
deba@338
  2283
deba@338
  2284
    void destroyStructures() {
deba@338
  2285
      _node_num = countNodes(_graph);
deba@338
  2286
      _blossom_num = _node_num * 3 / 2;
deba@338
  2287
deba@338
  2288
      if (_matching) {
deba@338
  2289
        delete _matching;
deba@338
  2290
      }
deba@338
  2291
      if (_node_potential) {
deba@338
  2292
        delete _node_potential;
deba@338
  2293
      }
deba@338
  2294
      if (_blossom_set) {
deba@338
  2295
        delete _blossom_index;
deba@338
  2296
        delete _blossom_set;
deba@338
  2297
        delete _blossom_data;
deba@338
  2298
      }
deba@338
  2299
deba@338
  2300
      if (_node_index) {
deba@338
  2301
        delete _node_index;
deba@338
  2302
        delete _node_heap_index;
deba@338
  2303
        delete _node_data;
deba@338
  2304
      }
deba@338
  2305
deba@338
  2306
      if (_tree_set) {
deba@338
  2307
        delete _tree_set_index;
deba@338
  2308
        delete _tree_set;
deba@338
  2309
      }
deba@338
  2310
      if (_delta2) {
deba@338
  2311
        delete _delta2_index;
deba@338
  2312
        delete _delta2;
deba@338
  2313
      }
deba@338
  2314
      if (_delta3) {
deba@338
  2315
        delete _delta3_index;
deba@338
  2316
        delete _delta3;
deba@338
  2317
      }
deba@338
  2318
      if (_delta4) {
deba@338
  2319
        delete _delta4_index;
deba@338
  2320
        delete _delta4;
deba@338
  2321
      }
deba@338
  2322
    }
deba@338
  2323
deba@338
  2324
    void matchedToEven(int blossom, int tree) {
deba@338
  2325
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
deba@338
  2326
        _delta2->erase(blossom);
deba@338
  2327
      }
deba@338
  2328
deba@338
  2329
      if (!_blossom_set->trivial(blossom)) {
deba@338
  2330
        (*_blossom_data)[blossom].pot -=
deba@338
  2331
          2 * (_delta_sum - (*_blossom_data)[blossom].offset);
deba@338
  2332
      }
deba@338
  2333
deba@338
  2334
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
deba@338
  2335
           n != INVALID; ++n) {
deba@338
  2336
deba@338
  2337
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
deba@338
  2338
        int ni = (*_node_index)[n];
deba@338
  2339
deba@338
  2340
        (*_node_data)[ni].heap.clear();
deba@338
  2341
        (*_node_data)[ni].heap_index.clear();
deba@338
  2342
deba@338
  2343
        (*_node_data)[ni].pot += _delta_sum - (*_blossom_data)[blossom].offset;
deba@338
  2344
deba@338
  2345
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
deba@338
  2346
          Node v = _graph.source(e);
deba@338
  2347
          int vb = _blossom_set->find(v);
deba@338
  2348
          int vi = (*_node_index)[v];
deba@338
  2349
deba@338
  2350
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
deba@338
  2351
            dualScale * _weight[e];
deba@338
  2352
deba@338
  2353
          if ((*_blossom_data)[vb].status == EVEN) {
deba@338
  2354
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
deba@338
  2355
              _delta3->push(e, rw / 2);
deba@338
  2356
            }
deba@338
  2357
          } else {
deba@338
  2358
            typename std::map<int, Arc>::iterator it =
deba@338
  2359
              (*_node_data)[vi].heap_index.find(tree);
deba@338
  2360
deba@338
  2361
            if (it != (*_node_data)[vi].heap_index.end()) {
deba@338
  2362
              if ((*_node_data)[vi].heap[it->second] > rw) {
deba@338
  2363
                (*_node_data)[vi].heap.replace(it->second, e);
deba@338
  2364
                (*_node_data)[vi].heap.decrease(e, rw);
deba@338
  2365
                it->second = e;
deba@338
  2366
              }
deba@338
  2367
            } else {
deba@338
  2368
              (*_node_data)[vi].heap.push(e, rw);
deba@338
  2369
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
deba@338
  2370
            }
deba@338
  2371
deba@338
  2372
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
deba@338
  2373
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
deba@338
  2374
deba@338
  2375
              if ((*_blossom_data)[vb].status == MATCHED) {
deba@338
  2376
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
deba@338
  2377
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
deba@338
  2378
                               (*_blossom_data)[vb].offset);
deba@338
  2379
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
deba@338
  2380
                           (*_blossom_data)[vb].offset){
deba@338
  2381
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
deba@338
  2382
                                   (*_blossom_data)[vb].offset);
deba@338
  2383
                }
deba@338
  2384
              }
deba@338
  2385
            }
deba@338
  2386
          }
deba@338
  2387
        }
deba@338
  2388
      }
deba@338
  2389
      (*_blossom_data)[blossom].offset = 0;
deba@338
  2390
    }
deba@338
  2391
deba@338
  2392
    void matchedToOdd(int blossom) {
deba@338
  2393
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
deba@338
  2394
        _delta2->erase(blossom);
deba@338
  2395
      }
deba@338
  2396
      (*_blossom_data)[blossom].offset += _delta_sum;
deba@338
  2397
      if (!_blossom_set->trivial(blossom)) {
deba@338
  2398
        _delta4->push(blossom, (*_blossom_data)[blossom].pot / 2 +
deba@338
  2399
                     (*_blossom_data)[blossom].offset);
deba@338
  2400
      }
deba@338
  2401
    }
deba@338
  2402
deba@338
  2403
    void evenToMatched(int blossom, int tree) {
deba@338
  2404
      if (!_blossom_set->trivial(blossom)) {
deba@338
  2405
        (*_blossom_data)[blossom].pot += 2 * _delta_sum;
deba@338
  2406
      }
deba@338
  2407
deba@338
  2408
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
deba@338
  2409
           n != INVALID; ++n) {
deba@338
  2410
        int ni = (*_node_index)[n];
deba@338
  2411
        (*_node_data)[ni].pot -= _delta_sum;
deba@338
  2412
deba@338
  2413
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
deba@338
  2414
          Node v = _graph.source(e);
deba@338
  2415
          int vb = _blossom_set->find(v);
deba@338
  2416
          int vi = (*_node_index)[v];
deba@338
  2417
deba@338
  2418
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
deba@338
  2419
            dualScale * _weight[e];
deba@338
  2420
deba@338
  2421
          if (vb == blossom) {
deba@338
  2422
            if (_delta3->state(e) == _delta3->IN_HEAP) {
deba@338
  2423
              _delta3->erase(e);
deba@338
  2424
            }
deba@338
  2425
          } else if ((*_blossom_data)[vb].status == EVEN) {
deba@338
  2426
deba@338
  2427
            if (_delta3->state(e) == _delta3->IN_HEAP) {
deba@338
  2428
              _delta3->erase(e);
deba@338
  2429
            }
deba@338
  2430
deba@338
  2431
            int vt = _tree_set->find(vb);
deba@338
  2432
deba@338
  2433
            if (vt != tree) {
deba@338
  2434
deba@338
  2435
              Arc r = _graph.oppositeArc(e);
deba@338
  2436
deba@338
  2437
              typename std::map<int, Arc>::iterator it =
deba@338
  2438
                (*_node_data)[ni].heap_index.find(vt);
deba@338
  2439
deba@338
  2440
              if (it != (*_node_data)[ni].heap_index.end()) {
deba@338
  2441
                if ((*_node_data)[ni].heap[it->second] > rw) {
deba@338
  2442
                  (*_node_data)[ni].heap.replace(it->second, r);
deba@338
  2443
                  (*_node_data)[ni].heap.decrease(r, rw);
deba@338
  2444
                  it->second = r;
deba@338
  2445
                }
deba@338
  2446
              } else {
deba@338
  2447
                (*_node_data)[ni].heap.push(r, rw);
deba@338
  2448
                (*_node_data)[ni].heap_index.insert(std::make_pair(vt, r));
deba@338
  2449
              }
deba@338
  2450
deba@338
  2451
              if ((*_blossom_set)[n] > (*_node_data)[ni].heap.prio()) {
deba@338
  2452
                _blossom_set->decrease(n, (*_node_data)[ni].heap.prio());
deba@338
  2453
deba@338
  2454
                if (_delta2->state(blossom) != _delta2->IN_HEAP) {
deba@338
  2455
                  _delta2->push(blossom, _blossom_set->classPrio(blossom) -
deba@338
  2456
                               (*_blossom_data)[blossom].offset);
deba@338
  2457
                } else if ((*_delta2)[blossom] >
deba@338
  2458
                           _blossom_set->classPrio(blossom) -
deba@338
  2459
                           (*_blossom_data)[blossom].offset){
deba@338
  2460
                  _delta2->decrease(blossom, _blossom_set->classPrio(blossom) -
deba@338
  2461
                                   (*_blossom_data)[blossom].offset);
deba@338
  2462
                }
deba@338
  2463
              }
deba@338
  2464
            }
deba@338
  2465
          } else {
deba@338
  2466
deba@338
  2467
            typename std::map<int, Arc>::iterator it =
deba@338
  2468
              (*_node_data)[vi].heap_index.find(tree);
deba@338
  2469
deba@338
  2470
            if (it != (*_node_data)[vi].heap_index.end()) {
deba@338
  2471
              (*_node_data)[vi].heap.erase(it->second);
deba@338
  2472
              (*_node_data)[vi].heap_index.erase(it);
deba@338
  2473
              if ((*_node_data)[vi].heap.empty()) {
deba@338
  2474
                _blossom_set->increase(v, std::numeric_limits<Value>::max());
deba@338
  2475
              } else if ((*_blossom_set)[v] < (*_node_data)[vi].heap.prio()) {
deba@338
  2476
                _blossom_set->increase(v, (*_node_data)[vi].heap.prio());
deba@338
  2477
              }
deba@338
  2478
deba@338
  2479
              if ((*_blossom_data)[vb].status == MATCHED) {
deba@338
  2480
                if (_blossom_set->classPrio(vb) ==
deba@338
  2481
                    std::numeric_limits<Value>::max()) {
deba@338
  2482
                  _delta2->erase(vb);
deba@338
  2483
                } else if ((*_delta2)[vb] < _blossom_set->classPrio(vb) -
deba@338
  2484
                           (*_blossom_data)[vb].offset) {
deba@338
  2485
                  _delta2->increase(vb, _blossom_set->classPrio(vb) -
deba@338
  2486
                                   (*_blossom_data)[vb].offset);
deba@338
  2487
                }
deba@338
  2488
              }
deba@338
  2489
            }
deba@338
  2490
          }
deba@338
  2491
        }
deba@338
  2492
      }
deba@338
  2493
    }
deba@338
  2494
deba@338
  2495
    void oddToMatched(int blossom) {
deba@338
  2496
      (*_blossom_data)[blossom].offset -= _delta_sum;
deba@338
  2497
deba@338
  2498
      if (_blossom_set->classPrio(blossom) !=
deba@338
  2499
          std::numeric_limits<Value>::max()) {
deba@338
  2500
        _delta2->push(blossom, _blossom_set->classPrio(blossom) -
deba@338
  2501
                       (*_blossom_data)[blossom].offset);
deba@338
  2502
      }
deba@338
  2503
deba@338
  2504
      if (!_blossom_set->trivial(blossom)) {
deba@338
  2505
        _delta4->erase(blossom);
deba@338
  2506
      }
deba@338
  2507
    }
deba@338
  2508
deba@338
  2509
    void oddToEven(int blossom, int tree) {
deba@338
  2510
      if (!_blossom_set->trivial(blossom)) {
deba@338
  2511
        _delta4->erase(blossom);
deba@338
  2512
        (*_blossom_data)[blossom].pot -=
deba@338
  2513
          2 * (2 * _delta_sum - (*_blossom_data)[blossom].offset);
deba@338
  2514
      }
deba@338
  2515
deba@338
  2516
      for (typename BlossomSet::ItemIt n(*_blossom_set, blossom);
deba@338
  2517
           n != INVALID; ++n) {
deba@338
  2518
        int ni = (*_node_index)[n];
deba@338
  2519
deba@338
  2520
        _blossom_set->increase(n, std::numeric_limits<Value>::max());
deba@338
  2521
deba@338
  2522
        (*_node_data)[ni].heap.clear();
deba@338
  2523
        (*_node_data)[ni].heap_index.clear();
deba@338
  2524
        (*_node_data)[ni].pot +=
deba@338
  2525
          2 * _delta_sum - (*_blossom_data)[blossom].offset;
deba@338
  2526
deba@338
  2527
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
deba@338
  2528
          Node v = _graph.source(e);
deba@338
  2529
          int vb = _blossom_set->find(v);
deba@338
  2530
          int vi = (*_node_index)[v];
deba@338
  2531
deba@338
  2532
          Value rw = (*_node_data)[ni].pot + (*_node_data)[vi].pot -
deba@338
  2533
            dualScale * _weight[e];
deba@338
  2534
deba@338
  2535
          if ((*_blossom_data)[vb].status == EVEN) {
deba@338
  2536
            if (_delta3->state(e) != _delta3->IN_HEAP && blossom != vb) {
deba@338
  2537
              _delta3->push(e, rw / 2);
deba@338
  2538
            }
deba@338
  2539
          } else {
deba@338
  2540
deba@338
  2541
            typename std::map<int, Arc>::iterator it =
deba@338
  2542
              (*_node_data)[vi].heap_index.find(tree);
deba@338
  2543
deba@338
  2544
            if (it != (*_node_data)[vi].heap_index.end()) {
deba@338
  2545
              if ((*_node_data)[vi].heap[it->second] > rw) {
deba@338
  2546
                (*_node_data)[vi].heap.replace(it->second, e);
deba@338
  2547
                (*_node_data)[vi].heap.decrease(e, rw);
deba@338
  2548
                it->second = e;
deba@338
  2549
              }
deba@338
  2550
            } else {
deba@338
  2551
              (*_node_data)[vi].heap.push(e, rw);
deba@338
  2552
              (*_node_data)[vi].heap_index.insert(std::make_pair(tree, e));
deba@338
  2553
            }
deba@338
  2554
deba@338
  2555
            if ((*_blossom_set)[v] > (*_node_data)[vi].heap.prio()) {
deba@338
  2556
              _blossom_set->decrease(v, (*_node_data)[vi].heap.prio());
deba@338
  2557
deba@338
  2558
              if ((*_blossom_data)[vb].status == MATCHED) {
deba@338
  2559
                if (_delta2->state(vb) != _delta2->IN_HEAP) {
deba@338
  2560
                  _delta2->push(vb, _blossom_set->classPrio(vb) -
deba@338
  2561
                               (*_blossom_data)[vb].offset);
deba@338
  2562
                } else if ((*_delta2)[vb] > _blossom_set->classPrio(vb) -
deba@338
  2563
                           (*_blossom_data)[vb].offset) {
deba@338
  2564
                  _delta2->decrease(vb, _blossom_set->classPrio(vb) -
deba@338
  2565
                                   (*_blossom_data)[vb].offset);
deba@338
  2566
                }
deba@338
  2567
              }
deba@338
  2568
            }
deba@338
  2569
          }
deba@338
  2570
        }
deba@338
  2571
      }
deba@338
  2572
      (*_blossom_data)[blossom].offset = 0;
deba@338
  2573
    }
deba@338
  2574
deba@338
  2575
    void alternatePath(int even, int tree) {
deba@338
  2576
      int odd;
deba@338
  2577
deba@338
  2578
      evenToMatched(even, tree);
deba@338
  2579
      (*_blossom_data)[even].status = MATCHED;
deba@338
  2580
deba@338
  2581
      while ((*_blossom_data)[even].pred != INVALID) {
deba@338
  2582
        odd = _blossom_set->find(_graph.target((*_blossom_data)[even].pred));
deba@338
  2583
        (*_blossom_data)[odd].status = MATCHED;
deba@338
  2584
        oddToMatched(odd);
deba@338
  2585
        (*_blossom_data)[odd].next = (*_blossom_data)[odd].pred;
deba@338
  2586
deba@338
  2587
        even = _blossom_set->find(_graph.target((*_blossom_data)[odd].pred));
deba@338
  2588
        (*_blossom_data)[even].status = MATCHED;
deba@338
  2589
        evenToMatched(even, tree);
deba@338
  2590
        (*_blossom_data)[even].next =
deba@338
  2591
          _graph.oppositeArc((*_blossom_data)[odd].pred);
deba@338
  2592
      }
deba@338
  2593
deba@338
  2594
    }
deba@338
  2595
deba@338
  2596
    void destroyTree(int tree) {
deba@338
  2597
      for (TreeSet::ItemIt b(*_tree_set, tree); b != INVALID; ++b) {
deba@338
  2598
        if ((*_blossom_data)[b].status == EVEN) {
deba@338
  2599
          (*_blossom_data)[b].status = MATCHED;
deba@338
  2600
          evenToMatched(b, tree);
deba@338
  2601
        } else if ((*_blossom_data)[b].status == ODD) {
deba@338
  2602
          (*_blossom_data)[b].status = MATCHED;
deba@338
  2603
          oddToMatched(b);
deba@338
  2604
        }
deba@338
  2605
      }
deba@338
  2606
      _tree_set->eraseClass(tree);
deba@338
  2607
    }
deba@338
  2608
deba@339
  2609
    void augmentOnEdge(const Edge& edge) {
deba@339
  2610
deba@339
  2611
      int left = _blossom_set->find(_graph.u(edge));
deba@339
  2612
      int right = _blossom_set->find(_graph.v(edge));
deba@338
  2613
deba@338
  2614
      int left_tree = _tree_set->find(left);
deba@338
  2615
      alternatePath(left, left_tree);
deba@338
  2616
      destroyTree(left_tree);
deba@338
  2617
deba@338
  2618
      int right_tree = _tree_set->find(right);
deba@338
  2619
      alternatePath(right, right_tree);
deba@338
  2620
      destroyTree(right_tree);
deba@338
  2621
deba@339
  2622
      (*_blossom_data)[left].next = _graph.direct(edge, true);
deba@339
  2623
      (*_blossom_data)[right].next = _graph.direct(edge, false);
deba@338
  2624
    }
deba@338
  2625
deba@338
  2626
    void extendOnArc(const Arc& arc) {
deba@338
  2627
      int base = _blossom_set->find(_graph.target(arc));
deba@338
  2628
      int tree = _tree_set->find(base);
deba@338
  2629
deba@338
  2630
      int odd = _blossom_set->find(_graph.source(arc));
deba@338
  2631
      _tree_set->insert(odd, tree);
deba@338
  2632
      (*_blossom_data)[odd].status = ODD;
deba@338
  2633
      matchedToOdd(odd);
deba@338
  2634
      (*_blossom_data)[odd].pred = arc;
deba@338
  2635
deba@338
  2636
      int even = _blossom_set->find(_graph.target((*_blossom_data)[odd].next));
deba@338
  2637
      (*_blossom_data)[even].pred = (*_blossom_data)[even].next;
deba@338
  2638
      _tree_set->insert(even, tree);
deba@338
  2639
      (*_blossom_data)[even].status = EVEN;
deba@338
  2640
      matchedToEven(even, tree);
deba@338
  2641
    }
deba@338
  2642
deba@339
  2643
    void shrinkOnEdge(const Edge& edge, int tree) {
deba@338
  2644
      int nca = -1;
deba@338
  2645
      std::vector<int> left_path, right_path;
deba@338
  2646
deba@338
  2647
      {
deba@338
  2648
        std::set<int> left_set, right_set;
deba@338
  2649
        int left = _blossom_set->find(_graph.u(edge));
deba@338
  2650
        left_path.push_back(left);
deba@338
  2651
        left_set.insert(left);
deba@338
  2652
deba@338
  2653
        int right = _blossom_set->find(_graph.v(edge));
deba@338
  2654
        right_path.push_back(right);
deba@338
  2655
        right_set.insert(right);
deba@338
  2656
deba@338
  2657
        while (true) {
deba@338
  2658
deba@338
  2659
          if ((*_blossom_data)[left].pred == INVALID) break;
deba@338
  2660
deba@338
  2661
          left =
deba@338
  2662
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
deba@338
  2663
          left_path.push_back(left);
deba@338
  2664
          left =
deba@338
  2665
            _blossom_set->find(_graph.target((*_blossom_data)[left].pred));
deba@338
  2666
          left_path.push_back(left);
deba@338
  2667
deba@338
  2668
          left_set.insert(left);
deba@338
  2669
deba@338
  2670
          if (right_set.find(left) != right_set.end()) {
deba@338
  2671
            nca = left;
deba@338
  2672
            break;
deba@338
  2673
          }
deba@338
  2674
deba@338
  2675
          if ((*_blossom_data)[right].pred == INVALID) break;
deba@338
  2676
deba@338
  2677
          right =
deba@338
  2678
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
deba@338
  2679
          right_path.push_back(right);
deba@338
  2680
          right =
deba@338
  2681
            _blossom_set->find(_graph.target((*_blossom_data)[right].pred));
deba@338
  2682
          right_path.push_back(right);
deba@338
  2683
deba@338
  2684
          right_set.insert(right);
deba@338
  2685
deba@338
  2686
          if (left_set.find(right) != left_set.end()) {
deba@338
  2687
            nca = right;
deba@338
  2688
            break;
deba@338
  2689
          }
deba@338
  2690
deba@338
  2691
        }
deba@338
  2692
deba@338
  2693
        if (nca == -1) {
deba@338
  2694
          if ((*_blossom_data)[left].pred == INVALID) {
deba@338
  2695
            nca = right;
deba@338
  2696
            while (left_set.find(nca) == left_set.end()) {
deba@338
  2697
              nca =
deba@338
  2698
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
deba@338
  2699
              right_path.push_back(nca);
deba@338
  2700
              nca =
deba@338
  2701
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
deba@338
  2702
              right_path.push_back(nca);
deba@338
  2703
            }
deba@338
  2704
          } else {
deba@338
  2705
            nca = left;
deba@338
  2706
            while (right_set.find(nca) == right_set.end()) {
deba@338
  2707
              nca =
deba@338
  2708
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
deba@338
  2709
              left_path.push_back(nca);
deba@338
  2710
              nca =
deba@338
  2711
                _blossom_set->find(_graph.target((*_blossom_data)[nca].pred));
deba@338
  2712
              left_path.push_back(nca);
deba@338
  2713
            }
deba@338
  2714
          }
deba@338
  2715
        }
deba@338
  2716
      }
deba@338
  2717
deba@338
  2718
      std::vector<int> subblossoms;
deba@338
  2719
      Arc prev;
deba@338
  2720
deba@338
  2721
      prev = _graph.direct(edge, true);
deba@338
  2722
      for (int i = 0; left_path[i] != nca; i += 2) {
deba@338
  2723
        subblossoms.push_back(left_path[i]);
deba@338
  2724
        (*_blossom_data)[left_path[i]].next = prev;
deba@338
  2725
        _tree_set->erase(left_path[i]);
deba@338
  2726
deba@338
  2727
        subblossoms.push_back(left_path[i + 1]);
deba@338
  2728
        (*_blossom_data)[left_path[i + 1]].status = EVEN;
deba@338
  2729
        oddToEven(left_path[i + 1], tree);
deba@338
  2730
        _tree_set->erase(left_path[i + 1]);
deba@338
  2731
        prev = _graph.oppositeArc((*_blossom_data)[left_path[i + 1]].pred);
deba@338
  2732
      }
deba@338
  2733
deba@338
  2734
      int k = 0;
deba@338
  2735
      while (right_path[k] != nca) ++k;
deba@338
  2736
deba@338
  2737
      subblossoms.push_back(nca);
deba@338
  2738
      (*_blossom_data)[nca].next = prev;
deba@338
  2739
deba@338
  2740
      for (int i = k - 2; i >= 0; i -= 2) {
deba@338
  2741
        subblossoms.push_back(right_path[i + 1]);
deba@338
  2742
        (*_blossom_data)[right_path[i + 1]].status = EVEN;
deba@338
  2743
        oddToEven(right_path[i + 1], tree);
deba@338
  2744
        _tree_set->erase(right_path[i + 1]);
deba@338
  2745
deba@338
  2746
        (*_blossom_data)[right_path[i + 1]].next =
deba@338
  2747
          (*_blossom_data)[right_path[i + 1]].pred;
deba@338
  2748
deba@338
  2749
        subblossoms.push_back(right_path[i]);
deba@338
  2750
        _tree_set->erase(right_path[i]);
deba@338
  2751
      }
deba@338
  2752
deba@338
  2753
      int surface =
deba@338
  2754
        _blossom_set->join(subblossoms.begin(), subblossoms.end());
deba@338
  2755
deba@338
  2756
      for (int i = 0; i < int(subblossoms.size()); ++i) {
deba@338
  2757
        if (!_blossom_set->trivial(subblossoms[i])) {
deba@338
  2758
          (*_blossom_data)[subblossoms[i]].pot += 2 * _delta_sum;
deba@338
  2759
        }
deba@338
  2760
        (*_blossom_data)[subblossoms[i]].status = MATCHED;
deba@338
  2761
      }
deba@338
  2762
deba@338
  2763
      (*_blossom_data)[surface].pot = -2 * _delta_sum;
deba@338
  2764
      (*_blossom_data)[surface].offset = 0;
deba@338
  2765
      (*_blossom_data)[surface].status = EVEN;
deba@338
  2766
      (*_blossom_data)[surface].pred = (*_blossom_data)[nca].pred;
deba@338
  2767
      (*_blossom_data)[surface].next = (*_blossom_data)[nca].pred;
deba@338
  2768
deba@338
  2769
      _tree_set->insert(surface, tree);
deba@338
  2770
      _tree_set->erase(nca);
deba@338
  2771
    }
deba@338
  2772
deba@338
  2773
    void splitBlossom(int blossom) {
deba@338
  2774
      Arc next = (*_blossom_data)[blossom].next;
deba@338
  2775
      Arc pred = (*_blossom_data)[blossom].pred;
deba@338
  2776
deba@338
  2777
      int tree = _tree_set->find(blossom);
deba@338
  2778
deba@338
  2779
      (*_blossom_data)[blossom].status = MATCHED;
deba@338
  2780
      oddToMatched(blossom);
deba@338
  2781
      if (_delta2->state(blossom) == _delta2->IN_HEAP) {
deba@338
  2782
        _delta2->erase(blossom);
deba@338
  2783
      }
deba@338
  2784
deba@338
  2785
      std::vector<int> subblossoms;
deba@338
  2786
      _blossom_set->split(blossom, std::back_inserter(subblossoms));
deba@338
  2787
deba@338
  2788
      Value offset = (*_blossom_data)[blossom].offset;
deba@338
  2789
      int b = _blossom_set->find(_graph.source(pred));
deba@338
  2790
      int d = _blossom_set->find(_graph.source(next));
deba@338
  2791
deba@338
  2792
      int ib = -1, id = -1;
deba@338
  2793
      for (int i = 0; i < int(subblossoms.size()); ++i) {
deba@338
  2794
        if (subblossoms[i] == b) ib = i;
deba@338
  2795
        if (subblossoms[i] == d) id = i;
deba@338
  2796
deba@338
  2797
        (*_blossom_data)[subblossoms[i]].offset = offset;
deba@338
  2798
        if (!_blossom_set->trivial(subblossoms[i])) {
deba@338
  2799
          (*_blossom_data)[subblossoms[i]].pot -= 2 * offset;
deba@338
  2800
        }
deba@338
  2801
        if (_blossom_set->classPrio(subblossoms[i]) !=
deba@338
  2802
            std::numeric_limits<Value>::max()) {
deba@338
  2803
          _delta2->push(subblossoms[i],
deba@338
  2804
                        _blossom_set->classPrio(subblossoms[i]) -
deba@338
  2805
                        (*_blossom_data)[subblossoms[i]].offset);
deba@338
  2806
        }
deba@338
  2807
      }
deba@338
  2808
deba@338
  2809
      if (id > ib ? ((id - ib) % 2 == 0) : ((ib - id) % 2 == 1)) {
deba@338
  2810
        for (int i = (id + 1) % subblossoms.size();
deba@338
  2811
             i != ib; i = (i + 2) % subblossoms.size()) {
deba@338
  2812
          int sb = subblossoms[i];
deba@338
  2813
          int tb = subblossoms[(i + 1) % subblossoms.size()];
deba@338
  2814
          (*_blossom_data)[sb].next =
deba@338
  2815
            _graph.oppositeArc((*_blossom_data)[tb].next);
deba@338
  2816
        }
deba@338
  2817
deba@338
  2818
        for (int i = ib; i != id; i = (i + 2) % subblossoms.size()) {
deba@338
  2819
          int sb = subblossoms[i];
deba@338
  2820
          int tb = subblossoms[(i + 1) % subblossoms.size()];
deba@338
  2821
          int ub = subblossoms[(i + 2) % subblossoms.size()];
deba@338
  2822
deba@338
  2823
          (*_blossom_data)[sb].status = ODD;
deba@338
  2824
          matchedToOdd(sb);
deba@338
  2825
          _tree_set->insert(sb, tree);
deba@338
  2826
          (*_blossom_data)[sb].pred = pred;
deba@338
  2827
          (*_blossom_data)[sb].next =
deba@338
  2828
                           _graph.oppositeArc((*_blossom_data)[tb].next);
deba@338
  2829
deba@338
  2830
          pred = (*_blossom_data)[ub].next;
deba@338
  2831
deba@338
  2832
          (*_blossom_data)[tb].status = EVEN;
deba@338
  2833
          matchedToEven(tb, tree);
deba@338
  2834
          _tree_set->insert(tb, tree);
deba@338
  2835
          (*_blossom_data)[tb].pred = (*_blossom_data)[tb].next;
deba@338
  2836
        }
deba@338
  2837
deba@338
  2838
        (*_blossom_data)[subblossoms[id]].status = ODD;
deba@338
  2839
        matchedToOdd(subblossoms[id]);
deba@338
  2840
        _tree_set->insert(subblossoms[id], tree);
deba@338
  2841
        (*_blossom_data)[subblossoms[id]].next = next;
deba@338
  2842
        (*_blossom_data)[subblossoms[id]].pred = pred;
deba@338
  2843
deba@338
  2844
      } else {
deba@338
  2845
deba@338
  2846
        for (int i = (ib + 1) % subblossoms.size();
deba@338
  2847
             i != id; i = (i + 2) % subblossoms.size()) {
deba@338
  2848
          int sb = subblossoms[i];
deba@338
  2849
          int tb = subblossoms[(i + 1) % subblossoms.size()];
deba@338
  2850
          (*_blossom_data)[sb].next =
deba@338
  2851
            _graph.oppositeArc((*_blossom_data)[tb].next);
deba@338
  2852
        }
deba@338
  2853
deba@338
  2854
        for (int i = id; i != ib; i = (i + 2) % subblossoms.size()) {
deba@338
  2855
          int sb = subblossoms[i];
deba@338
  2856
          int tb = subblossoms[(i + 1) % subblossoms.size()];
deba@338
  2857
          int ub = subblossoms[(i + 2) % subblossoms.size()];
deba@338
  2858
deba@338
  2859
          (*_blossom_data)[sb].status = ODD;
deba@338
  2860
          matchedToOdd(sb);
deba@338
  2861
          _tree_set->insert(sb, tree);
deba@338
  2862
          (*_blossom_data)[sb].next = next;
deba@338
  2863
          (*_blossom_data)[sb].pred =
deba@338
  2864
            _graph.oppositeArc((*_blossom_data)[tb].next);
deba@338
  2865
deba@338
  2866
          (*_blossom_data)[tb].status = EVEN;
deba@338
  2867
          matchedToEven(tb, tree);
deba@338
  2868
          _tree_set->insert(tb, tree);
deba@338
  2869
          (*_blossom_data)[tb].pred =
deba@338
  2870
            (*_blossom_data)[tb].next =
deba@338
  2871
            _graph.oppositeArc((*_blossom_data)[ub].next);
deba@338
  2872
          next = (*_blossom_data)[ub].next;
deba@338
  2873
        }
deba@338
  2874
deba@338
  2875
        (*_blossom_data)[subblossoms[ib]].status = ODD;
deba@338
  2876
        matchedToOdd(subblossoms[ib]);
deba@338
  2877
        _tree_set->insert(subblossoms[ib], tree);
deba@338
  2878
        (*_blossom_data)[subblossoms[ib]].next = next;
deba@338
  2879
        (*_blossom_data)[subblossoms[ib]].pred = pred;
deba@338
  2880
      }
deba@338
  2881
      _tree_set->erase(blossom);
deba@338
  2882
    }
deba@338
  2883
deba@338
  2884
    void extractBlossom(int blossom, const Node& base, const Arc& matching) {
deba@338
  2885
      if (_blossom_set->trivial(blossom)) {
deba@338
  2886
        int bi = (*_node_index)[base];
deba@338
  2887
        Value pot = (*_node_data)[bi].pot;
deba@338
  2888
kpeter@628
  2889
        (*_matching)[base] = matching;
deba@338
  2890
        _blossom_node_list.push_back(base);
kpeter@628
  2891
        (*_node_potential)[base] = pot;
deba@338
  2892
      } else {
deba@338
  2893
deba@338
  2894
        Value pot = (*_blossom_data)[blossom].pot;
deba@338
  2895
        int bn = _blossom_node_list.size();
deba@338
  2896
deba@338
  2897
        std::vector<int> subblossoms;
deba@338
  2898
        _blossom_set->split(blossom, std::back_inserter(subblossoms));
deba@338
  2899
        int b = _blossom_set->find(base);
deba@338
  2900
        int ib = -1;
deba@338
  2901
        for (int i = 0; i < int(subblossoms.size()); ++i) {
deba@338
  2902
          if (subblossoms[i] == b) { ib = i; break; }
deba@338
  2903
        }
deba@338
  2904
deba@338
  2905
        for (int i = 1; i < int(subblossoms.size()); i += 2) {
deba@338
  2906
          int sb = subblossoms[(ib + i) % subblossoms.size()];
deba@338
  2907
          int tb = subblossoms[(ib + i + 1) % subblossoms.size()];
deba@338
  2908
deba@338
  2909
          Arc m = (*_blossom_data)[tb].next;
deba@338
  2910
          extractBlossom(sb, _graph.target(m), _graph.oppositeArc(m));
deba@338
  2911
          extractBlossom(tb, _graph.source(m), m);
deba@338
  2912
        }
deba@338
  2913
        extractBlossom(subblossoms[ib], base, matching);
deba@338
  2914
deba@338
  2915
        int en = _blossom_node_list.size();
deba@338
  2916
deba@338
  2917
        _blossom_potential.push_back(BlossomVariable(bn, en, pot));
deba@338
  2918
      }
deba@338
  2919
    }
deba@338
  2920
deba@338
  2921
    void extractMatching() {
deba@338
  2922
      std::vector<int> blossoms;
deba@338
  2923
      for (typename BlossomSet::ClassIt c(*_blossom_set); c != INVALID; ++c) {
deba@338
  2924
        blossoms.push_back(c);
deba@338
  2925
      }
deba@338
  2926
deba@338
  2927
      for (int i = 0; i < int(blossoms.size()); ++i) {
deba@338
  2928
deba@338
  2929
        Value offset = (*_blossom_data)[blossoms[i]].offset;
deba@338
  2930
        (*_blossom_data)[blossoms[i]].pot += 2 * offset;
deba@338
  2931
        for (typename BlossomSet::ItemIt n(*_blossom_set, blossoms[i]);
deba@338
  2932
             n != INVALID; ++n) {
deba@338
  2933
          (*_node_data)[(*_node_index)[n]].pot -= offset;
deba@338
  2934
        }
deba@338
  2935
deba@338
  2936
        Arc matching = (*_blossom_data)[blossoms[i]].next;
deba@338
  2937
        Node base = _graph.source(matching);
deba@338
  2938
        extractBlossom(blossoms[i], base, matching);
deba@338
  2939
      }
deba@338
  2940
    }
deba@338
  2941
deba@338
  2942
  public:
deba@338
  2943
deba@338
  2944
    /// \brief Constructor
deba@338
  2945
    ///
deba@338
  2946
    /// Constructor.
deba@338
  2947
    MaxWeightedPerfectMatching(const Graph& graph, const WeightMap& weight)
deba@338
  2948
      : _graph(graph), _weight(weight), _matching(0),
deba@338
  2949
        _node_potential(0), _blossom_potential(), _blossom_node_list(),
deba@338
  2950
        _node_num(0), _blossom_num(0),
deba@338
  2951
deba@338
  2952
        _blossom_index(0), _blossom_set(0), _blossom_data(0),
deba@338
  2953
        _node_index(0), _node_heap_index(0), _node_data(0),
deba@338
  2954
        _tree_set_index(0), _tree_set(0),
deba@338
  2955
deba@338
  2956
        _delta2_index(0), _delta2(0),
deba@338
  2957
        _delta3_index(0), _delta3(0),
deba@338
  2958
        _delta4_index(0), _delta4(0),
deba@338
  2959
deba@338
  2960
        _delta_sum() {}
deba@338
  2961
deba@338
  2962
    ~MaxWeightedPerfectMatching() {
deba@338
  2963
      destroyStructures();
deba@338
  2964
    }
deba@338
  2965
kpeter@637
  2966
    /// \name Execution Control
alpar@342
  2967
    /// The simplest way to execute the algorithm is to use the
kpeter@637
  2968
    /// \ref run() member function.
deba@338
  2969
deba@338
  2970
    ///@{
deba@338
  2971
deba@338
  2972
    /// \brief Initialize the algorithm
deba@338
  2973
    ///
kpeter@637
  2974
    /// This function initializes the algorithm.
deba@338
  2975
    void init() {
deba@338
  2976
      createStructures();
deba@338
  2977
deba@945
  2978
      _blossom_node_list.clear();
deba@945
  2979
      _blossom_potential.clear();
deba@945
  2980
deba@338
  2981
      for (ArcIt e(_graph); e != INVALID; ++e) {
kpeter@628
  2982
        (*_node_heap_index)[e] = BinHeap<Value, IntArcMap>::PRE_HEAP;
deba@338
  2983
      }
deba@338
  2984
      for (EdgeIt e(_graph); e != INVALID; ++e) {
kpeter@628
  2985
        (*_delta3_index)[e] = _delta3->PRE_HEAP;
deba@338
  2986
      }
deba@338
  2987
      for (int i = 0; i < _blossom_num; ++i) {
kpeter@628
  2988
        (*_delta2_index)[i] = _delta2->PRE_HEAP;
kpeter@628
  2989
        (*_delta4_index)[i] = _delta4->PRE_HEAP;
deba@338
  2990
      }
deba@338
  2991
deba@945
  2992
      _delta2->clear();
deba@945
  2993
      _delta3->clear();
deba@945
  2994
      _delta4->clear();
deba@945
  2995
      _blossom_set->clear();
deba@945
  2996
      _tree_set->clear();
deba@945
  2997
deba@338
  2998
      int index = 0;
deba@338
  2999
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@338
  3000
        Value max = - std::numeric_limits<Value>::max();
deba@338
  3001
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
deba@338
  3002
          if (_graph.target(e) == n) continue;
deba@338
  3003
          if ((dualScale * _weight[e]) / 2 > max) {
deba@338
  3004
            max = (dualScale * _weight[e]) / 2;
deba@338
  3005
          }
deba@338
  3006
        }
kpeter@628
  3007
        (*_node_index)[n] = index;
deba@945
  3008
        (*_node_data)[index].heap_index.clear();
deba@945
  3009
        (*_node_data)[index].heap.clear();
deba@338
  3010
        (*_node_data)[index].pot = max;
deba@338
  3011
        int blossom =
deba@338
  3012
          _blossom_set->insert(n, std::numeric_limits<Value>::max());
deba@338
  3013
deba@338
  3014
        _tree_set->insert(blossom);
deba@338
  3015
deba@338
  3016
        (*_blossom_data)[blossom].status = EVEN;
deba@338
  3017
        (*_blossom_data)[blossom].pred = INVALID;
deba@338
  3018
        (*_blossom_data)[blossom].next = INVALID;
deba@338
  3019
        (*_blossom_data)[blossom].pot = 0;
deba@338
  3020
        (*_blossom_data)[blossom].offset = 0;
deba@338
  3021
        ++index;
deba@338
  3022
      }
deba@338
  3023
      for (EdgeIt e(_graph); e != INVALID; ++e) {
deba@338
  3024
        int si = (*_node_index)[_graph.u(e)];
deba@338
  3025
        int ti = (*_node_index)[_graph.v(e)];
deba@338
  3026
        if (_graph.u(e) != _graph.v(e)) {
deba@338
  3027
          _delta3->push(e, ((*_node_data)[si].pot + (*_node_data)[ti].pot -
deba@338
  3028
                            dualScale * _weight[e]) / 2);
deba@338
  3029
        }
deba@338
  3030
      }
deba@338
  3031
    }
deba@338
  3032
kpeter@637
  3033
    /// \brief Start the algorithm
deba@338
  3034
    ///
kpeter@637
  3035
    /// This function starts the algorithm.
kpeter@637
  3036
    ///
kpeter@637
  3037
    /// \pre \ref init() must be called before using this function.
deba@338
  3038
    bool start() {
deba@338
  3039
      enum OpType {
deba@338
  3040
        D2, D3, D4
deba@338
  3041
      };
deba@338
  3042
deba@338
  3043
      int unmatched = _node_num;
deba@338
  3044
      while (unmatched > 0) {
deba@338
  3045
        Value d2 = !_delta2->empty() ?
deba@338
  3046
          _delta2->prio() : std::numeric_limits<Value>::max();
deba@338
  3047
deba@338
  3048
        Value d3 = !_delta3->empty() ?
deba@338
  3049
          _delta3->prio() : std::numeric_limits<Value>::max();
deba@338
  3050
deba@338
  3051
        Value d4 = !_delta4->empty() ?
deba@338
  3052
          _delta4->prio() : std::numeric_limits<Value>::max();
deba@338
  3053
deba@338
  3054
        _delta_sum = d2; OpType ot = D2;
deba@338
  3055
        if (d3 < _delta_sum) { _delta_sum = d3; ot = D3; }
deba@338
  3056
        if (d4 < _delta_sum) { _delta_sum = d4; ot = D4; }
deba@338
  3057
deba@338
  3058
        if (_delta_sum == std::numeric_limits<Value>::max()) {
deba@338
  3059
          return false;
deba@338
  3060
        }
deba@338
  3061
deba@338
  3062
        switch (ot) {
deba@338
  3063
        case D2:
deba@338
  3064
          {
deba@338
  3065
            int blossom = _delta2->top();
deba@338
  3066
            Node n = _blossom_set->classTop(blossom);
deba@338
  3067
            Arc e = (*_node_data)[(*_node_index)[n]].heap.top();
deba@338
  3068
            extendOnArc(e);
deba@338
  3069
          }
deba@338
  3070
          break;
deba@338
  3071
        case D3:
deba@338
  3072
          {
deba@338
  3073
            Edge e = _delta3->top();
deba@338
  3074
deba@338
  3075
            int left_blossom = _blossom_set->find(_graph.u(e));
deba@338
  3076
            int right_blossom = _blossom_set->find(_graph.v(e));
deba@338
  3077
deba@338
  3078
            if (left_blossom == right_blossom) {
deba@338
  3079
              _delta3->pop();
deba@338
  3080
            } else {
deba@338
  3081
              int left_tree = _tree_set->find(left_blossom);
deba@338
  3082
              int right_tree = _tree_set->find(right_blossom);
deba@338
  3083
deba@338
  3084
              if (left_tree == right_tree) {
deba@339
  3085
                shrinkOnEdge(e, left_tree);
deba@338
  3086
              } else {
deba@339
  3087
                augmentOnEdge(e);
deba@338
  3088
                unmatched -= 2;
deba@338
  3089
              }
deba@338
  3090
            }
deba@338
  3091
          } break;
deba@338
  3092
        case D4:
deba@338
  3093
          splitBlossom(_delta4->top());
deba@338
  3094
          break;
deba@338
  3095
        }
deba@338
  3096
      }
deba@338
  3097
      extractMatching();
deba@338
  3098
      return true;
deba@338
  3099
    }
deba@338
  3100
kpeter@637
  3101
    /// \brief Run the algorithm.
deba@338
  3102
    ///
kpeter@637
  3103
    /// This method runs the \c %MaxWeightedPerfectMatching algorithm.
deba@338
  3104
    ///
kpeter@637
  3105
    /// \note mwpm.run() is just a shortcut of the following code.
deba@338
  3106
    /// \code
kpeter@637
  3107
    ///   mwpm.init();
kpeter@637
  3108
    ///   mwpm.start();
deba@338
  3109
    /// \endcode
deba@338
  3110
    bool run() {
deba@338
  3111
      init();
deba@338
  3112
      return start();
deba@338
  3113
    }
deba@338
  3114
deba@338
  3115
    /// @}
deba@338
  3116
kpeter@637
  3117
    /// \name Primal Solution
kpeter@637
  3118
    /// Functions to get the primal solution, i.e. the maximum weighted 
kpeter@637
  3119
    /// perfect matching.\n
kpeter@637
  3120
    /// Either \ref run() or \ref start() function should be called before
kpeter@637
  3121
    /// using them.
deba@338
  3122
deba@338
  3123
    /// @{
deba@338
  3124
kpeter@637
  3125
    /// \brief Return the weight of the matching.
deba@338
  3126
    ///
kpeter@637
  3127
    /// This function returns the weight of the found matching.
kpeter@637
  3128
    ///
kpeter@637
  3129
    /// \pre Either run() or start() must be called before using this function.
kpeter@640
  3130
    Value matchingWeight() const {
deba@338
  3131
      Value sum = 0;
deba@338
  3132
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@338
  3133
        if ((*_matching)[n] != INVALID) {
deba@338
  3134
          sum += _weight[(*_matching)[n]];
deba@338
  3135
        }
deba@338
  3136
      }
deba@338
  3137
      return sum /= 2;
deba@338
  3138
    }
deba@338
  3139
kpeter@637
  3140
    /// \brief Return \c true if the given edge is in the matching.
deba@338
  3141
    ///
kpeter@637
  3142
    /// This function returns \c true if the given edge is in the found 
kpeter@637
  3143
    /// matching.
kpeter@637
  3144
    ///
kpeter@637
  3145
    /// \pre Either run() or start() must be called before using this function.
deba@339
  3146
    bool matching(const Edge& edge) const {
deba@339
  3147
      return static_cast<const Edge&>((*_matching)[_graph.u(edge)]) == edge;
deba@338
  3148
    }
deba@338
  3149
kpeter@637
  3150
    /// \brief Return the matching arc (or edge) incident to the given node.
deba@338
  3151
    ///
kpeter@637
  3152
    /// This function returns the matching arc (or edge) incident to the
kpeter@637
  3153
    /// given node in the found matching or \c INVALID if the node is 
kpeter@637
  3154
    /// not covered by the matching.
kpeter@637
  3155
    ///
kpeter@637
  3156
    /// \pre Either run() or start() must be called before using this function.
deba@338
  3157
    Arc matching(const Node& node) const {
deba@338
  3158
      return (*_matching)[node];
deba@338
  3159
    }
deba@338
  3160
kpeter@640
  3161
    /// \brief Return a const reference to the matching map.
kpeter@640
  3162
    ///
kpeter@640
  3163
    /// This function returns a const reference to a node map that stores
kpeter@640
  3164
    /// the matching arc (or edge) incident to each node.
kpeter@640
  3165
    const MatchingMap& matchingMap() const {
kpeter@640
  3166
      return *_matching;
kpeter@640
  3167
    }
kpeter@640
  3168
kpeter@637
  3169
    /// \brief Return the mate of the given node.
deba@338
  3170
    ///
kpeter@637
  3171
    /// This function returns the mate of the given node in the found 
kpeter@637
  3172
    /// matching or \c INVALID if the node is not covered by the matching.
kpeter@637
  3173
    ///
kpeter@637
  3174
    /// \pre Either run() or start() must be called before using this function.
deba@338
  3175
    Node mate(const Node& node) const {
deba@338
  3176
      return _graph.target((*_matching)[node]);
deba@338
  3177
    }
deba@338
  3178
deba@338
  3179
    /// @}
deba@338
  3180
kpeter@637
  3181
    /// \name Dual Solution
kpeter@637
  3182
    /// Functions to get the dual solution.\n
kpeter@637
  3183
    /// Either \ref run() or \ref start() function should be called before
kpeter@637
  3184
    /// using them.
deba@338
  3185
deba@338
  3186
    /// @{
deba@338
  3187
kpeter@637
  3188
    /// \brief Return the value of the dual solution.
deba@338
  3189
    ///
kpeter@637
  3190
    /// This function returns the value of the dual solution. 
kpeter@637
  3191
    /// It should be equal to the primal value scaled by \ref dualScale 
kpeter@637
  3192
    /// "dual scale".
kpeter@637
  3193
    ///
kpeter@637
  3194
    /// \pre Either run() or start() must be called before using this function.
deba@338
  3195
    Value dualValue() const {
deba@338
  3196
      Value sum = 0;
deba@338
  3197
      for (NodeIt n(_graph); n != INVALID; ++n) {
deba@338
  3198
        sum += nodeValue(n);
deba@338
  3199
      }
deba@338
  3200
      for (int i = 0; i < blossomNum(); ++i) {
deba@338
  3201
        sum += blossomValue(i) * (blossomSize(i) / 2);
deba@338
  3202
      }
deba@338
  3203
      return sum;
deba@338
  3204
    }
deba@338
  3205
kpeter@637
  3206
    /// \brief Return the dual value (potential) of the given node.
deba@338
  3207
    ///
kpeter@637
  3208
    /// This function returns the dual value (potential) of the given node.
kpeter@637
  3209
    ///
kpeter@637
  3210
    /// \pre Either run() or start() must be called before using this function.
deba@338
  3211
    Value nodeValue(const Node& n) const {
deba@338
  3212
      return (*_node_potential)[n];
deba@338
  3213
    }
deba@338
  3214
kpeter@637
  3215
    /// \brief Return the number of the blossoms in the basis.
deba@338
  3216
    ///
kpeter@637
  3217
    /// This function returns the number of the blossoms in the basis.
kpeter@637
  3218
    ///
kpeter@637
  3219
    /// \pre Either run() or start() must be called before using this function.
deba@338
  3220
    /// \see BlossomIt
deba@338
  3221
    int blossomNum() const {
deba@338
  3222
      return _blossom_potential.size();
deba@338
  3223
    }
deba@338
  3224
kpeter@637
  3225
    /// \brief Return the number of the nodes in the given blossom.
deba@338
  3226
    ///
kpeter@637
  3227
    /// This function returns the number of the nodes in the given blossom.
kpeter@637
  3228
    ///
kpeter@637
  3229
    /// \pre Either run() or start() must be called before using this function.
kpeter@637
  3230
    /// \see BlossomIt
deba@338
  3231
    int blossomSize(int k) const {
deba@338
  3232
      return _blossom_potential[k].end - _blossom_potential[k].begin;
deba@338
  3233
    }
deba@338
  3234
kpeter@637
  3235
    /// \brief Return the dual value (ptential) of the given blossom.
deba@338
  3236
    ///
kpeter@637
  3237
    /// This function returns the dual value (ptential) of the given blossom.
kpeter@637
  3238
    ///
kpeter@637
  3239
    /// \pre Either run() or start() must be called before using this function.
deba@338
  3240
    Value blossomValue(int k) const {
deba@338
  3241
      return _blossom_potential[k].value;
deba@338
  3242
    }
deba@338
  3243
kpeter@637
  3244
    /// \brief Iterator for obtaining the nodes of a blossom.
deba@338
  3245
    ///
kpeter@637
  3246
    /// This class provides an iterator for obtaining the nodes of the 
kpeter@637
  3247
    /// given blossom. It lists a subset of the nodes.
kpeter@637
  3248
    /// Before using this iterator, you must allocate a 
kpeter@637
  3249
    /// MaxWeightedPerfectMatching class and execute it.
deba@338
  3250
    class BlossomIt {
deba@338
  3251
    public:
deba@338
  3252
deba@338
  3253
      /// \brief Constructor.
deba@338
  3254
      ///
kpeter@637
  3255
      /// Constructor to get the nodes of the given variable.
kpeter@637
  3256
      ///
kpeter@637
  3257
      /// \pre Either \ref MaxWeightedPerfectMatching::run() "algorithm.run()" 
kpeter@637
  3258
      /// or \ref MaxWeightedPerfectMatching::start() "algorithm.start()" 
kpeter@637
  3259
      /// must be called before initializing this iterator.
deba@338
  3260
      BlossomIt(const MaxWeightedPerfectMatching& algorithm, int variable)
deba@338
  3261
        : _algorithm(&algorithm)
deba@338
  3262
      {
deba@338
  3263
        _index = _algorithm->_blossom_potential[variable].begin;
deba@338
  3264
        _last = _algorithm->_blossom_potential[variable].end;
deba@338
  3265
      }
deba@338
  3266
kpeter@637
  3267
      /// \brief Conversion to \c Node.
deba@338
  3268
      ///
kpeter@637
  3269
      /// Conversion to \c Node.
deba@338
  3270
      operator Node() const {
deba@339
  3271
        return _algorithm->_blossom_node_list[_index];
deba@338
  3272
      }
deba@338
  3273
deba@338
  3274
      /// \brief Increment operator.
deba@338
  3275
      ///
deba@338
  3276
      /// Increment operator.
deba@338
  3277
      BlossomIt& operator++() {
deba@338
  3278
        ++_index;
deba@338
  3279
        return *this;
deba@338
  3280
      }
deba@338
  3281
deba@339
  3282
      /// \brief Validity checking
deba@339
  3283
      ///
kpeter@637
  3284
      /// This function checks whether the iterator is invalid.
deba@339
  3285
      bool operator==(Invalid) const { return _index == _last; }
deba@339
  3286
deba@339
  3287
      /// \brief Validity checking
deba@339
  3288
      ///
kpeter@637
  3289
      /// This function checks whether the iterator is valid.
deba@339
  3290
      bool operator!=(Invalid) const { return _index != _last; }
deba@338
  3291
deba@338
  3292
    private:
deba@338
  3293
      const MaxWeightedPerfectMatching* _algorithm;
deba@338
  3294
      int _last;
deba@338
  3295
      int _index;
deba@338
  3296
    };
deba@338
  3297
deba@338
  3298
    /// @}
deba@338
  3299
deba@338
  3300
  };
deba@338
  3301
deba@338
  3302
} //END OF NAMESPACE LEMON
deba@338
  3303
deba@338
  3304
#endif //LEMON_MAX_MATCHING_H