|
1 /* -*- C++ -*- |
|
2 * lemon/preflow_matching.h - Part of LEMON, a generic C++ optimization library |
|
3 * |
|
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
|
5 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
|
6 * |
|
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. |
|
10 * |
|
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 |
|
13 * purpose. |
|
14 * |
|
15 */ |
|
16 |
|
17 #ifndef LEMON_BP_MATCHING |
|
18 #define LEMON_BP_MATCHING |
|
19 |
|
20 #include <lemon/graph_utils.h> |
|
21 #include <lemon/iterable_maps.h> |
|
22 #include <iostream> |
|
23 #include <queue> |
|
24 #include <lemon/counter.h> |
|
25 #include <lemon/elevator.h> |
|
26 |
|
27 ///\ingroup matching |
|
28 ///\file |
|
29 ///\brief Push-prelabel maximum matching algorithms in bipartite graphs. |
|
30 /// |
|
31 ///\todo This file slightly conflicts with \ref lemon/bipartite_matching.h |
|
32 ///\todo (Re)move the XYZ_TYPEDEFS macros |
|
33 namespace lemon { |
|
34 |
|
35 #define BIPARTITE_TYPEDEFS(Graph) \ |
|
36 GRAPH_TYPEDEFS(Graph) \ |
|
37 typedef Graph::ANodeIt ANodeIt; \ |
|
38 typedef Graph::BNodeIt BNodeIt; |
|
39 |
|
40 #define UNDIRBIPARTITE_TYPEDEFS(Graph) \ |
|
41 UNDIRGRAPH_TYPEDEFS(Graph) \ |
|
42 typedef Graph::ANodeIt ANodeIt; \ |
|
43 typedef Graph::BNodeIt BNodeIt; |
|
44 |
|
45 template<class Graph, |
|
46 class MT=typename Graph::template ANodeMap<typename Graph::UEdge> > |
|
47 class BpMatching { |
|
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; |
|
53 |
|
54 const Graph &_g; |
|
55 int _node_num; |
|
56 MT &_matching; |
|
57 Elevator<Graph,typename Graph::BNode> _levels; |
|
58 typename Graph::template BNodeMap<int> _cov; |
|
59 |
|
60 public: |
|
61 BpMatching(const Graph &g, MT &matching) : |
|
62 _g(g), |
|
63 _node_num(countBNodes(g)), |
|
64 _matching(matching), |
|
65 _levels(g,_node_num), |
|
66 _cov(g,0) |
|
67 { |
|
68 } |
|
69 |
|
70 private: |
|
71 void init() |
|
72 { |
|
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])]; |
|
77 |
|
78 std::queue<Node> q; |
|
79 _levels.initStart(); |
|
80 for(BNodeIt n(_g);n!=INVALID;++n) |
|
81 if(_cov[n]>1) { |
|
82 _levels.initAddItem(n); |
|
83 q.push(n); |
|
84 } |
|
85 int hlev=0; |
|
86 while(!q.empty()) { |
|
87 Node n=q.front(); |
|
88 q.pop(); |
|
89 int nlev=_levels[n]+1; |
|
90 for(IncEdgeIt e(_g,n);e!=INVALID;++e) { |
|
91 Node m=_g.runningNode(e); |
|
92 if(e==_matching[m]) { |
|
93 for(IncEdgeIt f(_g,m);f!=INVALID;++f) { |
|
94 Node r=_g.runningNode(f); |
|
95 if(_levels[r]>nlev) { |
|
96 for(;nlev>hlev;hlev++) |
|
97 _levels.initNewLevel(); |
|
98 _levels.initAddItem(r); |
|
99 q.push(r); |
|
100 } |
|
101 } |
|
102 } |
|
103 } |
|
104 } |
|
105 _levels.initFinish(); |
|
106 for(BNodeIt n(_g);n!=INVALID;++n) |
|
107 if(_cov[n]<1&&_levels[n]<_node_num) |
|
108 _levels.activate(n); |
|
109 } |
|
110 public: |
|
111 int run() |
|
112 { |
|
113 init(); |
|
114 |
|
115 Node act; |
|
116 Node bact=INVALID; |
|
117 Node last_activated=INVALID; |
|
118 // while((act=last_activated!=INVALID? |
|
119 // last_activated:_levels.highestActive()) |
|
120 // !=INVALID) |
|
121 while((act=_levels.highestActive())!=INVALID) { |
|
122 last_activated=INVALID; |
|
123 int actlevel=_levels[act]; |
|
124 |
|
125 UEdge bedge=INVALID; |
|
126 int nlevel=_node_num; |
|
127 { |
|
128 int nnlevel; |
|
129 for(IncEdgeIt tbedge(_g,act); |
|
130 tbedge!=INVALID && nlevel>=actlevel; |
|
131 ++tbedge) |
|
132 if((nnlevel=_levels[_g.bNode(_matching[_g.runningNode(tbedge)])])< |
|
133 nlevel) |
|
134 { |
|
135 nlevel=nnlevel; |
|
136 bedge=tbedge; |
|
137 } |
|
138 } |
|
139 if(nlevel<_node_num) { |
|
140 if(nlevel>=actlevel) |
|
141 _levels.liftHighestActiveTo(nlevel+1); |
|
142 // _levels.liftTo(act,nlevel+1); |
|
143 bact=_g.bNode(_matching[_g.aNode(bedge)]); |
|
144 if(--_cov[bact]<1) { |
|
145 _levels.activate(bact); |
|
146 last_activated=bact; |
|
147 } |
|
148 _matching[_g.aNode(bedge)]=bedge; |
|
149 _cov[act]=1; |
|
150 _levels.deactivate(act); |
|
151 } |
|
152 else { |
|
153 if(_node_num>actlevel) |
|
154 _levels.liftHighestActiveTo(_node_num); |
|
155 // _levels.liftTo(act,_node_num); |
|
156 _levels.deactivate(act); |
|
157 } |
|
158 |
|
159 if(_levels.onLevel(actlevel)==0) |
|
160 _levels.liftToTop(actlevel); |
|
161 } |
|
162 |
|
163 int ret=_node_num; |
|
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])]--; |
|
168 ret--; |
|
169 _matching[n]=INVALID; |
|
170 } |
|
171 return ret; |
|
172 } |
|
173 |
|
174 ///\returns -1 if there is a perfect matching, or an empty level |
|
175 ///if it doesn't exists |
|
176 int runPerfect() |
|
177 { |
|
178 init(); |
|
179 |
|
180 Node act; |
|
181 Node bact=INVALID; |
|
182 Node last_activated=INVALID; |
|
183 while((act=_levels.highestActive())!=INVALID) { |
|
184 last_activated=INVALID; |
|
185 int actlevel=_levels[act]; |
|
186 |
|
187 UEdge bedge=INVALID; |
|
188 int nlevel=_node_num; |
|
189 { |
|
190 int nnlevel; |
|
191 for(IncEdgeIt tbedge(_g,act); |
|
192 tbedge!=INVALID && nlevel>=actlevel; |
|
193 ++tbedge) |
|
194 if((nnlevel=_levels[_g.bNode(_matching[_g.runningNode(tbedge)])])< |
|
195 nlevel) |
|
196 { |
|
197 nlevel=nnlevel; |
|
198 bedge=tbedge; |
|
199 } |
|
200 } |
|
201 if(nlevel<_node_num) { |
|
202 if(nlevel>=actlevel) |
|
203 _levels.liftHighestActiveTo(nlevel+1); |
|
204 bact=_g.bNode(_matching[_g.aNode(bedge)]); |
|
205 if(--_cov[bact]<1) { |
|
206 _levels.activate(bact); |
|
207 last_activated=bact; |
|
208 } |
|
209 _matching[_g.aNode(bedge)]=bedge; |
|
210 _cov[act]=1; |
|
211 _levels.deactivate(act); |
|
212 } |
|
213 else { |
|
214 if(_node_num>actlevel) |
|
215 _levels.liftHighestActiveTo(_node_num); |
|
216 _levels.deactivate(act); |
|
217 } |
|
218 |
|
219 if(_levels.onLevel(actlevel)==0) |
|
220 return actlevel; |
|
221 } |
|
222 return -1; |
|
223 } |
|
224 |
|
225 template<class GT> |
|
226 void aBarrier(GT &bar,int empty_level=-1) |
|
227 { |
|
228 if(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; |
|
233 } |
|
234 template<class GT> |
|
235 void bBarrier(GT &bar, int empty_level=-1) |
|
236 { |
|
237 if(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); |
|
240 } |
|
241 |
|
242 }; |
|
243 |
|
244 |
|
245 ///Maximum cardinality of the matchings in a bipartite graph |
|
246 |
|
247 ///\ingroup matching |
|
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. |
|
252 /// |
|
253 ///\note The the implementation is based |
|
254 ///on the push-relabel principle. |
|
255 template<class Graph> |
|
256 int maxBpMatching(const Graph &g) |
|
257 { |
|
258 typename Graph::template ANodeMap<typename Graph::UEdge> matching(g); |
|
259 return maxBpMatching(g,matching); |
|
260 } |
|
261 |
|
262 ///Maximum cardinality matching in a bipartite graph |
|
263 |
|
264 ///\ingroup matching |
|
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. |
|
274 /// |
|
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) |
|
279 { |
|
280 return BpMatching<Graph,MT>(g,matching).run(); |
|
281 } |
|
282 |
|
283 ///Maximum cardinality matching in a bipartite graph |
|
284 |
|
285 ///\ingroup matching |
|
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. |
|
300 /// |
|
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) |
|
305 { |
|
306 BpMatching<Graph,MT> bpm(g,matching); |
|
307 int ret=bpm.run(); |
|
308 bpm.barrier(barrier); |
|
309 return ret; |
|
310 } |
|
311 |
|
312 ///Perfect matching in a bipartite graph |
|
313 |
|
314 ///\ingroup matching |
|
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. |
|
319 /// |
|
320 ///\note The the implementation is based |
|
321 ///on the push-relabel principle. |
|
322 template<class Graph> |
|
323 bool perfectBpMatching(const Graph &g) |
|
324 { |
|
325 typename Graph::template ANodeMap<typename Graph::UEdge> matching(g); |
|
326 return perfectBpMatching(g,matching); |
|
327 } |
|
328 |
|
329 ///Perfect matching in a bipartite graph |
|
330 |
|
331 ///\ingroup matching |
|
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. |
|
341 /// |
|
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) |
|
346 { |
|
347 return BpMatching<Graph,MT>(g,matching).runPerfect()<0; |
|
348 } |
|
349 |
|
350 ///Perfect matching in a bipartite graph |
|
351 |
|
352 ///\ingroup matching |
|
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. |
|
367 /// |
|
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) |
|
372 { |
|
373 BpMatching<Graph,MT> bpm(g,matching); |
|
374 int ret=bpm.run(); |
|
375 if(ret>=0) |
|
376 bpm.barrier(barrier,ret); |
|
377 return ret<0; |
|
378 } |
|
379 } |
|
380 |
|
381 #endif |