2 * src/lemon/merge_node_graph_wrapper.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Combinatorial Optimization Research Group, EGRES).
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.
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
17 #ifndef LEMON_MERGE_NODE_GRAPH_WRAPPER_H
18 #define LEMON_MERGE_NODE_GRAPH_WRAPPER_H
20 #include <lemon/invalid.h>
21 #include <lemon/maps.h>
22 #include <lemon/map_defines.h>
23 #include <lemon/graph_wrapper.h>
29 #include <boost/type_traits.hpp>
30 #include <boost/utility/enable_if.hpp>
34 template <class _Graph1>
35 class P1 : public GraphWrapperBase<_Graph1> {
38 template <class _Graph2>
39 class P2 : public GraphWrapperBase<_Graph2> {
43 /*! A graph wrapper base class
44 for merging the node-set of two node-disjoint graphs
45 into the node-set of one graph.
46 Generic implementation for unrelated _Graph1::Node and _Graph2::Node.
48 template <typename _Graph1, typename _Graph2, typename Enable=void>
49 class MergeNodeGraphWrapperBase :
50 public P1<_Graph1>, public P2<_Graph2> {
52 static void printNode() { std::cout << "node: generic" << std::endl; }
53 typedef _Graph1 Graph1;
54 typedef _Graph2 Graph2;
55 typedef P1<_Graph1> Parent1;
56 typedef P2<_Graph2> Parent2;
57 typedef typename Parent1::Node Graph1Node;
58 typedef typename Parent2::Node Graph2Node;
60 MergeNodeGraphWrapperBase() { }
62 template <typename _Value> class NodeMap;
64 class Node : public Graph1Node, public Graph2Node {
65 friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
66 template <typename _Value> friend class NodeMap;
68 bool backward; //true, iff backward
71 /// \todo =false is needed, or causes problems?
72 /// If \c _backward is false, then we get an edge corresponding to the
73 /// original one, otherwise its oppositely directed pair is obtained.
74 Node(const Graph1Node& n1,
75 const Graph2Node& n2, bool _backward) :
76 Graph1Node(n1), Graph2Node(n2), backward(_backward) { }
77 Node(Invalid i) : Graph1Node(i), Graph2Node(i), backward(true) { }
78 bool operator==(const Node& v) const {
81 static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v));
83 return (!v.backward &&
84 static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v));
86 bool operator!=(const Node& v) const {
94 void first(Node& i) const {
95 Parent1::graph->first(*static_cast<Graph1Node*>(&i));
97 if (*static_cast<Graph1Node*>(&i)==INVALID) {
98 Parent2::graph->first(*static_cast<Graph2Node*>(&i));
102 void next(Node& i) const {
104 Parent1::graph->next(*static_cast<Graph1Node*>(&i));
105 if (*static_cast<Graph1Node*>(&i)==INVALID) {
106 Parent2::graph->first(*static_cast<Graph2Node*>(&i));
110 Parent2::graph->next(*static_cast<Graph2Node*>(&i));
114 int id(const Node& n) const {
116 return this->Parent1::graph->id(n);
118 return this->Parent2::graph->id(n);
121 template <typename _Value>
124 typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
125 typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
126 ParentMap1 forward_map;
127 ParentMap2 backward_map;
129 typedef _Value Value;
131 NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) :
132 forward_map(*(gw.Parent1::graph)),
133 backward_map(*(gw.Parent2::graph)) { }
134 NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw,
135 const _Value& value) :
136 forward_map(*(gw.Parent1::graph), value),
137 backward_map(*(gw.Parent2::graph), value) { }
138 _Value operator[](const Node& n) const {
140 return forward_map[n];
142 return backward_map[n];
144 void set(const Node& n, const _Value& value) {
146 forward_map.set(n, value);
148 backward_map.set(n, value);
150 // using ParentMap1::operator[];
151 // using ParentMap2::operator[];
157 /*! A graph wrapper base class
158 for merging the node-set of two node-disjoint graphs
159 into the node-set of one graph.
160 Specialization for the case when _Graph1::Node are the same _Graph2::Node.
162 template <typename _Graph1, typename _Graph2>
163 class MergeNodeGraphWrapperBase<
164 _Graph1, _Graph2, typename boost::enable_if<
165 boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> :
166 public P1<_Graph1>, public P2<_Graph2> {
168 static void printNode() { std::cout << "node: same" << std::endl; }
169 typedef _Graph1 Graph1;
170 typedef _Graph2 Graph2;
171 typedef P1<_Graph1> Parent1;
172 typedef P2<_Graph2> Parent2;
173 typedef typename Parent1::Node Graph1Node;
174 typedef typename Parent2::Node Graph2Node;
176 MergeNodeGraphWrapperBase() { }
178 template <typename _Value> class NodeMap;
180 class Node : public Graph1Node {
181 friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
182 template <typename _Value> friend class NodeMap;
184 bool backward; //true, iff backward
187 /// \todo =false is needed, or causes problems?
188 /// If \c _backward is false, then we get an edge corresponding to the
189 /// original one, otherwise its oppositely directed pair is obtained.
190 Node(const Graph1Node& n1,
191 const Graph2Node& n2, bool _backward) :
192 Graph1Node(!backward ? n1 : n2), backward(_backward) { }
193 Node(Invalid i) : Graph1Node(i), backward(true) { }
194 bool operator==(const Node& v) const {
195 return (backward==v.backward &&
196 static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v));
198 bool operator!=(const Node& v) const {
206 void first(Node& i) const {
207 Parent1::graph->first(*static_cast<Graph1Node*>(&i));
209 if (*static_cast<Graph1Node*>(&i)==INVALID) {
210 Parent2::graph->first(*static_cast<Graph1Node*>(&i));
214 void next(Node& i) const {
216 Parent1::graph->next(*static_cast<Graph1Node*>(&i));
217 if (*static_cast<Graph1Node*>(&i)==INVALID) {
218 Parent2::graph->first(*static_cast<Graph1Node*>(&i));
222 Parent2::graph->next(*static_cast<Graph1Node*>(&i));
226 int id(const Node& n) const {
228 return this->Parent1::graph->id(n);
230 return this->Parent2::graph->id(n);
233 template <typename _Value>
236 typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
237 typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
238 ParentMap1 forward_map;
239 ParentMap2 backward_map;
241 typedef _Value Value;
243 NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) :
244 forward_map(*(gw.Parent1::graph)),
245 backward_map(*(gw.Parent2::graph)) { }
246 NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw,
247 const _Value& value) :
248 forward_map(*(gw.Parent1::graph), value),
249 backward_map(*(gw.Parent2::graph), value) { }
250 _Value operator[](const Node& n) const {
252 return forward_map[n];
254 return backward_map[n];
256 void set(const Node& n, const _Value& value) {
258 forward_map.set(n, value);
260 backward_map.set(n, value);
262 // using ParentMap1::operator[];
263 // using ParentMap2::operator[];
269 /*! A graph wrapper base class
270 for merging the node-set of two node-disjoint graphs
271 into the node-set of one graph.
272 Specialization for the case when
273 _Graph1::Node are base and derived _Graph2::Node.
276 template <typename _Graph1, typename _Graph2>
277 class MergeNodeGraphWrapperBase<
278 _Graph1, _Graph2, typename boost::enable_if<
279 boost::is_base_and_derived<typename _Graph1::Node, typename _Graph2::Node> >::type> :
280 public P1<_Graph1>, public P2<_Graph2> {
282 static void printNode() { std::cout << "node: 2nd is derived" << std::endl; }
283 typedef _Graph1 Graph1;
284 typedef _Graph2 Graph2;
285 typedef P1<_Graph1> Parent1;
286 typedef P2<_Graph2> Parent2;
287 typedef typename Parent1::Node Graph1Node;
288 typedef typename Parent2::Node Graph2Node;
290 MergeNodeGraphWrapperBase() { }
299 template <typename _Graph1, typename _Graph2>
300 class MergeNodeGraphWrapperBase<
301 _Graph1, _Graph2, typename boost::enable_if<
302 boost::is_base_and_derived<typename _Graph2::Node, typename _Graph1::Node> >::type> :
303 public P1<_Graph1>, public P2<_Graph2> {
305 static void printNode() { std::cout << "node: 1st is derived" << std::endl; }
306 typedef _Graph1 Graph1;
307 typedef _Graph2 Graph2;
308 typedef P1<_Graph1> Parent1;
309 typedef P2<_Graph2> Parent2;
310 typedef typename Parent1::Node Graph1Node;
311 typedef typename Parent2::Node Graph2Node;
313 MergeNodeGraphWrapperBase() { }
322 /*! A graph wrapper class
323 fors merging the node-set of two node-disjoint graphs
324 into one node-set. It does not satisfy
325 StaticGraph concept as it has no edge-set which
326 works together with the node-set.
328 template <typename _Graph1, typename _Graph2>
329 class MergeNodeGraphWrapper : public
330 IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2> > {
332 typedef _Graph1 Graph1;
333 typedef _Graph2 Graph2;
334 typedef IterableGraphExtender<
335 MergeNodeGraphWrapperBase<_Graph1, _Graph2> > Parent;
337 MergeNodeGraphWrapper() { }
339 MergeNodeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) {
340 Parent::Parent1::setGraph(_graph1);
341 Parent::Parent2::setGraph(_graph2);
346 /*! A grah wrapper base class
347 for merging the node-sets and edge-sets of
348 two node-disjoint graphs
350 Generic implementation for unrelated _Graph1::Edge and _Graph2::Edge.
352 template <typename _Graph1, typename _Graph2, typename Enable=void>
353 class MergeEdgeGraphWrapperBase :
354 public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
356 static void printEdge() { std::cout << "edge: generic" << std::endl; }
357 typedef _Graph1 Graph1;
358 typedef _Graph2 Graph2;
359 typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
360 typedef typename Parent::Parent1 Parent1;
361 typedef typename Parent::Parent2 Parent2;
362 // typedef P1<_Graph1> Parent1;
363 // typedef P2<_Graph2> Parent2;
364 typedef typename Parent1::Edge Graph1Edge;
365 typedef typename Parent2::Edge Graph2Edge;
367 MergeEdgeGraphWrapperBase() { }
369 template <typename _Value> class EdgeMap;
371 typedef typename Parent::Node Node;
373 class Edge : public Graph1Edge, public Graph2Edge {
374 friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
375 template <typename _Value> friend class EdgeMap;
377 bool backward; //true, iff backward
380 /// \todo =false is needed, or causes problems?
381 /// If \c _backward is false, then we get an edge corresponding to the
382 /// original one, otherwise its oppositely directed pair is obtained.
383 Edge(const Graph1Edge& n1,
384 const Graph2Edge& n2, bool _backward) :
385 Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { }
386 Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { }
387 bool operator==(const Edge& v) const {
389 return (v.backward &&
390 static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v));
392 return (!v.backward &&
393 static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
395 bool operator!=(const Edge& v) const {
401 void first(Edge& i) const {
402 Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
404 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
405 Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
409 void firstIn(Edge& i, const Node& n) const {
410 Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
412 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
413 Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
417 void firstOut(Edge& i, const Node& n) const {
418 Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
420 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
421 Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
427 void next(Edge& i) const {
429 Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
430 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
431 Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
435 Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
438 void nextIn(Edge& i) const {
440 Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
441 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
442 Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
446 Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
449 void nextOut(Edge& i) const {
451 Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
452 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
453 Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
457 Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
461 Node source(const Edge& i) const {
464 Node(Parent1::graph->source(i), INVALID, false);
467 Node(INVALID, Parent2::graph->source(i), true);
471 Node target(const Edge& i) const {
474 Node(Parent1::graph->target(i), INVALID, false);
477 Node(INVALID, Parent2::graph->target(i), true);
482 int id(const Edge& n) const {
484 return this->Parent1::graph->id(n);
486 return this->Parent2::graph->id(n);
489 template <typename _Value>
492 typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
493 typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
494 ParentMap1 forward_map;
495 ParentMap2 backward_map;
497 typedef _Value Value;
499 EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) :
500 forward_map(*(gw.Parent1::graph)),
501 backward_map(*(gw.Parent2::graph)) { }
502 EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw,
503 const _Value& value) :
504 forward_map(*(gw.Parent1::graph), value),
505 backward_map(*(gw.Parent2::graph), value) { }
506 _Value operator[](const Edge& n) const {
508 return forward_map[n];
510 return backward_map[n];
512 void set(const Edge& n, const _Value& value) {
514 forward_map.set(n, value);
516 backward_map.set(n, value);
518 // using ParentMap1::operator[];
519 // using ParentMap2::operator[];
525 /*! A graph wrapper base class
526 for merging the node-sets and edge-sets of
527 two node-disjoint graphs
529 Specialization for the case when _Graph1::Edge and _Graph2::Edge
532 template <typename _Graph1, typename _Graph2>
533 class MergeEdgeGraphWrapperBase<
534 _Graph1, _Graph2, typename boost::enable_if<
535 boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> :
536 public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
538 static void printEdge() { std::cout << "edge: same" << std::endl; }
539 typedef _Graph1 Graph1;
540 typedef _Graph2 Graph2;
541 typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
542 typedef typename Parent::Parent1 Parent1;
543 typedef typename Parent::Parent2 Parent2;
544 // typedef P1<_Graph1> Parent1;
545 // typedef P2<_Graph2> Parent2;
546 typedef typename Parent1::Edge Graph1Edge;
547 typedef typename Parent2::Edge Graph2Edge;
549 MergeEdgeGraphWrapperBase() { }
551 template <typename _Value> class EdgeMap;
553 typedef typename Parent::Node Node;
555 class Edge : public Graph1Edge {
556 friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
557 template <typename _Value> friend class EdgeMap;
559 bool backward; //true, iff backward
562 /// \todo =false is needed, or causes problems?
563 /// If \c _backward is false, then we get an edge corresponding to the
564 /// original one, otherwise its oppositely directed pair is obtained.
565 Edge(const Graph1Edge& n1,
566 const Graph2Edge& n2, bool _backward) :
567 Graph1Edge(!backward ? n1 : n2), backward(_backward) { }
568 Edge(Invalid i) : Graph1Edge(i), backward(true) { }
569 bool operator==(const Edge& v) const {
570 return (backward==v.backward &&
571 static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
573 bool operator!=(const Edge& v) const {
579 void first(Edge& i) const {
580 Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
582 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
583 Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
587 void firstIn(Edge& i, const Node& n) const {
588 Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
590 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
591 Parent2::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
595 void firstOut(Edge& i, const Node& n) const {
596 Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
598 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
599 Parent2::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
605 void next(Edge& i) const {
607 Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
608 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
609 Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
613 Parent2::graph->next(*static_cast<Graph1Edge*>(&i));
616 void nextIn(Edge& i) const {
618 Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
619 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
620 Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
624 Parent2::graph->nextIn(*static_cast<Graph1Edge*>(&i));
627 void nextOut(Edge& i) const {
629 Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
630 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
631 Parent2::graph->first(*static_cast<Graph1Edge*>(&i));
635 Parent2::graph->nextOut(*static_cast<Graph1Edge*>(&i));
639 Node source(const Edge& i) const {
642 Node(Parent1::graph->source(i), INVALID, false);
645 Node(INVALID, Parent2::graph->source(i), true);
649 Node target(const Edge& i) const {
652 Node(Parent1::graph->target(i), INVALID, false);
655 Node(INVALID, Parent2::graph->target(i), true);
660 int id(const Edge& n) const {
662 return this->Parent1::graph->id(n);
664 return this->Parent2::graph->id(n);
667 template <typename _Value>
670 typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
671 typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
672 ParentMap1 forward_map;
673 ParentMap2 backward_map;
675 typedef _Value Value;
677 EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) :
678 forward_map(*(gw.Parent1::graph)),
679 backward_map(*(gw.Parent2::graph)) { }
680 EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw,
681 const _Value& value) :
682 forward_map(*(gw.Parent1::graph), value),
683 backward_map(*(gw.Parent2::graph), value) { }
684 _Value operator[](const Edge& n) const {
686 return forward_map[n];
688 return backward_map[n];
690 void set(const Edge& n, const _Value& value) {
692 forward_map.set(n, value);
694 backward_map.set(n, value);
696 // using ParentMap1::operator[];
697 // using ParentMap2::operator[];
703 /*! A graph wrapper class
704 for merging the node-sets and edge-sets of
705 two node-disjoint graphs
708 template <typename _Graph1, typename _Graph2>
709 class MergeEdgeGraphWrapper : public
710 IterableGraphExtender<MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > {
712 typedef _Graph1 Graph1;
713 typedef _Graph2 Graph2;
714 typedef IterableGraphExtender<
715 MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > Parent;
717 MergeEdgeGraphWrapper() { }
719 MergeEdgeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) {
720 Parent::Parent1::setGraph(_graph1);
721 Parent::Parent2::setGraph(_graph2);
726 /*! A graph wrapper base class for the following functionality.
727 If a bijection is given between the node-sets of two graphs,
728 then the second one can be considered as a new edge-set
729 over th first node-set.
731 template <typename _Graph, typename _EdgeSetGraph>
732 class NewEdgeSetGraphWrapperBase : public GraphWrapperBase<_Graph> {
734 typedef GraphWrapperBase<_Graph> Parent;
735 typedef _Graph Graph;
736 typedef _EdgeSetGraph EdgeSetGraph;
737 typedef typename _Graph::Node Node;
738 typedef typename _EdgeSetGraph::Node ENode;
740 EdgeSetGraph* edge_set_graph;
741 typename Graph::NodeMap<ENode>* e_node;
742 typename EdgeSetGraph::NodeMap<Node>* n_node;
743 void setEdgeSetGraph(EdgeSetGraph& _edge_set_graph) {
744 edge_set_graph=&_edge_set_graph;
746 /// For each node of \c Graph, this gives a node of \c EdgeSetGraph .
747 void setNodeMap(typename EdgeSetGraph::NodeMap<Node>& _n_node) {
750 /// For each node of \c EdgeSetGraph, this gives a node of \c Graph .
751 void setENodeMap(typename Graph::NodeMap<ENode>& _e_node) {
755 class Edge : public EdgeSetGraph::Edge {
756 typedef typename EdgeSetGraph::Edge Parent;
759 Edge(const Parent& e) : Parent(e) { }
760 Edge(Invalid i) : Parent(i) { }
764 void first(Edge &e) const {
765 edge_set_graph->first(e);
767 void firstOut(Edge& e, const Node& n) const {
768 // cout << e_node << endl;
769 // cout << n_node << endl;
770 edge_set_graph->firstOut(e, (*e_node)[n]);
772 void firstIn(Edge& e, const Node& n) const {
773 edge_set_graph->firstIn(e, (*e_node)[n]);
777 void next(Edge &e) const {
778 edge_set_graph->next(e);
780 void nextOut(Edge& e) const {
781 edge_set_graph->nextOut(e);
783 void nextIn(Edge& e) const {
784 edge_set_graph->nextIn(e);
787 Node source(const Edge& e) const {
788 return (*n_node)[edge_set_graph->source(e)];
790 Node target(const Edge& e) const {
791 return (*n_node)[edge_set_graph->target(e)];
794 int edgeNum() const { return edge_set_graph->edgeNum(); }
796 Edge addEdge(const Node& u, const Node& v) {
797 return edge_set_graph->addEdge((*e_node)[u], (*e_node)[v]);
801 void erase(const Edge& i) const { edge_set_graph->erase(i); }
803 void clear() const { Parent::clear(); edge_set_graph->clear(); }
805 bool forward(const Edge& e) const { return edge_set_graph->forward(e); }
806 bool backward(const Edge& e) const { return edge_set_graph->backward(e); }
808 int id(const Node& e) const { return Parent::id(e); }
809 int id(const Edge& e) const { return edge_set_graph->id(e); }
811 Edge opposite(const Edge& e) const { return edge_set_graph->opposite(e); }
813 template <typename _Value>
814 class EdgeMap : public EdgeSetGraph::EdgeMap<_Value> {
816 typedef typename EdgeSetGraph::EdgeMap<_Value> Parent;
817 typedef _Value Value;
819 EdgeMap(const NewEdgeSetGraphWrapperBase& gw) :
820 Parent(*(gw.edge_set_graph)) { }
821 EdgeMap(const NewEdgeSetGraphWrapperBase& gw, const _Value& _value) :
822 Parent(*(gw.edge_set_graph), _value) { }
828 /*! A graph wrapper class for the following functionality.
829 If a bijection is given between the node-sets of two graphs,
830 then the second one can be considered as a new edge-set
831 over th first node-set.
833 template <typename _Graph, typename _EdgeSetGraph>
834 class NewEdgeSetGraphWrapper :
835 public IterableGraphExtender<
836 NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > {
838 typedef _Graph Graph;
839 typedef _EdgeSetGraph EdgeSetGraph;
840 typedef IterableGraphExtender<
841 NewEdgeSetGraphWrapper<_Graph, _EdgeSetGraph> > Parent;
843 NewEdgeSetGraphWrapper() { }
845 NewEdgeSetGraphWrapper(_Graph& _graph,
846 _EdgeSetGraph& _edge_set_graph,
848 NodeMap<typename _EdgeSetGraph::Node>& _e_node,
849 typename _EdgeSetGraph::
850 NodeMap<typename _Graph::Node>& _n_node) {
852 setEdgeSetGraph(_edge_set_graph);
854 setENodeMap(_e_node);
859 /*! A graph wrapper base class
860 for merging graphs of type _Graph1 and _Graph2
861 which are given on the same node-set
862 (specially on the node-set of Graph1)
864 In an other point of view, _Graph1 is extended with
865 the edge-set of _Graph2.
867 template <typename _Graph1, typename _Graph2, typename Enable=void>
868 class AugmentingGraphWrapperBase :
871 void printAugment() const { std::cout << "generic" << std::endl; }
872 typedef _Graph1 Graph1;
873 typedef _Graph2 Graph2;
874 typedef P1<_Graph1> Parent1;
875 typedef P2<_Graph2> Parent2;
876 typedef typename Parent1::Edge Graph1Edge;
877 typedef typename Parent2::Edge Graph2Edge;
879 AugmentingGraphWrapperBase() { }
881 void setGraph2(_Graph2& _graph2) { graph2=&_graph2; }
884 template <typename _Value> class EdgeMap;
886 typedef typename Parent1::Node Node;
888 class Edge : public Graph1Edge, public Graph2Edge {
889 friend class AugmentingGraphWrapperBase<_Graph1, _Graph2>;
890 template <typename _Value> friend class EdgeMap;
892 bool backward; //true, iff backward
895 /// \todo =false is needed, or causes problems?
896 /// If \c _backward is false, then we get an edge corresponding to the
897 /// original one, otherwise its oppositely directed pair is obtained.
898 Edge(const Graph1Edge& n1,
899 const Graph2Edge& n2, bool _backward) :
900 Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { }
901 Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { }
902 bool operator==(const Edge& v) const {
904 return (v.backward &&
905 static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v));
907 return (!v.backward &&
908 static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v));
910 bool operator!=(const Edge& v) const {
915 using Parent1::first;
916 void first(Edge& i) const {
917 Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
919 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
920 graph2->first(*static_cast<Graph2Edge*>(&i));
924 void firstIn(Edge& i, const Node& n) const {
925 Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
927 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
928 graph2->firstIn(*static_cast<Graph2Edge*>(&i), n);
932 void firstOut(Edge& i, const Node& n) const {
933 Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
935 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
936 graph2->firstOut(*static_cast<Graph2Edge*>(&i), n);
942 void next(Edge& i) const {
944 Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
945 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
946 graph2->first(*static_cast<Graph2Edge*>(&i));
950 graph2->next(*static_cast<Graph2Edge*>(&i));
953 void nextIn(Edge& i) const {
955 Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
956 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
957 graph2->first(*static_cast<Graph2Edge*>(&i));
961 graph2->nextIn(*static_cast<Graph2Edge*>(&i));
964 void nextOut(Edge& i) const {
966 Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
967 if (*static_cast<Graph1Edge*>(&i)==INVALID) {
968 graph2->first(*static_cast<Graph2Edge*>(&i));
972 graph2->nextOut(*static_cast<Graph2Edge*>(&i));
976 Node source(const Edge& i) const {
978 return Parent1::graph->source(i);
980 return graph2->source(i);
984 Node target(const Edge& i) const {
986 return Parent1::graph->target(i);
988 return graph2->target(i);
992 int id(const Node& n) const {
993 return Parent1::id(n);
995 int id(const Edge& n) const {
997 return this->Parent1::graph->id(n);
999 return this->graph2->id(n);
1002 template <typename _Value>
1005 typedef typename _Graph1::template EdgeMap<_Value> ParentMap1;
1006 typedef typename _Graph2::template EdgeMap<_Value> ParentMap2;
1007 ParentMap1 forward_map;
1008 ParentMap2 backward_map;
1010 typedef _Value Value;
1012 EdgeMap(const AugmentingGraphWrapperBase<_Graph1, _Graph2>& gw) :
1013 forward_map(*(gw.Parent1::graph)),
1014 backward_map(*(gw.graph2)) { }
1015 EdgeMap(const AugmentingGraphWrapperBase<_Graph1, _Graph2>& gw,
1016 const _Value& value) :
1017 forward_map(*(gw.Parent1::graph), value),
1018 backward_map(*(gw.graph2), value) { }
1019 _Value operator[](const Edge& n) const {
1021 return forward_map[n];
1023 return backward_map[n];
1025 void set(const Edge& n, const _Value& value) {
1027 forward_map.set(n, value);
1029 backward_map.set(n, value);
1031 // using ParentMap1::operator[];
1032 // using ParentMap2::operator[];
1038 /*! A graph wrapper class
1039 for merging two graphs (of type _Graph1 and _Graph2)
1040 with the same node-set
1041 (specially on the node-set of Graph1)
1043 In an other point of view, _Graph1 is extended with
1044 the edge-set of _Graph2.
1046 template <typename _Graph1, typename _Graph2>
1047 class AugmentingGraphWrapper : public
1048 IterableGraphExtender<AugmentingGraphWrapperBase<_Graph1, _Graph2> > {
1051 IterableGraphExtender<AugmentingGraphWrapperBase<_Graph1, _Graph2> >
1053 typedef _Graph1 Graph1;
1054 typedef _Graph2 Graph2;
1056 AugmentingGraphWrapper() { }
1058 AugmentingGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) {
1066 #endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H