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