lemon/pr_bipartite_matching.h
author alpar
Mon, 01 Oct 2007 18:57:21 +0000
changeset 2483 bf6d7b624d5c
parent 2463 19651a04d056
child 2512 371cf309fc3c
permissions -rw-r--r--
- Gamma distributon random variable.
- Test file for random.h
alpar@2353
     1
/* -*- C++ -*-
alpar@2353
     2
 *
alpar@2391
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@2391
     4
 *
alpar@2391
     5
 * Copyright (C) 2003-2007
alpar@2391
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@2353
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@2353
     8
 *
alpar@2353
     9
 * Permission to use, modify and distribute this software is granted
alpar@2353
    10
 * provided that this copyright notice appears in all copies. For
alpar@2353
    11
 * precise terms see the accompanying LICENSE file.
alpar@2353
    12
 *
alpar@2353
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@2353
    14
 * express or implied, and with no claim as to its suitability for any
alpar@2353
    15
 * purpose.
alpar@2353
    16
 *
alpar@2353
    17
 */
alpar@2353
    18
deba@2462
    19
#ifndef LEMON_PR_BIPARTITE_MATCHING
deba@2462
    20
#define LEMON_PR_BIPARTITE_MATCHING
alpar@2353
    21
alpar@2353
    22
#include <lemon/graph_utils.h>
alpar@2353
    23
#include <lemon/iterable_maps.h>
alpar@2353
    24
#include <iostream>
alpar@2353
    25
#include <queue>
alpar@2353
    26
#include <lemon/elevator.h>
alpar@2353
    27
alpar@2353
    28
///\ingroup matching
alpar@2353
    29
///\file
alpar@2353
    30
///\brief Push-prelabel maximum matching algorithms in bipartite graphs.
alpar@2353
    31
///
alpar@2353
    32
