2 * lemon/graph_adaptor.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2006 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, 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_GRAPH_ADAPTOR_H
18 #define LEMON_GRAPH_ADAPTOR_H
20 ///\ingroup graph_adaptors
22 ///\brief Several graph adaptors.
24 ///This file contains several useful graph adaptor functions.
26 ///\author Marton Makai
28 #include <lemon/invalid.h>
29 #include <lemon/maps.h>
30 #include <lemon/bits/erasable_graph_extender.h>
31 #include <lemon/bits/clearable_graph_extender.h>
32 #include <lemon/bits/extendable_graph_extender.h>
33 #include <lemon/bits/iterable_graph_extender.h>
34 #include <lemon/bits/alteration_notifier.h>
35 #include <lemon/bits/default_map.h>
36 #include <lemon/bits/graph_extender.h>
44 \addtogroup graph_adaptors
49 Base type for the Graph Adaptors
51 \warning Graph adaptors are in even more experimental state than the other
52 parts of the lib. Use them at you own risk.
54 This is the base type for most of LEMON graph adaptors.
55 This class implements a trivial graph adaptor i.e. it only wraps the
56 functions and types of the graph. The purpose of this class is to
57 make easier implementing graph adaptors. E.g. if an adaptor is
58 considered which differs from the wrapped graph only in some of its
59 functions or types, then it can be derived from GraphAdaptor, and only the
60 differences should be implemented.
64 template<typename _Graph>
65 class GraphAdaptorBase {
68 typedef Graph ParentGraph;
72 GraphAdaptorBase() : graph(0) { }
73 void setGraph(Graph& _graph) { graph=&_graph; }
76 GraphAdaptorBase(Graph& _graph) : graph(&_graph) { }
78 typedef typename Graph::Node Node;
79 typedef typename Graph::Edge Edge;
81 void first(Node& i) const { graph->first(i); }
82 void first(Edge& i) const { graph->first(i); }
83 void firstIn(Edge& i, const Node& n) const { graph->firstIn(i, n); }
84 void firstOut(Edge& i, const Node& n ) const { graph->firstOut(i, n); }
86 void next(Node& i) const { graph->next(i); }
87 void next(Edge& i) const { graph->next(i); }
88 void nextIn(Edge& i) const { graph->nextIn(i); }
89 void nextOut(Edge& i) const { graph->nextOut(i); }
91 Node source(const Edge& e) const { return graph->source(e); }
92 Node target(const Edge& e) const { return graph->target(e); }
94 typedef NodeNumTagIndicator<Graph> NodeNumTag;
95 int nodeNum() const { return graph->nodeNum(); }
97 typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
98 int edgeNum() const { return graph->edgeNum(); }
100 typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
101 Edge findEdge(const Node& source, const Node& target,
102 const Edge& prev = INVALID) {
103 return graph->findEdge(source, target, prev);
106 Node addNode() const {
107 return Node(graph->addNode());
110 Edge addEdge(const Node& source, const Node& target) const {
111 return Edge(graph->addEdge(source, target));
114 void erase(const Node& i) const { graph->erase(i); }
115 void erase(const Edge& i) const { graph->erase(i); }
117 void clear() const { graph->clear(); }
119 int id(const Node& v) const { return graph->id(v); }
120 int id(const Edge& e) const { return graph->id(e); }
122 Edge oppositeNode(const Edge& e) const {
123 return Edge(graph->opposite(e));
126 template <typename _Value>
127 class NodeMap : public _Graph::template NodeMap<_Value> {
129 typedef typename _Graph::template NodeMap<_Value> Parent;
130 explicit NodeMap(const GraphAdaptorBase<_Graph>& gw)
131 : Parent(*gw.graph) { }
132 NodeMap(const GraphAdaptorBase<_Graph>& gw, const _Value& value)
133 : Parent(*gw.graph, value) { }
136 template <typename _Value>
137 class EdgeMap : public _Graph::template EdgeMap<_Value> {
139 typedef typename _Graph::template EdgeMap<_Value> Parent;
140 explicit EdgeMap(const GraphAdaptorBase<_Graph>& gw)
141 : Parent(*gw.graph) { }
142 EdgeMap(const GraphAdaptorBase<_Graph>& gw, const _Value& value)
143 : Parent(*gw.graph, value) { }
148 template <typename _Graph>
150 public IterableGraphExtender<GraphAdaptorBase<_Graph> > {
152 typedef _Graph Graph;
153 typedef IterableGraphExtender<GraphAdaptorBase<_Graph> > Parent;
155 GraphAdaptor() : Parent() { }
158 explicit GraphAdaptor(Graph& _graph) { setGraph(_graph); }
161 template <typename _Graph>
162 class RevGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
164 typedef _Graph Graph;
165 typedef GraphAdaptorBase<_Graph> Parent;
167 RevGraphAdaptorBase() : Parent() { }
169 typedef typename Parent::Node Node;
170 typedef typename Parent::Edge Edge;
172 void firstIn(Edge& i, const Node& n) const { Parent::firstOut(i, n); }
173 void firstOut(Edge& i, const Node& n ) const { Parent::firstIn(i, n); }
175 void nextIn(Edge& i) const { Parent::nextOut(i); }
176 void nextOut(Edge& i) const { Parent::nextIn(i); }
178 Node source(const Edge& e) const { return Parent::target(e); }
179 Node target(const Edge& e) const { return Parent::source(e); }
183 /// A graph adaptor which reverses the orientation of the edges.
185 ///\warning Graph adaptors are in even more experimental state than the other
186 ///parts of the lib. Use them at you own risk.
188 /// Let \f$G=(V, A)\f$ be a directed graph and
189 /// suppose that a graph instange \c g of type
190 /// \c ListGraph implements \f$G\f$.
194 /// For each directed edge
195 /// \f$e\in A\f$, let \f$\bar e\f$ denote the edge obtained by
196 /// reversing its orientation.
197 /// Then RevGraphAdaptor implements the graph structure with node-set
198 /// \f$V\f$ and edge-set
199 /// \f$\{\bar e : e\in A \}\f$, i.e. the graph obtained from \f$G\f$ be
200 /// reversing the orientation of its edges. The following code shows how
201 /// such an instance can be constructed.
203 /// RevGraphAdaptor<ListGraph> gw(g);
205 ///\author Marton Makai
207 template<typename _Graph>
208 class RevGraphAdaptor :
209 public IterableGraphExtender<RevGraphAdaptorBase<_Graph> > {
211 typedef _Graph Graph;
212 typedef IterableGraphExtender<
213 RevGraphAdaptorBase<_Graph> > Parent;
215 RevGraphAdaptor() { }
217 explicit RevGraphAdaptor(_Graph& _graph) { setGraph(_graph); }
221 template <typename _Graph, typename NodeFilterMap,
222 typename EdgeFilterMap, bool checked = true>
223 class SubGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
225 typedef _Graph Graph;
226 typedef GraphAdaptorBase<_Graph> Parent;
228 NodeFilterMap* node_filter_map;
229 EdgeFilterMap* edge_filter_map;
230 SubGraphAdaptorBase() : Parent(),
231 node_filter_map(0), edge_filter_map(0) { }
233 void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
234 node_filter_map=&_node_filter_map;
236 void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
237 edge_filter_map=&_edge_filter_map;
242 typedef typename Parent::Node Node;
243 typedef typename Parent::Edge Edge;
245 void first(Node& i) const {
247 while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
250 void first(Edge& i) const {
252 while (i!=INVALID && (!(*edge_filter_map)[i]
253 || !(*node_filter_map)[Parent::source(i)]
254 || !(*node_filter_map)[Parent::target(i)])) Parent::next(i);
257 void firstIn(Edge& i, const Node& n) const {
258 Parent::firstIn(i, n);
259 while (i!=INVALID && (!(*edge_filter_map)[i]
260 || !(*node_filter_map)[Parent::source(i)])) Parent::nextIn(i);
263 void firstOut(Edge& i, const Node& n) const {
264 Parent::firstOut(i, n);
265 while (i!=INVALID && (!(*edge_filter_map)[i]
266 || !(*node_filter_map)[Parent::target(i)])) Parent::nextOut(i);
269 void next(Node& i) const {
271 while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
274 void next(Edge& i) const {
276 while (i!=INVALID && (!(*edge_filter_map)[i]
277 || !(*node_filter_map)[Parent::source(i)]
278 || !(*node_filter_map)[Parent::target(i)])) Parent::next(i);
281 void nextIn(Edge& i) const {
283 while (i!=INVALID && (!(*edge_filter_map)[i]
284 || !(*node_filter_map)[Parent::source(i)])) Parent::nextIn(i);
287 void nextOut(Edge& i) const {
289 while (i!=INVALID && (!(*edge_filter_map)[i]
290 || !(*node_filter_map)[Parent::target(i)])) Parent::nextOut(i);
293 /// This function hides \c n in the graph, i.e. the iteration
294 /// jumps over it. This is done by simply setting the value of \c n
295 /// to be false in the corresponding node-map.
296 void hide(const Node& n) const { node_filter_map->set(n, false); }
298 /// This function hides \c e in the graph, i.e. the iteration
299 /// jumps over it. This is done by simply setting the value of \c e
300 /// to be false in the corresponding edge-map.
301 void hide(const Edge& e) const { edge_filter_map->set(e, false); }
303 /// The value of \c n is set to be true in the node-map which stores
304 /// hide information. If \c n was hidden previuosly, then it is shown
306 void unHide(const Node& n) const { node_filter_map->set(n, true); }
308 /// The value of \c e is set to be true in the edge-map which stores
309 /// hide information. If \c e was hidden previuosly, then it is shown
311 void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
313 /// Returns true if \c n is hidden.
314 bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
316 /// Returns true if \c n is hidden.
317 bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
319 typedef False NodeNumTag;
320 typedef False EdgeNumTag;
323 template <typename _Graph, typename NodeFilterMap, typename EdgeFilterMap>
324 class SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap, false>
325 : public GraphAdaptorBase<_Graph> {
327 typedef _Graph Graph;
328 typedef GraphAdaptorBase<_Graph> Parent;
330 NodeFilterMap* node_filter_map;
331 EdgeFilterMap* edge_filter_map;
332 SubGraphAdaptorBase() : Parent(),
333 node_filter_map(0), edge_filter_map(0) { }
335 void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
336 node_filter_map=&_node_filter_map;
338 void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
339 edge_filter_map=&_edge_filter_map;
344 typedef typename Parent::Node Node;
345 typedef typename Parent::Edge Edge;
347 void first(Node& i) const {
349 while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
352 void first(Edge& i) const {
354 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::next(i);
357 void firstIn(Edge& i, const Node& n) const {
358 Parent::firstIn(i, n);
359 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextIn(i);
362 void firstOut(Edge& i, const Node& n) const {
363 Parent::firstOut(i, n);
364 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i);
367 void next(Node& i) const {
369 while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
371 void next(Edge& i) const {
373 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::next(i);
375 void nextIn(Edge& i) const {
377 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextIn(i);
380 void nextOut(Edge& i) const {
382 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i);
385 /// This function hides \c n in the graph, i.e. the iteration
386 /// jumps over it. This is done by simply setting the value of \c n
387 /// to be false in the corresponding node-map.
388 void hide(const Node& n) const { node_filter_map->set(n, false); }
390 /// This function hides \c e in the graph, i.e. the iteration
391 /// jumps over it. This is done by simply setting the value of \c e
392 /// to be false in the corresponding edge-map.
393 void hide(const Edge& e) const { edge_filter_map->set(e, false); }
395 /// The value of \c n is set to be true in the node-map which stores
396 /// hide information. If \c n was hidden previuosly, then it is shown
398 void unHide(const Node& n) const { node_filter_map->set(n, true); }
400 /// The value of \c e is set to be true in the edge-map which stores
401 /// hide information. If \c e was hidden previuosly, then it is shown
403 void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
405 /// Returns true if \c n is hidden.
406 bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
408 /// Returns true if \c n is hidden.
409 bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
411 typedef False NodeNumTag;
412 typedef False EdgeNumTag;
415 /*! \brief A graph adaptor for hiding nodes and edges from a graph.
417 \warning Graph adaptors are in even more experimental state than the other
418 parts of the lib. Use them at you own risk.
420 SubGraphAdaptor shows the graph with filtered node-set and
421 edge-set. If the \c checked parameter is true then it filters the edgeset
422 to do not get invalid edges without source or target.
423 Let \f$G=(V, A)\f$ be a directed graph
424 and suppose that the graph instance \c g of type ListGraph implements
426 Let moreover \f$b_V\f$ and
427 \f$b_A\f$ be bool-valued functions resp. on the node-set and edge-set.
428 SubGraphAdaptor<...>::NodeIt iterates
429 on the node-set \f$\{v\in V : b_V(v)=true\}\f$ and
430 SubGraphAdaptor<...>::EdgeIt iterates
431 on the edge-set \f$\{e\in A : b_A(e)=true\}\f$. Similarly,
432 SubGraphAdaptor<...>::OutEdgeIt and SubGraphAdaptor<...>::InEdgeIt iterates
433 only on edges leaving and entering a specific node which have true value.
435 If the \c checked template parameter is false then we have to note that
436 the node-iterator cares only the filter on the node-set, and the
437 edge-iterator cares only the filter on the edge-set. This way the edge-map
438 should filter all edges which's source or target is filtered by the
441 typedef ListGraph Graph;
443 typedef Graph::Node Node;
444 typedef Graph::Edge Edge;
445 Node u=g.addNode(); //node of id 0
446 Node v=g.addNode(); //node of id 1
447 Node e=g.addEdge(u, v); //edge of id 0
448 Node f=g.addEdge(v, u); //edge of id 1
449 Graph::NodeMap<bool> nm(g, true);
451 Graph::EdgeMap<bool> em(g, true);
453 typedef SubGraphAdaptor<Graph, Graph::NodeMap<bool>, Graph::EdgeMap<bool> > SubGW;
455 for (SubGW::NodeIt n(gw); n!=INVALID; ++n) std::cout << g.id(n) << std::endl;
456 std::cout << ":-)" << std::endl;
457 for (SubGW::EdgeIt e(gw); e!=INVALID; ++e) std::cout << g.id(e) << std::endl;
459 The output of the above code is the following.
465 Note that \c n is of type \c SubGW::NodeIt, but it can be converted to
466 \c Graph::Node that is why \c g.id(n) can be applied.
468 For other examples see also the documentation of NodeSubGraphAdaptor and
473 template<typename _Graph, typename NodeFilterMap,
474 typename EdgeFilterMap, bool checked = true>
475 class SubGraphAdaptor :
476 public IterableGraphExtender<
477 SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap, checked> > {
479 typedef _Graph Graph;
480 typedef IterableGraphExtender<
481 SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap> > Parent;
483 SubGraphAdaptor() { }
485 SubGraphAdaptor(_Graph& _graph, NodeFilterMap& _node_filter_map,
486 EdgeFilterMap& _edge_filter_map) {
488 setNodeFilterMap(_node_filter_map);
489 setEdgeFilterMap(_edge_filter_map);
495 /*! \brief An adaptor for hiding nodes from a graph.
497 \warning Graph adaptors are in even more experimental state than the other
498 parts of the lib. Use them at you own risk.
500 An adaptor for hiding nodes from a graph.
501 This adaptor specializes SubGraphAdaptor in the way that only the node-set
502 can be filtered. In usual case the checked parameter is true, we get the
503 induced subgraph. But if the checked parameter is false then we can only
504 filter only isolated nodes.
507 template<typename Graph, typename NodeFilterMap, bool checked = true>
508 class NodeSubGraphAdaptor :
509 public SubGraphAdaptor<Graph, NodeFilterMap,
510 ConstMap<typename Graph::Edge,bool>, checked> {
512 typedef SubGraphAdaptor<Graph, NodeFilterMap,
513 ConstMap<typename Graph::Edge,bool> > Parent;
515 ConstMap<typename Graph::Edge, bool> const_true_map;
517 NodeSubGraphAdaptor(Graph& _graph, NodeFilterMap& _node_filter_map) :
518 Parent(), const_true_map(true) {
519 Parent::setGraph(_graph);
520 Parent::setNodeFilterMap(_node_filter_map);
521 Parent::setEdgeFilterMap(const_true_map);
526 /*! \brief An adaptor for hiding edges from a graph.
528 \warning Graph adaptors are in even more experimental state than the other
529 parts of the lib. Use them at you own risk.
531 An adaptor for hiding edges from a graph.
532 This adaptor specializes SubGraphAdaptor in the way that only the edge-set
533 can be filtered. The usefulness of this adaptor is demonstrated in the
534 problem of searching a maximum number of edge-disjoint shortest paths
536 two nodes \c s and \c t. Shortest here means being shortest w.r.t.
537 non-negative edge-lengths. Note that
538 the comprehension of the presented solution
539 need's some elementary knowledge from combinatorial optimization.
541 If a single shortest path is to be
542 searched between \c s and \c t, then this can be done easily by
543 applying the Dijkstra algorithm. What happens, if a maximum number of
544 edge-disjoint shortest paths is to be computed. It can be proved that an
545 edge can be in a shortest path if and only if it is tight with respect to
546 the potential function computed by Dijkstra. Moreover, any path containing
547 only such edges is a shortest one. Thus we have to compute a maximum number
548 of edge-disjoint paths between \c s and \c t in the graph which has edge-set
549 all the tight edges. The computation will be demonstrated on the following
550 graph, which is read from the dimacs file \c sub_graph_adaptor_demo.dim.
551 The full source code is available in \ref sub_graph_adaptor_demo.cc.
552 If you are interested in more demo programs, you can use
553 \ref dim_to_dot.cc to generate .dot files from dimacs files.
554 The .dot file of the following figure was generated by
555 the demo program \ref dim_to_dot.cc.
558 digraph lemon_dot_example {
559 node [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
560 n0 [ label="0 (s)" ];
566 n6 [ label="6 (t)" ];
567 edge [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
568 n5 -> n6 [ label="9, length:4" ];
569 n4 -> n6 [ label="8, length:2" ];
570 n3 -> n5 [ label="7, length:1" ];
571 n2 -> n5 [ label="6, length:3" ];
572 n2 -> n6 [ label="5, length:5" ];
573 n2 -> n4 [ label="4, length:2" ];
574 n1 -> n4 [ label="3, length:3" ];
575 n0 -> n3 [ label="2, length:1" ];
576 n0 -> n2 [ label="1, length:2" ];
577 n0 -> n1 [ label="0, length:3" ];
586 readDimacs(std::cin, g, length, s, t);
588 cout << "edges with lengths (of form id, source--length->target): " << endl;
589 for(EdgeIt e(g); e!=INVALID; ++e)
590 cout << g.id(e) << ", " << g.id(g.source(e)) << "--"
591 << length[e] << "->" << g.id(g.target(e)) << endl;
593 cout << "s: " << g.id(s) << " t: " << g.id(t) << endl;
595 Next, the potential function is computed with Dijkstra.
597 typedef Dijkstra<Graph, LengthMap> Dijkstra;
598 Dijkstra dijkstra(g, length);
601 Next, we consrtruct a map which filters the edge-set to the tight edges.
603 typedef TightEdgeFilterMap<Graph, const Dijkstra::DistMap, LengthMap>
605 TightEdgeFilter tight_edge_filter(g, dijkstra.distMap(), length);
607 typedef EdgeSubGraphAdaptor<Graph, TightEdgeFilter> SubGW;
608 SubGW gw(g, tight_edge_filter);
610 Then, the maximum nimber of edge-disjoint \c s-\c t paths are computed
611 with a max flow algorithm Preflow.
613 ConstMap<Edge, int> const_1_map(1);
614 Graph::EdgeMap<int> flow(g, 0);
616 Preflow<SubGW, int, ConstMap<Edge, int>, Graph::EdgeMap<int> >
617 preflow(gw, s, t, const_1_map, flow);
622 cout << "maximum number of edge-disjoint shortest path: "
623 << preflow.flowValue() << endl;
624 cout << "edges of the maximum number of edge-disjoint shortest s-t paths: "
626 for(EdgeIt e(g); e!=INVALID; ++e)
628 cout << " " << g.id(g.source(e)) << "--"
629 << length[e] << "->" << g.id(g.target(e)) << endl;
631 The program has the following (expected :-)) output:
633 edges with lengths (of form id, source--length->target):
645 maximum number of edge-disjoint shortest path: 2
646 edges of the maximum number of edge-disjoint shortest s-t paths:
657 template<typename Graph, typename EdgeFilterMap>
658 class EdgeSubGraphAdaptor :
659 public SubGraphAdaptor<Graph, ConstMap<typename Graph::Node,bool>,
660 EdgeFilterMap, false> {
662 typedef SubGraphAdaptor<Graph, ConstMap<typename Graph::Node,bool>,
663 EdgeFilterMap, false> Parent;
665 ConstMap<typename Graph::Node, bool> const_true_map;
667 EdgeSubGraphAdaptor(Graph& _graph, EdgeFilterMap& _edge_filter_map) :
668 Parent(), const_true_map(true) {
669 Parent::setGraph(_graph);
670 Parent::setNodeFilterMap(const_true_map);
671 Parent::setEdgeFilterMap(_edge_filter_map);
675 template <typename _Graph>
676 class UGraphAdaptorBase :
677 public UGraphExtender<GraphAdaptorBase<_Graph> > {
679 typedef _Graph Graph;
680 typedef UGraphExtender<GraphAdaptorBase<_Graph> > Parent;
682 UGraphAdaptorBase() : Parent() { }
684 typedef typename Parent::UEdge UEdge;
685 typedef typename Parent::Edge Edge;
687 template <typename T>
690 const UGraphAdaptorBase<_Graph>* g;
691 template <typename TT> friend class EdgeMap;
692 typename _Graph::template EdgeMap<T> forward_map, backward_map;
697 EdgeMap(const UGraphAdaptorBase<_Graph>& _g) : g(&_g),
698 forward_map(*(g->graph)), backward_map(*(g->graph)) { }
700 EdgeMap(const UGraphAdaptorBase<_Graph>& _g, T a) : g(&_g),
701 forward_map(*(g->graph), a), backward_map(*(g->graph), a) { }
703 void set(Edge e, T a) {
705 forward_map.set(e, a);
707 backward_map.set(e, a);
710 T operator[](Edge e) const {
712 return forward_map[e];
714 return backward_map[e];
718 template <typename T>
720 template <typename TT> friend class UEdgeMap;
721 typename _Graph::template EdgeMap<T> map;
726 UEdgeMap(const UGraphAdaptorBase<_Graph>& g) :
729 UEdgeMap(const UGraphAdaptorBase<_Graph>& g, T a) :
730 map(*(g.graph), a) { }
732 void set(UEdge e, T a) {
736 T operator[](UEdge e) const {
743 /// \brief An undirected graph is made from a directed graph by an adaptor
745 /// Undocumented, untested!!!
746 /// If somebody knows nice demo application, let's polulate it.
748 /// \author Marton Makai
749 template<typename _Graph>
750 class UGraphAdaptor :
751 public IterableUGraphExtender<
752 UGraphAdaptorBase<_Graph> > {
754 typedef _Graph Graph;
755 typedef IterableUGraphExtender<
756 UGraphAdaptorBase<_Graph> > Parent;
760 UGraphAdaptor(_Graph& _graph) {
766 template <typename _Graph,
767 typename ForwardFilterMap, typename BackwardFilterMap>
768 class SubBidirGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
770 typedef _Graph Graph;
771 typedef GraphAdaptorBase<_Graph> Parent;
773 ForwardFilterMap* forward_filter;
774 BackwardFilterMap* backward_filter;
775 SubBidirGraphAdaptorBase() : Parent(),
776 forward_filter(0), backward_filter(0) { }
778 void setForwardFilterMap(ForwardFilterMap& _forward_filter) {
779 forward_filter=&_forward_filter;
781 void setBackwardFilterMap(BackwardFilterMap& _backward_filter) {
782 backward_filter=&_backward_filter;
786 // SubGraphAdaptorBase(Graph& _graph,
787 // NodeFilterMap& _node_filter_map,
788 // EdgeFilterMap& _edge_filter_map) :
790 // node_filter_map(&node_filter_map),
791 // edge_filter_map(&edge_filter_map) { }
793 typedef typename Parent::Node Node;
794 typedef typename _Graph::Edge GraphEdge;
795 template <typename T> class EdgeMap;
796 /// SubBidirGraphAdaptorBase<..., ..., ...>::Edge is inherited from
797 /// _Graph::Edge. It contains an extra bool flag which is true
798 /// if and only if the
799 /// edge is the backward version of the original edge.
800 class Edge : public _Graph::Edge {
801 friend class SubBidirGraphAdaptorBase<
802 Graph, ForwardFilterMap, BackwardFilterMap>;
803 template<typename T> friend class EdgeMap;
805 bool backward; //true, iff backward
808 /// \todo =false is needed, or causes problems?
809 /// If \c _backward is false, then we get an edge corresponding to the
810 /// original one, otherwise its oppositely directed pair is obtained.
811 Edge(const typename _Graph::Edge& e, bool _backward/*=false*/) :
812 _Graph::Edge(e), backward(_backward) { }
813 Edge(Invalid i) : _Graph::Edge(i), backward(true) { }
814 bool operator==(const Edge& v) const {
815 return (this->backward==v.backward &&
816 static_cast<typename _Graph::Edge>(*this)==
817 static_cast<typename _Graph::Edge>(v));
819 bool operator!=(const Edge& v) const {
820 return (this->backward!=v.backward ||
821 static_cast<typename _Graph::Edge>(*this)!=
822 static_cast<typename _Graph::Edge>(v));
826 void first(Node& i) const {
830 void first(Edge& i) const {
833 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
834 !(*forward_filter)[i]) Parent::next(i);
835 if (*static_cast<GraphEdge*>(&i)==INVALID) {
838 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
839 !(*backward_filter)[i]) Parent::next(i);
843 void firstIn(Edge& i, const Node& n) const {
844 Parent::firstIn(i, n);
846 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
847 !(*forward_filter)[i]) Parent::nextIn(i);
848 if (*static_cast<GraphEdge*>(&i)==INVALID) {
849 Parent::firstOut(i, n);
851 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
852 !(*backward_filter)[i]) Parent::nextOut(i);
856 void firstOut(Edge& i, const Node& n) const {
857 Parent::firstOut(i, n);
859 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
860 !(*forward_filter)[i]) Parent::nextOut(i);
861 if (*static_cast<GraphEdge*>(&i)==INVALID) {
862 Parent::firstIn(i, n);
864 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
865 !(*backward_filter)[i]) Parent::nextIn(i);
869 void next(Node& i) const {
873 void next(Edge& i) const {
876 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
877 !(*forward_filter)[i]) Parent::next(i);
878 if (*static_cast<GraphEdge*>(&i)==INVALID) {
881 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
882 !(*backward_filter)[i]) Parent::next(i);
886 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
887 !(*backward_filter)[i]) Parent::next(i);
891 void nextIn(Edge& i) const {
893 Node n=Parent::target(i);
895 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
896 !(*forward_filter)[i]) Parent::nextIn(i);
897 if (*static_cast<GraphEdge*>(&i)==INVALID) {
898 Parent::firstOut(i, n);
900 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
901 !(*backward_filter)[i]) Parent::nextOut(i);
905 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
906 !(*backward_filter)[i]) Parent::nextOut(i);
910 void nextOut(Edge& i) const {
912 Node n=Parent::source(i);
914 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
915 !(*forward_filter)[i]) Parent::nextOut(i);
916 if (*static_cast<GraphEdge*>(&i)==INVALID) {
917 Parent::firstIn(i, n);
919 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
920 !(*backward_filter)[i]) Parent::nextIn(i);
924 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
925 !(*backward_filter)[i]) Parent::nextIn(i);
929 Node source(Edge e) const {
930 return ((!e.backward) ? this->graph->source(e) : this->graph->target(e)); }
931 Node target(Edge e) const {
932 return ((!e.backward) ? this->graph->target(e) : this->graph->source(e)); }
934 /// Gives back the opposite edge.
935 Edge opposite(const Edge& e) const {
937 f.backward=!f.backward;
941 /// \warning This is a linear time operation and works only if
942 /// \c Graph::EdgeIt is defined.
944 int edgeNum() const {
947 for (first(e); e!=INVALID; next(e)) ++i;
951 bool forward(const Edge& e) const { return !e.backward; }
952 bool backward(const Edge& e) const { return e.backward; }
954 template <typename T>
955 /// \c SubBidirGraphAdaptorBase<..., ..., ...>::EdgeMap contains two
956 /// _Graph::EdgeMap one for the forward edges and
957 /// one for the backward edges.
959 template <typename TT> friend class EdgeMap;
960 typename _Graph::template EdgeMap<T> forward_map, backward_map;
965 EdgeMap(const SubBidirGraphAdaptorBase<_Graph,
966 ForwardFilterMap, BackwardFilterMap>& g) :
967 forward_map(*(g.graph)), backward_map(*(g.graph)) { }
969 EdgeMap(const SubBidirGraphAdaptorBase<_Graph,
970 ForwardFilterMap, BackwardFilterMap>& g, T a) :
971 forward_map(*(g.graph), a), backward_map(*(g.graph), a) { }
973 void set(Edge e, T a) {
975 forward_map.set(e, a);
977 backward_map.set(e, a);
980 // typename _Graph::template EdgeMap<T>::ConstReference
981 // operator[](Edge e) const {
983 // return forward_map[e];
985 // return backward_map[e];
988 // typename _Graph::template EdgeMap<T>::Reference
989 T operator[](Edge e) const {
991 return forward_map[e];
993 return backward_map[e];
997 forward_map.update();
998 backward_map.update();
1005 ///\brief An adaptor for composing a subgraph of a
1006 /// bidirected graph made from a directed one.
1008 /// An adaptor for composing a subgraph of a
1009 /// bidirected graph made from a directed one.
1011 ///\warning Graph adaptors are in even more experimental state than the other
1012 ///parts of the lib. Use them at you own risk.
1014 /// Let \f$G=(V, A)\f$ be a directed graph and for each directed edge
1015 /// \f$e\in A\f$, let \f$\bar e\f$ denote the edge obtained by
1016 /// reversing its orientation. We are given moreover two bool valued
1017 /// maps on the edge-set,
1018 /// \f$forward\_filter\f$, and \f$backward\_filter\f$.
1019 /// SubBidirGraphAdaptor implements the graph structure with node-set
1020 /// \f$V\f$ and edge-set
1021 /// \f$\{e : e\in A \mbox{ and } forward\_filter(e) \mbox{ is true}\}+\{\bar e : e\in A \mbox{ and } backward\_filter(e) \mbox{ is true}\}\f$.
1022 /// The purpose of writing + instead of union is because parallel
1023 /// edges can arise. (Similarly, antiparallel edges also can arise).
1024 /// In other words, a subgraph of the bidirected graph obtained, which
1025 /// is given by orienting the edges of the original graph in both directions.
1026 /// As the oppositely directed edges are logically different,
1027 /// the maps are able to attach different values for them.
1029 /// An example for such a construction is \c RevGraphAdaptor where the
1030 /// forward_filter is everywhere false and the backward_filter is
1031 /// everywhere true. We note that for sake of efficiency,
1032 /// \c RevGraphAdaptor is implemented in a different way.
1033 /// But BidirGraphAdaptor is obtained from
1034 /// SubBidirGraphAdaptor by considering everywhere true
1035 /// valued maps both for forward_filter and backward_filter.
1037 /// The most important application of SubBidirGraphAdaptor
1038 /// is ResGraphAdaptor, which stands for the residual graph in directed
1039 /// flow and circulation problems.
1040 /// As adaptors usually, the SubBidirGraphAdaptor implements the
1041 /// above mentioned graph structure without its physical storage,
1042 /// that is the whole stuff is stored in constant memory.
1043 template<typename _Graph,
1044 typename ForwardFilterMap, typename BackwardFilterMap>
1045 class SubBidirGraphAdaptor :
1046 public IterableGraphExtender<
1047 SubBidirGraphAdaptorBase<_Graph, ForwardFilterMap, BackwardFilterMap> > {
1049 typedef _Graph Graph;
1050 typedef IterableGraphExtender<
1051 SubBidirGraphAdaptorBase<
1052 _Graph, ForwardFilterMap, BackwardFilterMap> > Parent;
1054 SubBidirGraphAdaptor() { }
1056 SubBidirGraphAdaptor(_Graph& _graph, ForwardFilterMap& _forward_filter,
1057 BackwardFilterMap& _backward_filter) {
1059 setForwardFilterMap(_forward_filter);
1060 setBackwardFilterMap(_backward_filter);
1066 ///\brief An adaptor for composing bidirected graph from a directed one.
1068 ///\warning Graph adaptors are in even more experimental state than the other
1069 ///parts of the lib. Use them at you own risk.
1071 /// An adaptor for composing bidirected graph from a directed one.
1072 /// A bidirected graph is composed over the directed one without physical
1073 /// storage. As the oppositely directed edges are logically different ones
1074 /// the maps are able to attach different values for them.
1075 template<typename Graph>
1076 class BidirGraphAdaptor :
1077 public SubBidirGraphAdaptor<
1079 ConstMap<typename Graph::Edge, bool>,
1080 ConstMap<typename Graph::Edge, bool> > {
1082 typedef SubBidirGraphAdaptor<
1084 ConstMap<typename Graph::Edge, bool>,
1085 ConstMap<typename Graph::Edge, bool> > Parent;
1087 ConstMap<typename Graph::Edge, bool> cm;
1089 BidirGraphAdaptor() : Parent(), cm(true) {
1090 Parent::setForwardFilterMap(cm);
1091 Parent::setBackwardFilterMap(cm);
1094 BidirGraphAdaptor(Graph& _graph) : Parent(), cm(true) {
1095 Parent::setGraph(_graph);
1096 Parent::setForwardFilterMap(cm);
1097 Parent::setBackwardFilterMap(cm);
1100 int edgeNum() const {
1101 return 2*this->graph->edgeNum();
1106 template<typename Graph, typename Number,
1107 typename CapacityMap, typename FlowMap>
1108 class ResForwardFilter {
1109 // const Graph* graph;
1110 const CapacityMap* capacity;
1111 const FlowMap* flow;
1113 ResForwardFilter(/*const Graph& _graph, */
1114 const CapacityMap& _capacity, const FlowMap& _flow) :
1115 /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
1116 ResForwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
1117 void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
1118 void setFlow(const FlowMap& _flow) { flow=&_flow; }
1119 bool operator[](const typename Graph::Edge& e) const {
1120 return (Number((*flow)[e]) < Number((*capacity)[e]));
1124 template<typename Graph, typename Number,
1125 typename CapacityMap, typename FlowMap>
1126 class ResBackwardFilter {
1127 const CapacityMap* capacity;
1128 const FlowMap* flow;
1130 ResBackwardFilter(/*const Graph& _graph,*/
1131 const CapacityMap& _capacity, const FlowMap& _flow) :
1132 /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
1133 ResBackwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
1134 void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
1135 void setFlow(const FlowMap& _flow) { flow=&_flow; }
1136 bool operator[](const typename Graph::Edge& e) const {
1137 return (Number(0) < Number((*flow)[e]));
1142 /*! \brief An adaptor for composing the residual graph for directed flow and circulation problems.
1144 An adaptor for composing the residual graph for directed flow and circulation problems.
1145 Let \f$G=(V, A)\f$ be a directed graph and let \f$F\f$ be a
1146 number type. Let moreover
1147 \f$f,c:A\to F\f$, be functions on the edge-set.
1148 In the appications of ResGraphAdaptor, \f$f\f$ usually stands for a flow
1149 and \f$c\f$ for a capacity function.
1150 Suppose that a graph instange \c g of type
1151 \c ListGraph implements \f$G\f$.
1155 Then RevGraphAdaptor implements the graph structure with node-set
1156 \f$V\f$ and edge-set \f$A_{forward}\cup A_{backward}\f$, where
1157 \f$A_{forward}=\{uv : uv\in A, f(uv)<c(uv)\}\f$ and
1158 \f$A_{backward}=\{vu : uv\in A, f(uv)>0\}\f$,
1159 i.e. the so called residual graph.
1160 When we take the union \f$A_{forward}\cup A_{backward}\f$,
1161 multilicities are counted, i.e. if an edge is in both
1162 \f$A_{forward}\f$ and \f$A_{backward}\f$, then in the adaptor it
1164 The following code shows how
1165 such an instance can be constructed.
1167 typedef ListGraph Graph;
1168 Graph::EdgeMap<int> f(g);
1169 Graph::EdgeMap<int> c(g);
1170 ResGraphAdaptor<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> > gw(g);
1172 \author Marton Makai
1174 template<typename Graph, typename Number,
1175 typename CapacityMap, typename FlowMap>
1176 class ResGraphAdaptor :
1177 public SubBidirGraphAdaptor<
1179 ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,
1180 ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > {
1182 typedef SubBidirGraphAdaptor<
1184 ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,
1185 ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > Parent;
1187 const CapacityMap* capacity;
1189 ResForwardFilter<Graph, Number, CapacityMap, FlowMap> forward_filter;
1190 ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> backward_filter;
1191 ResGraphAdaptor() : Parent(),
1192 capacity(0), flow(0) { }
1193 void setCapacityMap(const CapacityMap& _capacity) {
1194 capacity=&_capacity;
1195 forward_filter.setCapacity(_capacity);
1196 backward_filter.setCapacity(_capacity);
1198 void setFlowMap(FlowMap& _flow) {
1200 forward_filter.setFlow(_flow);
1201 backward_filter.setFlow(_flow);
1204 ResGraphAdaptor(Graph& _graph, const CapacityMap& _capacity,
1206 Parent(), capacity(&_capacity), flow(&_flow),
1207 forward_filter(/*_graph,*/ _capacity, _flow),
1208 backward_filter(/*_graph,*/ _capacity, _flow) {
1209 Parent::setGraph(_graph);
1210 Parent::setForwardFilterMap(forward_filter);
1211 Parent::setBackwardFilterMap(backward_filter);
1214 typedef typename Parent::Edge Edge;
1216 void augment(const Edge& e, Number a) const {
1217 if (Parent::forward(e))
1218 flow->set(e, (*flow)[e]+a);
1220 flow->set(e, (*flow)[e]-a);
1223 /// \brief Residual capacity map.
1225 /// In generic residual graphs the residual capacity can be obtained
1229 const ResGraphAdaptor<Graph, Number, CapacityMap, FlowMap>* res_graph;
1231 typedef Number Value;
1233 ResCap(const ResGraphAdaptor<Graph, Number, CapacityMap, FlowMap>&
1234 _res_graph) : res_graph(&_res_graph) { }
1235 Number operator[](const Edge& e) const {
1236 if (res_graph->forward(e))
1237 return (*(res_graph->capacity))[e]-(*(res_graph->flow))[e];
1239 return (*(res_graph->flow))[e];
1243 // KEEP_MAPS(Parent, ResGraphAdaptor);
1248 template <typename _Graph, typename FirstOutEdgesMap>
1249 class ErasingFirstGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
1251 typedef _Graph Graph;
1252 typedef GraphAdaptorBase<_Graph> Parent;
1254 FirstOutEdgesMap* first_out_edges;
1255 ErasingFirstGraphAdaptorBase() : Parent(),
1256 first_out_edges(0) { }
1258 void setFirstOutEdgesMap(FirstOutEdgesMap& _first_out_edges) {
1259 first_out_edges=&_first_out_edges;
1264 typedef typename Parent::Node Node;
1265 typedef typename Parent::Edge Edge;
1267 void firstOut(Edge& i, const Node& n) const {
1268 i=(*first_out_edges)[n];
1271 void erase(const Edge& e) const {
1275 first_out_edges->set(n, f);
1280 /// For blocking flows.
1282 ///\warning Graph adaptors are in even more
1283 ///experimental state than the other
1284 ///parts of the lib. Use them at you own risk.
1286 ///This graph adaptor is used for on-the-fly
1287 ///Dinits blocking flow computations.
1288 ///For each node, an out-edge is stored which is used when the
1289 ///\code OutEdgeIt& first(OutEdgeIt&, const Node&)\endcode
1292 ///\author Marton Makai
1294 template <typename _Graph, typename FirstOutEdgesMap>
1295 class ErasingFirstGraphAdaptor :
1296 public IterableGraphExtender<
1297 ErasingFirstGraphAdaptorBase<_Graph, FirstOutEdgesMap> > {
1299 typedef _Graph Graph;
1300 typedef IterableGraphExtender<
1301 ErasingFirstGraphAdaptorBase<_Graph, FirstOutEdgesMap> > Parent;
1302 ErasingFirstGraphAdaptor(Graph& _graph,
1303 FirstOutEdgesMap& _first_out_edges) {
1305 setFirstOutEdgesMap(_first_out_edges);
1310 template <typename _Graph>
1311 class SplitGraphAdaptorBase
1312 : public GraphAdaptorBase<_Graph> {
1314 typedef GraphAdaptorBase<_Graph> Parent;
1318 template <typename T> class NodeMap;
1319 template <typename T> class EdgeMap;
1322 class Node : public Parent::Node {
1323 friend class SplitGraphAdaptorBase;
1324 template <typename T> friend class NodeMap;
1325 typedef typename Parent::Node NodeParent;
1329 Node(typename Parent::Node _node, bool _entry)
1330 : Parent::Node(_node), entry(_entry) {}
1334 Node(Invalid) : NodeParent(INVALID), entry(true) {}
1336 bool operator==(const Node& node) const {
1337 return NodeParent::operator==(node) && entry == node.entry;
1340 bool operator!=(const Node& node) const {
1341 return !(*this == node);
1344 bool operator<(const Node& node) const {
1345 return NodeParent::operator<(node) ||
1346 (NodeParent::operator==(node) && entry < node.entry);
1350 /// \todo May we want VARIANT/union type
1351 class Edge : public Parent::Edge {
1352 friend class SplitGraphAdaptorBase;
1353 template <typename T> friend class EdgeMap;
1355 typedef typename Parent::Edge EdgeParent;
1356 typedef typename Parent::Node NodeParent;
1359 Edge(const EdgeParent& edge, const NodeParent& node)
1360 : EdgeParent(edge), bind(node) {}
1363 Edge(Invalid) : EdgeParent(INVALID), bind(INVALID) {}
1365 bool operator==(const Edge& edge) const {
1366 return EdgeParent::operator==(edge) && bind == edge.bind;
1369 bool operator!=(const Edge& edge) const {
1370 return !(*this == edge);
1373 bool operator<(const Edge& edge) const {
1374 return EdgeParent::operator<(edge) ||
1375 (EdgeParent::operator==(edge) && bind < edge.bind);
1379 void first(Node& node) const {
1380 Parent::first(node);
1384 void next(Node& node) const {
1393 void first(Edge& edge) const {
1394 Parent::first(edge);
1395 if ((typename Parent::Edge&)edge == INVALID) {
1396 Parent::first(edge.bind);
1398 edge.bind = INVALID;
1402 void next(Edge& edge) const {
1403 if ((typename Parent::Edge&)edge != INVALID) {
1405 if ((typename Parent::Edge&)edge == INVALID) {
1406 Parent::first(edge.bind);
1409 Parent::next(edge.bind);
1413 void firstIn(Edge& edge, const Node& node) const {
1415 Parent::firstIn(edge, node);
1416 edge.bind = INVALID;
1418 (typename Parent::Edge&)edge = INVALID;
1423 void nextIn(Edge& edge) const {
1424 if ((typename Parent::Edge&)edge != INVALID) {
1425 Parent::nextIn(edge);
1427 edge.bind = INVALID;
1431 void firstOut(Edge& edge, const Node& node) const {
1433 Parent::firstOut(edge, node);
1434 edge.bind = INVALID;
1436 (typename Parent::Edge&)edge = INVALID;
1441 void nextOut(Edge& edge) const {
1442 if ((typename Parent::Edge&)edge != INVALID) {
1443 Parent::nextOut(edge);
1445 edge.bind = INVALID;
1449 Node source(const Edge& edge) const {
1450 if ((typename Parent::Edge&)edge != INVALID) {
1451 return Node(Parent::source(edge), false);
1453 return Node(edge.bind, true);
1457 Node target(const Edge& edge) const {
1458 if ((typename Parent::Edge&)edge != INVALID) {
1459 return Node(Parent::target(edge), true);
1461 return Node(edge.bind, false);
1465 static bool entryNode(const Node& node) {
1469 static bool exitNode(const Node& node) {
1473 static Node getEntry(const typename Parent::Node& node) {
1474 return Node(node, true);
1477 static Node getExit(const typename Parent::Node& node) {
1478 return Node(node, false);
1481 static bool originalEdge(const Edge& edge) {
1482 return (typename Parent::Edge&)edge != INVALID;
1485 static bool bindingEdge(const Edge& edge) {
1486 return edge.bind != INVALID;
1489 static Node getBindedNode(const Edge& edge) {
1493 int nodeNum() const {
1494 return Parent::nodeNum() * 2;
1497 typedef CompileTimeAnd<typename Parent::NodeNumTag,
1498 typename Parent::EdgeNumTag> EdgeNumTag;
1500 int edgeNum() const {
1501 return Parent::edgeNum() + Parent::nodeNum();
1504 Edge findEdge(const Node& source, const Node& target,
1505 const Edge& prev = INVALID) const {
1506 if (exitNode(source) && entryNode(target)) {
1507 return Parent::findEdge(source, target, prev);
1509 if (prev == INVALID && entryNode(source) && exitNode(target) &&
1510 (typename Parent::Node&)source == (typename Parent::Node&)target) {
1511 return Edge(INVALID, source);
1518 template <typename T>
1519 class NodeMap : public MapBase<Node, T> {
1520 typedef typename Parent::template NodeMap<T> NodeImpl;
1522 NodeMap(const SplitGraphAdaptorBase& _graph)
1523 : entry(_graph), exit(_graph) {}
1524 NodeMap(const SplitGraphAdaptorBase& _graph, const T& t)
1525 : entry(_graph, t), exit(_graph, t) {}
1527 void set(const Node& key, const T& val) {
1528 if (key.entry) { entry.set(key, val); }
1529 else {exit.set(key, val); }
1532 typename MapTraits<NodeImpl>::ReturnValue
1533 operator[](const Node& key) {
1534 if (key.entry) { return entry[key]; }
1535 else { return exit[key]; }
1538 typename MapTraits<NodeImpl>::ConstReturnValue
1539 operator[](const Node& key) const {
1540 if (key.entry) { return entry[key]; }
1541 else { return exit[key]; }
1545 NodeImpl entry, exit;
1548 template <typename T>
1549 class EdgeMap : public MapBase<Edge, T> {
1550 typedef typename Parent::template NodeMap<T> NodeImpl;
1551 typedef typename Parent::template EdgeMap<T> EdgeImpl;
1553 EdgeMap(const SplitGraphAdaptorBase& _graph)
1554 : bind(_graph), orig(_graph) {}
1555 EdgeMap(const SplitGraphAdaptorBase& _graph, const T& t)
1556 : bind(_graph, t), orig(_graph, t) {}
1558 void set(const Edge& key, const T& val) {
1559 if ((typename Parent::Edge&)key != INVALID) { orig.set(key, val); }
1560 else {bind.set(key.bind, val); }
1563 typename MapTraits<EdgeImpl>::ReturnValue
1564 operator[](const Edge& key) {
1565 if ((typename Parent::Edge&)key != INVALID) { return orig[key]; }
1566 else {return bind[key.bind]; }
1569 typename MapTraits<EdgeImpl>::ConstReturnValue
1570 operator[](const Edge& key) const {
1571 if ((typename Parent::Edge&)key != INVALID) { return orig[key]; }
1572 else {return bind[key.bind]; }
1576 typename Parent::template NodeMap<T> bind;
1577 typename Parent::template EdgeMap<T> orig;
1580 template <typename EntryMap, typename ExitMap>
1581 class CombinedNodeMap : public MapBase<Node, typename EntryMap::Value> {
1583 typedef MapBase<Node, typename EntryMap::Value> Parent;
1585 typedef typename Parent::Key Key;
1586 typedef typename Parent::Value Value;
1588 CombinedNodeMap(EntryMap& _entryMap, ExitMap& _exitMap)
1589 : entryMap(_entryMap), exitMap(_exitMap) {}
1591 Value& operator[](const Key& key) {
1593 return entryMap[key];
1595 return exitMap[key];
1599 Value operator[](const Key& key) const {
1601 return entryMap[key];
1603 return exitMap[key];
1607 void set(const Key& key, const Value& value) {
1609 entryMap.set(key, value);
1611 exitMap.set(key, value);
1622 template <typename EdgeMap, typename NodeMap>
1623 class CombinedEdgeMap : public MapBase<Edge, typename EdgeMap::Value> {
1625 typedef MapBase<Edge, typename EdgeMap::Value> Parent;
1627 typedef typename Parent::Key Key;
1628 typedef typename Parent::Value Value;
1630 CombinedEdgeMap(EdgeMap& _edgeMap, NodeMap& _nodeMap)
1631 : edgeMap(_edgeMap), nodeMap(_nodeMap) {}
1633 void set(const Edge& edge, const Value& val) {
1634 if (SplitGraphAdaptorBase::originalEdge(edge)) {
1635 edgeMap.set(edge, val);
1637 nodeMap.set(SplitGraphAdaptorBase::bindedNode(edge), val);
1641 Value operator[](const Key& edge) const {
1642 if (SplitGraphAdaptorBase::originalEdge(edge)) {
1643 return edgeMap[edge];
1645 return nodeMap[SplitGraphAdaptorBase::bindedNode(edge)];
1649 Value& operator[](const Key& edge) {
1650 if (SplitGraphAdaptorBase::originalEdge(edge)) {
1651 return edgeMap[edge];
1653 return nodeMap[SplitGraphAdaptorBase::bindedNode(edge)];
1664 template <typename _Graph>
1665 class SplitGraphAdaptor
1666 : public IterableGraphExtender<SplitGraphAdaptorBase<_Graph> > {
1668 typedef IterableGraphExtender<SplitGraphAdaptorBase<_Graph> > Parent;
1670 SplitGraphAdaptor(_Graph& graph) {
1671 Parent::setGraph(graph);
1681 #endif //LEMON_GRAPH_ADAPTOR_H