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