2 * lemon/preflow_matching.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
17 #ifndef LEMON_BP_MATCHING
18 #define LEMON_BP_MATCHING
20 #include <lemon/graph_utils.h>
21 #include <lemon/iterable_maps.h>
24 #include <lemon/counter.h>
25 #include <lemon/elevator.h>
29 ///\brief Push-prelabel maximum matching algorithms in bipartite graphs.
31 ///\todo This file slightly conflicts with \ref lemon/bipartite_matching.h
32 ///\todo (Re)move the XYZ_TYPEDEFS macros
35 #define BIPARTITE_TYPEDEFS(Graph) \
36 GRAPH_TYPEDEFS(Graph) \
37 typedef Graph::ANodeIt ANodeIt; \
38 typedef Graph::BNodeIt BNodeIt;
40 #define UNDIRBIPARTITE_TYPEDEFS(Graph) \
41 UNDIRGRAPH_TYPEDEFS(Graph) \
42 typedef Graph::ANodeIt ANodeIt; \
43 typedef Graph::BNodeIt BNodeIt;
46 class MT=typename Graph::template ANodeMap<typename Graph::UEdge> >
48 typedef typename Graph::Node Node;
49 typedef typename Graph::ANodeIt ANodeIt;
50 typedef typename Graph::BNodeIt BNodeIt;
51 typedef typename Graph::UEdge UEdge;
52 typedef typename Graph::IncEdgeIt IncEdgeIt;
57 Elevator<Graph,typename Graph::BNode> _levels;
58 typename Graph::template BNodeMap<int> _cov;
61 BpMatching(const Graph &g, MT &matching) :
63 _node_num(countBNodes(g)),
73 // for(BNodeIt n(g);n!=INVALID;++n) cov[n]=0;
74 for(ANodeIt n(_g);n!=INVALID;++n)
75 if((_matching[n]=IncEdgeIt(_g,n))!=INVALID)
76 ++_cov[_g.oppositeNode(n,_matching[n])];
80 for(BNodeIt n(_g);n!=INVALID;++n)
82 _levels.initAddItem(n);
89 int nlev=_levels[n]+1;
90 for(IncEdgeIt e(_g,n);e!=INVALID;++e) {
91 Node m=_g.runningNode(e);
93 for(IncEdgeIt f(_g,m);f!=INVALID;++f) {
94 Node r=_g.runningNode(f);
96 for(;nlev>hlev;hlev++)
97 _levels.initNewLevel();
98 _levels.initAddItem(r);
105 _levels.initFinish();
106 for(BNodeIt n(_g);n!=INVALID;++n)
107 if(_cov[n]<1&&_levels[n]<_node_num)
117 Node last_activated=INVALID;
118 // while((act=last_activated!=INVALID?
119 // last_activated:_levels.highestActive())
121 while((act=_levels.highestActive())!=INVALID) {
122 last_activated=INVALID;
123 int actlevel=_levels[act];
126 int nlevel=_node_num;
129 for(IncEdgeIt tbedge(_g,act);
130 tbedge!=INVALID && nlevel>=actlevel;
132 if((nnlevel=_levels[_g.bNode(_matching[_g.runningNode(tbedge)])])<
139 if(nlevel<_node_num) {
141 _levels.liftHighestActiveTo(nlevel+1);
142 // _levels.liftTo(act,nlevel+1);
143 bact=_g.bNode(_matching[_g.aNode(bedge)]);
145 _levels.activate(bact);
148 _matching[_g.aNode(bedge)]=bedge;
150 _levels.deactivate(act);
153 if(_node_num>actlevel)
154 _levels.liftHighestActiveTo(_node_num);
155 // _levels.liftTo(act,_node_num);
156 _levels.deactivate(act);
159 if(_levels.onLevel(actlevel)==0)
160 _levels.liftToTop(actlevel);
164 for(ANodeIt n(_g);n!=INVALID;++n)
165 if(_matching[n]==INVALID) ret--;
166 else if (_cov[_g.bNode(_matching[n])]>1) {
167 _cov[_g.bNode(_matching[n])]--;
169 _matching[n]=INVALID;
174 ///\returns -1 if there is a perfect matching, or an empty level
175 ///if it doesn't exists
182 Node last_activated=INVALID;
183 while((act=_levels.highestActive())!=INVALID) {
184 last_activated=INVALID;
185 int actlevel=_levels[act];
188 int nlevel=_node_num;
191 for(IncEdgeIt tbedge(_g,act);
192 tbedge!=INVALID && nlevel>=actlevel;
194 if((nnlevel=_levels[_g.bNode(_matching[_g.runningNode(tbedge)])])<
201 if(nlevel<_node_num) {
203 _levels.liftHighestActiveTo(nlevel+1);
204 bact=_g.bNode(_matching[_g.aNode(bedge)]);
206 _levels.activate(bact);
209 _matching[_g.aNode(bedge)]=bedge;
211 _levels.deactivate(act);
214 if(_node_num>actlevel)
215 _levels.liftHighestActiveTo(_node_num);
216 _levels.deactivate(act);
219 if(_levels.onLevel(actlevel)==0)
226 void aBarrier(GT &bar,int empty_level=-1)
229 for(empty_level=0;_levels.onLevel(empty_level);empty_level++) ;
230 for(ANodeIt n(_g);n!=INVALID;++n)
231 bar[n] = _matching[n]==INVALID ||
232 _levels[_g.bNode(_matching[n])]<empty_level;
235 void bBarrier(GT &bar, int empty_level=-1)
238 for(empty_level=0;_levels.onLevel(empty_level);empty_level++) ;
239 for(BNodeIt n(_g);n!=INVALID;++n) bar[n]=(_levels[n]>empty_level);
245 ///Maximum cardinality of the matchings in a bipartite graph
248 ///This function finds the maximum cardinality of the matchings
249 ///in a bipartite graph \c g.
250 ///\param g An undirected bipartite graph.
251 ///\return The cardinality of the maximum matching.
253 ///\note The the implementation is based
254 ///on the push-relabel principle.
255 template<class Graph>
256 int maxBpMatching(const Graph &g)
258 typename Graph::template ANodeMap<typename Graph::UEdge> matching(g);
259 return maxBpMatching(g,matching);
262 ///Maximum cardinality matching in a bipartite graph
265 ///This function finds a maximum cardinality matching
266 ///in a bipartite graph \c g.
267 ///\param g An undirected bipartite graph.
268 ///\retval matching A readwrite ANodeMap of value type \c Edge.
269 /// The found edges will be returned in this map,
270 /// i.e. for an \c ANode \c n,
271 /// the edge <tt>matching[n]</tt> is the one that covers the node \c n, or
272 /// \ref INVALID if it is uncovered.
273 ///\return The cardinality of the maximum matching.
275 ///\note The the implementation is based
276 ///on the push-relabel principle.
277 template<class Graph,class MT>
278 int maxBpMatching(const Graph &g,MT &matching)
280 return BpMatching<Graph,MT>(g,matching).run();
283 ///Maximum cardinality matching in a bipartite graph
286 ///This function finds a maximum cardinality matching
287 ///in a bipartite graph \c g.
288 ///\param g An undirected bipartite graph.
289 ///\retval matching A readwrite ANodeMap of value type \c Edge.
290 /// The found edges will be returned in this map,
291 /// i.e. for an \c ANode \c n,
292 /// the edge <tt>matching[n]</tt> is the one that covers the node \c n, or
293 /// \ref INVALID if it is uncovered.
294 ///\retval barrier A \c bool WriteMap on the BNodes. The map will be set
295 /// exactly once for each BNode. The nodes with \c true value represent
296 /// a barrier \e B, i.e. the cardinality of \e B minus the number of its
297 /// neighbor is equal to the number of the <tt>BNode</tt>s minus the
298 /// cardinality of the maximum matching.
299 ///\return The cardinality of the maximum matching.
301 ///\note The the implementation is based
302 ///on the push-relabel principle.
303 template<class Graph,class MT, class GT>
304 int maxBpMatching(const Graph &g,MT &matching,GT &barrier)
306 BpMatching<Graph,MT> bpm(g,matching);
308 bpm.barrier(barrier);
312 ///Perfect matching in a bipartite graph
315 ///This function checks whether the bipartite graph \c g
316 ///has a perfect matching.
317 ///\param g An undirected bipartite graph.
318 ///\return \c true iff \c g has a perfect matching.
320 ///\note The the implementation is based
321 ///on the push-relabel principle.
322 template<class Graph>
323 bool perfectBpMatching(const Graph &g)
325 typename Graph::template ANodeMap<typename Graph::UEdge> matching(g);
326 return perfectBpMatching(g,matching);
329 ///Perfect matching in a bipartite graph
332 ///This function finds a perfect matching in a bipartite graph \c g.
333 ///\param g An undirected bipartite graph.
334 ///\retval matching A readwrite ANodeMap of value type \c Edge.
335 /// The found edges will be returned in this map,
336 /// i.e. for an \c ANode \c n,
337 /// the edge <tt>matching[n]</tt> is the one that covers the node \c n.
338 /// The values are unspecified if the graph
339 /// has no perfect matching.
340 ///\return \c true iff \c g has a perfect matching.
342 ///\note The the implementation is based
343 ///on the push-relabel principle.
344 template<class Graph,class MT>
345 bool perfectBpMatching(const Graph &g,MT &matching)
347 return BpMatching<Graph,MT>(g,matching).runPerfect()<0;
350 ///Perfect matching in a bipartite graph
353 ///This function finds a perfect matching in a bipartite graph \c g.
354 ///\param g An undirected bipartite graph.
355 ///\retval matching A readwrite ANodeMap of value type \c Edge.
356 /// The found edges will be returned in this map,
357 /// i.e. for an \c ANode \c n,
358 /// the edge <tt>matching[n]</tt> is the one that covers the node \c n.
359 /// The values are unspecified if the graph
360 /// has no perfect matching.
361 ///\retval barrier A \c bool WriteMap on the BNodes. The map will only
362 /// be set if \c g has no perfect matching. In this case it is set
363 /// exactly once for each BNode. The nodes with \c true value represent
364 /// a barrier, i.e. a subset \e B a of BNodes with the property that
365 /// the cardinality of \e B is greater than the numner of its neighbors.
366 ///\return \c true iff \c g has a perfect matching.
368 ///\note The the implementation is based
369 ///on the push-relabel principle.
370 template<class Graph,class MT, class GT>
371 int perfectBpMatching(const Graph &g,MT &matching,GT &barrier)
373 BpMatching<Graph,MT> bpm(g,matching);
376 bpm.barrier(barrier,ret);