lemon/max_matching.h
author Peter Kovacs <kpeter@inf.elte.hu>
Fri, 03 Apr 2009 18:59:15 +0200
changeset 600 6ac5d9ae1d3d
parent 425 cace3206223b
child 550 c5fd2d996909
permissions -rw-r--r--
Support real types + numerical stability fix in NS (#254)

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