3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
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_BIPARTITE_MATCHING
20 #define LEMON_BIPARTITE_MATCHING
22 #include <lemon/bpugraph_adaptor.h>
23 #include <lemon/bfs.h>
29 ///\brief Maximum matching algorithms in bipartite graphs.
35 /// \brief Bipartite Max Cardinality Matching algorithm
37 /// Bipartite Max Cardinality Matching algorithm. This class implements
38 /// the Hopcroft-Karp algorithm wich has \f$ O(e\sqrt{n}) \f$ time
40 template <typename BpUGraph>
41 class MaxBipartiteMatching {
44 typedef BpUGraph Graph;
46 typedef typename Graph::Node Node;
47 typedef typename Graph::ANodeIt ANodeIt;
48 typedef typename Graph::BNodeIt BNodeIt;
49 typedef typename Graph::UEdge UEdge;
50 typedef typename Graph::UEdgeIt UEdgeIt;
51 typedef typename Graph::IncEdgeIt IncEdgeIt;
53 typedef typename BpUGraph::template ANodeMap<UEdge> ANodeMatchingMap;
54 typedef typename BpUGraph::template BNodeMap<UEdge> BNodeMatchingMap;
59 /// \brief Constructor.
61 /// Constructor of the algorithm.
62 MaxBipartiteMatching(const BpUGraph& _graph)
63 : anode_matching(_graph), bnode_matching(_graph), graph(&_graph) {}
65 /// \name Execution control
66 /// The simplest way to execute the algorithm is to use
67 /// one of the member functions called \c run().
69 /// If you need more control on the execution,
70 /// first you must call \ref init() or one alternative for it.
71 /// Finally \ref start() will perform the matching computation or
72 /// with step-by-step execution you can augment the solution.
76 /// \brief Initalize the data structures.
78 /// It initalizes the data structures and creates an empty matching.
80 for (ANodeIt it(*graph); it != INVALID; ++it) {
81 anode_matching[it] = INVALID;
83 for (BNodeIt it(*graph); it != INVALID; ++it) {
84 bnode_matching[it] = INVALID;
89 /// \brief Initalize the data structures.
91 /// It initalizes the data structures and creates a greedy
92 /// matching. From this matching sometimes it is faster to get
93 /// the matching than from the initial empty matching.
96 for (BNodeIt it(*graph); it != INVALID; ++it) {
97 bnode_matching[it] = INVALID;
99 for (ANodeIt it(*graph); it != INVALID; ++it) {
100 anode_matching[it] = INVALID;
101 for (IncEdgeIt jt(*graph, it); jt != INVALID; ++jt) {
102 if (bnode_matching[graph->bNode(jt)] == INVALID) {
103 anode_matching[it] = jt;
104 bnode_matching[graph->bNode(jt)] = jt;
112 /// \brief Initalize the data structures with an initial matching.
114 /// It initalizes the data structures with an initial matching.
115 template <typename MatchingMap>
116 void matchingInit(const MatchingMap& matching) {
117 for (ANodeIt it(*graph); it != INVALID; ++it) {
118 anode_matching[it] = INVALID;
120 for (BNodeIt it(*graph); it != INVALID; ++it) {
121 bnode_matching[it] = INVALID;
124 for (UEdgeIt it(*graph); it != INVALID; ++it) {
127 anode_matching[graph->aNode(it)] = it;
128 bnode_matching[graph->bNode(it)] = it;
133 /// \brief Initalize the data structures with an initial matching.
135 /// It initalizes the data structures with an initial matching.
136 /// \return %True when the given map contains really a matching.
137 template <typename MatchingMap>
138 void checkedMatchingInit(const MatchingMap& matching) {
139 for (ANodeIt it(*graph); it != INVALID; ++it) {
140 anode_matching[it] = INVALID;
142 for (BNodeIt it(*graph); it != INVALID; ++it) {
143 bnode_matching[it] = INVALID;
146 for (UEdgeIt it(*graph); it != INVALID; ++it) {
149 if (anode_matching[graph->aNode(it)] != INVALID) {
152 anode_matching[graph->aNode(it)] = it;
153 if (bnode_matching[graph->aNode(it)] != INVALID) {
156 bnode_matching[graph->bNode(it)] = it;
162 /// \brief An augmenting phase of the Hopcroft-Karp algorithm
164 /// It runs an augmenting phase of the Hopcroft-Karp
165 /// algorithm. The phase finds maximum count of edge disjoint
166 /// augmenting paths and augments on these paths. The algorithm
167 /// consists at most of \f$ O(\sqrt{n}) \f$ phase and one phase is
168 /// \f$ O(e) \f$ long.
171 typename Graph::template ANodeMap<bool> areached(*graph, false);
172 typename Graph::template BNodeMap<bool> breached(*graph, false);
174 typename Graph::template BNodeMap<UEdge> bpred(*graph, INVALID);
176 std::vector<Node> queue, bqueue;
177 for (ANodeIt it(*graph); it != INVALID; ++it) {
178 if (anode_matching[it] == INVALID) {
184 bool success = false;
186 while (!success && !queue.empty()) {
187 std::vector<Node> newqueue;
188 for (int i = 0; i < (int)queue.size(); ++i) {
189 Node anode = queue[i];
190 for (IncEdgeIt jt(*graph, anode); jt != INVALID; ++jt) {
191 Node bnode = graph->bNode(jt);
192 if (breached[bnode]) continue;
193 breached[bnode] = true;
195 if (bnode_matching[bnode] == INVALID) {
196 bqueue.push_back(bnode);
199 Node newanode = graph->aNode(bnode_matching[bnode]);
200 if (!areached[newanode]) {
201 areached[newanode] = true;
202 newqueue.push_back(newanode);
207 queue.swap(newqueue);
212 typename Graph::template ANodeMap<bool> aused(*graph, false);
214 for (int i = 0; i < (int)bqueue.size(); ++i) {
215 Node bnode = bqueue[i];
219 while (bnode != INVALID) {
220 UEdge uedge = bpred[bnode];
221 Node anode = graph->aNode(uedge);
228 bnode = anode_matching[anode] != INVALID ?
229 graph->bNode(anode_matching[anode]) : INVALID;
236 while (bnode != INVALID) {
237 UEdge uedge = bpred[bnode];
238 Node anode = graph->aNode(uedge);
240 bnode_matching[bnode] = uedge;
242 bnode = anode_matching[anode] != INVALID ?
243 graph->bNode(anode_matching[anode]) : INVALID;
245 anode_matching[anode] = uedge;
256 /// \brief An augmenting phase of the Ford-Fulkerson algorithm
258 /// It runs an augmenting phase of the Ford-Fulkerson
259 /// algorithm. The phase finds only one augmenting path and
260 /// augments only on this paths. The algorithm consists at most
261 /// of \f$ O(n) \f$ simple phase and one phase is at most
262 /// \f$ O(e) \f$ long.
263 bool simpleAugment() {
265 typename Graph::template ANodeMap<bool> areached(*graph, false);
266 typename Graph::template BNodeMap<bool> breached(*graph, false);
268 typename Graph::template BNodeMap<UEdge> bpred(*graph, INVALID);
270 std::vector<Node> queue;
271 for (ANodeIt it(*graph); it != INVALID; ++it) {
272 if (anode_matching[it] == INVALID) {
278 while (!queue.empty()) {
279 std::vector<Node> newqueue;
280 for (int i = 0; i < (int)queue.size(); ++i) {
281 Node anode = queue[i];
282 for (IncEdgeIt jt(*graph, anode); jt != INVALID; ++jt) {
283 Node bnode = graph->bNode(jt);
284 if (breached[bnode]) continue;
285 breached[bnode] = true;
287 if (bnode_matching[bnode] == INVALID) {
288 while (bnode != INVALID) {
289 UEdge uedge = bpred[bnode];
290 anode = graph->aNode(uedge);
292 bnode_matching[bnode] = uedge;
294 bnode = anode_matching[anode] != INVALID ?
295 graph->bNode(anode_matching[anode]) : INVALID;
297 anode_matching[anode] = uedge;
303 Node newanode = graph->aNode(bnode_matching[bnode]);
304 if (!areached[newanode]) {
305 areached[newanode] = true;
306 newqueue.push_back(newanode);
311 queue.swap(newqueue);
317 /// \brief Starts the algorithm.
319 /// Starts the algorithm. It runs augmenting phases until the optimal
320 /// solution reached.
325 /// \brief Runs the algorithm.
327 /// It just initalize the algorithm and then start it.
335 /// \name Query Functions
336 /// The result of the %Matching algorithm can be obtained using these
338 /// Before the use of these functions,
339 /// either run() or start() must be called.
343 /// \brief Returns an minimum covering of the nodes.
345 /// The minimum covering set problem is the dual solution of the
346 /// maximum bipartite matching. It provides an solution for this
347 /// problem what is proof of the optimality of the matching.
348 /// \return The size of the cover set.
349 template <typename CoverMap>
350 int coverSet(CoverMap& covering) {
352 typename Graph::template ANodeMap<bool> areached(*graph, false);
353 typename Graph::template BNodeMap<bool> breached(*graph, false);
355 std::vector<Node> queue;
356 for (ANodeIt it(*graph); it != INVALID; ++it) {
357 if (anode_matching[it] == INVALID) {
362 while (!queue.empty()) {
363 std::vector<Node> newqueue;
364 for (int i = 0; i < (int)queue.size(); ++i) {
365 Node anode = queue[i];
366 for (IncEdgeIt jt(*graph, anode); jt != INVALID; ++jt) {
367 Node bnode = graph->bNode(jt);
368 if (breached[bnode]) continue;
369 breached[bnode] = true;
370 if (bnode_matching[bnode] != INVALID) {
371 Node newanode = graph->aNode(bnode_matching[bnode]);
372 if (!areached[newanode]) {
373 areached[newanode] = true;
374 newqueue.push_back(newanode);
379 queue.swap(newqueue);
383 for (ANodeIt it(*graph); it != INVALID; ++it) {
384 covering[it] = !areached[it] && anode_matching[it] != INVALID;
385 if (!areached[it] && anode_matching[it] != INVALID) {
389 for (BNodeIt it(*graph); it != INVALID; ++it) {
390 covering[it] = breached[it];
398 /// \brief Set true all matching uedge in the map.
400 /// Set true all matching uedge in the map. It does not change the
401 /// value mapped to the other uedges.
402 /// \return The number of the matching edges.
403 template <typename MatchingMap>
404 int quickMatching(MatchingMap& matching) {
405 for (ANodeIt it(*graph); it != INVALID; ++it) {
406 if (anode_matching[it] != INVALID) {
407 matching[anode_matching[it]] = true;
410 return matching_value;
413 /// \brief Set true all matching uedge in the map and the others to false.
415 /// Set true all matching uedge in the map and the others to false.
416 /// \return The number of the matching edges.
417 template <typename MatchingMap>
418 int matching(MatchingMap& matching) {
419 for (UEdgeIt it(*graph); it != INVALID; ++it) {
420 matching[it] = it == anode_matching[graph->aNode(it)];
422 return matching_value;
426 /// \brief Return true if the given uedge is in the matching.
428 /// It returns true if the given uedge is in the matching.
429 bool matchingEdge(const UEdge& edge) {
430 return anode_matching[graph->aNode(edge)] == edge;
433 /// \brief Returns the matching edge from the node.
435 /// Returns the matching edge from the node. If there is not such
436 /// edge it gives back \c INVALID.
437 UEdge matchingEdge(const Node& node) {
438 if (graph->aNode(node)) {
439 return anode_matching[node];
441 return bnode_matching[node];
445 /// \brief Gives back the number of the matching edges.
447 /// Gives back the number of the matching edges.
448 int matchingValue() const {
449 return matching_value;
456 ANodeMatchingMap anode_matching;
457 BNodeMatchingMap bnode_matching;