namespace lemon {
alpar@2353
    33
deba@2462
    34
  ///Max cardinality matching algorithm based on push-relabel principle
alpar@2353
    35
deba@2462
    36
  ///\ingroup matching
deba@2462
    37
  ///Bipartite Max Cardinality Matching algorithm. This class uses the
deba@2462
    38
  ///push-relabel principle which in several cases has better runtime
deba@2462
    39
  ///performance than the augmenting path solutions.
deba@2462
    40
  ///
deba@2462
    41
  ///\author Alpar Juttner
deba@2462
    42
  template<class Graph>
deba@2462
    43
  class PrBipartiteMatching {
alpar@2353
    44
    typedef typename Graph::Node Node;
alpar@2353
    45
    typedef typename Graph::ANodeIt ANodeIt;
alpar@2353
    46
    typedef typename Graph::BNodeIt BNodeIt;
alpar@2353
    47
    typedef typename Graph::UEdge UEdge;
deba@2462
    48
    typedef typename Graph::UEdgeIt UEdgeIt;
alpar@2353
    49
    typedef typename Graph::IncEdgeIt IncEdgeIt;
alpar@2353
    50
    
alpar@2353
    51
    const Graph &_g;
alpar@2353
    52
    int _node_num;
deba@2462
    53
    int _matching_size;
deba@2462
    54
    int _empty_level;
deba@2462
    55
    
deba@2462
    56
    typename Graph::template ANodeMap<typename Graph::UEdge> _matching;
alpar@2353
    57
    Elevator<Graph,typename Graph::BNode> _levels;
alpar@2353
    58
    typename Graph::template BNodeMap<int> _cov;
alpar@2353
    59
alpar@2353
    60
  public:
deba@2462
    61
deba@2466
    62
    /// Constructor
deba@2466
    63
deba@2466
    64
    /// Constructor
deba@2466
    65
    ///
deba@2462
    66
    PrBipartiteMatching(const Graph &g) :
alpar@2353
    67
      _g(g),
alpar@2353
    68
      _node_num(countBNodes(g)),
deba@2462
    69
      _matching(g),
alpar@2353
    70
      _levels(g,_node_num),
alpar@2353
    71
      _cov(g,0)
alpar@2353
    72
    {
alpar@2353
    73
    }
alpar@2353
    74
    
deba@2462
    75
    /// \name Execution control 
deba@2462
    76
    /// The simplest way to execute the algorithm is to use one of the
deba@2462
    77
    /// member functions called \c run(). \n
deba@2462
    78
    /// If you need more control on the execution, first
deba@2462
    79
    /// you must call \ref init() and then one variant of the start()
deba@2462
    80
    /// member. 
deba@2462
    81
deba@2462
    82
    /// @{
deba@2462
    83
deba@2462
    84
    ///Initialize the data structures
deba@2462
    85
deba@2462
    86
    ///This function constructs a prematching first, which is a
deba@2462
    87
    ///regular matching on the A-side of the graph, but on the B-side
deba@2462
    88
    ///each node could cover more matching edges. After that, the
deba@2462
    89
    ///B-nodes which multiple matched, will be pushed into the lowest
deba@2462
    90
    ///level of the Elevator. The remaning B-nodes will be pushed to
deba@2462
    91
    ///the consequent levels respect to a Bfs on following graph: the
deba@2462
    92
    ///nodes are the B-nodes of the original bipartite graph and two
deba@2462
    93
    ///nodes are adjacent if a node can pass over a matching edge to
deba@2462
    94
    ///an other node. The source of the Bfs are the lowest level
deba@2462
    95
    ///nodes. Last, the reached B-nodes without covered matching edge
deba@2462
    96
    ///becomes active.
deba@2462
    97
    void init() {
deba@2462
    98
      _matching_size=0;
deba@2462
    99
      _empty_level=_node_num;
alpar@2353
   100
      for(ANodeIt n(_g);n!=INVALID;++n)
alpar@2353
   101
	if((_matching[n]=IncEdgeIt(_g,n))!=INVALID)
deba@2462
   102
	  ++_cov[_g.bNode(_matching[n])];
alpar@2353
   103
alpar@2353
   104
      std::queue<Node> q;
alpar@2353
   105
      _levels.initStart();
alpar@2353
   106
      for(BNodeIt n(_g);n!=INVALID;++n)
alpar@2353
   107
	if(_cov[n]>1) {
alpar@2353
   108
	  _levels.initAddItem(n);
alpar@2353
   109
	  q.push(n);
alpar@2353
   110
	}
alpar@2353
   111
      int hlev=0;
alpar@2353
   112
      while(!q.empty()) {
alpar@2353
   113
	Node n=q.front();
alpar@2353
   114
	q.pop();
alpar@2353
   115
	int nlev=_levels[n]+1;
alpar@2353
   116
	for(IncEdgeIt e(_g,n);e!=INVALID;++e) {
alpar@2353
   117
	  Node m=_g.runningNode(e);
alpar@2353
   118
	  if(e==_matching[m]) {
alpar@2353
   119
	    for(IncEdgeIt f(_g,m);f!=INVALID;++f) {
alpar@2353
   120
	      Node r=_g.runningNode(f);
alpar@2353
   121
	      if(_levels[r]>nlev) {
alpar@2353
   122
		for(;nlev>hlev;hlev++)
alpar@2353
   123
		  _levels.initNewLevel();
alpar@2353
   124
		_levels.initAddItem(r);
alpar@2353
   125
		q.push(r);
alpar@2353
   126
	      }
alpar@2353
   127
	    }
alpar@2353
   128
	  }
alpar@2353
   129
	}
alpar@2353
   130
      }
alpar@2353
   131
      _levels.initFinish();
alpar@2353
   132
      for(BNodeIt n(_g);n!=INVALID;++n)
alpar@2353
   133
	if(_cov[n]<1&&_levels[n]<_node_num)
alpar@2353
   134
	  _levels.activate(n);
alpar@2353
   135
    }
alpar@2353
   136
deba@2462
   137
    ///Start the main phase of the algorithm
alpar@2353
   138
    
deba@2462
   139
    ///This algorithm calculates the maximum matching with the
deba@2462
   140
    ///push-relabel principle. This function should be called just
deba@2462
   141
    ///after the init() function which already set the initial
deba@2462
   142
    ///prematching, the level function on the B-nodes and the active,
deba@2462
   143
    ///ie. unmatched B-nodes.
deba@2462
   144
    ///
deba@2462
   145
    ///The algorithm always takes highest active B-node, and it try to
deba@2462
   146
    ///find a B-node which is eligible to pass over one of it's
deba@2462
   147
    ///matching edge. This condition holds when the B-node is one
deba@2462
   148
    ///level lower, and the opposite node of it's matching edge is
deba@2462
   149
    ///adjacent to the highest active node. In this case the current
deba@2462
   150
    ///node steals the matching edge and becomes inactive. If there is
deba@2462
   151
    ///not eligible node then the highest active node should be lift
deba@2462
   152
    ///to the next proper level.
deba@2462
   153
    ///
deba@2462
   154
    ///The nodes should not lift higher than the number of the
deba@2462
   155
    ///B-nodes, if a node reach this level it remains unmatched. If
deba@2462
   156
    ///during the execution one level becomes empty the nodes above it
deba@2462
   157
    ///can be deactivated and lift to the highest level.
deba@2462
   158
    void start() {
alpar@2353
   159
      Node act;
alpar@2353
   160
      Node bact=INVALID;
alpar@2353
   161
      Node last_activated=INVALID;
alpar@2353
   162
      while((act=_levels.highestActive())!=INVALID) {
alpar@2353
   163
	last_activated=INVALID;
alpar@2353
   164
	int actlevel=_levels[act];
alpar@2353
   165
	
alpar@2353
   166
	UEdge bedge=INVALID;
alpar@2353
   167
	int nlevel=_node_num;
alpar@2353
   168
	{
alpar@2353
   169
	  int nnlevel;
alpar@2353
   170
	  for(IncEdgeIt tbedge(_g,act);
alpar@2353
   171
	      tbedge!=INVALID && nlevel>=actlevel;
alpar@2353
   172
	      ++tbedge)
alpar@2353
   173
	    if((nnlevel=_levels[_g.bNode(_matching[_g.runningNode(tbedge)])])<
alpar@2353
   174
	       nlevel)
alpar@2353
   175
	      {
alpar@2353
   176
		nlevel=nnlevel;
alpar@2353
   177
		bedge=tbedge;
alpar@2353
   178
	      }
alpar@2353
   179
	}
alpar@2353
   180
	if(nlevel<_node_num) {
alpar@2353
   181
	  if(nlevel>=actlevel)
alpar@2353
   182
	    _levels.liftHighestActiveTo(nlevel+1);
alpar@2353
   183
	  bact=_g.bNode(_matching[_g.aNode(bedge)]);
alpar@2353
   184
	  if(--_cov[bact]<1) {
alpar@2353
   185
	    _levels.activate(bact);
alpar@2353
   186
	    last_activated=bact;
alpar@2353
   187
	  }
alpar@2353
   188
	  _matching[_g.aNode(bedge)]=bedge;
alpar@2353
   189
	  _cov[act]=1;
alpar@2353
   190
	  _levels.deactivate(act);
alpar@2353
   191
	}
alpar@2353
   192
	else {
alpar@2353
   193
	  if(_node_num>actlevel) 
alpar@2353
   194
	    _levels.liftHighestActiveTo(_node_num);
alpar@2353
   195
	  _levels.deactivate(act); 
alpar@2353
   196
	}
alpar@2353
   197
alpar@2353
   198
	if(_levels.onLevel(actlevel)==0)
deba@2462
   199
	  _levels.liftToTop(actlevel);
alpar@2353
   200
      }
deba@2462
   201
      
deba@2466
   202
      for(ANodeIt n(_g);n!=INVALID;++n) {
deba@2466
   203
	if (_matching[n]==INVALID)continue;
deba@2466
   204
	if (_cov[_g.bNode(_matching[n])]>1) {
deba@2462
   205
	  _cov[_g.bNode(_matching[n])]--;
deba@2462
   206
	  _matching[n]=INVALID;
deba@2466
   207
	} else {
deba@2466
   208
	  ++_matching_size;
deba@2462
   209
	}
deba@2466
   210
      }
alpar@2353
   211
    }
deba@2462
   212
deba@2462
   213
    ///Start the algorithm to find a perfect matching
deba@2462
   214
deba@2462
   215
    ///This function is close to identical to the simple start()
deba@2462
   216
    ///member function but it calculates just perfect matching.
deba@2462
   217
    ///However, the perfect property is only checked on the B-side of
deba@2462
   218
    ///the graph
deba@2462
   219
    ///
deba@2462
   220
    ///The main difference between the two function is the handling of
deba@2462
   221
    ///the empty levels. The simple start() function let the nodes
deba@2462
   222
    ///above the empty levels unmatched while this variant if it find
deba@2462
   223
    ///an empty level immediately terminates and gives back false
deba@2462
   224
    ///return value.
deba@2462
   225
    bool startPerfect() {
deba@2462
   226
      Node act;
deba@2462
   227
      Node bact=INVALID;
deba@2462
   228
      Node last_activated=INVALID;
deba@2462
   229
      while((act=_levels.highestActive())!=INVALID) {
deba@2462
   230
	last_activated=INVALID;
deba@2462
   231
	int actlevel=_levels[act];
deba@2462
   232
	
deba@2462
   233
	UEdge bedge=INVALID;
deba@2462
   234
	int nlevel=_node_num;
deba@2462
   235
	{
deba@2462
   236
	  int nnlevel;
deba@2462
   237
	  for(IncEdgeIt tbedge(_g,act);
deba@2462
   238
	      tbedge!=INVALID && nlevel>=actlevel;
deba@2462
   239
	      ++tbedge)
deba@2462
   240
	    if((nnlevel=_levels[_g.bNode(_matching[_g.runningNode(tbedge)])])<
deba@2462
   241
	       nlevel)
deba@2462
   242
	      {
deba@2462
   243
		nlevel=nnlevel;
deba@2462
   244
		bedge=tbedge;
deba@2462
   245
	      }
deba@2462
   246
	}
deba@2462
   247
	if(nlevel<_node_num) {
deba@2462
   248
	  if(nlevel>=actlevel)
deba@2462
   249
	    _levels.liftHighestActiveTo(nlevel+1);
deba@2462
   250
	  bact=_g.bNode(_matching[_g.aNode(bedge)]);
deba@2462
   251
	  if(--_cov[bact]<1) {
deba@2462
   252
	    _levels.activate(bact);
deba@2462
   253
	    last_activated=bact;
deba@2462
   254
	  }
deba@2462
   255
	  _matching[_g.aNode(bedge)]=bedge;
deba@2462
   256
	  _cov[act]=1;
deba@2462
   257
	  _levels.deactivate(act);
deba@2462
   258
	}
deba@2462
   259
	else {
deba@2462
   260
	  if(_node_num>actlevel) 
deba@2462
   261
	    _levels.liftHighestActiveTo(_node_num);
deba@2462
   262
	  _levels.deactivate(act); 
deba@2462
   263
	}
deba@2462
   264
deba@2462
   265
	if(_levels.onLevel(actlevel)==0)
deba@2462
   266
	  _empty_level=actlevel;
deba@2462
   267
	  return false;
deba@2462
   268
      }
deba@2466
   269
      _matching_size = _node_num;
deba@2462
   270
      return true;
deba@2462
   271
    }
deba@2462
   272
  
deba@2462
   273
    ///Runs the algorithm
deba@2462
   274
    
deba@2462
   275
    ///Just a shortcut for the next code:
deba@2462
   276
    ///\code
deba@2462
   277
    /// init();
deba@2462
   278
    /// start();
deba@2462
   279
    ///\endcode
deba@2462
   280
    void run() {
deba@2462
   281
      init();
deba@2462
   282
      start();
deba@2462
   283
    }
deba@2462
   284
    
deba@2462
   285
    ///Runs the algorithm to find a perfect matching
deba@2462
   286
    
deba@2462
   287
    ///Just a shortcut for the next code:
deba@2462
   288
    ///\code
deba@2462
   289
    /// init();
deba@2462
   290
    /// startPerfect();
deba@2462
   291
    ///\endcode
deba@2462
   292
    ///
deba@2462
   293
    ///\note If the two nodesets of the graph have different size then
deba@2462
   294
    ///this algorithm checks the perfect property on the B-side.
deba@2462
   295
    bool runPerfect() {
deba@2462
   296
      init();
deba@2462
   297
      return startPerfect();
deba@2462
   298
    }
deba@2462
   299
deba@2462
   300
    ///Runs the algorithm to find a perfect matching
deba@2462
   301
    
deba@2462
   302
    ///Just a shortcut for the next code:
deba@2462
   303
    ///\code
deba@2462
   304
    /// init();
deba@2462
   305
    /// startPerfect();
deba@2462
   306
    ///\endcode
deba@2462
   307
    ///
deba@2462
   308
    ///\note It checks that the size of the two nodesets are equal.
deba@2462
   309
    bool checkedRunPerfect() {
deba@2462
   310
      if (countANodes(_g) != _node_num) return false;
deba@2462
   311
      init();
deba@2462
   312
      return startPerfect();
deba@2462
   313
    }
deba@2462
   314
deba@2462
   315
    ///@}
deba@2462
   316
deba@2462
   317
    /// \name Query Functions
deba@2462
   318
    /// The result of the %Matching algorithm can be obtained using these
deba@2462
   319
    /// functions.\n
deba@2462
   320
    /// Before the use of these functions,
deba@2462
   321
    /// either run() or start() must be called.
deba@2462
   322
    ///@{
deba@2462
   323
deba@2463
   324
    ///Set true all matching uedge in the map.
deba@2463
   325
deba@2463
   326
    ///Set true all matching uedge in the map. It does not change the
deba@2463
   327
    ///value mapped to the other uedges.
deba@2463
   328
    ///\return The number of the matching edges.
deba@2462
   329
    template <typename MatchingMap>
deba@2462
   330
    int quickMatching(MatchingMap& mm) const {
deba@2462
   331
      for (ANodeIt n(_g);n!=INVALID;++n) {
deba@2462
   332
        if (_matching[n]!=INVALID) mm.set(_matching[n],true);
deba@2462
   333
      }
deba@2462
   334
      return _matching_size;
deba@2462
   335
    }
deba@2462
   336
deba@2463
   337
    ///Set true all matching uedge in the map and the others to false.
deba@2462
   338
deba@2462
   339
    ///Set true all matching uedge in the map and the others to false.
deba@2462
   340
    ///\return The number of the matching edges.
deba@2462
   341
    template<class MatchingMap>
deba@2462
   342
    int matching(MatchingMap& mm) const {
deba@2462
   343
      for (UEdgeIt e(_g);e!=INVALID;++e) {
deba@2462
   344
        mm.set(e,e==_matching[_g.aNode(e)]);
deba@2462
   345
      }
deba@2462
   346
      return _matching_size;
deba@2462
   347
    }
deba@2462
   348
deba@2463
   349
    ///Gives back the matching in an ANodeMap.
deba@2463
   350
deba@2463
   351
    ///Gives back the matching in an ANodeMap. The parameter should
deba@2463
   352
    ///be a write ANodeMap of UEdge values.
deba@2463
   353
    ///\return The number of the matching edges.
deba@2463
   354
    template<class MatchingMap>
deba@2463
   355
    int aMatching(MatchingMap& mm) const {
deba@2463
   356
      for (ANodeIt n(_g);n!=INVALID;++n) {
deba@2463
   357
        mm.set(n,_matching[n]);
deba@2463
   358
      }
deba@2463
   359
      return _matching_size;
deba@2463
   360
    }
deba@2463
   361
deba@2463
   362
    ///Gives back the matching in a BNodeMap.
deba@2463
   363
deba@2463
   364
    ///Gives back the matching in a BNodeMap. The parameter should
deba@2463
   365
    ///be a write BNodeMap of UEdge values.
deba@2463
   366
    ///\return The number of the matching edges.
deba@2463
   367
    template<class MatchingMap>
deba@2463
   368
    int bMatching(MatchingMap& mm) const {
deba@2463
   369
      for (BNodeIt n(_g);n!=INVALID;++n) {
deba@2463
   370
        mm.set(n,INVALID);
deba@2463
   371
      }
deba@2463
   372
      for (ANodeIt n(_g);n!=INVALID;++n) {
deba@2463
   373
        if (_matching[n]!=INVALID)
deba@2463
   374
	  mm.set(_g.bNode(_matching[n]),_matching[n]);
deba@2463
   375
      }
deba@2463
   376
      return _matching_size;
deba@2463
   377
    }
deba@2463
   378
deba@2462
   379
deba@2462
   380
    ///Returns true if the given uedge is in the matching.
deba@2462
   381
deba@2462
   382
    ///It returns true if the given uedge is in the matching.
deba@2462
   383
    ///
deba@2462
   384
    bool matchingEdge(const UEdge& e) const {
deba@2462
   385
      return _matching[_g.aNode(e)]==e;
deba@2462
   386
    }
deba@2462
   387
deba@2462
   388
    ///Returns the matching edge from the node.
deba@2462
   389
deba@2462
   390
    ///Returns the matching edge from the node. If there is not such
deba@2462
   391
    ///edge it gives back \c INVALID.  
deba@2462
   392
    ///\note If the parameter node is a B-node then the running time is
deba@2462
   393
    ///propotional to the degree of the node.
deba@2462
   394
    UEdge matchingEdge(const Node& n) const {
deba@2462
   395
      if (_g.aNode(n)) {
deba@2462
   396
        return _matching[n];
deba@2462
   397
      } else {
deba@2462
   398
	for (IncEdgeIt e(_g,n);e!=INVALID;++e)
deba@2462
   399
	  if (e==_matching[_g.aNode(e)]) return e;
deba@2462
   400
	return INVALID;
deba@2462
   401
      }
deba@2462
   402
    }
deba@2462
   403
deba@2462
   404
    ///Gives back the number of the matching edges.
deba@2462
   405
deba@2462
   406
    ///Gives back the number of the matching edges.
deba@2462
   407
    int matchingSize() const {
deba@2462
   408
      return _matching_size;
deba@2462
   409
    }
deba@2462
   410
deba@2462
   411
    ///Gives back a barrier on the A-nodes
deba@2462
   412
    
deba@2462
   413
    ///The barrier is s subset of the nodes on the same side of the
deba@2462
   414
    ///graph. If we tried to find a perfect matching and it failed
deba@2462
   415
    ///then the barrier size will be greater than its neighbours. If
deba@2462
   416
    ///the maximum matching searched then the barrier size minus its
deba@2462
   417
    ///neighbours will be exactly the unmatched nodes on the A-side.
deba@2462
   418
    ///\retval bar A WriteMap on the ANodes with bool value.
deba@2462
   419
    template<class BarrierMap>
deba@2462
   420
    void aBarrier(BarrierMap &bar) const 
alpar@2353
   421
    {
alpar@2353
   422
      for(ANodeIt n(_g);n!=INVALID;++n)
deba@2462
   423
	bar.set(n,_matching[n]==INVALID ||
deba@2462
   424
	  _levels[_g.bNode(_matching[n])]<_empty_level);  
alpar@2353
   425
    }  
deba@2462
   426
deba@2462
   427
    ///Gives back a barrier on the B-nodes
deba@2462
   428
    
deba@2462
   429
    ///The barrier is s subset of the nodes on the same side of the
deba@2462
   430
    ///graph. If we tried to find a perfect matching and it failed
deba@2462
   431
    ///then the barrier size will be greater than its neighbours. If
deba@2462
   432
    ///the maximum matching searched then the barrier size minus its
deba@2462
   433
    ///neighbours will be exactly the unmatched nodes on the B-side.
deba@2462
   434
    ///\retval bar A WriteMap on the BNodes with bool value.
deba@2462
   435
    template<class BarrierMap>
deba@2462
   436
    void bBarrier(BarrierMap &bar) const
alpar@2353
   437
    {
deba@2462
   438
      for(BNodeIt n(_g);n!=INVALID;++n) bar.set(n,_levels[n]>=_empty_level);  
deba@2462
   439
    }
deba@2462
   440
deba@2462
   441
    ///Returns a minimum covering of the nodes.
deba@2462
   442
deba@2462
   443
    ///The minimum covering set problem is the dual solution of the
deba@2462
   444
    ///maximum bipartite matching. It provides a solution for this
deba@2462
   445
    ///problem what is proof of the optimality of the matching.
deba@2462
   446
    ///\param covering NodeMap of bool values, the nodes of the cover
deba@2462
   447
    ///set will set true while the others false.  
deba@2462
   448
    ///\return The size of the cover set.
deba@2462
   449
    ///\note This function can be called just after the algorithm have
deba@2462
   450
    ///already found a matching. 
deba@2462
   451
    template<class CoverMap>
deba@2462
   452
    int coverSet(CoverMap& covering) const {
deba@2462
   453
      int ret=0;
deba@2462
   454
      for(BNodeIt n(_g);n!=INVALID;++n) {
deba@2462
   455
	if (_levels[n]<_empty_level) { covering.set(n,true); ++ret; }
deba@2462
   456
	else covering.set(n,false);
deba@2462
   457
      }
deba@2462
   458
      for(ANodeIt n(_g);n!=INVALID;++n) {
deba@2462
   459
	if (_matching[n]!=INVALID &&
deba@2462
   460
	    _levels[_g.bNode(_matching[n])]>=_empty_level) 
deba@2462
   461
	  { covering.set(n,true); ++ret; }
deba@2462
   462
	else covering.set(n,false);
deba@2462
   463
      }
deba@2462
   464
      return ret;
deba@2462
   465
    }
deba@2462
   466
deba@2462
   467
deba@2462
   468
    /// @}
deba@2462
   469
    
alpar@2353
   470
  };
alpar@2353
   471
  
alpar@2353
   472
  
alpar@2353
   473
  ///Maximum cardinality of the matchings in a bipartite graph
alpar@2353
   474
alpar@2353
   475
  ///\ingroup matching
alpar@2353
   476
  ///This function finds the maximum cardinality of the matchings
alpar@2353
   477
  ///in a bipartite graph \c g.
alpar@2353
   478
  ///\param g An undirected bipartite graph.
alpar@2353
   479
  ///\return The cardinality of the maximum matching.
alpar@2353
   480
  ///
alpar@2353
   481
  ///\note The the implementation is based
alpar@2353
   482
  ///on the push-relabel principle.
alpar@2353
   483
  template<class Graph>
deba@2462
   484
  int prBipartiteMatching(const Graph &g)
alpar@2353
   485
  {
deba@2462
   486
    PrBipartiteMatching<Graph> bpm(g);
deba@2462
   487
    return bpm.matchingSize();
alpar@2353
   488
  }
alpar@2353
   489
alpar@2353
   490
  ///Maximum cardinality matching in a bipartite graph
alpar@2353
   491
alpar@2353
   492
  ///\ingroup matching
alpar@2353
   493
  ///This function finds a maximum cardinality matching
alpar@2353
   494
  ///in a bipartite graph \c g.
alpar@2353
   495
  ///\param g An undirected bipartite graph.
deba@2463
   496
  ///\retval matching A write ANodeMap of value type \c UEdge.
deba@2463
   497
  /// The found edges will be returned in this map,
deba@2463
   498
  /// i.e. for an \c ANode \c n the edge <tt>matching[n]</tt> is the one
deba@2463
   499
  /// that covers the node \c n.
alpar@2353
   500
  ///\return The cardinality of the maximum matching.
alpar@2353
   501
  ///
alpar@2353
   502
  ///\note The the implementation is based
alpar@2353
   503
  ///on the push-relabel principle.
alpar@2353
   504
  template<class Graph,class MT>
deba@2462
   505
  int prBipartiteMatching(const Graph &g,MT &matching) 
alpar@2353
   506
  {
deba@2462
   507
    PrBipartiteMatching<Graph> bpm(g);
deba@2462
   508
    bpm.run();
deba@2463
   509
    bpm.aMatching(matching);
deba@2462
   510
    return bpm.matchingSize();
alpar@2353
   511
  }
alpar@2353
   512
alpar@2353
   513
  ///Maximum cardinality matching in a bipartite graph
alpar@2353
   514
alpar@2353
   515
  ///\ingroup matching
alpar@2353
   516
  ///This function finds a maximum cardinality matching
alpar@2353
   517
  ///in a bipartite graph \c g.
alpar@2353
   518
  ///\param g An undirected bipartite graph.
deba@2463
   519
  ///\retval matching A write ANodeMap of value type \c UEdge.
deba@2463
   520
  /// The found edges will be returned in this map,
deba@2463
   521
  /// i.e. for an \c ANode \c n the edge <tt>matching[n]</tt> is the one
deba@2463
   522
  /// that covers the node \c n.
alpar@2353
   523
  ///\retval barrier A \c bool WriteMap on the BNodes. The map will be set
alpar@2353
   524
  /// exactly once for each BNode. The nodes with \c true value represent
alpar@2353
   525
  /// a barrier \e B, i.e. the cardinality of \e B minus the number of its
alpar@2353
   526
  /// neighbor is equal to the number of the <tt>BNode</tt>s minus the
alpar@2353
   527
  /// cardinality of the maximum matching.
alpar@2353
   528
  ///\return The cardinality of the maximum matching.
alpar@2353
   529
  ///
alpar@2353
   530
  ///\note The the implementation is based
alpar@2353
   531
  ///on the push-relabel principle.
alpar@2353
   532
  template<class Graph,class MT, class GT>
deba@2462
   533
  int prBipartiteMatching(const Graph &g,MT &matching,GT &barrier) 
alpar@2353
   534
  {
deba@2462
   535
    PrBipartiteMatching<Graph> bpm(g);
deba@2462
   536
    bpm.run();
deba@2463
   537
    bpm.aMatching(matching);
deba@2462
   538
    bpm.bBarrier(barrier);
deba@2462
   539
    return bpm.matchingSize();
alpar@2353
   540
  }  
alpar@2353
   541
alpar@2353
   542
  ///Perfect matching in a bipartite graph
alpar@2353
   543
alpar@2353
   544
  ///\ingroup matching
alpar@2353
   545
  ///This function checks whether the bipartite graph \c g
alpar@2353
   546
  ///has a perfect matching.
alpar@2353
   547
  ///\param g An undirected bipartite graph.
alpar@2353
   548
  ///\return \c true iff \c g has a perfect matching.
alpar@2353
   549
  ///
alpar@2353
   550
  ///\note The the implementation is based
alpar@2353
   551
  ///on the push-relabel principle.
alpar@2353
   552
  template<class Graph>
deba@2462
   553
  bool prPerfectBipartiteMatching(const Graph &g)
alpar@2353
   554
  {
deba@2462
   555
    PrBipartiteMatching<Graph> bpm(g);
deba@2462
   556
    return bpm.runPerfect();
alpar@2353
   557
  }
alpar@2353
   558
alpar@2353
   559
  ///Perfect matching in a bipartite graph
alpar@2353
   560
alpar@2353
   561
  ///\ingroup matching
alpar@2353
   562
  ///This function finds a perfect matching in a bipartite graph \c g.
alpar@2353
   563
  ///\param g An undirected bipartite graph.
deba@2463
   564
  ///\retval matching A write ANodeMap of value type \c UEdge.
deba@2463
   565
  /// The found edges will be returned in this map,
deba@2463
   566
  /// i.e. for an \c ANode \c n the edge <tt>matching[n]</tt> is the one
deba@2463
   567
  /// that covers the node \c n.
deba@2462
   568
  /// The values are unchanged if the graph
alpar@2353
   569
  /// has no perfect matching.
alpar@2353
   570
  ///\return \c true iff \c g has a perfect matching.
alpar@2353
   571
  ///
alpar@2353
   572
  ///\note The the implementation is based
alpar@2353
   573
  ///on the push-relabel principle.
alpar@2353
   574
  template<class Graph,class MT>
deba@2462
   575
  bool prPerfectBipartiteMatching(const Graph &g,MT &matching) 
alpar@2353
   576
  {
deba@2462
   577
    PrBipartiteMatching<Graph> bpm(g);
deba@2463
   578
    bool ret = bpm.checkedRunPerfect();
deba@2463
   579
    if (ret) bpm.aMatching(matching);
deba@2462
   580
    return ret;
alpar@2353
   581
  }
alpar@2353
   582
alpar@2353
   583
  ///Perfect matching in a bipartite graph
alpar@2353
   584
alpar@2353
   585
  ///\ingroup matching
alpar@2353
   586
  ///This function finds a perfect matching in a bipartite graph \c g.
alpar@2353
   587
  ///\param g An undirected bipartite graph.
deba@2463
   588
  ///\retval matching A write ANodeMap of value type \c UEdge.
deba@2463
   589
  /// The found edges will be returned in this map,
deba@2463
   590
  /// i.e. for an \c ANode \c n the edge <tt>matching[n]</tt> is the one
deba@2463
   591
  /// that covers the node \c n.
deba@2462
   592
  /// The values are unchanged if the graph
alpar@2353
   593
  /// has no perfect matching.
alpar@2353
   594
  ///\retval barrier A \c bool WriteMap on the BNodes. The map will only
alpar@2353
   595
  /// be set if \c g has no perfect matching. In this case it is set 
alpar@2353
   596
  /// exactly once for each BNode. The nodes with \c true value represent
alpar@2353
   597
  /// a barrier, i.e. a subset \e B a of BNodes with the property that
deba@2462
   598
  /// the cardinality of \e B is greater than the number of its neighbors.
alpar@2353
   599
  ///\return \c true iff \c g has a perfect matching.
alpar@2353
   600
  ///
alpar@2353
   601
  ///\note The the implementation is based
alpar@2353
   602
  ///on the push-relabel principle.
alpar@2353
   603
  template<class Graph,class MT, class GT>
deba@2463
   604
  bool prPerfectBipartiteMatching(const Graph &g,MT &matching,GT &barrier) 
alpar@2353
   605
  {
deba@2462
   606
    PrBipartiteMatching<Graph> bpm(g);
deba@2463
   607
    bool ret=bpm.checkedRunPerfect();
deba@2462
   608
    if(ret)
deba@2463
   609
      bpm.aMatching(matching);
deba@2462
   610
    else
deba@2462
   611
      bpm.bBarrier(barrier);
deba@2462
   612
    return ret;
alpar@2353
   613
  }  
alpar@2353
   614
}
alpar@2353
   615
alpar@2353
   616
#endif