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