Distribute Makefiles.
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_BPUGRAPH_ADAPTOR_H
20 #define LEMON_BPUGRAPH_ADAPTOR_H
22 #include <lemon/bits/invalid.h>
23 #include <lemon/maps.h>
25 #include <lemon/bits/graph_adaptor_extender.h>
27 #include <lemon/bits/traits.h>
31 ///\ingroup graph_adaptors
33 ///\brief Several graph adaptors.
35 ///This file contains several useful bpugraph adaptor functions.
37 ///\author Balazs Dezso
41 /// \ingroup graph_adaptors
43 /// \brief Base type for the Bipartite Undirected Graph Adaptors
45 /// This is the base type for most of LEMON bpugraph adaptors.
46 /// This class implements a trivial graph adaptor i.e. it only wraps the
47 /// functions and types of the graph. The purpose of this class is to
48 /// make easier implementing graph adaptors. E.g. if an adaptor is
49 /// considered which differs from the wrapped graph only in some of its
50 /// functions or types, then it can be derived from BpUGraphAdaptor, and
51 /// only the differences should be implemented.
53 /// \author Balazs Dezso
54 template<typename _BpUGraph>
55 class BpUGraphAdaptorBase {
57 typedef _BpUGraph Graph;
58 typedef Graph ParentGraph;
63 BpUGraphAdaptorBase() : graph(0) {}
65 void setGraph(Graph& _graph) { graph = &_graph; }
67 Graph& getGraph() { return *graph; }
68 const Graph& getGraph() const { return *graph; }
72 BpUGraphAdaptorBase(Graph& _graph) : graph(&_graph) {}
74 typedef typename Graph::Node Node;
75 typedef typename Graph::ANode ANode;
76 typedef typename Graph::BNode BNode;
77 typedef typename Graph::Edge Edge;
78 typedef typename Graph::UEdge UEdge;
80 void first(Node& i) const { graph->first(i); }
81 void firstANode(Node& i) const { graph->firstANode(i); }
82 void firstBNode(Node& i) const { graph->firstBNode(i); }
83 void first(Edge& i) const { graph->first(i); }
84 void first(UEdge& i) const { graph->first(i); }
85 void firstIn(Edge& i, const Node& n) const { graph->firstIn(i, n); }
86 void firstOut(Edge& i, const Node& n ) const { graph->firstOut(i, n); }
87 void firstInc(UEdge &i, bool &d, const Node &n) const {
88 graph->firstInc(i, d, n);
91 void next(Node& i) const { graph->next(i); }
92 void nextANode(Node& i) const { graph->nextANode(i); }
93 void nextBNode(Node& i) const { graph->nextBNode(i); }
94 void next(Edge& i) const { graph->next(i); }
95 void next(UEdge& i) const { graph->next(i); }
96 void nextIn(Edge& i) const { graph->nextIn(i); }
97 void nextOut(Edge& i) const { graph->nextOut(i); }
98 void nextInc(UEdge &i, bool &d) const { graph->nextInc(i, d); }
100 Node source(const UEdge& e) const { return graph->source(e); }
101 Node target(const UEdge& e) const { return graph->target(e); }
103 Node source(const Edge& e) const { return graph->source(e); }
104 Node target(const Edge& e) const { return graph->target(e); }
106 Node aNode(const UEdge& e) const { return graph->aNode(e); }
107 Node bNode(const UEdge& e) const { return graph->bNode(e); }
109 bool aNode(const Node& n) const { return graph->aNode(n); }
110 bool bNode(const Node& n) const { return graph->bNode(n); }
112 typedef NodeNumTagIndicator<Graph> NodeNumTag;
113 int nodeNum() const { return graph->nodeNum(); }
114 int aNodeNum() const { return graph->aNodeNum(); }
115 int bNodeNum() const { return graph->bNodeNum(); }
117 typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
118 int edgeNum() const { return graph->edgeNum(); }
119 int uEdgeNum() const { return graph->uEdgeNum(); }
121 typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
122 Edge findEdge(const Node& source, const Node& target,
123 const Edge& prev = INVALID) {
124 return graph->findEdge(source, target, prev);
126 UEdge findUEdge(const Node& source, const Node& target,
127 const UEdge& prev = INVALID) {
128 return graph->findUEdge(source, target, prev);
131 Node addANode() const { return graph->addANode(); }
132 Node addBNode() const { return graph->addBNode(); }
133 UEdge addEdge(const Node& source, const Node& target) const {
134 return graph->addEdge(source, target);
137 void erase(const Node& i) const { graph->erase(i); }
138 void erase(const UEdge& i) const { graph->erase(i); }
140 void clear() const { graph->clear(); }
142 bool direction(const Edge& e) const { return graph->direction(e); }
143 Edge direct(const UEdge& e, bool d) const { return graph->direct(e, d); }
145 int id(const Node& v) const { return graph->id(v); }
146 int id(const ANode& v) const { return graph->id(v); }
147 int id(const BNode& v) const { return graph->id(v); }
148 int id(const Edge& e) const { return graph->id(e); }
149 int id(const UEdge& e) const { return graph->id(e); }
151 Node fromNodeId(int id) const { return graph->fromNodeId(id); }
152 ANode fromANodeId(int id) const { return graph->fromANodeId(id); }
153 BNode fromBNodeId(int id) const { return graph->fromBNodeId(id); }
154 Edge fromEdgeId(int id) const { return graph->fromEdgeId(id); }
155 UEdge fromUEdgeId(int id) const { return graph->fromUEdgeId(id); }
157 int maxNodeId() const { return graph->maxNodeId(); }
158 int maxANodeId() const { return graph->maxANodeId(); }
159 int maxBNodeId() const { return graph->maxBNodeId(); }
160 int maxEdgeId() const { return graph->maxEdgeId(); }
161 int maxUEdgeId() const { return graph->maxEdgeId(); }
163 typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
164 NodeNotifier& getNotifier(Node) const {
165 return graph->getNotifier(Node());
168 typedef typename ItemSetTraits<Graph, ANode>::ItemNotifier ANodeNotifier;
169 ANodeNotifier& getNotifier(ANode) const {
170 return graph->getNotifier(ANode());
173 typedef typename ItemSetTraits<Graph, BNode>::ItemNotifier BNodeNotifier;
174 BNodeNotifier& getNotifier(BNode) const {
175 return graph->getNotifier(BNode());
178 typedef typename ItemSetTraits<Graph, Edge>::ItemNotifier EdgeNotifier;
179 EdgeNotifier& getNotifier(Edge) const {
180 return graph->getNotifier(Edge());
183 typedef typename ItemSetTraits<Graph, UEdge>::ItemNotifier UEdgeNotifier;
184 UEdgeNotifier& getNotifier(UEdge) const {
185 return graph->getNotifier(UEdge());
188 template <typename _Value>
189 class NodeMap : public Graph::template NodeMap<_Value> {
191 typedef typename Graph::template NodeMap<_Value> Parent;
192 explicit NodeMap(const BpUGraphAdaptorBase<Graph>& ga)
193 : Parent(*ga.graph) {}
194 NodeMap(const BpUGraphAdaptorBase<Graph>& ga, const _Value& value)
195 : Parent(*ga.graph, value) {}
197 NodeMap& operator=(const NodeMap& cmap) {
198 return operator=<NodeMap>(cmap);
201 template <typename CMap>
202 NodeMap& operator=(const CMap& cmap) {
203 Parent::operator=(cmap);
208 template <typename _Value>
209 class ANodeMap : public Graph::template ANodeMap<_Value> {
211 typedef typename Graph::template ANodeMap<_Value> Parent;
212 explicit ANodeMap(const BpUGraphAdaptorBase& ga)
213 : Parent(*ga.graph) {}
214 ANodeMap(const BpUGraphAdaptorBase& ga, const _Value& value)
215 : Parent(*ga.graph, value) {}
217 ANodeMap& operator=(const ANodeMap& cmap) {
218 return operator=<ANodeMap>(cmap);
221 template <typename CMap>
222 ANodeMap& operator=(const CMap& cmap) {
223 Parent::operator=(cmap);
228 template <typename _Value>
229 class BNodeMap : public Graph::template BNodeMap<_Value> {
231 typedef typename Graph::template BNodeMap<_Value> Parent;
232 explicit BNodeMap(const BpUGraphAdaptorBase<Graph>& ga)
233 : Parent(*ga.graph) {}
234 BNodeMap(const BpUGraphAdaptorBase<Graph>& ga, const _Value& value)
235 : Parent(*ga.graph, value) {}
237 BNodeMap& operator=(const BNodeMap& cmap) {
238 return operator=<BNodeMap>(cmap);
241 template <typename CMap>
242 BNodeMap& operator=(const CMap& cmap) {
243 Parent::operator=(cmap);
248 template <typename _Value>
249 class EdgeMap : public Graph::template EdgeMap<_Value> {
251 typedef typename Graph::template EdgeMap<_Value> Parent;
252 explicit EdgeMap(const BpUGraphAdaptorBase<Graph>& ga)
253 : Parent(*ga.graph) {}
254 EdgeMap(const BpUGraphAdaptorBase<Graph>& ga, const _Value& value)
255 : Parent(*ga.graph, value) {}
257 EdgeMap& operator=(const EdgeMap& cmap) {
258 return operator=<EdgeMap>(cmap);
261 template <typename CMap>
262 EdgeMap& operator=(const CMap& cmap) {
263 Parent::operator=(cmap);
268 template <typename _Value>
269 class UEdgeMap : public Graph::template UEdgeMap<_Value> {
271 typedef typename Graph::template UEdgeMap<_Value> Parent;
272 explicit UEdgeMap(const BpUGraphAdaptorBase<Graph>& ga)
273 : Parent(*ga.graph) {}
274 UEdgeMap(const BpUGraphAdaptorBase<Graph>& ga, const _Value& value)
275 : Parent(*ga.graph, value) {}
277 UEdgeMap& operator=(const UEdgeMap& cmap) {
278 return operator=<UEdgeMap>(cmap);
281 template <typename CMap>
282 UEdgeMap& operator=(const CMap& cmap) {
283 Parent::operator=(cmap);
290 /// \ingroup graph_adaptors
292 /// \brief Trivial Bipartite Undirected Graph Adaptor
294 /// Trivial Bipartite Undirected Graph Adaptor. It does not change
295 /// the functionality of the adapted graph.
296 template <typename _BpUGraph>
297 class BpUGraphAdaptor
298 : public BpUGraphAdaptorExtender< BpUGraphAdaptorBase<_BpUGraph> > {
300 typedef _BpUGraph Graph;
301 typedef BpUGraphAdaptorExtender<BpUGraphAdaptorBase<_BpUGraph> > Parent;
303 BpUGraphAdaptor() : Parent() {}
306 explicit BpUGraphAdaptor(Graph& _graph) { setGraph(_graph); }
309 template <typename _BpUGraph>
310 class SwapBpUGraphAdaptorBase : public BpUGraphAdaptorBase<_BpUGraph> {
313 typedef _BpUGraph Graph;
314 typedef BpUGraphAdaptorBase<_BpUGraph> Parent;
318 SwapBpUGraphAdaptorBase() {}
322 typedef typename Parent::Node Node;
323 typedef typename Parent::BNode ANode;
324 typedef typename Parent::ANode BNode;
325 typedef typename Parent::Edge Edge;
326 typedef typename Parent::UEdge UEdge;
328 bool direction(const Edge& e) const { return !Parent::direction(e); }
329 Edge direct(const UEdge& e, bool b) const { return Parent::direct(e, !b); }
331 Node aNode(const UEdge& e) const { return Parent::bNode(e); }
332 Node bNode(const UEdge& e) const { return Parent::aNode(e); }
334 bool aNode(const Node& n) const { return Parent::bNode(n); }
335 bool bNode(const Node& n) const { return Parent::aNode(n); }
337 void firstANode(Node& i) const { Parent::firstBNode(i); }
338 void firstBNode(Node& i) const { Parent::firstANode(i); }
340 void nextANode(Node& i) const { Parent::nextBNode(i); }
341 void nextBNode(Node& i) const { Parent::nextANode(i); }
343 int id(const ANode& v) const { return Parent::id(v); }
344 int id(const BNode& v) const { return Parent::id(v); }
346 ANode fromANodeId(int id) const { return Parent::fromBNodeId(id); }
347 BNode fromBNodeId(int id) const { return Parent::fromANodeId(id); }
349 int maxANodeId() const { return Parent::maxBNodeId(); }
350 int maxBNodeId() const { return Parent::maxANodeId(); }
352 int aNodeNum() const { return Parent::bNodeNum(); }
353 int bNodeNum() const { return Parent::aNodeNum(); }
355 typedef typename Parent::BNodeNotifier ANodeNotifier;
356 ANodeNotifier& getNotifier(ANode) const {
357 return Parent::getNotifier(typename Parent::BNode());
360 typedef typename Parent::ANodeNotifier BNodeNotifier;
361 BNodeNotifier& getNotifier(BNode) const {
362 return Parent::getNotifier(typename Parent::ANode());
365 template <typename _Value>
366 class ANodeMap : public Graph::template BNodeMap<_Value> {
368 typedef typename Graph::template BNodeMap<_Value> Parent;
369 explicit ANodeMap(const SwapBpUGraphAdaptorBase& ga)
370 : Parent(*ga.graph) {}
371 ANodeMap(const SwapBpUGraphAdaptorBase& ga, const _Value& value)
372 : Parent(*ga.graph, value) {}
374 ANodeMap& operator=(const ANodeMap& cmap) {
375 return operator=<ANodeMap>(cmap);
378 template <typename CMap>
379 ANodeMap& operator=(const CMap& cmap) {
380 Parent::operator=(cmap);
385 template <typename _Value>
386 class BNodeMap : public Graph::template ANodeMap<_Value> {
388 typedef typename Graph::template ANodeMap<_Value> Parent;
389 explicit BNodeMap(const SwapBpUGraphAdaptorBase<Graph>& ga)
390 : Parent(*ga.graph) {}
391 BNodeMap(const SwapBpUGraphAdaptorBase<Graph>& ga, const _Value& value)
392 : Parent(*ga.graph, value) {}
394 BNodeMap& operator=(const BNodeMap& cmap) {
395 return operator=<BNodeMap>(cmap);
398 template <typename CMap>
399 BNodeMap& operator=(const CMap& cmap) {
400 Parent::operator=(cmap);
407 /// \ingroup graph_adaptors
409 /// \brief Bipartite graph adaptor which swaps the two nodeset.
411 /// Bipartite graph adaptor which swaps the two nodeset. The adaptor's
412 /// anode-set will be the original graph's bnode-set and the adaptor's
413 /// bnode-set will be the original graph's anode-set.
415 /// As example look at an algorithm what can be sped up with the
416 /// swap bipartite undirected graph adaptor. If we want to find the
417 /// maximum matching in the bipartite graph then it will be not changed
418 /// if we swap the two nodesets. But the algorithm use the two nodeset
419 /// different way. If we swap the nodesets it provides different
420 /// running time. We run a test on random bipartite graphs with
421 /// different rate of the anode-set size and bnode-set size.
422 /// We always made graphs with 10000 nodes and 20000 edges and we
423 /// computed the maximum cardinality matching with the Hopcroft-Karp
426 /// The next diagram shows the running time of the tests. If the anode-set
427 /// is smaller than the bnode-set the running time is better than with
428 /// the swapped graph. Other conclusion is that the running time
429 /// is greater when the two nodesets size are nearly equal.
431 /// \image html swap_test.png
432 /// \image latex swap_test.eps "Swapping nodesets" width=\textwidth
434 /// The next part shows how can we swap the two nodeset:
437 /// typedef SwapBpUGraphAdaptor<BpUGraph> SBpUGraph;
438 /// SBpUGraph sbpugraph(bpugraph);
439 /// MaxBipartiteMatching<SBpUGraph> sbpumatch(sbpugraph);
441 template <typename _BpUGraph>
442 class SwapBpUGraphAdaptor
443 : public BpUGraphAdaptorExtender<SwapBpUGraphAdaptorBase<_BpUGraph> > {
446 typedef _BpUGraph Graph;
447 typedef BpUGraphAdaptorExtender<SwapBpUGraphAdaptorBase<_BpUGraph> >
451 SwapBpUGraphAdaptor() : Parent() {}
455 /// \brief Construct a swapped graph.
457 /// Construct a swapped graph.
458 explicit SwapBpUGraphAdaptor(Graph& _graph) { setGraph(_graph); }
463 template <typename _BpUGraph,
464 typename _ANMatchingMap, typename _BNMatchingMap>
465 class MatchingBpUGraphAdaptorBase
466 : public BpUGraphAdaptorBase<const _BpUGraph>
470 typedef _BpUGraph Graph;
471 typedef _ANMatchingMap ANodeMatchingMap;
472 typedef _BNMatchingMap BNodeMatchingMap;
474 typedef BpUGraphAdaptorBase<const _BpUGraph> Parent;
478 MatchingBpUGraphAdaptorBase() {}
480 void setANodeMatchingMap(ANodeMatchingMap& _anode_matching) {
481 anode_matching = &_anode_matching;
484 void setBNodeMatchingMap(BNodeMatchingMap& _bnode_matching) {
485 bnode_matching = &_bnode_matching;
490 typedef typename Parent::Node Node;
491 typedef typename Parent::Edge Edge;
493 void firstOut(Edge& edge, const Node& node) const {
494 if (Parent::aNode(node)) {
495 Parent::firstOut(edge, node);
496 if (edge != INVALID && (*anode_matching)[node] == edge) {
497 Parent::nextOut(edge);
500 edge = (*bnode_matching)[node] != INVALID ?
501 Parent::direct((*bnode_matching)[node], false) : INVALID;
505 void nextOut(Edge& edge) const {
506 if (Parent::aNode(Parent::source(edge))) {
507 Parent::nextOut(edge);
508 if (edge != INVALID && (*anode_matching)[Parent::aNode(edge)] == edge) {
509 Parent::nextOut(edge);
516 void firstIn(Edge& edge, const Node& node) const {
517 if (Parent::aNode(node)) {
518 edge = (*bnode_matching)[node] != INVALID ?
519 Parent::direct((*anode_matching)[node], false) : INVALID;
521 Parent::firstIn(edge, node);
522 if (edge != INVALID && (*bnode_matching)[node] == edge) {
523 Parent::nextIn(edge);
528 void nextIn(Edge& edge) const {
529 if (Parent::aNode(Parent::target(edge))) {
532 Parent::nextIn(edge);
533 if (edge != INVALID && (*bnode_matching)[Parent::bNode(edge)] == edge) {
534 Parent::nextIn(edge);
540 ANodeMatchingMap* anode_matching;
541 BNodeMatchingMap* bnode_matching;
545 /// \ingroup graph_adaptors
547 /// \brief Bipartite graph adaptor to implement matching algorithms.
549 /// Bipartite graph adaptor to implement matchings. It implements
550 /// the residual graph of the matching.
551 template <typename _BpUGraph,
552 typename _ANMatchingMap, typename _BNMatchingMap>
553 class MatchingBpUGraphAdaptor
554 : public BpUGraphAdaptorExtender<
555 MatchingBpUGraphAdaptorBase<_BpUGraph, _ANMatchingMap, _BNMatchingMap> >
559 typedef _BpUGraph BpUGraph;
560 typedef _BpUGraph Graph;
561 typedef _ANMatchingMap ANodeMatchingMap;
562 typedef _BNMatchingMap BNodeMatchingMap;
563 typedef BpUGraphAdaptorExtender<
564 MatchingBpUGraphAdaptorBase<BpUGraph,
565 ANodeMatchingMap, BNodeMatchingMap> >
569 MatchingBpUGraphAdaptor() : Parent() {}
573 MatchingBpUGraphAdaptor(const Graph& _graph,
574 ANodeMatchingMap& _anode_matching,
575 BNodeMatchingMap& _bnode_matching) {
577 setANodeMatchingMap(_anode_matching);
578 setBNodeMatchingMap(_bnode_matching);