3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2007
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
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.
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
19 #ifndef LEMON_BP_MATCHING
20 #define LEMON_BP_MATCHING
22 #include <lemon/graph_utils.h>
23 #include <lemon/iterable_maps.h>
26 #include <lemon/counter.h>
27 #include <lemon/elevator.h>
31 ///\brief Push-prelabel maximum matching algorithms in bipartite graphs.
33 ///\todo This file slightly conflicts with \ref lemon/bipartite_matching.h
34 ///\todo (Re)move the XYZ_TYPEDEFS macros
37 #define BIPARTITE_TYPEDEFS(Graph) \
38 GRAPH_TYPEDEFS(Graph) \
39 typedef Graph::ANodeIt ANodeIt; \
40 typedef Graph::BNodeIt BNodeIt;
42 #define UNDIRBIPARTITE_TYPEDEFS(Graph) \
43 UNDIRGRAPH_TYPEDEFS(Graph) \
44 typedef Graph::ANodeIt ANodeIt; \
45 typedef Graph::BNodeIt BNodeIt;
48 class MT=typename Graph::template ANodeMap<typename Graph::UEdge> >
50 typedef typename Graph::Node Node;
51 typedef typename Graph::ANodeIt ANodeIt;
52 typedef typename Graph::BNodeIt BNodeIt;
53 typedef typename Graph::UEdge UEdge;
54 typedef typename Graph::IncEdgeIt IncEdgeIt;
59 Elevator<Graph,typename Graph::BNode> _levels;
60 typename Graph::template BNodeMap<int> _cov;
63 BpMatching(const Graph &g, MT &matching) :
65 _node_num(countBNodes(g)),
75 // for(BNodeIt n(g);n!=INVALID;++n) cov[n]=0;
76 for(ANodeIt n(_g);n!=INVALID;++n)
77 if((_matching[n]=IncEdgeIt(_g,n))!=INVALID)
78 ++_cov[_g.oppositeNode(n,_matching[n])];
82 for(BNodeIt n(_g);n!=INVALID;++n)
84 _levels.initAddItem(n);
91 int nlev=_levels[n]+1;
92 for(IncEdgeIt e(_g,n);e!=INVALID;++e) {
93 Node m=_g.runningNode(e);
95 for(IncEdgeIt f(_g,m);f!=INVALID;++f) {
96 Node r=_g.runningNode(f);
98 for(;nlev>hlev;hlev++)
99 _levels.initNewLevel();
100 _levels.initAddItem(r);
107 _levels.initFinish();
108 for(BNodeIt n(_g);n!=INVALID;++n)
109 if(_cov[n]<1&&_levels[n]<_node_num)
119 Node last_activated=INVALID;
120 // while((act=last_activated!=INVALID?
121 // last_activated:_levels.highestActive())
123 while((act=_levels.highestActive())!=INVALID) {
124 last_activated=INVALID;
125 int actlevel=_levels[act];
128 int nlevel=_node_num;
131 for(IncEdgeIt tbedge(_g,act);
132 tbedge!=INVALID && nlevel>=actlevel;
134 if((nnlevel=_levels[_g.bNode(_matching[_g.runningNode(tbedge)])])<
141 if(nlevel<_node_num) {
143 _levels.liftHighestActiveTo(nlevel+1);
144 // _levels.liftTo(act,nlevel+1);
145 bact=_g.bNode(_matching[_g.aNode(bedge)]);
147 _levels.activate(bact);
150 _matching[_g.aNode(bedge)]=bedge;
152 _levels.deactivate(act);
155 if(_node_num>actlevel)
156 _levels.liftHighestActiveTo(_node_num);
157 // _levels.liftTo(act,_node_num);
158 _levels.deactivate(act);
161 if(_levels.onLevel(actlevel)==0)
162 _levels.liftToTop(actlevel);
166 for(ANodeIt n(_g);n!=INVALID;++n)
167 if(_matching[n]==INVALID) ret--;
168 else if (_cov[_g.bNode(_matching[n])]>1) {
169 _cov[_g.bNode(_matching[n])]--;
171 _matching[n]=INVALID;
176 ///\returns -1 if there is a perfect matching, or an empty level
177 ///if it doesn't exists
184 Node last_activated=INVALID;
185 while((act=_levels.highestActive())!=INVALID) {
186 last_activated=INVALID;
187 int actlevel=_levels[act];
190 int nlevel=_node_num;
193 for(IncEdgeIt tbedge(_g,act);
194 tbedge!=INVALID && nlevel>=actlevel;
196 if((nnlevel=_levels[_g.bNode(_matching[_g.runningNode(tbedge)])])<
203 if(nlevel<_node_num) {
205 _levels.liftHighestActiveTo(nlevel+1);
206 bact=_g.bNode(_matching[_g.aNode(bedge)]);
208 _levels.activate(bact);
211 _matching[_g.aNode(bedge)]=bedge;
213 _levels.deactivate(act);
216 if(_node_num>actlevel)
217 _levels.liftHighestActiveTo(_node_num);
218 _levels.deactivate(act);
221 if(_levels.onLevel(actlevel)==0)
228 void aBarrier(GT &bar,int empty_level=-1)
231 for(empty_level=0;_levels.onLevel(empty_level);empty_level++) ;
232 for(ANodeIt n(_g);n!=INVALID;++n)
233 bar[n] = _matching[n]==INVALID ||
234 _levels[_g.bNode(_matching[n])]<empty_level;
237 void bBarrier(GT &bar, int empty_level=-1)
240 for(empty_level=0;_levels.onLevel(empty_level);empty_level++) ;
241 for(BNodeIt n(_g);n!=INVALID;++n) bar[n]=(_levels[n]>empty_level);
247 ///Maximum cardinality of the matchings in a bipartite graph
250 ///This function finds the maximum cardinality of the matchings
251 ///in a bipartite graph \c g.
252 ///\param g An undirected bipartite graph.
253 ///\return The cardinality of the maximum matching.
255 ///\note The the implementation is based
256 ///on the push-relabel principle.
257 template<class Graph>
258 int maxBpMatching(const Graph &g)
260 typename Graph::template ANodeMap<typename Graph::UEdge> matching(g);
261 return maxBpMatching(g,matching);
264 ///Maximum cardinality matching in a bipartite graph
267 ///This function finds a maximum cardinality matching
268 ///in a bipartite graph \c g.
269 ///\param g An undirected bipartite graph.
270 ///\retval matching A readwrite ANodeMap of value type \c Edge.
271 /// The found edges will be returned in this map,
272 /// i.e. for an \c ANode \c n,
273 /// the edge <tt>matching[n]</tt> is the one that covers the node \c n, or
274 /// \ref INVALID if it is uncovered.
275 ///\return The cardinality of the maximum matching.
277 ///\note The the implementation is based
278 ///on the push-relabel principle.
279 template<class Graph,class MT>
280 int maxBpMatching(const Graph &g,MT &matching)
282 return BpMatching<Graph,MT>(g,matching).run();
285 ///Maximum cardinality matching in a bipartite graph
288 ///This function finds a maximum cardinality matching
289 ///in a bipartite graph \c g.
290 ///\param g An undirected bipartite graph.
291 ///\retval matching A readwrite ANodeMap of value type \c Edge.
292 /// The found edges will be returned in this map,
293 /// i.e. for an \c ANode \c n,
294 /// the edge <tt>matching[n]</tt> is the one that covers the node \c n, or
295 /// \ref INVALID if it is uncovered.
296 ///\retval barrier A \c bool WriteMap on the BNodes. The map will be set
297 /// exactly once for each BNode. The nodes with \c true value represent
298 /// a barrier \e B, i.e. the cardinality of \e B minus the number of its
299 /// neighbor is equal to the number of the <tt>BNode</tt>s minus the
300 /// cardinality of the maximum matching.
301 ///\return The cardinality of the maximum matching.
303 ///\note The the implementation is based
304 ///on the push-relabel principle.
305 template<class Graph,class MT, class GT>
306 int maxBpMatching(const Graph &g,MT &matching,GT &barrier)
308 BpMatching<Graph,MT> bpm(g,matching);
310 bpm.barrier(barrier);
314 ///Perfect matching in a bipartite graph
317 ///This function checks whether the bipartite graph \c g
318 ///has a perfect matching.
319 ///\param g An undirected bipartite graph.
320 ///\return \c true iff \c g has a perfect matching.
322 ///\note The the implementation is based
323 ///on the push-relabel principle.
324 template<class Graph>
325 bool perfectBpMatching(const Graph &g)
327 typename Graph::template ANodeMap<typename Graph::UEdge> matching(g);
328 return perfectBpMatching(g,matching);
331 ///Perfect matching in a bipartite graph
334 ///This function finds a perfect matching in a bipartite graph \c g.
335 ///\param g An undirected bipartite graph.
336 ///\retval matching A readwrite ANodeMap of value type \c Edge.
337 /// The found edges will be returned in this map,
338 /// i.e. for an \c ANode \c n,
339 /// the edge <tt>matching[n]</tt> is the one that covers the node \c n.
340 /// The values are unspecified if the graph
341 /// has no perfect matching.
342 ///\return \c true iff \c g has a perfect matching.
344 ///\note The the implementation is based
345 ///on the push-relabel principle.
346 template<class Graph,class MT>
347 bool perfectBpMatching(const Graph &g,MT &matching)
349 return BpMatching<Graph,MT>(g,matching).runPerfect()<0;
352 ///Perfect matching in a bipartite graph
355 ///This function finds a perfect matching in a bipartite graph \c g.
356 ///\param g An undirected bipartite graph.
357 ///\retval matching A readwrite ANodeMap of value type \c Edge.
358 /// The found edges will be returned in this map,
359 /// i.e. for an \c ANode \c n,
360 /// the edge <tt>matching[n]</tt> is the one that covers the node \c n.
361 /// The values are unspecified if the graph
362 /// has no perfect matching.
363 ///\retval barrier A \c bool WriteMap on the BNodes. The map will only
364 /// be set if \c g has no perfect matching. In this case it is set
365 /// exactly once for each BNode. The nodes with \c true value represent
366 /// a barrier, i.e. a subset \e B a of BNodes with the property that
367 /// the cardinality of \e B is greater than the numner of its neighbors.
368 ///\return \c true iff \c g has a perfect matching.
370 ///\note The the implementation is based
371 ///on the push-relabel principle.
372 template<class Graph,class MT, class GT>
373 int perfectBpMatching(const Graph &g,MT &matching,GT &barrier)
375 BpMatching<Graph,MT> bpm(g,matching);
378 bpm.barrier(barrier,ret);