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