Added new make target 'benchmark'.
2 #ifndef HUGO_BIPARTITE_GRAPH_WRAPPER_H
3 #define HUGO_BIPARTITE_GRAPH_WRAPPER_H
7 ///\brief Several graph wrappers.
9 ///This file contains several useful graph wrapper functions.
11 ///\author Marton Makai
13 #include <hugo/invalid.h>
15 #include <hugo/graph_wrapper.h>
19 /// \brief A wrapper for composing a bipartite graph from a graph
20 /// and from a node-map showing for any node which color class it belongs to.
22 /// A wrapper for composing a bipartite graph.
23 /// \c _graph have to be a reference to a graph of type \c Graph
24 /// and \c _s_false_t_true_map is an \c IterableBoolMap
25 /// reference containing the elements for the
26 /// color classes S and T. \c _graph is to be referred to an undirected
27 /// graph or a directed graph with edges oriented from S to T.
29 /// \author Marton Makai
30 template<typename Graph>
31 class BipartiteGraphWrapper : public GraphWrapper<Graph> {
33 typedef IterableBoolMap< typename Graph::template NodeMap<int> >
35 SFalseTTrueMap* s_false_t_true_map;
37 BipartiteGraphWrapper() : GraphWrapper<Graph>()/*,
38 S_CLASS(false), T_CLASS(true)*/ { }
39 void setSFalseTTrueMap(SFalseTTrueMap& _s_false_t_true_map) {
40 s_false_t_true_map=&_s_false_t_true_map;
45 //FIXME vhogy igy kellene, csak az en forditom nem eszi meg
46 static const bool S_CLASS;
47 static const bool T_CLASS;
52 BipartiteGraphWrapper(Graph& _graph, SFalseTTrueMap& _s_false_t_true_map)
53 : GraphWrapper<Graph>(_graph),
54 s_false_t_true_map(&_s_false_t_true_map)/*,
55 S_CLASS(false), T_CLASS(true)*/ { }
56 typedef typename GraphWrapper<Graph>::Node Node;
57 //using GraphWrapper<Graph>::NodeIt;
58 typedef typename GraphWrapper<Graph>::Edge Edge;
59 //using GraphWrapper<Graph>::EdgeIt;
61 friend class ClassNodeIt;
63 friend class OutEdgeIt;
65 friend class InEdgeIt;
67 friend class BipartiteGraphWrapper<Graph>;
72 ClassNodeIt(const Invalid& i) : n(i) { }
73 ClassNodeIt(const BipartiteGraphWrapper<Graph>& _G, bool _class) {
74 _G.s_false_t_true_map->first(n, _class);
76 //FIXME needed in new concept, important here
77 ClassNodeIt(const Node& _n) : n(_n) { }
78 operator Node() const { return n; }
84 // SNodeIt(const Invalid& i) : n(i) { }
85 // SNodeIt(const BipartiteGraphWrapper<Graph>& _G) {
86 // _G.s_false_t_true_map->first(n, false);
88 // operator Node() const { return n; }
94 // TNodeIt(const Invalid& i) : n(i) { }
95 // TNodeIt(const BipartiteGraphWrapper<Graph>& _G) {
96 // _G.s_false_t_true_map->first(n, true);
98 // operator Node() const { return n; }
101 friend class BipartiteGraphWrapper<Graph>;
103 typename Graph::OutEdgeIt e;
106 OutEdgeIt(const Invalid& i) : e(i) { }
107 OutEdgeIt(const BipartiteGraphWrapper<Graph>& _G, const Node& _n) {
108 if (!(*(_G.s_false_t_true_map))[_n])
109 e=typename Graph::OutEdgeIt(*(_G.graph), typename Graph::Node(_n));
113 operator Edge() const { return Edge(typename Graph::Edge(e)); }
116 friend class BipartiteGraphWrapper<Graph>;
118 typename Graph::InEdgeIt e;
121 InEdgeIt(const Invalid& i) : e(i) { }
122 InEdgeIt(const BipartiteGraphWrapper<Graph>& _G, const Node& _n) {
123 if ((*(_G.s_false_t_true_map))[_n])
124 e=typename Graph::InEdgeIt(*(_G.graph), typename Graph::Node(_n));
128 operator Edge() const { return Edge(typename Graph::Edge(e)); }
131 using GraphWrapper<Graph>::first;
132 ClassNodeIt& first(ClassNodeIt& n, bool _class) const {
133 n=ClassNodeIt(*this, _class) ; return n; }
134 // SNodeIt& first(SNodeIt& n) const { n=SNodeIt(*this); return n; }
135 // TNodeIt& first(TNodeIt& n) const { n=TNodeIt(*this); return n; }
136 OutEdgeIt& first(OutEdgeIt& i, const Node& p) const {
137 i=OutEdgeIt(*this, p); return i;
139 InEdgeIt& first(InEdgeIt& i, const Node& p) const {
140 i=InEdgeIt(*this, p); return i;
143 using GraphWrapper<Graph>::next;
144 ClassNodeIt& next(ClassNodeIt& n) const {
145 this->s_false_t_true_map->next(n.n); return n;
147 // SNodeIt& next(SNodeIt& n) const {
148 // this->s_false_t_true_map->next(n); return n;
150 // TNodeIt& next(TNodeIt& n) const {
151 // this->s_false_t_true_map->next(n); return n;
153 OutEdgeIt& next(OutEdgeIt& i) const { this->graph->next(i.e); return i; }
154 InEdgeIt& next(InEdgeIt& i) const { this->graph->next(i.e); return i; }
156 Node tail(const Edge& e) {
157 if (!(*(this->s_false_t_true_map))[this->graph->tail(e)])
158 return Node(this->graph->tail(e));
160 return Node(this->graph->head(e));
162 Node head(const Edge& e) {
163 if (!(*(this->s_false_t_true_map))[this->graph->tail(e)])
164 return Node(this->graph->head(e));
166 return Node(this->graph->tail(e));
169 Node aNode(const OutEdgeIt& e) const {
170 return Node(this->graph->aNode(e.e));
172 Node aNode(const InEdgeIt& e) const {
173 return Node(this->graph->aNode(e.e));
175 Node bNode(const OutEdgeIt& e) const {
176 return Node(this->graph->bNode(e.e));
178 Node bNode(const InEdgeIt& e) const {
179 return Node(this->graph->bNode(e.e));
182 /// Returns true iff \c n is in S.
183 bool inSClass(const Node& n) const {
184 return !(*(this->s_false_t_true_map))[n];
187 /// Returns true iff \c n is in T.
188 bool inTClass(const Node& n) const {
189 return (*(this->s_false_t_true_map))[n];
195 const bool BipartiteGraphWrapper<G>::S_CLASS=false;
197 const bool BipartiteGraphWrapper<G>::T_CLASS=true;
199 /// \brief A bipartite graph template class
201 /// This class composes a bipartite graph over a directed or undirected
202 /// graph structure of type \c Graph.
203 /// \c _graph have to be a reference to a graph of type \c Graph
204 /// and \c _s_false_t_true_map is an \c IterableBoolMap
205 /// reference containing the elements for the
206 /// color classes S and T. \c _graph is to be referred to an undirected
207 /// graph or a directed graph with edges oriented from S to T.
209 ///\bug experimental. Do not use this while the bipartitemap augmentation
210 /// does not work well.
211 template<typename Graph>
212 class BipartiteGraph : public BipartiteGraphWrapper<Graph> {
213 typedef IterableBoolMap< typename Graph::template NodeMap<int> >
215 typedef BipartiteGraphWrapper<Graph> Parent;
218 typename Graph::template NodeMap<int> bipartite_map;
219 SFalseTTrueMap s_false_t_true_map;
221 typedef typename Parent::Node Node;
222 typedef typename Parent::Edge Edge;
223 BipartiteGraph() : BipartiteGraphWrapper<Graph>(),
224 gr(), bipartite_map(gr, -1),
225 s_false_t_true_map(bipartite_map) {
226 Parent::setGraph(gr);
227 Parent::setSFalseTTrueMap(s_false_t_true_map);
230 /// the \c bool parameter which can be \c S_Class or \c T_Class shows
231 /// the color class where the new node is to be inserted.
232 Node addNode(bool b) {
233 Node n=Parent::graph->addNode();
234 bipartite_map.update();
235 //bipartite_map.set(n, -1);
236 s_false_t_true_map.insert(n, b);
240 /// A new edge is inserted.
241 ///\pre \c tail have to be in \c S_Class and \c head in \c T_Class.
242 Edge addEdge(const Node& tail, const Node& head) {
243 return Parent::graph->addEdge(tail, head);
246 void erase(const Node& n) {
247 s_false_t_true_map.remove(n);
248 Parent::graph->erase(n);
250 void erase(const Edge& e) {
251 Parent::graph->erase(e);
255 FOR_EACH_LOC(typename Parent::EdgeIt, e, *this) erase(e);
256 FOR_EACH_LOC(typename Parent::NodeIt, n, *this) erase(n);
261 template<typename Graph>
262 class stGraphWrapper;
264 // template<typename Graph>
266 // operator<<(std::ostream& os, const typename stGraphWrapper<Graph>::Node& i) {
267 // os << "(node: " << typename Graph::Node(i) << " spec: " << i.spec <<")";
270 // template<typename Graph>
272 // operator<<(std::ostream& os, const typename stGraphWrapper<Graph>::Edge& i) {
273 // os << "(edge: " << typename Graph::Edge(i) << " spec: " << i.spec <<
274 // " node: " << i.n << ")";
278 /// \brief A wrapper for adding extra nodes s and t to a bipartite graph
279 /// and edges from s to each node of S and form each node of T to t.
281 /// A wrapper for adding extra nodes s and t to a bipartite graph
282 /// and edges from s to each node of S and form each node of T to t.
283 /// This class is very useful to reduce some matching or more
284 /// generally, capacitataed b-matching problem to a flow problem.
285 /// According to the bipartite graph concepts the bipartite
286 /// graph have to be oriented from S to T.
288 /// \author Marton Makai
289 template<typename Graph>
290 class stGraphWrapper : public GraphWrapper<Graph> {
295 //0 normalis, 1 s, 2, true, ez az iteralasi sorrend,
296 //es a vege a false azaz (invalid, 3)
303 //0 normalis, 1 s->vmi, 2 vmi->t, ez a sorrend,
304 //invalid: (invalid, 3, invalid)
306 friend class OutEdgeIt;
308 //normalis pontbol (first, 0, invalid), ..., (invalid, 2, vmi), ... (invalid, 3, invalid)
309 //s-bol (invalid, 1, first), ... (invalid, 3, invalid)
310 //t-bol (invalid, 3, invalid)
312 friend class InEdgeIt;
314 //normalis pontbol (first, 0, invalid), ..., (invalid, 1, vmi), ... (invalid, 3, invalid)
315 //s-be (invalid, 3, invalid)
316 //t-be (invalid, 2, first), ... (invalid, 3, invalid)
319 //(first, 0, invalid) ...
322 //invalid, 3, invalid)
323 template <typename T> class NodeMap;
324 template <typename T> class EdgeMap;
326 // template <typename T> friend class NodeMap;
327 // template <typename T> friend class EdgeMap;
329 ///\todo FIXME ezt majd static-ra kell javitani
333 static const bool S_CLASS=false;
334 static const bool T_CLASS=true;
336 stGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) ,
338 T_NODE(INVALID, 2) { }
342 // operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Node& i);
343 // friend std::ostream&
344 // operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Node& i);
345 // friend std::ostream&
346 // operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Edge& i);
348 class Node : public Graph::Node {
350 friend class GraphWrapper<Graph>;
351 friend class stGraphWrapper<Graph>;
352 template <typename T> friend class NodeMap;
354 friend class OutEdgeIt;
355 friend class InEdgeIt;
360 Node(const typename Graph::Node& _n, int _spec=0) :
361 Graph::Node(_n), spec(_spec) { }
362 Node(const Invalid& i) : Graph::Node(i), spec(3) { }
363 friend bool operator==(const Node& u, const Node& v) {
364 return (u.spec==v.spec &&
365 static_cast<typename Graph::Node>(u)==
366 static_cast<typename Graph::Node>(v));
368 friend bool operator!=(const Node& u, const Node& v) {
369 return (v.spec!=u.spec ||
370 static_cast<typename Graph::Node>(u)!=
371 static_cast<typename Graph::Node>(v));
373 // template<typename G>
374 // friend std::ostream&
375 // operator<<(std::ostream& os, const typename stGraphWrapper<G>::Node& i);
376 friend std::ostream& operator<< (std::ostream& os, const Node& i);
377 int getSpec() const { return spec; }
381 friend class GraphWrapper<Graph>;
382 friend class stGraphWrapper<Graph>;
383 typename Graph::NodeIt n;
387 NodeIt(const typename Graph::NodeIt& _n, int _spec) :
388 n(_n), spec(_spec) { }
389 NodeIt(const Invalid& i) : n(i), spec(3) { }
390 NodeIt(const stGraphWrapper<Graph>& _G) : n(*(_G.graph)), spec(0) {
391 if (!_G.graph->valid(n)) spec=1;
393 operator Node() const { return Node(n, spec); }
396 class Edge : public Graph::Edge {
397 friend class GraphWrapper<Graph>;
398 friend class stGraphWrapper<Graph>;
399 template <typename T> friend class EdgeMap;
401 typename Graph::Node n;
404 Edge(const typename Graph::Edge& _e, int _spec,
405 const typename Graph::Node& _n) :
406 Graph::Edge(_e), spec(_spec), n(_n) {
408 Edge(const Invalid& i) : Graph::Edge(i), spec(3), n(i) { }
409 friend bool operator==(const Edge& u, const Edge& v) {
410 return (u.spec==v.spec &&
411 static_cast<typename Graph::Edge>(u)==
412 static_cast<typename Graph::Edge>(v) &&
415 friend bool operator!=(const Edge& u, const Edge& v) {
416 return (v.spec!=u.spec ||
417 static_cast<typename Graph::Edge>(u)!=
418 static_cast<typename Graph::Edge>(v) ||
421 // template<typename G>
422 // friend std::ostream&
423 // operator<<(std::ostream& os, const typename stGraphWrapper<G>::Edge& i);
424 friend std::ostream& operator<< (std::ostream& os, const Edge& i);
425 int getSpec() const { return spec; }
426 typename Graph::Node getNode() const { return n; }
430 friend class GraphWrapper<Graph>;
431 friend class stGraphWrapper<Graph>;
432 typename Graph::OutEdgeIt e;
434 typename Graph::ClassNodeIt n;
437 OutEdgeIt(const typename Graph::OutEdgeIt& _e, int _spec,
438 const typename Graph::ClassNodeIt& _n) :
439 e(_e), spec(_spec), n(_n) {
441 OutEdgeIt(const Invalid& i) : e(i), spec(3), n(i) { }
442 OutEdgeIt(const stGraphWrapper<Graph>& _G, const Node& _n) {
445 if (_G.graph->inSClass(_n)) { //S, van normalis kiel
446 e=typename Graph::OutEdgeIt(*(_G.graph),
447 typename Graph::Node(_n));
450 if (!_G.graph->valid(e)) spec=3;
451 } else { //T, specko kiel van
460 _G.graph->first(n, S_CLASS); //s->vmi;
461 if (!_G.graph->valid(n)) spec=3; //Ha S ures
470 operator Edge() const { return Edge(e, spec, n); }
474 friend class GraphWrapper<Graph>;
475 friend class stGraphWrapper<Graph>;
476 typename Graph::InEdgeIt e;
478 typename Graph::ClassNodeIt n;
481 InEdgeIt(const typename Graph::InEdgeIt& _e, int _spec,
482 const typename Graph::ClassNodeIt& _n) :
483 e(_e), spec(_spec), n(_n) {
485 InEdgeIt(const Invalid& i) : e(i), spec(3), n(i) { }
486 InEdgeIt(const stGraphWrapper<Graph>& _G, const Node& _n) {
489 if (_G.graph->inTClass(_n)) { //T, van normalis beel
490 e=typename Graph::InEdgeIt(*(_G.graph),
491 typename Graph::Node(_n));
494 if (!_G.graph->valid(e)) spec=3;
495 } else { //S, specko beel van
509 _G.graph->first(n, T_CLASS); //vmi->t;
510 if (!_G.graph->valid(n)) spec=3; //Ha T ures
514 operator Edge() const { return Edge(e, spec, n); }
518 friend class GraphWrapper<Graph>;
519 friend class stGraphWrapper<Graph>;
520 typename Graph::EdgeIt e;
522 typename Graph::ClassNodeIt n;
525 EdgeIt(const typename Graph::EdgeIt& _e, int _spec,
526 const typename Graph::ClassNodeIt& _n) :
527 e(_e), spec(_spec), n(_n) { }
528 EdgeIt(const Invalid& i) : e(i), spec(3), n(i) { }
529 EdgeIt(const stGraphWrapper<Graph>& _G) :
530 e(*(_G.graph)), spec(0), n(INVALID) {
531 if (!_G.graph->valid(e)) {
533 _G.graph->first(n, S_CLASS);
534 if (!_G.graph->valid(n)) { //Ha S ures
536 _G.graph->first(n, T_CLASS);
537 if (!_G.graph->valid(n)) { //Ha T ures
543 operator Edge() const { return Edge(e, spec, n); }
546 NodeIt& first(NodeIt& i) const {
547 i=NodeIt(*this); return i;
549 OutEdgeIt& first(OutEdgeIt& i, const Node& p) const {
550 i=OutEdgeIt(*this, p); return i;
552 InEdgeIt& first(InEdgeIt& i, const Node& p) const {
553 i=InEdgeIt(*this, p); return i;
555 EdgeIt& first(EdgeIt& i) const {
556 i=EdgeIt(*this); return i;
559 NodeIt& next(NodeIt& i) const {
562 this->graph->next(i.n);
563 if (!this->graph->valid(i.n)) {
576 OutEdgeIt& next(OutEdgeIt& i) const {
577 typename Graph::Node v;
579 case 0: //normal edge
580 v=this->graph->aNode(i.e);
581 this->graph->next(i.e);
582 if (!this->graph->valid(i.e)) { //Az igazi elek vegere ertunk
583 if (this->graph->inSClass(v)) { //S, nincs kiel
586 } else { //T, van kiel
593 this->graph->next(i.n);
594 if (!this->graph->valid(i.n)) i.spec=3;
603 InEdgeIt& next(InEdgeIt& i) const {
604 typename Graph::Node v;
606 case 0: //normal edge
607 v=this->graph->aNode(i.e);
608 this->graph->next(i.e);
609 if (!this->graph->valid(i.e)) { //Az igazi elek vegere ertunk
610 if (this->graph->inTClass(v)) { //S, nincs beel
613 } else { //S, van beel
624 this->graph->next(i.n);
625 if (!this->graph->valid(i.n)) i.spec=3;
631 EdgeIt& next(EdgeIt& i) const {
634 this->graph->next(i.e);
635 if (!this->graph->valid(i.e)) {
637 this->graph->first(i.n, S_CLASS);
638 if (!this->graph->valid(i.n)) {
640 this->graph->first(i.n, T_CLASS);
641 if (!this->graph->valid(i.n)) i.spec=3;
646 this->graph->next(i.n);
647 if (!this->graph->valid(i.n)) {
649 this->graph->first(i.n, T_CLASS);
650 if (!this->graph->valid(i.n)) i.spec=3;
654 this->graph->next(i.n);
655 if (!this->graph->valid(i.n)) i.spec=3;
661 Node tail(const Edge& e) const {
664 return Node(this->graph->tail(e));
675 Node head(const Edge& e) const {
678 return Node(this->graph->head(e));
690 bool valid(const Node& n) const { return (n.spec<3); }
691 bool valid(const Edge& e) const { return (e.spec<3); }
693 int nodeNum() const { return this->graph->nodeNum()+2; }
694 int edgeNum() const {
695 return this->graph->edgeNum()+this->graph->nodeNum();
698 Node aNode(const OutEdgeIt& e) const { return tail(e); }
699 Node aNode(const InEdgeIt& e) const { return head(e); }
700 Node bNode(const OutEdgeIt& e) const { return head(e); }
701 Node bNode(const InEdgeIt& e) const { return tail(e); }
703 void addNode() const { }
704 void addEdge() const { }
706 // Node addNode() const { return Node(this->graph->addNode()); }
707 // Edge addEdge(const Node& tail, const Node& head) const {
708 // return Edge(this->graph->addEdge(tail, head)); }
710 // void erase(const Node& i) const { this->graph->erase(i); }
711 // void erase(const Edge& i) const { this->graph->erase(i); }
713 // void clear() const { this->graph->clear(); }
715 template<typename T> class NodeMap : public GraphWrapper<Graph>::template NodeMap<T> {
716 typedef typename GraphWrapper<Graph>::template NodeMap<T> Parent;
720 NodeMap(const stGraphWrapper<Graph>& _G) : Parent(_G),
723 NodeMap(const stGraphWrapper<Graph>& _G, T a) : Parent(_G, a),
726 T operator[](const Node& n) const {
729 return Parent::operator[](n);
737 void set(const Node& n, T t) {
740 GraphWrapper<Graph>::template NodeMap<T>::set(n, t);
753 /// This class is to wrap a node-map of \c Graph and two variables
754 /// storing values for \c S_NODE and \c T_NODE to a node-map of
755 /// stGraphWrapper<Graph>.
756 template<typename NM> class NodeMapWrapper {
758 typedef Node KeyType;
759 typedef typename NM::ValueType ValueType;
762 ValueType* s_value, t_value;
764 NodeMapWrapper(NM& _nm, ValueType& _s_value, ValueType& _t_value) :
765 nm(&_nm), s_value(&_s_value), t_value(&_t_value) { }
766 ValueType operator[](const Node& n) const {
767 switch (n.getSpec()) {
777 void set(const Node& n, ValueType t) {
778 switch (n.getSpec()) {
794 class EdgeMap : public GraphWrapper<Graph>::template EdgeMap<T> {
795 typedef typename GraphWrapper<Graph>::template EdgeMap<T> Parent;
797 typename GraphWrapper<Graph>::template NodeMap<T> node_value;
799 EdgeMap(const stGraphWrapper<Graph>& _G) : Parent(_G),
801 EdgeMap(const stGraphWrapper<Graph>& _G, T a) : Parent(_G, a),
802 node_value(_G, a) { }
803 T operator[](const Edge& e) const {
806 return Parent::operator[](e);
808 return node_value[e.n];
811 return node_value[e.n];
814 void set(const Edge& e, T t) {
820 node_value.set(e.n, t);
824 node_value.set(e.n, t);
830 /// This class is to wrap an edge-map and a node-map of \c Graph
831 /// to an edge-map of stGraphWrapper<Graph>.
832 template<typename EM, typename NM>
833 class EdgeMapWrapper {
835 typedef Edge KeyType;
836 typedef typename EM::ValueType ValueType;
841 EdgeMapWrapper(EM& _em, NM& _nm) : em(&_em), nm(&_nm) { }
842 ValueType operator[](const Edge& e) const {
843 switch (e.getSpec()) {
847 return (*nm)[e.getNode()];
850 return (*nm)[e.getNode()];
853 void set(const Edge& e, ValueType t) {
854 switch (e.getSpec()) {
859 nm->set(e.getNode(), t);
863 nm->set(e.getNode(), t);
870 // template<typename G>
872 operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Node& i) {
873 os << "(node: " << typename Graph::Node(i) << " spec: " << i.spec <<")";
876 // template<typename G>
878 operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Edge& i) {
879 os << "(edge: " << typename Graph::Edge(i) << " spec: " << i.spec <<
880 " node: " << i.n << ")";
891 #endif //HUGO_BIPARTITE_GRAPH_WRAPPER_H