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