vmap.h: Enables one to create maps with a virtual base class.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_GRAPH_ADAPTOR_H
20 #define LEMON_GRAPH_ADAPTOR_H
22 ///\ingroup graph_adaptors
24 ///\brief Several graph adaptors.
26 ///This file contains several useful graph adaptor functions.
28 ///\author Marton Makai
30 #include <lemon/invalid.h>
31 #include <lemon/maps.h>
32 #include <lemon/bits/erasable_graph_extender.h>
33 #include <lemon/bits/clearable_graph_extender.h>
34 #include <lemon/bits/extendable_graph_extender.h>
35 #include <lemon/bits/iterable_graph_extender.h>
36 #include <lemon/bits/alteration_notifier.h>
37 #include <lemon/bits/default_map.h>
38 #include <lemon/bits/graph_extender.h>
43 ///\brief Base type for the Graph Adaptors
44 ///\ingroup graph_adaptors
46 ///Base type for the Graph Adaptors
48 ///\warning Graph adaptors are in even
49 ///more experimental state than the other
50 ///parts of the lib. Use them at you own risk.
52 ///This is the base type for most of LEMON graph adaptors.
53 ///This class implements a trivial graph adaptor i.e. it only wraps the
54 ///functions and types of the graph. The purpose of this class is to
55 ///make easier implementing graph adaptors. E.g. if an adaptor is
56 ///considered which differs from the wrapped graph only in some of its
57 ///functions or types, then it can be derived from GraphAdaptor,
59 ///differences should be implemented.
61 ///author Marton Makai
62 template<typename _Graph>
63 class GraphAdaptorBase {
66 typedef Graph ParentGraph;
70 GraphAdaptorBase() : graph(0) { }
71 void setGraph(Graph& _graph) { graph=&_graph; }
74 GraphAdaptorBase(Graph& _graph) : graph(&_graph) { }
76 typedef typename Graph::Node Node;
77 typedef typename Graph::Edge Edge;
79 void first(Node& i) const { graph->first(i); }
80 void first(Edge& i) const { graph->first(i); }
81 void firstIn(Edge& i, const Node& n) const { graph->firstIn(i, n); }
82 void firstOut(Edge& i, const Node& n ) const { graph->firstOut(i, n); }
84 void next(Node& i) const { graph->next(i); }
85 void next(Edge& i) const { graph->next(i); }
86 void nextIn(Edge& i) const { graph->nextIn(i); }
87 void nextOut(Edge& i) const { graph->nextOut(i); }
89 Node source(const Edge& e) const { return graph->source(e); }
90 Node target(const Edge& e) const { return graph->target(e); }
92 typedef NodeNumTagIndicator<Graph> NodeNumTag;
93 int nodeNum() const { return graph->nodeNum(); }
95 typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
96 int edgeNum() const { return graph->edgeNum(); }
98 typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
99 Edge findEdge(const Node& source, const Node& target,
100 const Edge& prev = INVALID) {
101 return graph->findEdge(source, target, prev);
104 Node addNode() const {
105 return Node(graph->addNode());
108 Edge addEdge(const Node& source, const Node& target) const {
109 return Edge(graph->addEdge(source, target));
112 void erase(const Node& i) const { graph->erase(i); }
113 void erase(const Edge& i) const { graph->erase(i); }
115 void clear() const { graph->clear(); }
117 int id(const Node& v) const { return graph->id(v); }
118 int id(const Edge& e) const { return graph->id(e); }
120 Edge oppositeNode(const Edge& e) const {
121 return Edge(graph->opposite(e));
124 template <typename _Value>
125 class NodeMap : public _Graph::template NodeMap<_Value> {
127 typedef typename _Graph::template NodeMap<_Value> Parent;
128 explicit NodeMap(const GraphAdaptorBase<_Graph>& gw)
129 : Parent(*gw.graph) { }
130 NodeMap(const GraphAdaptorBase<_Graph>& gw, const _Value& value)
131 : Parent(*gw.graph, value) { }
134 template <typename _Value>
135 class EdgeMap : public _Graph::template EdgeMap<_Value> {
137 typedef typename _Graph::template EdgeMap<_Value> Parent;
138 explicit EdgeMap(const GraphAdaptorBase<_Graph>& gw)
139 : Parent(*gw.graph) { }
140 EdgeMap(const GraphAdaptorBase<_Graph>& gw, const _Value& value)
141 : Parent(*gw.graph, value) { }
146 template <typename _Graph>
148 public IterableGraphExtender<GraphAdaptorBase<_Graph> > {
150 typedef _Graph Graph;
151 typedef IterableGraphExtender<GraphAdaptorBase<_Graph> > Parent;
153 GraphAdaptor() : Parent() { }
156 explicit GraphAdaptor(Graph& _graph) { setGraph(_graph); }
159 template <typename _Graph>
160 class RevGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
162 typedef _Graph Graph;
163 typedef GraphAdaptorBase<_Graph> Parent;
165 RevGraphAdaptorBase() : Parent() { }
167 typedef typename Parent::Node Node;
168 typedef typename Parent::Edge Edge;
170 void firstIn(Edge& i, const Node& n) const { Parent::firstOut(i, n); }
171 void firstOut(Edge& i, const Node& n ) const { Parent::firstIn(i, n); }
173 void nextIn(Edge& i) const { Parent::nextOut(i); }
174 void nextOut(Edge& i) const { Parent::nextIn(i); }
176 Node source(const Edge& e) const { return Parent::target(e); }
177 Node target(const Edge& e) const { return Parent::source(e); }
181 ///\brief A graph adaptor which reverses the orientation of the edges.
182 ///\ingroup graph_adaptors
184 ///\warning Graph adaptors are in even more experimental
185 ///state than the other
186 ///parts of the lib. Use them at you own risk.
188 /// If \c g is defined as
194 /// RevGraphAdaptor<ListGraph> gw(g);
196 ///implements the graph obtained from \c g by
197 /// reversing the orientation of its edges.
199 template<typename _Graph>
200 class RevGraphAdaptor :
201 public IterableGraphExtender<RevGraphAdaptorBase<_Graph> > {
203 typedef _Graph Graph;
204 typedef IterableGraphExtender<
205 RevGraphAdaptorBase<_Graph> > Parent;
207 RevGraphAdaptor() { }
209 explicit RevGraphAdaptor(_Graph& _graph) { setGraph(_graph); }
213 template <typename _Graph, typename NodeFilterMap,
214 typename EdgeFilterMap, bool checked = true>
215 class SubGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
217 typedef _Graph Graph;
218 typedef GraphAdaptorBase<_Graph> Parent;
220 NodeFilterMap* node_filter_map;
221 EdgeFilterMap* edge_filter_map;
222 SubGraphAdaptorBase() : Parent(),
223 node_filter_map(0), edge_filter_map(0) { }
225 void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
226 node_filter_map=&_node_filter_map;
228 void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
229 edge_filter_map=&_edge_filter_map;
234 typedef typename Parent::Node Node;
235 typedef typename Parent::Edge Edge;
237 void first(Node& i) const {
239 while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
242 void first(Edge& i) const {
244 while (i!=INVALID && (!(*edge_filter_map)[i]
245 || !(*node_filter_map)[Parent::source(i)]
246 || !(*node_filter_map)[Parent::target(i)])) Parent::next(i);
249 void firstIn(Edge& i, const Node& n) const {
250 Parent::firstIn(i, n);
251 while (i!=INVALID && (!(*edge_filter_map)[i]
252 || !(*node_filter_map)[Parent::source(i)])) Parent::nextIn(i);
255 void firstOut(Edge& i, const Node& n) const {
256 Parent::firstOut(i, n);
257 while (i!=INVALID && (!(*edge_filter_map)[i]
258 || !(*node_filter_map)[Parent::target(i)])) Parent::nextOut(i);
261 void next(Node& i) const {
263 while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
266 void next(Edge& i) const {
268 while (i!=INVALID && (!(*edge_filter_map)[i]
269 || !(*node_filter_map)[Parent::source(i)]
270 || !(*node_filter_map)[Parent::target(i)])) Parent::next(i);
273 void nextIn(Edge& i) const {
275 while (i!=INVALID && (!(*edge_filter_map)[i]
276 || !(*node_filter_map)[Parent::source(i)])) Parent::nextIn(i);
279 void nextOut(Edge& i) const {
281 while (i!=INVALID && (!(*edge_filter_map)[i]
282 || !(*node_filter_map)[Parent::target(i)])) Parent::nextOut(i);
287 /// This function hides \c n in the graph, i.e. the iteration
288 /// jumps over it. This is done by simply setting the value of \c n
289 /// to be false in the corresponding node-map.
290 void hide(const Node& n) const { node_filter_map->set(n, false); }
294 /// This function hides \c e in the graph, i.e. the iteration
295 /// jumps over it. This is done by simply setting the value of \c e
296 /// to be false in the corresponding edge-map.
297 void hide(const Edge& e) const { edge_filter_map->set(e, false); }
301 /// The value of \c n is set to be true in the node-map which stores
302 /// hide information. If \c n was hidden previuosly, then it is shown
304 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.
317 bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
319 /// Returns true if \c n is hidden.
323 bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
325 typedef False NodeNumTag;
326 typedef False EdgeNumTag;
329 template <typename _Graph, typename NodeFilterMap, typename EdgeFilterMap>
330 class SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap, false>
331 : public GraphAdaptorBase<_Graph> {
333 typedef _Graph Graph;
334 typedef GraphAdaptorBase<_Graph> Parent;
336 NodeFilterMap* node_filter_map;
337 EdgeFilterMap* edge_filter_map;
338 SubGraphAdaptorBase() : Parent(),
339 node_filter_map(0), edge_filter_map(0) { }
341 void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
342 node_filter_map=&_node_filter_map;
344 void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
345 edge_filter_map=&_edge_filter_map;
350 typedef typename Parent::Node Node;
351 typedef typename Parent::Edge Edge;
353 void first(Node& i) const {
355 while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
358 void first(Edge& i) const {
360 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::next(i);
363 void firstIn(Edge& i, const Node& n) const {
364 Parent::firstIn(i, n);
365 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextIn(i);
368 void firstOut(Edge& i, const Node& n) const {
369 Parent::firstOut(i, n);
370 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i);
373 void next(Node& i) const {
375 while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
377 void next(Edge& i) const {
379 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::next(i);
381 void nextIn(Edge& i) const {
383 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextIn(i);
386 void nextOut(Edge& i) const {
388 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i);
393 /// This function hides \c n in the graph, i.e. the iteration
394 /// jumps over it. This is done by simply setting the value of \c n
395 /// to be false in the corresponding node-map.
396 void hide(const Node& n) const { node_filter_map->set(n, false); }
400 /// This function hides \c e in the graph, i.e. the iteration
401 /// jumps over it. This is done by simply setting the value of \c e
402 /// to be false in the corresponding edge-map.
403 void hide(const Edge& e) const { edge_filter_map->set(e, false); }
407 /// The value of \c n is set to be true in the node-map which stores
408 /// hide information. If \c n was hidden previuosly, then it is shown
410 void unHide(const Node& n) const { node_filter_map->set(n, true); }
414 /// The value of \c e is set to be true in the edge-map which stores
415 /// hide information. If \c e was hidden previuosly, then it is shown
417 void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
419 /// Returns true if \c n is hidden.
423 bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
425 /// Returns true if \c n is hidden.
429 bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
431 typedef False NodeNumTag;
432 typedef False EdgeNumTag;
435 /// \brief A graph adaptor for hiding nodes and edges from a graph.
436 /// \ingroup graph_adaptors
438 /// \warning Graph adaptors are in even more experimental state than the
439 /// other parts of the lib. Use them at you own risk.
441 /// SubGraphAdaptor shows the graph with filtered node-set and
442 /// edge-set. If the \c checked parameter is true then it filters the edgeset
443 /// to do not get invalid edges without source or target.
444 /// Let \f$ G=(V, A) \f$ be a directed graph
445 /// and suppose that the graph instance \c g of type ListGraph
446 /// implements \f$ G \f$.
447 /// Let moreover \f$ b_V \f$ and \f$ b_A \f$ be bool-valued functions resp.
448 /// on the node-set and edge-set.
449 /// SubGraphAdaptor<...>::NodeIt iterates
450 /// on the node-set \f$ \{v\in V : b_V(v)=true\} \f$ and
451 /// SubGraphAdaptor<...>::EdgeIt iterates
452 /// on the edge-set \f$ \{e\in A : b_A(e)=true\} \f$. Similarly,
453 /// SubGraphAdaptor<...>::OutEdgeIt and
454 /// SubGraphAdaptor<...>::InEdgeIt iterates
455 /// only on edges leaving and entering a specific node which have true value.
457 /// If the \c checked template parameter is false then we have to note that
458 /// the node-iterator cares only the filter on the node-set, and the
459 /// edge-iterator cares only the filter on the edge-set.
460 /// This way the edge-map
461 /// should filter all edges which's source or target is filtered by the
464 /// typedef ListGraph Graph;
466 /// typedef Graph::Node Node;
467 /// typedef Graph::Edge Edge;
468 /// Node u=g.addNode(); //node of id 0
469 /// Node v=g.addNode(); //node of id 1
470 /// Node e=g.addEdge(u, v); //edge of id 0
471 /// Node f=g.addEdge(v, u); //edge of id 1
472 /// Graph::NodeMap<bool> nm(g, true);
473 /// nm.set(u, false);
474 /// Graph::EdgeMap<bool> em(g, true);
475 /// em.set(e, false);
476 /// typedef SubGraphAdaptor<Graph, Graph::NodeMap<bool>, Graph::EdgeMap<bool> > SubGW;
477 /// SubGW gw(g, nm, em);
478 /// for (SubGW::NodeIt n(gw); n!=INVALID; ++n) std::cout << g.id(n) << std::endl;
479 /// std::cout << ":-)" << std::endl;
480 /// for (SubGW::EdgeIt e(gw); e!=INVALID; ++e) std::cout << g.id(e) << std::endl;
482 /// The output of the above code is the following.
488 /// Note that \c n is of type \c SubGW::NodeIt, but it can be converted to
489 /// \c Graph::Node that is why \c g.id(n) can be applied.
491 /// For other examples see also the documentation of NodeSubGraphAdaptor and
492 /// EdgeSubGraphAdaptor.
494 /// \author Marton Makai
496 template<typename _Graph, typename NodeFilterMap,
497 typename EdgeFilterMap, bool checked = true>
498 class SubGraphAdaptor :
499 public IterableGraphExtender<
500 SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap, checked> > {
502 typedef _Graph Graph;
503 typedef IterableGraphExtender<
504 SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap> > Parent;
506 SubGraphAdaptor() { }
508 SubGraphAdaptor(_Graph& _graph, NodeFilterMap& _node_filter_map,
509 EdgeFilterMap& _edge_filter_map) {
511 setNodeFilterMap(_node_filter_map);
512 setEdgeFilterMap(_edge_filter_map);
518 ///\brief An adaptor for hiding nodes from a graph.
519 ///\ingroup graph_adaptors
521 ///\warning Graph adaptors are in even more experimental state
523 ///parts of the lib. Use them at you own risk.
525 ///An adaptor for hiding nodes from a graph.
526 ///This adaptor specializes SubGraphAdaptor in the way that only
528 ///can be filtered. In usual case the checked parameter is true, we get the
529 ///induced subgraph. But if the checked parameter is false then we can only
530 ///filter only isolated nodes.
531 ///\author Marton Makai
532 template<typename Graph, typename NodeFilterMap, bool checked = true>
533 class NodeSubGraphAdaptor :
534 public SubGraphAdaptor<Graph, NodeFilterMap,
535 ConstMap<typename Graph::Edge,bool>, checked> {
537 typedef SubGraphAdaptor<Graph, NodeFilterMap,
538 ConstMap<typename Graph::Edge,bool> > Parent;
540 ConstMap<typename Graph::Edge, bool> const_true_map;
542 NodeSubGraphAdaptor(Graph& _graph, NodeFilterMap& _node_filter_map) :
543 Parent(), const_true_map(true) {
544 Parent::setGraph(_graph);
545 Parent::setNodeFilterMap(_node_filter_map);
546 Parent::setEdgeFilterMap(const_true_map);
551 ///\brief An adaptor for hiding edges from a graph.
553 ///\warning Graph adaptors are in even more experimental state
554 ///than the other parts of the lib. Use them at you own risk.
556 ///An adaptor for hiding edges from a graph.
557 ///This adaptor specializes SubGraphAdaptor in the way that
559 ///can be filtered. The usefulness of this adaptor is demonstrated in the
560 ///problem of searching a maximum number of edge-disjoint shortest paths
562 ///two nodes \c s and \c t. Shortest here means being shortest w.r.t.
563 ///non-negative edge-lengths. Note that
564 ///the comprehension of the presented solution
565 ///need's some elementary knowledge from combinatorial optimization.
567 ///If a single shortest path is to be
568 ///searched between \c s and \c t, then this can be done easily by
569 ///applying the Dijkstra algorithm. What happens, if a maximum number of
570 ///edge-disjoint shortest paths is to be computed. It can be proved that an
571 ///edge can be in a shortest path if and only
572 ///if it is tight with respect to
573 ///the potential function computed by Dijkstra.
574 ///Moreover, any path containing
575 ///only such edges is a shortest one.
576 ///Thus we have to compute a maximum number
577 ///of edge-disjoint paths between \c s and \c t in
578 ///the graph which has edge-set
579 ///all the tight edges. The computation will be demonstrated
581 ///graph, which is read from the dimacs file \c sub_graph_adaptor_demo.dim.
582 ///The full source code is available in \ref sub_graph_adaptor_demo.cc.
583 ///If you are interested in more demo programs, you can use
584 ///\ref dim_to_dot.cc to generate .dot files from dimacs files.
585 ///The .dot file of the following figure was generated by
586 ///the demo program \ref dim_to_dot.cc.
589 ///digraph lemon_dot_example {
590 ///node [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
591 ///n0 [ label="0 (s)" ];
597 ///n6 [ label="6 (t)" ];
598 ///edge [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
599 ///n5 -> n6 [ label="9, length:4" ];
600 ///n4 -> n6 [ label="8, length:2" ];
601 ///n3 -> n5 [ label="7, length:1" ];
602 ///n2 -> n5 [ label="6, length:3" ];
603 ///n2 -> n6 [ label="5, length:5" ];
604 ///n2 -> n4 [ label="4, length:2" ];
605 ///n1 -> n4 [ label="3, length:3" ];
606 ///n0 -> n3 [ label="2, length:1" ];
607 ///n0 -> n2 [ label="1, length:2" ];
608 ///n0 -> n1 [ label="0, length:3" ];
615 ///LengthMap length(g);
617 ///readDimacs(std::cin, g, length, s, t);
619 ///cout << "edges with lengths (of form id, source--length->target): " << endl;
620 ///for(EdgeIt e(g); e!=INVALID; ++e)
621 /// cout << g.id(e) << ", " << g.id(g.source(e)) << "--"
622 /// << length[e] << "->" << g.id(g.target(e)) << endl;
624 ///cout << "s: " << g.id(s) << " t: " << g.id(t) << endl;
626 ///Next, the potential function is computed with Dijkstra.
628 ///typedef Dijkstra<Graph, LengthMap> Dijkstra;
629 ///Dijkstra dijkstra(g, length);
632 ///Next, we consrtruct a map which filters the edge-set to the tight edges.
634 ///typedef TightEdgeFilterMap<Graph, const Dijkstra::DistMap, LengthMap>
636 ///TightEdgeFilter tight_edge_filter(g, dijkstra.distMap(), length);
638 ///typedef EdgeSubGraphAdaptor<Graph, TightEdgeFilter> SubGW;
639 ///SubGW gw(g, tight_edge_filter);
641 ///Then, the maximum nimber of edge-disjoint \c s-\c t paths are computed
642 ///with a max flow algorithm Preflow.
644 ///ConstMap<Edge, int> const_1_map(1);
645 ///Graph::EdgeMap<int> flow(g, 0);
647 ///Preflow<SubGW, int, ConstMap<Edge, int>, Graph::EdgeMap<int> >
648 /// preflow(gw, s, t, const_1_map, flow);
651 ///Last, the output is:
653 ///cout << "maximum number of edge-disjoint shortest path: "
654 /// << preflow.flowValue() << endl;
655 ///cout << "edges of the maximum number of edge-disjoint shortest s-t paths: "
657 ///for(EdgeIt e(g); e!=INVALID; ++e)
659 /// cout << " " << g.id(g.source(e)) << "--"
660 /// << length[e] << "->" << g.id(g.target(e)) << endl;
662 ///The program has the following (expected :-)) output:
664 ///edges with lengths (of form id, source--length->target):
676 ///maximum number of edge-disjoint shortest path: 2
677 ///edges of the maximum number of edge-disjoint shortest s-t paths:
686 ///\author Marton Makai
687 template<typename Graph, typename EdgeFilterMap>
688 class EdgeSubGraphAdaptor :
689 public SubGraphAdaptor<Graph, ConstMap<typename Graph::Node,bool>,
690 EdgeFilterMap, false> {
692 typedef SubGraphAdaptor<Graph, ConstMap<typename Graph::Node,bool>,
693 EdgeFilterMap, false> Parent;
695 ConstMap<typename Graph::Node, bool> const_true_map;
697 EdgeSubGraphAdaptor(Graph& _graph, EdgeFilterMap& _edge_filter_map) :
698 Parent(), const_true_map(true) {
699 Parent::setGraph(_graph);
700 Parent::setNodeFilterMap(const_true_map);
701 Parent::setEdgeFilterMap(_edge_filter_map);
705 template <typename _Graph>
706 class UGraphAdaptorBase :
707 public UGraphExtender<GraphAdaptorBase<_Graph> > {
709 typedef _Graph Graph;
710 typedef UGraphExtender<GraphAdaptorBase<_Graph> > Parent;
712 UGraphAdaptorBase() : Parent() { }
714 typedef typename Parent::UEdge UEdge;
715 typedef typename Parent::Edge Edge;
717 template <typename T>
720 const UGraphAdaptorBase<_Graph>* g;
721 template <typename TT> friend class EdgeMap;
722 typename _Graph::template EdgeMap<T> forward_map, backward_map;
727 EdgeMap(const UGraphAdaptorBase<_Graph>& _g) : g(&_g),
728 forward_map(*(g->graph)), backward_map(*(g->graph)) { }
730 EdgeMap(const UGraphAdaptorBase<_Graph>& _g, T a) : g(&_g),
731 forward_map(*(g->graph), a), backward_map(*(g->graph), a) { }
733 void set(Edge e, T a) {
735 forward_map.set(e, a);
737 backward_map.set(e, a);
740 T operator[](Edge e) const {
742 return forward_map[e];
744 return backward_map[e];
748 template <typename T>
750 template <typename TT> friend class UEdgeMap;
751 typename _Graph::template EdgeMap<T> map;
756 UEdgeMap(const UGraphAdaptorBase<_Graph>& g) :
759 UEdgeMap(const UGraphAdaptorBase<_Graph>& g, T a) :
760 map(*(g.graph), a) { }
762 void set(UEdge e, T a) {
766 T operator[](UEdge e) const {
773 ///\brief An undirected graph is made from a directed graph by an adaptor
774 ///\ingroup graph_adaptors
776 /// Undocumented, untested!!!
777 /// If somebody knows nice demo application, let's polulate it.
779 /// \author Marton Makai
780 template<typename _Graph>
781 class UGraphAdaptor :
782 public IterableUGraphExtender<
783 UGraphAdaptorBase<_Graph> > {
785 typedef _Graph Graph;
786 typedef IterableUGraphExtender<
787 UGraphAdaptorBase<_Graph> > Parent;
791 UGraphAdaptor(_Graph& _graph) {
797 template <typename _Graph,
798 typename ForwardFilterMap, typename BackwardFilterMap>
799 class SubBidirGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
801 typedef _Graph Graph;
802 typedef GraphAdaptorBase<_Graph> Parent;
804 ForwardFilterMap* forward_filter;
805 BackwardFilterMap* backward_filter;
806 SubBidirGraphAdaptorBase() : Parent(),
807 forward_filter(0), backward_filter(0) { }
809 void setForwardFilterMap(ForwardFilterMap& _forward_filter) {
810 forward_filter=&_forward_filter;
812 void setBackwardFilterMap(BackwardFilterMap& _backward_filter) {
813 backward_filter=&_backward_filter;
817 // SubGraphAdaptorBase(Graph& _graph,
818 // NodeFilterMap& _node_filter_map,
819 // EdgeFilterMap& _edge_filter_map) :
821 // node_filter_map(&node_filter_map),
822 // edge_filter_map(&edge_filter_map) { }
824 typedef typename Parent::Node Node;
825 typedef typename _Graph::Edge GraphEdge;
826 template <typename T> class EdgeMap;
827 // SubBidirGraphAdaptorBase<..., ..., ...>::Edge is inherited from
828 // _Graph::Edge. It contains an extra bool flag which is true
829 // if and only if the
830 // edge is the backward version of the original edge.
831 class Edge : public _Graph::Edge {
832 friend class SubBidirGraphAdaptorBase<
833 Graph, ForwardFilterMap, BackwardFilterMap>;
834 template<typename T> friend class EdgeMap;
836 bool backward; //true, iff backward
839 // \todo =false is needed, or causes problems?
840 // If \c _backward is false, then we get an edge corresponding to the
841 // original one, otherwise its oppositely directed pair is obtained.
842 Edge(const typename _Graph::Edge& e, bool _backward/*=false*/) :
843 _Graph::Edge(e), backward(_backward) { }
844 Edge(Invalid i) : _Graph::Edge(i), backward(true) { }
845 bool operator==(const Edge& v) const {
846 return (this->backward==v.backward &&
847 static_cast<typename _Graph::Edge>(*this)==
848 static_cast<typename _Graph::Edge>(v));
850 bool operator!=(const Edge& v) const {
851 return (this->backward!=v.backward ||
852 static_cast<typename _Graph::Edge>(*this)!=
853 static_cast<typename _Graph::Edge>(v));
857 void first(Node& i) const {
861 void first(Edge& i) const {
864 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
865 !(*forward_filter)[i]) Parent::next(i);
866 if (*static_cast<GraphEdge*>(&i)==INVALID) {
869 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
870 !(*backward_filter)[i]) Parent::next(i);
874 void firstIn(Edge& i, const Node& n) const {
875 Parent::firstIn(i, n);
877 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
878 !(*forward_filter)[i]) Parent::nextIn(i);
879 if (*static_cast<GraphEdge*>(&i)==INVALID) {
880 Parent::firstOut(i, n);
882 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
883 !(*backward_filter)[i]) Parent::nextOut(i);
887 void firstOut(Edge& i, const Node& n) const {
888 Parent::firstOut(i, n);
890 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
891 !(*forward_filter)[i]) Parent::nextOut(i);
892 if (*static_cast<GraphEdge*>(&i)==INVALID) {
893 Parent::firstIn(i, n);
895 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
896 !(*backward_filter)[i]) Parent::nextIn(i);
900 void next(Node& i) const {
904 void next(Edge& i) const {
907 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
908 !(*forward_filter)[i]) Parent::next(i);
909 if (*static_cast<GraphEdge*>(&i)==INVALID) {
912 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
913 !(*backward_filter)[i]) Parent::next(i);
917 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
918 !(*backward_filter)[i]) Parent::next(i);
922 void nextIn(Edge& i) const {
924 Node n=Parent::target(i);
926 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
927 !(*forward_filter)[i]) Parent::nextIn(i);
928 if (*static_cast<GraphEdge*>(&i)==INVALID) {
929 Parent::firstOut(i, n);
931 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
932 !(*backward_filter)[i]) Parent::nextOut(i);
936 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
937 !(*backward_filter)[i]) Parent::nextOut(i);
941 void nextOut(Edge& i) const {
943 Node n=Parent::source(i);
945 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
946 !(*forward_filter)[i]) Parent::nextOut(i);
947 if (*static_cast<GraphEdge*>(&i)==INVALID) {
948 Parent::firstIn(i, n);
950 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
951 !(*backward_filter)[i]) Parent::nextIn(i);
955 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
956 !(*backward_filter)[i]) Parent::nextIn(i);
960 Node source(Edge e) const {
961 return ((!e.backward) ? this->graph->source(e) : this->graph->target(e)); }
962 Node target(Edge e) const {
963 return ((!e.backward) ? this->graph->target(e) : this->graph->source(e)); }
965 /// Gives back the opposite edge.
969 Edge opposite(const Edge& e) const {
971 f.backward=!f.backward;
977 /// \warning This is a linear time operation and works only if
978 /// \c Graph::EdgeIt is defined.
980 int edgeNum() const {
983 for (first(e); e!=INVALID; next(e)) ++i;
987 bool forward(const Edge& e) const { return !e.backward; }
988 bool backward(const Edge& e) const { return e.backward; }
992 /// \c SubBidirGraphAdaptorBase<..., ..., ...>::EdgeMap contains two
993 /// _Graph::EdgeMap one for the forward edges and
994 /// one for the backward edges.
995 template <typename T>
997 template <typename TT> friend class EdgeMap;
998 typename _Graph::template EdgeMap<T> forward_map, backward_map;
1003 EdgeMap(const SubBidirGraphAdaptorBase<_Graph,
1004 ForwardFilterMap, BackwardFilterMap>& g) :
1005 forward_map(*(g.graph)), backward_map(*(g.graph)) { }
1007 EdgeMap(const SubBidirGraphAdaptorBase<_Graph,
1008 ForwardFilterMap, BackwardFilterMap>& g, T a) :
1009 forward_map(*(g.graph), a), backward_map(*(g.graph), a) { }
1011 void set(Edge e, T a) {
1013 forward_map.set(e, a);
1015 backward_map.set(e, a);
1018 // typename _Graph::template EdgeMap<T>::ConstReference
1019 // operator[](Edge e) const {
1021 // return forward_map[e];
1023 // return backward_map[e];
1026 // typename _Graph::template EdgeMap<T>::Reference
1027 T operator[](Edge e) const {
1029 return forward_map[e];
1031 return backward_map[e];
1035 forward_map.update();
1036 backward_map.update();
1043 ///\brief An adaptor for composing a subgraph of a
1044 /// bidirected graph made from a directed one.
1045 ///\ingroup graph_adaptors
1047 /// An adaptor for composing a subgraph of a
1048 /// bidirected graph made from a directed one.
1050 ///\warning Graph adaptors are in even more experimental state
1052 ///parts of the lib. Use them at you own risk.
1054 /// Let \f$ G=(V, A) \f$ be a directed graph and for each directed edge
1055 ///\f$ e\in A \f$, let \f$ \bar e \f$ denote the edge obtained by
1056 /// reversing its orientation. We are given moreover two bool valued
1057 /// maps on the edge-set,
1058 ///\f$ forward\_filter \f$, and \f$ backward\_filter \f$.
1059 /// SubBidirGraphAdaptor implements the graph structure with node-set
1060 ///\f$ V \f$ and edge-set
1061 ///\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$.
1062 /// The purpose of writing + instead of union is because parallel
1063 /// edges can arise. (Similarly, antiparallel edges also can arise).
1064 /// In other words, a subgraph of the bidirected graph obtained, which
1065 /// is given by orienting the edges of the original graph in both directions.
1066 /// As the oppositely directed edges are logically different,
1067 /// the maps are able to attach different values for them.
1069 /// An example for such a construction is \c RevGraphAdaptor where the
1070 /// forward_filter is everywhere false and the backward_filter is
1071 /// everywhere true. We note that for sake of efficiency,
1072 /// \c RevGraphAdaptor is implemented in a different way.
1073 /// But BidirGraphAdaptor is obtained from
1074 /// SubBidirGraphAdaptor by considering everywhere true
1075 /// valued maps both for forward_filter and backward_filter.
1077 /// The most important application of SubBidirGraphAdaptor
1078 /// is ResGraphAdaptor, which stands for the residual graph in directed
1079 /// flow and circulation problems.
1080 /// As adaptors usually, the SubBidirGraphAdaptor implements the
1081 /// above mentioned graph structure without its physical storage,
1082 /// that is the whole stuff is stored in constant memory.
1083 template<typename _Graph,
1084 typename ForwardFilterMap, typename BackwardFilterMap>
1085 class SubBidirGraphAdaptor :
1086 public IterableGraphExtender<
1087 SubBidirGraphAdaptorBase<_Graph, ForwardFilterMap, BackwardFilterMap> > {
1089 typedef _Graph Graph;
1090 typedef IterableGraphExtender<
1091 SubBidirGraphAdaptorBase<
1092 _Graph, ForwardFilterMap, BackwardFilterMap> > Parent;
1094 SubBidirGraphAdaptor() { }
1096 SubBidirGraphAdaptor(_Graph& _graph, ForwardFilterMap& _forward_filter,
1097 BackwardFilterMap& _backward_filter) {
1099 setForwardFilterMap(_forward_filter);
1100 setBackwardFilterMap(_backward_filter);
1106 ///\brief An adaptor for composing bidirected graph from a directed one.
1107 ///\ingroup graph_adaptors
1109 ///\warning Graph adaptors are in even more experimental state
1111 ///parts of the lib. Use them at you own risk.
1113 /// An adaptor for composing bidirected graph from a directed one.
1114 /// A bidirected graph is composed over the directed one without physical
1115 /// storage. As the oppositely directed edges are logically different ones
1116 /// the maps are able to attach different values for them.
1117 template<typename Graph>
1118 class BidirGraphAdaptor :
1119 public SubBidirGraphAdaptor<
1121 ConstMap<typename Graph::Edge, bool>,
1122 ConstMap<typename Graph::Edge, bool> > {
1124 typedef SubBidirGraphAdaptor<
1126 ConstMap<typename Graph::Edge, bool>,
1127 ConstMap<typename Graph::Edge, bool> > Parent;
1129 ConstMap<typename Graph::Edge, bool> cm;
1131 BidirGraphAdaptor() : Parent(), cm(true) {
1132 Parent::setForwardFilterMap(cm);
1133 Parent::setBackwardFilterMap(cm);
1136 BidirGraphAdaptor(Graph& _graph) : Parent(), cm(true) {
1137 Parent::setGraph(_graph);
1138 Parent::setForwardFilterMap(cm);
1139 Parent::setBackwardFilterMap(cm);
1142 int edgeNum() const {
1143 return 2*this->graph->edgeNum();
1148 template<typename Graph, typename Number,
1149 typename CapacityMap, typename FlowMap>
1150 class ResForwardFilter {
1151 // const Graph* graph;
1152 const CapacityMap* capacity;
1153 const FlowMap* flow;
1155 ResForwardFilter(/*const Graph& _graph, */
1156 const CapacityMap& _capacity, const FlowMap& _flow) :
1157 /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
1158 ResForwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
1159 void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
1160 void setFlow(const FlowMap& _flow) { flow=&_flow; }
1161 bool operator[](const typename Graph::Edge& e) const {
1162 return (Number((*flow)[e]) < Number((*capacity)[e]));
1166 template<typename Graph, typename Number,
1167 typename CapacityMap, typename FlowMap>
1168 class ResBackwardFilter {
1169 const CapacityMap* capacity;
1170 const FlowMap* flow;
1172 ResBackwardFilter(/*const Graph& _graph,*/
1173 const CapacityMap& _capacity, const FlowMap& _flow) :
1174 /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
1175 ResBackwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
1176 void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
1177 void setFlow(const FlowMap& _flow) { flow=&_flow; }
1178 bool operator[](const typename Graph::Edge& e) const {
1179 return (Number(0) < Number((*flow)[e]));
1184 ///\brief An adaptor for composing the residual
1185 ///graph for directed flow and circulation problems.
1186 ///\ingroup graph_adaptors
1188 ///An adaptor for composing the residual graph for
1189 ///directed flow and circulation problems.
1190 ///Let \f$ G=(V, A) \f$ be a directed graph and let \f$ F \f$ be a
1191 ///number type. Let moreover
1192 ///\f$ f,c:A\to F \f$, be functions on the edge-set.
1193 ///In the appications of ResGraphAdaptor, \f$ f \f$ usually stands for a flow
1194 ///and \f$ c \f$ for a capacity function.
1195 ///Suppose that a graph instange \c g of type
1196 ///\c ListGraph implements \f$ G \f$.
1200 ///Then RevGraphAdaptor implements the graph structure with node-set
1201 ///\f$ V \f$ and edge-set \f$ A_{forward}\cup A_{backward} \f$, where
1202 ///\f$ A_{forward}=\{uv : uv\in A, f(uv)<c(uv)\} \f$ and
1203 ///\f$ A_{backward}=\{vu : uv\in A, f(uv)>0\} \f$,
1204 ///i.e. the so called residual graph.
1205 ///When we take the union \f$ A_{forward}\cup A_{backward} \f$,
1206 ///multilicities are counted, i.e. if an edge is in both
1207 ///\f$ A_{forward} \f$ and \f$ A_{backward} \f$, then in the adaptor it
1209 ///The following code shows how
1210 ///such an instance can be constructed.
1212 ///typedef ListGraph Graph;
1213 ///Graph::EdgeMap<int> f(g);
1214 ///Graph::EdgeMap<int> c(g);
1215 ///ResGraphAdaptor<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> > gw(g);
1217 ///\author Marton Makai
1219 template<typename Graph, typename Number,
1220 typename CapacityMap, typename FlowMap>
1221 class ResGraphAdaptor :
1222 public SubBidirGraphAdaptor<
1224 ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,
1225 ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > {
1227 typedef SubBidirGraphAdaptor<
1229 ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,
1230 ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > Parent;
1232 const CapacityMap* capacity;
1234 ResForwardFilter<Graph, Number, CapacityMap, FlowMap> forward_filter;
1235 ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> backward_filter;
1236 ResGraphAdaptor() : Parent(),
1237 capacity(0), flow(0) { }
1238 void setCapacityMap(const CapacityMap& _capacity) {
1239 capacity=&_capacity;
1240 forward_filter.setCapacity(_capacity);
1241 backward_filter.setCapacity(_capacity);
1243 void setFlowMap(FlowMap& _flow) {
1245 forward_filter.setFlow(_flow);
1246 backward_filter.setFlow(_flow);
1249 ResGraphAdaptor(Graph& _graph, const CapacityMap& _capacity,
1251 Parent(), capacity(&_capacity), flow(&_flow),
1252 forward_filter(/*_graph,*/ _capacity, _flow),
1253 backward_filter(/*_graph,*/ _capacity, _flow) {
1254 Parent::setGraph(_graph);
1255 Parent::setForwardFilterMap(forward_filter);
1256 Parent::setBackwardFilterMap(backward_filter);
1259 typedef typename Parent::Edge Edge;
1261 void augment(const Edge& e, Number a) const {
1262 if (Parent::forward(e))
1263 flow->set(e, (*flow)[e]+a);
1265 flow->set(e, (*flow)[e]-a);
1268 /// \brief Residual capacity map.
1270 /// In generic residual graphs the residual capacity can be obtained
1274 const ResGraphAdaptor<Graph, Number, CapacityMap, FlowMap>* res_graph;
1276 typedef Number Value;
1278 ResCap(const ResGraphAdaptor<Graph, Number, CapacityMap, FlowMap>&
1279 _res_graph) : res_graph(&_res_graph) { }
1280 Number operator[](const Edge& e) const {
1281 if (res_graph->forward(e))
1282 return (*(res_graph->capacity))[e]-(*(res_graph->flow))[e];
1284 return (*(res_graph->flow))[e];
1288 // KEEP_MAPS(Parent, ResGraphAdaptor);
1293 template <typename _Graph, typename FirstOutEdgesMap>
1294 class ErasingFirstGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
1296 typedef _Graph Graph;
1297 typedef GraphAdaptorBase<_Graph> Parent;
1299 FirstOutEdgesMap* first_out_edges;
1300 ErasingFirstGraphAdaptorBase() : Parent(),
1301 first_out_edges(0) { }
1303 void setFirstOutEdgesMap(FirstOutEdgesMap& _first_out_edges) {
1304 first_out_edges=&_first_out_edges;
1309 typedef typename Parent::Node Node;
1310 typedef typename Parent::Edge Edge;
1312 void firstOut(Edge& i, const Node& n) const {
1313 i=(*first_out_edges)[n];
1316 void erase(const Edge& e) const {
1320 first_out_edges->set(n, f);
1325 ///\brief For blocking flows.
1326 ///\ingroup graph_adaptors
1328 ///\warning Graph adaptors are in even more
1329 ///experimental state than the other
1330 ///parts of the lib. Use them at you own risk.
1332 ///This graph adaptor is used for on-the-fly
1333 ///Dinits blocking flow computations.
1334 ///For each node, an out-edge is stored which is used when the
1336 ///OutEdgeIt& first(OutEdgeIt&, const Node&)
1340 ///\author Marton Makai
1342 template <typename _Graph, typename FirstOutEdgesMap>
1343 class ErasingFirstGraphAdaptor :
1344 public IterableGraphExtender<
1345 ErasingFirstGraphAdaptorBase<_Graph, FirstOutEdgesMap> > {
1347 typedef _Graph Graph;
1348 typedef IterableGraphExtender<
1349 ErasingFirstGraphAdaptorBase<_Graph, FirstOutEdgesMap> > Parent;
1350 ErasingFirstGraphAdaptor(Graph& _graph,
1351 FirstOutEdgesMap& _first_out_edges) {
1353 setFirstOutEdgesMap(_first_out_edges);
1358 template <typename _Graph>
1359 class SplitGraphAdaptorBase
1360 : public GraphAdaptorBase<_Graph> {
1362 typedef GraphAdaptorBase<_Graph> Parent;
1366 template <typename T> class NodeMap;
1367 template <typename T> class EdgeMap;
1370 class Node : public Parent::Node {
1371 friend class SplitGraphAdaptorBase;
1372 template <typename T> friend class NodeMap;
1373 typedef typename Parent::Node NodeParent;
1377 Node(typename Parent::Node _node, bool _entry)
1378 : Parent::Node(_node), entry(_entry) {}
1382 Node(Invalid) : NodeParent(INVALID), entry(true) {}
1384 bool operator==(const Node& node) const {
1385 return NodeParent::operator==(node) && entry == node.entry;
1388 bool operator!=(const Node& node) const {
1389 return !(*this == node);
1392 bool operator<(const Node& node) const {
1393 return NodeParent::operator<(node) ||
1394 (NodeParent::operator==(node) && entry < node.entry);
1398 /// \todo May we want VARIANT/union type
1399 class Edge : public Parent::Edge {
1400 friend class SplitGraphAdaptorBase;
1401 template <typename T> friend class EdgeMap;
1403 typedef typename Parent::Edge EdgeParent;
1404 typedef typename Parent::Node NodeParent;
1407 Edge(const EdgeParent& edge, const NodeParent& node)
1408 : EdgeParent(edge), bind(node) {}
1411 Edge(Invalid) : EdgeParent(INVALID), bind(INVALID) {}
1413 bool operator==(const Edge& edge) const {
1414 return EdgeParent::operator==(edge) && bind == edge.bind;
1417 bool operator!=(const Edge& edge) const {
1418 return !(*this == edge);
1421 bool operator<(const Edge& edge) const {
1422 return EdgeParent::operator<(edge) ||
1423 (EdgeParent::operator==(edge) && bind < edge.bind);
1427 void first(Node& node) const {
1428 Parent::first(node);
1432 void next(Node& node) const {
1441 void first(Edge& edge) const {
1442 Parent::first(edge);
1443 if ((typename Parent::Edge&)edge == INVALID) {
1444 Parent::first(edge.bind);
1446 edge.bind = INVALID;
1450 void next(Edge& edge) const {
1451 if ((typename Parent::Edge&)edge != INVALID) {
1453 if ((typename Parent::Edge&)edge == INVALID) {
1454 Parent::first(edge.bind);
1457 Parent::next(edge.bind);
1461 void firstIn(Edge& edge, const Node& node) const {
1463 Parent::firstIn(edge, node);
1464 edge.bind = INVALID;
1466 (typename Parent::Edge&)edge = INVALID;
1471 void nextIn(Edge& edge) const {
1472 if ((typename Parent::Edge&)edge != INVALID) {
1473 Parent::nextIn(edge);
1475 edge.bind = INVALID;
1479 void firstOut(Edge& edge, const Node& node) const {
1481 Parent::firstOut(edge, node);
1482 edge.bind = INVALID;
1484 (typename Parent::Edge&)edge = INVALID;
1489 void nextOut(Edge& edge) const {
1490 if ((typename Parent::Edge&)edge != INVALID) {
1491 Parent::nextOut(edge);
1493 edge.bind = INVALID;
1497 Node source(const Edge& edge) const {
1498 if ((typename Parent::Edge&)edge != INVALID) {
1499 return Node(Parent::source(edge), false);
1501 return Node(edge.bind, true);
1505 Node target(const Edge& edge) const {
1506 if ((typename Parent::Edge&)edge != INVALID) {
1507 return Node(Parent::target(edge), true);
1509 return Node(edge.bind, false);
1513 static bool entryNode(const Node& node) {
1517 static bool exitNode(const Node& node) {
1521 static Node getEntry(const typename Parent::Node& node) {
1522 return Node(node, true);
1525 static Node getExit(const typename Parent::Node& node) {
1526 return Node(node, false);
1529 static bool originalEdge(const Edge& edge) {
1530 return (typename Parent::Edge&)edge != INVALID;
1533 static bool bindingEdge(const Edge& edge) {
1534 return edge.bind != INVALID;
1537 static Node getBindedNode(const Edge& edge) {
1541 int nodeNum() const {
1542 return Parent::nodeNum() * 2;
1545 typedef CompileTimeAnd<typename Parent::NodeNumTag,
1546 typename Parent::EdgeNumTag> EdgeNumTag;
1548 int edgeNum() const {
1549 return Parent::edgeNum() + Parent::nodeNum();
1552 Edge findEdge(const Node& source, const Node& target,
1553 const Edge& prev = INVALID) const {
1554 if (exitNode(source) && entryNode(target)) {
1555 return Parent::findEdge(source, target, prev);
1557 if (prev == INVALID && entryNode(source) && exitNode(target) &&
1558 (typename Parent::Node&)source == (typename Parent::Node&)target) {
1559 return Edge(INVALID, source);
1566 template <typename T>
1567 class NodeMap : public MapBase<Node, T> {
1568 typedef typename Parent::template NodeMap<T> NodeImpl;
1570 NodeMap(const SplitGraphAdaptorBase& _graph)
1571 : entry(_graph), exit(_graph) {}
1572 NodeMap(const SplitGraphAdaptorBase& _graph, const T& t)
1573 : entry(_graph, t), exit(_graph, t) {}
1575 void set(const Node& key, const T& val) {
1576 if (key.entry) { entry.set(key, val); }
1577 else {exit.set(key, val); }
1580 typename MapTraits<NodeImpl>::ReturnValue
1581 operator[](const Node& key) {
1582 if (key.entry) { return entry[key]; }
1583 else { return exit[key]; }
1586 typename MapTraits<NodeImpl>::ConstReturnValue
1587 operator[](const Node& key) const {
1588 if (key.entry) { return entry[key]; }
1589 else { return exit[key]; }
1593 NodeImpl entry, exit;
1596 template <typename T>
1597 class EdgeMap : public MapBase<Edge, T> {
1598 typedef typename Parent::template NodeMap<T> NodeImpl;
1599 typedef typename Parent::template EdgeMap<T> EdgeImpl;
1601 EdgeMap(const SplitGraphAdaptorBase& _graph)
1602 : bind(_graph), orig(_graph) {}
1603 EdgeMap(const SplitGraphAdaptorBase& _graph, const T& t)
1604 : bind(_graph, t), orig(_graph, t) {}
1606 void set(const Edge& key, const T& val) {
1607 if ((typename Parent::Edge&)key != INVALID) { orig.set(key, val); }
1608 else {bind.set(key.bind, val); }
1611 typename MapTraits<EdgeImpl>::ReturnValue
1612 operator[](const Edge& key) {
1613 if ((typename Parent::Edge&)key != INVALID) { return orig[key]; }
1614 else {return bind[key.bind]; }
1617 typename MapTraits<EdgeImpl>::ConstReturnValue
1618 operator[](const Edge& key) const {
1619 if ((typename Parent::Edge&)key != INVALID) { return orig[key]; }
1620 else {return bind[key.bind]; }
1624 typename Parent::template NodeMap<T> bind;
1625 typename Parent::template EdgeMap<T> orig;
1628 template <typename EntryMap, typename ExitMap>
1629 class CombinedNodeMap : public MapBase<Node, typename EntryMap::Value> {
1631 typedef MapBase<Node, typename EntryMap::Value> Parent;
1633 typedef typename Parent::Key Key;
1634 typedef typename Parent::Value Value;
1636 CombinedNodeMap(EntryMap& _entryMap, ExitMap& _exitMap)
1637 : entryMap(_entryMap), exitMap(_exitMap) {}
1639 Value& operator[](const Key& key) {
1641 return entryMap[key];
1643 return exitMap[key];
1647 Value operator[](const Key& key) const {
1649 return entryMap[key];
1651 return exitMap[key];
1655 void set(const Key& key, const Value& value) {
1657 entryMap.set(key, value);
1659 exitMap.set(key, value);
1670 template <typename EdgeMap, typename NodeMap>
1671 class CombinedEdgeMap : public MapBase<Edge, typename EdgeMap::Value> {
1673 typedef MapBase<Edge, typename EdgeMap::Value> Parent;
1675 typedef typename Parent::Key Key;
1676 typedef typename Parent::Value Value;
1678 CombinedEdgeMap(EdgeMap& _edgeMap, NodeMap& _nodeMap)
1679 : edgeMap(_edgeMap), nodeMap(_nodeMap) {}
1681 void set(const Edge& edge, const Value& val) {
1682 if (SplitGraphAdaptorBase::originalEdge(edge)) {
1683 edgeMap.set(edge, val);
1685 nodeMap.set(SplitGraphAdaptorBase::bindedNode(edge), val);
1689 Value operator[](const Key& edge) const {
1690 if (SplitGraphAdaptorBase::originalEdge(edge)) {
1691 return edgeMap[edge];
1693 return nodeMap[SplitGraphAdaptorBase::bindedNode(edge)];
1697 Value& operator[](const Key& edge) {
1698 if (SplitGraphAdaptorBase::originalEdge(edge)) {
1699 return edgeMap[edge];
1701 return nodeMap[SplitGraphAdaptorBase::bindedNode(edge)];
1712 template <typename _Graph>
1713 class SplitGraphAdaptor
1714 : public IterableGraphExtender<SplitGraphAdaptorBase<_Graph> > {
1716 typedef IterableGraphExtender<SplitGraphAdaptorBase<_Graph> > Parent;
1718 SplitGraphAdaptor(_Graph& graph) {
1719 Parent::setGraph(graph);
1727 #endif //LEMON_GRAPH_ADAPTOR_H