lemon/max_matching.h
author deba
Sat, 17 Nov 2007 20:58:11 +0000
changeset 2514 57143c09dc20
parent 2391 14a343be7a5a
child 2548 a3ba22ebccc6
permissions -rwxr-xr-x
Redesign the maximum flow algorithms

Redesigned interface
Preflow changed to use elevator
Edmonds-Karp does not use the ResGraphAdaptor
Goldberg-Tarjan algorithm (Preflow with Dynamic Trees)
Dinitz-Sleator-Tarjan (Blocking flow with Dynamic Tree)
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@2391
     5
 * Copyright (C) 2003-2007
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
jacint@1077
    22
#include <queue>
deba@1993
    23
#include <lemon/bits/invalid.h>
jacint@1093
    24
#include <lemon/unionfind.h>
jacint@1077
    25
#include <lemon/graph_utils.h>
jacint@1077
    26
deba@2042
    27
///\ingroup matching
jacint@1077
    28
///\file
deba@2042
    29
///\brief Maximum matching algorithm in undirected graph.
jacint@1077
    30
jacint@1077
    31
namespace lemon {
jacint@1077
    32
deba@2505
    33
  ///\ingroup matching
jacint@1077
    34
deba@2505
    35
  ///\brief Edmonds' alternating forest maximum matching algorithm.
deba@2505
    36
  ///
jacint@1077
    37
  ///This class provides Edmonds' alternating forest matching
jacint@1077
    38
  ///algorithm. The starting matching (if any) can be passed to the
deba@2505
    39
  ///algorithm using some of init functions.
jacint@1077
    40
  ///
jacint@1077
    41
  ///The dual side of a matching is a map of the nodes to
deba@2505
    42
  ///MaxMatching::DecompType, having values \c D, \c A and \c C
deba@2505
    43
  ///showing the Gallai-Edmonds decomposition of the graph. The nodes
deba@2505
    44
  ///in \c D induce a graph with factor-critical components, the nodes
deba@2505
    45
  ///in \c A form the barrier, and the nodes in \c C induce a graph
deba@2505
    46
  ///having a perfect matching. This decomposition can be attained by
deba@2505
    47
  ///calling \c decomposition() after running the algorithm.
jacint@1077
    48
  ///
jacint@1077
    49
  ///\param Graph The undirected graph type the algorithm runs on.
jacint@1077
    50
  ///
jacint@1077
    51
  ///\author Jacint Szabo  
jacint@1077
    52
  template <typename Graph>
jacint@1077
    53
  class MaxMatching {
jacint@1165
    54
jacint@1165
    55
  protected:
jacint@1165
    56
jacint@1077
    57
    typedef typename Graph::Node Node;
jacint@1077
    58
    typedef typename Graph::Edge Edge;
klao@1909
    59
    typedef typename Graph::UEdge UEdge;
klao@1909
    60
    typedef typename Graph::UEdgeIt UEdgeIt;
jacint@1077
    61
    typedef typename Graph::NodeIt NodeIt;
jacint@1077
    62
    typedef typename Graph::IncEdgeIt IncEdgeIt;
jacint@1077
    63
deba@2205
    64
    typedef typename Graph::template NodeMap<int> UFECrossRef;
deba@2308
    65
    typedef UnionFindEnum<UFECrossRef> UFE;
deba@2505
    66
    typedef std::vector<Node> NV;
deba@2505
    67
deba@2505
    68
    typedef typename Graph::template NodeMap<int> EFECrossRef;
deba@2505
    69
    typedef ExtendFindEnum<EFECrossRef> EFE;
jacint@1077
    70
jacint@1077
    71
  public:
jacint@1077
    72
    
deba@2505
    73
    ///\brief Indicates the Gallai-Edmonds decomposition of the graph.
deba@2505
    74
    ///
jacint@1077
    75
    ///Indicates the Gallai-Edmonds decomposition of the graph, which
jacint@1077
    76
    ///shows an upper bound on the size of a maximum matching. The
deba@2505
    77
    ///nodes with DecompType \c D induce a graph with factor-critical
jacint@1077
    78
    ///components, the nodes in \c A form the canonical barrier, and the
jacint@1077
    79
    ///nodes in \c C induce a graph having a perfect matching. 
deba@2505
    80
    enum DecompType {
jacint@1077
    81
      D=0,
jacint@1077
    82
      A=1,
jacint@1077
    83
      C=2
jacint@1077
    84
    }; 
jacint@1077
    85
jacint@1165
    86
  protected:
jacint@1077
    87
jacint@1077
    88
    static const int HEUR_density=2;
jacint@1077
    89
    const Graph& g;
jacint@1093
    90
    typename Graph::template NodeMap<Node> _mate;
deba@2505
    91
    typename Graph::template NodeMap<DecompType> position;
jacint@1077
    92
     
jacint@1077
    93
  public:
jacint@1077
    94
    
deba@2505
    95
    MaxMatching(const Graph& _g) 
deba@2505
    96
      : g(_g), _mate(_g), position(_g) {}
jacint@1077
    97
deba@2505
    98
    ///\brief Sets the actual matching to the empty matching.
deba@2505
    99
    ///
deba@2505
   100
    ///Sets the actual matching to the empty matching.  
deba@2505
   101
    ///
deba@2505
   102
    void init() {
alpar@1587
   103
      for(NodeIt v(g); v!=INVALID; ++v) {
deba@2505
   104
	_mate.set(v,INVALID);      
deba@2505
   105
	position.set(v,C);
alpar@1587
   106
      }
alpar@1587
   107
    }
alpar@1587
   108
deba@2505
   109
    ///\brief Finds a greedy matching for initial matching.
deba@2505
   110
    ///
deba@2505
   111
    ///For initial matchig it finds a maximal greedy matching.
deba@2505
   112
    void greedyInit() {
deba@2505
   113
      for(NodeIt v(g); v!=INVALID; ++v) {
deba@2505
   114
	_mate.set(v,INVALID);      
deba@2505
   115
	position.set(v,C);
deba@2505
   116
      }
alpar@1587
   117
      for(NodeIt v(g); v!=INVALID; ++v)
alpar@1587
   118
	if ( _mate[v]==INVALID ) {
alpar@1587
   119
	  for( IncEdgeIt e(g,v); e!=INVALID ; ++e ) {
alpar@1587
   120
	    Node y=g.runningNode(e);
alpar@1587
   121
	    if ( _mate[y]==INVALID && y!=v ) {
alpar@1587
   122
	      _mate.set(v,y);
alpar@1587
   123
	      _mate.set(y,v);
alpar@1587
   124
	      break;
alpar@1587
   125
	    }
alpar@1587
   126
	  }
alpar@1587
   127
	} 
alpar@1587
   128
    }
jacint@1077
   129
deba@2505
   130
    ///\brief Initialize the matching from each nodes' mate.
deba@2505
   131
    ///
deba@2505
   132
    ///Initialize the matching from a \c Node valued \c Node map. This
deba@2505
   133
    ///map must be \e symmetric, i.e. if \c map[u]==v then \c
deba@2505
   134
    ///map[v]==u must hold, and \c uv will be an edge of the initial
deba@2505
   135
    ///matching.
deba@2505
   136
    template <typename MateMap>
deba@2505
   137
    void mateMapInit(MateMap& map) {
deba@2505
   138
      for(NodeIt v(g); v!=INVALID; ++v) {
deba@2505
   139
	_mate.set(v,map[v]);
deba@2505
   140
	position.set(v,C);
deba@2505
   141
      } 
deba@2505
   142
    }
jacint@1077
   143
deba@2505
   144
    ///\brief Initialize the matching from a node map with the
deba@2505
   145
    ///incident matching edges.
deba@2505
   146
    ///
deba@2505
   147
    ///Initialize the matching from an \c UEdge valued \c Node map. \c
deba@2505
   148
    ///map[v] must be an \c UEdge incident to \c v. This map must have
deba@2505
   149
    ///the property that if \c g.oppositeNode(u,map[u])==v then \c \c
deba@2505
   150
    ///g.oppositeNode(v,map[v])==u holds, and now some edge joining \c
deba@2505
   151
    ///u to \c v will be an edge of the matching.
deba@2505
   152
    template<typename MatchingMap>
deba@2505
   153
    void matchingMapInit(MatchingMap& map) {
deba@2505
   154
      for(NodeIt v(g); v!=INVALID; ++v) {
deba@2505
   155
	position.set(v,C);
deba@2505
   156
	UEdge e=map[v];
deba@2505
   157
	if ( e!=INVALID )
deba@2505
   158
	  _mate.set(v,g.oppositeNode(v,e));
deba@2505
   159
	else 
deba@2505
   160
	  _mate.set(v,INVALID);
deba@2505
   161
      } 
deba@2505
   162
    } 
deba@2505
   163
deba@2505
   164
    ///\brief Initialize the matching from the map containing the
deba@2505
   165
    ///undirected matching edges.
deba@2505
   166
    ///
deba@2505
   167
    ///Initialize the matching from a \c bool valued \c UEdge map. This
deba@2505
   168
    ///map must have the property that there are no two incident edges
deba@2505
   169
    ///\c e, \c f with \c map[e]==map[f]==true. The edges \c e with \c
deba@2505
   170
    ///map[e]==true form the matching.
deba@2505
   171
    template <typename MatchingMap>
deba@2505
   172
    void matchingInit(MatchingMap& map) {
deba@2505
   173
      for(NodeIt v(g); v!=INVALID; ++v) {
deba@2505
   174
	_mate.set(v,INVALID);      
deba@2505
   175
	position.set(v,C);
deba@2505
   176
      }
deba@2505
   177
      for(UEdgeIt e(g); e!=INVALID; ++e) {
deba@2505
   178
	if ( map[e] ) {
deba@2505
   179
	  Node u=g.source(e);	  
deba@2505
   180
	  Node v=g.target(e);
deba@2505
   181
	  _mate.set(u,v);
deba@2505
   182
	  _mate.set(v,u);
deba@2505
   183
	} 
deba@2505
   184
      } 
deba@2505
   185
    }
deba@2505
   186
deba@2505
   187
deba@2505
   188
    ///\brief Runs Edmonds' algorithm.
deba@2505
   189
    ///
deba@2505
   190
    ///Runs Edmonds' algorithm for sparse graphs (number of edges <
deba@2505
   191
    ///2*number of nodes), and a heuristical Edmonds' algorithm with a
deba@2505
   192
    ///heuristic of postponing shrinks for dense graphs. 
deba@2505
   193
    void run() {
deba@2505
   194
      if (countUEdges(g) < HEUR_density * countNodes(g)) {
deba@2505
   195
	greedyInit();
deba@2505
   196
	startSparse();
deba@2505
   197
      } else {
deba@2505
   198
	init();
deba@2505
   199
	startDense();
deba@2505
   200
      }
deba@2505
   201
    }
deba@2505
   202
deba@2505
   203
deba@2505
   204
    ///\brief Starts Edmonds' algorithm.
deba@2505
   205
    /// 
deba@2505
   206
    ///If runs the original Edmonds' algorithm.  
deba@2505
   207
    void startSparse() {
deba@2505
   208
            
deba@2505
   209
      typename Graph::template NodeMap<Node> ear(g,INVALID); 
deba@2505
   210
      //undefined for the base nodes of the blossoms (i.e. for the
deba@2505
   211
      //representative elements of UFE blossom) and for the nodes in C 
deba@2505
   212
      
deba@2505
   213
      UFECrossRef blossom_base(g);
deba@2505
   214
      UFE blossom(blossom_base);
deba@2505
   215
      NV rep(countNodes(g));
deba@2505
   216
deba@2505
   217
      EFECrossRef tree_base(g);
deba@2505
   218
      EFE tree(tree_base);
deba@2505
   219
deba@2505
   220
      //If these UFE's would be members of the class then also
deba@2505
   221
      //blossom_base and tree_base should be a member.
deba@2505
   222
      
deba@2505
   223
      //We build only one tree and the other vertices uncovered by the
deba@2505
   224
      //matching belong to C. (They can be considered as singleton
deba@2505
   225
      //trees.) If this tree can be augmented or no more
deba@2505
   226
      //grow/augmentation/shrink is possible then we return to this
deba@2505
   227
      //"for" cycle.
deba@2505
   228
      for(NodeIt v(g); v!=INVALID; ++v) {
deba@2505
   229
	if (position[v]==C && _mate[v]==INVALID) {
deba@2505
   230
	  rep[blossom.insert(v)] = v;
deba@2505
   231
	  tree.insert(v); 
deba@2505
   232
	  position.set(v,D);
deba@2505
   233
	  normShrink(v, ear, blossom, rep, tree);
deba@2505
   234
	}
deba@2505
   235
      }
deba@2505
   236
    }
deba@2505
   237
deba@2505
   238
    ///\brief Starts Edmonds' algorithm.
deba@2505
   239
    /// 
deba@2505
   240
    ///It runs Edmonds' algorithm with a heuristic of postponing
deba@2505
   241
    ///shrinks, giving a faster algorithm for dense graphs.
deba@2505
   242
    void startDense() {
deba@2505
   243
            
deba@2505
   244
      typename Graph::template NodeMap<Node> ear(g,INVALID); 
deba@2505
   245
      //undefined for the base nodes of the blossoms (i.e. for the
deba@2505
   246
      //representative elements of UFE blossom) and for the nodes in C 
deba@2505
   247
      
deba@2505
   248
      UFECrossRef blossom_base(g);
deba@2505
   249
      UFE blossom(blossom_base);
deba@2505
   250
      NV rep(countNodes(g));
deba@2505
   251
deba@2505
   252
      EFECrossRef tree_base(g);
deba@2505
   253
      EFE tree(tree_base);
deba@2505
   254
deba@2505
   255
      //If these UFE's would be members of the class then also
deba@2505
   256
      //blossom_base and tree_base should be a member.
deba@2505
   257
      
deba@2505
   258
      //We build only one tree and the other vertices uncovered by the
deba@2505
   259
      //matching belong to C. (They can be considered as singleton
deba@2505
   260
      //trees.) If this tree can be augmented or no more
deba@2505
   261
      //grow/augmentation/shrink is possible then we return to this
deba@2505
   262
      //"for" cycle.
deba@2505
   263
      for(NodeIt v(g); v!=INVALID; ++v) {
deba@2505
   264
	if ( position[v]==C && _mate[v]==INVALID ) {
deba@2505
   265
	  rep[blossom.insert(v)] = v;
deba@2505
   266
	  tree.insert(v); 
deba@2505
   267
	  position.set(v,D);
deba@2505
   268
	  lateShrink(v, ear, blossom, rep, tree);
deba@2505
   269
	}
deba@2505
   270
      }
deba@2505
   271
    }
deba@2505
   272
deba@2505
   273
deba@2505
   274
deba@2505
   275
    ///\brief Returns the size of the actual matching stored.
deba@2505
   276
    ///
jacint@1077
   277
    ///Returns the size of the actual matching stored. After \ref
jacint@1077
   278
    ///run() it returns the size of a maximum matching in the graph.
alpar@1587
   279
    int size() const {
alpar@1587
   280
      int s=0;
alpar@1587
   281
      for(NodeIt v(g); v!=INVALID; ++v) {
alpar@1587
   282
	if ( _mate[v]!=INVALID ) {
alpar@1587
   283
	  ++s;
alpar@1587
   284
	}
alpar@1587
   285
      }
alpar@1587
   286
      return s/2;
alpar@1587
   287
    }
alpar@1587
   288
jacint@1077
   289
deba@2505
   290
    ///\brief Returns the mate of a node in the actual matching.
jacint@1077
   291
    ///
jacint@1093
   292
    ///Returns the mate of a \c node in the actual matching. 
jacint@1093
   293
    ///Returns INVALID if the \c node is not covered by the actual matching. 
deba@2505
   294
    Node mate(const Node& node) const {
jacint@1093
   295
      return _mate[node];
jacint@1093
   296
    } 
jacint@1093
   297
deba@2505
   298
    ///\brief Returns the matching edge incident to the given node.
deba@2505
   299
    ///
deba@2505
   300
    ///Returns the matching edge of a \c node in the actual matching. 
deba@2505
   301
    ///Returns INVALID if the \c node is not covered by the actual matching. 
deba@2505
   302
    UEdge matchingEdge(const Node& node) const {
deba@2505
   303
      if (_mate[node] == INVALID) return INVALID;
deba@2505
   304
      Node n = node < _mate[node] ? node : _mate[node];
deba@2505
   305
      for (IncEdgeIt e(g, n); e != INVALID; ++e) {
deba@2505
   306
	if (g.oppositeNode(n, e) == _mate[n]) {
deba@2505
   307
	  return e;
deba@2505
   308
	}
deba@2505
   309
      }
deba@2505
   310
      return INVALID;
deba@2505
   311
    } 
jacint@1077
   312
deba@2505
   313
    /// \brief Returns the class of the node in the Edmonds-Gallai
deba@2505
   314
    /// decomposition.
deba@2505
   315
    ///
deba@2505
   316
    /// Returns the class of the node in the Edmonds-Gallai
deba@2505
   317
    /// decomposition.
deba@2505
   318
    DecompType decomposition(const Node& n) {
deba@2505
   319
      return position[n] == A;
deba@2505
   320
    }
deba@2505
   321
deba@2505
   322
    /// \brief Returns true when the node is in the barrier.
deba@2505
   323
    ///
deba@2505
   324
    /// Returns true when the node is in the barrier.
deba@2505
   325
    bool barrier(const Node& n) {
deba@2505
   326
      return position[n] == A;
deba@2505
   327
    }
jacint@1077
   328
    
deba@2505
   329
    ///\brief Gives back the matching in a \c Node of mates.
deba@2505
   330
    ///
jacint@1165
   331
    ///Writes the stored matching to a \c Node valued \c Node map. The
jacint@1077
   332
    ///resulting map will be \e symmetric, i.e. if \c map[u]==v then \c
jacint@1077
   333
    ///map[v]==u will hold, and now \c uv is an edge of the matching.
deba@2505
   334
    template <typename MateMap>
deba@2505
   335
    void mateMap(MateMap& map) const {
jacint@1077
   336
      for(NodeIt v(g); v!=INVALID; ++v) {
jacint@1093
   337
	map.set(v,_mate[v]);   
jacint@1077
   338
      } 
jacint@1077
   339
    } 
jacint@1077
   340
    
deba@2505
   341
    ///\brief Gives back the matching in an \c UEdge valued \c Node
deba@2505
   342
    ///map.
deba@2505
   343
    ///
klao@1909
   344
    ///Writes the stored matching to an \c UEdge valued \c Node
klao@1909
   345
    ///map. \c map[v] will be an \c UEdge incident to \c v. This
jacint@1165
   346
    ///map will have the property that if \c g.oppositeNode(u,map[u])
jacint@1165
   347
    ///== v then \c map[u]==map[v] holds, and now this edge is an edge
jacint@1165
   348
    ///of the matching.
deba@2505
   349
    template <typename MatchingMap>
deba@2505
   350
    void matchingMap(MatchingMap& map)  const {
jacint@1077
   351
      typename Graph::template NodeMap<bool> todo(g,true); 
jacint@1077
   352
      for(NodeIt v(g); v!=INVALID; ++v) {
deba@2505
   353
	if (_mate[v]!=INVALID && v < _mate[v]) {
jacint@1093
   354
	  Node u=_mate[v];
jacint@1077
   355
	  for(IncEdgeIt e(g,v); e!=INVALID; ++e) {
klao@1158
   356
	    if ( g.runningNode(e) == u ) {
jacint@1077
   357
	      map.set(u,e);
jacint@1077
   358
	      map.set(v,e);
jacint@1077
   359
	      todo.set(u,false);
jacint@1077
   360
	      todo.set(v,false);
jacint@1077
   361
	      break;
jacint@1077
   362
	    }
jacint@1077
   363
	  }
jacint@1077
   364
	}
jacint@1077
   365
      } 
jacint@1077
   366
    }
jacint@1077
   367
jacint@1077
   368
deba@2505
   369
    ///\brief Gives back the matching in a \c bool valued \c UEdge
deba@2505
   370
    ///map.
deba@2505
   371
    ///
jacint@1165
   372
    ///Writes the matching stored to a \c bool valued \c Edge
jacint@1165
   373
    ///map. This map will have the property that there are no two
jacint@1165
   374
    ///incident edges \c e, \c f with \c map[e]==map[f]==true. The
jacint@1165
   375
    ///edges \c e with \c map[e]==true form the matching.
deba@2505
   376
    template<typename MatchingMap>
deba@2505
   377
    void matching(MatchingMap& map) const {
klao@1909
   378
      for(UEdgeIt e(g); e!=INVALID; ++e) map.set(e,false);
jacint@1077
   379
jacint@1077
   380
      typename Graph::template NodeMap<bool> todo(g,true); 
jacint@1077
   381
      for(NodeIt v(g); v!=INVALID; ++v) {
jacint@1093
   382
	if ( todo[v] && _mate[v]!=INVALID ) {
jacint@1093
   383
	  Node u=_mate[v];
jacint@1077
   384
	  for(IncEdgeIt e(g,v); e!=INVALID; ++e) {
klao@1158
   385
	    if ( g.runningNode(e) == u ) {
jacint@1077
   386
	      map.set(e,true);
jacint@1077
   387
	      todo.set(u,false);
jacint@1077
   388
	      todo.set(v,false);
jacint@1077
   389
	      break;
jacint@1077
   390
	    }
jacint@1077
   391
	  }
jacint@1077
   392
	}
jacint@1077
   393
      } 
jacint@1077
   394
    }
jacint@1077
   395
jacint@1077
   396
deba@2505
   397
    ///\brief Returns the canonical decomposition of the graph after running
jacint@1077
   398
    ///the algorithm.
deba@2505
   399
    ///
jacint@1090
   400
    ///After calling any run methods of the class, it writes the
jacint@1090
   401
    ///Gallai-Edmonds canonical decomposition of the graph. \c map
deba@2505
   402
    ///must be a node map of \ref DecompType 's.
deba@2505
   403
    template <typename DecompositionMap>
deba@2505
   404
    void decomposition(DecompositionMap& map) const {
deba@2505
   405
      for(NodeIt v(g); v!=INVALID; ++v) map.set(v,position[v]);
deba@2505
   406
    }
deba@2505
   407
deba@2505
   408
    ///\brief Returns a barrier on the nodes.
deba@2505
   409
    ///
deba@2505
   410
    ///After calling any run methods of the class, it writes a
deba@2505
   411
    ///canonical barrier on the nodes. The odd component number of the
deba@2505
   412
    ///remaining graph minus the barrier size is a lower bound for the
deba@2505
   413
    ///uncovered nodes in the graph. The \c map must be a node map of
deba@2505
   414
    ///bools.
deba@2505
   415
    template <typename BarrierMap>
deba@2505
   416
    void barrier(BarrierMap& barrier) {
deba@2505
   417
      for(NodeIt v(g); v!=INVALID; ++v) barrier.set(v,position[v] == A);    
jacint@1077
   418
    }
jacint@1077
   419
jacint@1077
   420
  private: 
jacint@1077
   421
jacint@1165
   422
 
jacint@1077
   423
    void lateShrink(Node v, typename Graph::template NodeMap<Node>& ear,  
deba@2505
   424
		    UFE& blossom, NV& rep, EFE& tree) {
deba@2505
   425
      //We have one tree which we grow, and also shrink but only if it
deba@2505
   426
      //cannot be postponed. If we augment then we return to the "for"
deba@2505
   427
      //cycle of runEdmonds().
deba@2505
   428
deba@2505
   429
      std::queue<Node> Q;   //queue of the totally unscanned nodes
deba@2505
   430
      Q.push(v);  
deba@2505
   431
      std::queue<Node> R;   
deba@2505
   432
      //queue of the nodes which must be scanned for a possible shrink
deba@2505
   433
      
deba@2505
   434
      while ( !Q.empty() ) {
deba@2505
   435
	Node x=Q.front();
deba@2505
   436
	Q.pop();
deba@2505
   437
	for( IncEdgeIt e(g,x); e!= INVALID; ++e ) {
deba@2505
   438
	  Node y=g.runningNode(e);
deba@2505
   439
	  //growOrAugment grows if y is covered by the matching and
deba@2505
   440
	  //augments if not. In this latter case it returns 1.
deba@2505
   441
	  if (position[y]==C && 
deba@2505
   442
	      growOrAugment(y, x, ear, blossom, rep, tree, Q)) return;
deba@2505
   443
	}
deba@2505
   444
	R.push(x);
deba@2505
   445
      }
deba@2505
   446
      
deba@2505
   447
      while ( !R.empty() ) {
deba@2505
   448
	Node x=R.front();
deba@2505
   449
	R.pop();
deba@2505
   450
	
deba@2505
   451
	for( IncEdgeIt e(g,x); e!=INVALID ; ++e ) {
deba@2505
   452
	  Node y=g.runningNode(e);
deba@2505
   453
deba@2505
   454
	  if ( position[y] == D && blossom.find(x) != blossom.find(y) )  
deba@2505
   455
	    //Recall that we have only one tree.
deba@2505
   456
	    shrink( x, y, ear, blossom, rep, tree, Q);	
deba@2505
   457
	
deba@2505
   458
	  while ( !Q.empty() ) {
deba@2505
   459
	    Node z=Q.front();
deba@2505
   460
	    Q.pop();
deba@2505
   461
	    for( IncEdgeIt f(g,z); f!= INVALID; ++f ) {
deba@2505
   462
	      Node w=g.runningNode(f);
deba@2505
   463
	      //growOrAugment grows if y is covered by the matching and
deba@2505
   464
	      //augments if not. In this latter case it returns 1.
deba@2505
   465
	      if (position[w]==C && 
deba@2505
   466
		  growOrAugment(w, z, ear, blossom, rep, tree, Q)) return;
deba@2505
   467
	    }
deba@2505
   468
	    R.push(z);
deba@2505
   469
	  }
deba@2505
   470
	} //for e
deba@2505
   471
      } // while ( !R.empty() )
deba@2505
   472
    }
jacint@1077
   473
alpar@1234
   474
    void normShrink(Node v, typename Graph::template NodeMap<Node>& ear,  
deba@2505
   475
		    UFE& blossom, NV& rep, EFE& tree) {
deba@2505
   476
      //We have one tree, which we grow and shrink. If we augment then we
deba@2505
   477
      //return to the "for" cycle of runEdmonds().
deba@2505
   478
    
deba@2505
   479
      std::queue<Node> Q;   //queue of the unscanned nodes
deba@2505
   480
      Q.push(v);  
deba@2505
   481
      while ( !Q.empty() ) {
deba@2505
   482
deba@2505
   483
	Node x=Q.front();
deba@2505
   484
	Q.pop();
deba@2505
   485
	
deba@2505
   486
	for( IncEdgeIt e(g,x); e!=INVALID; ++e ) {
deba@2505
   487
	  Node y=g.runningNode(e);
deba@2505
   488
	      
deba@2505
   489
	  switch ( position[y] ) {
deba@2505
   490
	  case D:          //x and y must be in the same tree
deba@2505
   491
	    if ( blossom.find(x) != blossom.find(y))
deba@2505
   492
	      //x and y are in the same tree
deba@2505
   493
	      shrink(x, y, ear, blossom, rep, tree, Q);
deba@2505
   494
	    break;
deba@2505
   495
	  case C:
deba@2505
   496
	    //growOrAugment grows if y is covered by the matching and
deba@2505
   497
	    //augments if not. In this latter case it returns 1.
deba@2505
   498
	    if (growOrAugment(y, x, ear, blossom, rep, tree, Q)) return;
deba@2505
   499
	    break;
deba@2505
   500
	  default: break;
deba@2505
   501
	  }
deba@2505
   502
	}
deba@2505
   503
      }
deba@2505
   504
    }
jacint@1077
   505
jacint@2023
   506
    void shrink(Node x,Node y, typename Graph::template NodeMap<Node>& ear,  
deba@2505
   507
		UFE& blossom, NV& rep, EFE& tree,std::queue<Node>& Q) {
deba@2505
   508
      //x and y are the two adjacent vertices in two blossoms.
deba@2505
   509
   
deba@2505
   510
      typename Graph::template NodeMap<bool> path(g,false);
deba@2505
   511
    
deba@2505
   512
      Node b=rep[blossom.find(x)];
deba@2505
   513
      path.set(b,true);
deba@2505
   514
      b=_mate[b];
deba@2505
   515
      while ( b!=INVALID ) { 
deba@2505
   516
	b=rep[blossom.find(ear[b])];
deba@2505
   517
	path.set(b,true);
deba@2505
   518
	b=_mate[b];
deba@2505
   519
      } //we go until the root through bases of blossoms and odd vertices
deba@2505
   520
    
deba@2505
   521
      Node top=y;
deba@2505
   522
      Node middle=rep[blossom.find(top)];
deba@2505
   523
      Node bottom=x;
deba@2505
   524
      while ( !path[middle] )
deba@2505
   525
	shrinkStep(top, middle, bottom, ear, blossom, rep, tree, Q);
deba@2505
   526
      //Until we arrive to a node on the path, we update blossom, tree
deba@2505
   527
      //and the positions of the odd nodes.
deba@2505
   528
    
deba@2505
   529
      Node base=middle;
deba@2505
   530
      top=x;
deba@2505
   531
      middle=rep[blossom.find(top)];
deba@2505
   532
      bottom=y;
deba@2505
   533
      Node blossom_base=rep[blossom.find(base)];
deba@2505
   534
      while ( middle!=blossom_base )
deba@2505
   535
	shrinkStep(top, middle, bottom, ear, blossom, rep, tree, Q);
deba@2505
   536
      //Until we arrive to a node on the path, we update blossom, tree
deba@2505
   537
      //and the positions of the odd nodes.
deba@2505
   538
    
deba@2505
   539
      rep[blossom.find(base)] = base;
deba@2505
   540
    }
jacint@1077
   541
alpar@1234
   542
    void shrinkStep(Node& top, Node& middle, Node& bottom,
alpar@1234
   543
		    typename Graph::template NodeMap<Node>& ear,  
deba@2505
   544
		    UFE& blossom, NV& rep, EFE& tree, std::queue<Node>& Q) {
deba@2505
   545
      //We traverse a blossom and update everything.
deba@2505
   546
    
deba@2505
   547
      ear.set(top,bottom);
deba@2505
   548
      Node t=top;
deba@2505
   549
      while ( t!=middle ) {
deba@2505
   550
	Node u=_mate[t];
deba@2505
   551
	t=ear[u];
deba@2505
   552
	ear.set(t,u);
deba@2505
   553
      } 
deba@2505
   554
      bottom=_mate[middle];
deba@2505
   555
      position.set(bottom,D);
deba@2505
   556
      Q.push(bottom);
deba@2505
   557
      top=ear[bottom];		
deba@2505
   558
      Node oldmiddle=middle;
deba@2505
   559
      middle=rep[blossom.find(top)];
deba@2505
   560
      tree.erase(bottom);
deba@2505
   561
      tree.erase(oldmiddle);
deba@2505
   562
      blossom.insert(bottom);
deba@2505
   563
      blossom.join(bottom, oldmiddle);
deba@2505
   564
      blossom.join(top, oldmiddle);
deba@2505
   565
    }
deba@2505
   566
deba@2505
   567
jacint@1077
   568
jacint@2023
   569
    bool growOrAugment(Node& y, Node& x, typename Graph::template 
deba@2505
   570
		       NodeMap<Node>& ear, UFE& blossom, NV& rep, EFE& tree, 
deba@2505
   571
		       std::queue<Node>& Q) {
deba@2505
   572
      //x is in a blossom in the tree, y is outside. If y is covered by
deba@2505
   573
      //the matching we grow, otherwise we augment. In this case we
deba@2505
   574
      //return 1.
deba@2505
   575
    
deba@2505
   576
      if ( _mate[y]!=INVALID ) {       //grow
deba@2505
   577
	ear.set(y,x);
deba@2505
   578
	Node w=_mate[y];
deba@2505
   579
	rep[blossom.insert(w)] = w;
deba@2505
   580
	position.set(y,A);
deba@2505
   581
	position.set(w,D);
deba@2505
   582
	int t = tree.find(rep[blossom.find(x)]);
deba@2505
   583
	tree.insert(y,t);  
deba@2505
   584
	tree.insert(w,t);  
deba@2505
   585
	Q.push(w);
deba@2505
   586
      } else {                      //augment 
deba@2505
   587
	augment(x, ear, blossom, rep, tree);
deba@2505
   588
	_mate.set(x,y);
deba@2505
   589
	_mate.set(y,x);
deba@2505
   590
	return true;
deba@2505
   591
      }
deba@2505
   592
      return false;
deba@2505
   593
    }
jacint@2023
   594
alpar@1234
   595
    void augment(Node x, typename Graph::template NodeMap<Node>& ear,  
deba@2505
   596
		 UFE& blossom, NV& rep, EFE& tree) {
deba@2505
   597
      Node v=_mate[x];
deba@2505
   598
      while ( v!=INVALID ) {
deba@2505
   599
	
deba@2505
   600
	Node u=ear[v];
deba@2505
   601
	_mate.set(v,u);
deba@2505
   602
	Node tmp=v;
deba@2505
   603
	v=_mate[u];
deba@2505
   604
	_mate.set(u,tmp);
deba@2505
   605
      }
deba@2505
   606
      int y = tree.find(rep[blossom.find(x)]);
deba@2505
   607
      for (typename EFE::ItemIt tit(tree, y); tit != INVALID; ++tit) {   
deba@2505
   608
	if ( position[tit] == D ) {
deba@2505
   609
	  int b = blossom.find(tit);
deba@2505
   610
	  for (typename UFE::ItemIt bit(blossom, b); bit != INVALID; ++bit) { 
deba@2505
   611
	    position.set(bit, C);
deba@2505
   612
	  }
deba@2505
   613
	  blossom.eraseClass(b);
deba@2505
   614
	} else position.set(tit, C);
deba@2505
   615
      }
deba@2505
   616
      tree.eraseClass(y);
deba@2505
   617
deba@2505
   618
    }
jacint@1077
   619
jacint@1077
   620
  };
jacint@1077
   621
  
jacint@1077
   622
} //END OF NAMESPACE LEMON
jacint@1077
   623
jacint@1165
   624
#endif //LEMON_MAX_MATCHING_H