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