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