2 * lemon/graph_adaptor.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 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/undir_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 NodeMap(const GraphAdaptorBase<_Graph>& gw) : Parent(*gw.graph) { }
131 NodeMap(const GraphAdaptorBase<_Graph>& gw, const _Value& value)
132 : Parent(*gw.graph, value) { }
135 template <typename _Value>
136 class EdgeMap : public _Graph::template EdgeMap<_Value> {
138 typedef typename _Graph::template EdgeMap<_Value> Parent;
139 EdgeMap(const GraphAdaptorBase<_Graph>& gw) : 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 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 /// A graph adaptor which reverses the orientation of the edges.
183 ///\warning Graph adaptors are in even more experimental state than the other
184 ///parts of the lib. Use them at you own risk.
186 /// Let \f$G=(V, A)\f$ be a directed graph and
187 /// suppose that a graph instange \c g of type
188 /// \c ListGraph implements \f$G\f$.
192 /// For each directed edge
193 /// \f$e\in A\f$, let \f$\bar e\f$ denote the edge obtained by
194 /// reversing its orientation.
195 /// Then RevGraphAdaptor implements the graph structure with node-set
196 /// \f$V\f$ and edge-set
197 /// \f$\{\bar e : e\in A \}\f$, i.e. the graph obtained from \f$G\f$ be
198 /// reversing the orientation of its edges. The following code shows how
199 /// such an instance can be constructed.
201 /// RevGraphAdaptor<ListGraph> gw(g);
203 ///\author Marton Makai
204 template<typename _Graph>
205 class RevGraphAdaptor :
206 public IterableGraphExtender<RevGraphAdaptorBase<_Graph> > {
208 typedef _Graph Graph;
209 typedef IterableGraphExtender<
210 RevGraphAdaptorBase<_Graph> > Parent;
212 RevGraphAdaptor() { }
214 RevGraphAdaptor(_Graph& _graph) { setGraph(_graph); }
218 template <typename _Graph, typename NodeFilterMap,
219 typename EdgeFilterMap, bool checked = true>
220 class SubGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
222 typedef _Graph Graph;
223 typedef GraphAdaptorBase<_Graph> Parent;
225 NodeFilterMap* node_filter_map;
226 EdgeFilterMap* edge_filter_map;
227 SubGraphAdaptorBase() : Parent(),
228 node_filter_map(0), edge_filter_map(0) { }
230 void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
231 node_filter_map=&_node_filter_map;
233 void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
234 edge_filter_map=&_edge_filter_map;
239 typedef typename Parent::Node Node;
240 typedef typename Parent::Edge Edge;
242 void first(Node& i) const {
244 while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
247 void first(Edge& i) const {
249 while (i!=INVALID && (!(*edge_filter_map)[i]
250 || !(*node_filter_map)[Parent::source(i)]
251 || !(*node_filter_map)[Parent::target(i)])) Parent::next(i);
254 void firstIn(Edge& i, const Node& n) const {
255 Parent::firstIn(i, n);
256 while (i!=INVALID && (!(*edge_filter_map)[i]
257 || !(*node_filter_map)[Parent::source(i)])) Parent::nextIn(i);
260 void firstOut(Edge& i, const Node& n) const {
261 Parent::firstOut(i, n);
262 while (i!=INVALID && (!(*edge_filter_map)[i]
263 || !(*node_filter_map)[Parent::target(i)])) Parent::nextOut(i);
266 void next(Node& i) const {
268 while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
271 void next(Edge& i) const {
273 while (i!=INVALID && (!(*edge_filter_map)[i]
274 || !(*node_filter_map)[Parent::source(i)]
275 || !(*node_filter_map)[Parent::target(i)])) Parent::next(i);
278 void nextIn(Edge& i) const {
280 while (i!=INVALID && (!(*edge_filter_map)[i]
281 || !(*node_filter_map)[Parent::source(i)])) Parent::nextIn(i);
284 void nextOut(Edge& i) const {
286 while (i!=INVALID && (!(*edge_filter_map)[i]
287 || !(*node_filter_map)[Parent::target(i)])) Parent::nextOut(i);
290 /// This function hides \c n in the graph, i.e. the iteration
291 /// jumps over it. This is done by simply setting the value of \c n
292 /// to be false in the corresponding node-map.
293 void hide(const Node& n) const { node_filter_map->set(n, false); }
295 /// This function hides \c e in the graph, i.e. the iteration
296 /// jumps over it. This is done by simply setting the value of \c e
297 /// to be false in the corresponding edge-map.
298 void hide(const Edge& e) const { edge_filter_map->set(e, false); }
300 /// The value of \c n is set to be true in the node-map which stores
301 /// hide information. If \c n was hidden previuosly, then it is shown
303 void unHide(const Node& n) const { node_filter_map->set(n, true); }
305 /// The value of \c e is set to be true in the edge-map which stores
306 /// hide information. If \c e was hidden previuosly, then it is shown
308 void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
310 /// Returns true if \c n is hidden.
311 bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
313 /// Returns true if \c n is hidden.
314 bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
316 typedef False NodeNumTag;
317 typedef False EdgeNumTag;
320 template <typename _Graph, typename NodeFilterMap, typename EdgeFilterMap>
321 class SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap, false>
322 : public GraphAdaptorBase<_Graph> {
324 typedef _Graph Graph;
325 typedef GraphAdaptorBase<_Graph> Parent;
327 NodeFilterMap* node_filter_map;
328 EdgeFilterMap* edge_filter_map;
329 SubGraphAdaptorBase() : Parent(),
330 node_filter_map(0), edge_filter_map(0) { }
332 void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
333 node_filter_map=&_node_filter_map;
335 void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
336 edge_filter_map=&_edge_filter_map;
341 typedef typename Parent::Node Node;
342 typedef typename Parent::Edge Edge;
344 void first(Node& i) const {
346 while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
349 void first(Edge& i) const {
351 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::next(i);
354 void firstIn(Edge& i, const Node& n) const {
355 Parent::firstIn(i, n);
356 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextIn(i);
359 void firstOut(Edge& i, const Node& n) const {
360 Parent::firstOut(i, n);
361 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i);
364 void next(Node& i) const {
366 while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
368 void next(Edge& i) const {
370 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::next(i);
372 void nextIn(Edge& i) const {
374 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextIn(i);
377 void nextOut(Edge& i) const {
379 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i);
382 /// This function hides \c n in the graph, i.e. the iteration
383 /// jumps over it. This is done by simply setting the value of \c n
384 /// to be false in the corresponding node-map.
385 void hide(const Node& n) const { node_filter_map->set(n, false); }
387 /// This function hides \c e in the graph, i.e. the iteration
388 /// jumps over it. This is done by simply setting the value of \c e
389 /// to be false in the corresponding edge-map.
390 void hide(const Edge& e) const { edge_filter_map->set(e, false); }
392 /// The value of \c n is set to be true in the node-map which stores
393 /// hide information. If \c n was hidden previuosly, then it is shown
395 void unHide(const Node& n) const { node_filter_map->set(n, true); }
397 /// The value of \c e is set to be true in the edge-map which stores
398 /// hide information. If \c e was hidden previuosly, then it is shown
400 void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
402 /// Returns true if \c n is hidden.
403 bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
405 /// Returns true if \c n is hidden.
406 bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
408 typedef False NodeNumTag;
409 typedef False EdgeNumTag;
412 /*! \brief A graph adaptor for hiding nodes and edges from a graph.
414 \warning Graph adaptors are in even more experimental state than the other
415 parts of the lib. Use them at you own risk.
417 SubGraphAdaptor shows the graph with filtered node-set and
418 edge-set. If the \c checked parameter is true then it filters the edgeset
419 to do not get invalid edges without source or target.
420 Let \f$G=(V, A)\f$ be a directed graph
421 and suppose that the graph instance \c g of type ListGraph implements
423 Let moreover \f$b_V\f$ and
424 \f$b_A\f$ be bool-valued functions resp. on the node-set and edge-set.
425 SubGraphAdaptor<...>::NodeIt iterates
426 on the node-set \f$\{v\in V : b_V(v)=true\}\f$ and
427 SubGraphAdaptor<...>::EdgeIt iterates
428 on the edge-set \f$\{e\in A : b_A(e)=true\}\f$. Similarly,
429 SubGraphAdaptor<...>::OutEdgeIt and SubGraphAdaptor<...>::InEdgeIt iterates
430 only on edges leaving and entering a specific node which have true value.
432 If the \c checked template parameter is false then we have to note that
433 the node-iterator cares only the filter on the node-set, and the
434 edge-iterator cares only the filter on the edge-set. This way the edge-map
435 should filter all edges which's source or target is filtered by the
438 typedef ListGraph Graph;
440 typedef Graph::Node Node;
441 typedef Graph::Edge Edge;
442 Node u=g.addNode(); //node of id 0
443 Node v=g.addNode(); //node of id 1
444 Node e=g.addEdge(u, v); //edge of id 0
445 Node f=g.addEdge(v, u); //edge of id 1
446 Graph::NodeMap<bool> nm(g, true);
448 Graph::EdgeMap<bool> em(g, true);
450 typedef SubGraphAdaptor<Graph, Graph::NodeMap<bool>, Graph::EdgeMap<bool> > SubGW;
452 for (SubGW::NodeIt n(gw); n!=INVALID; ++n) std::cout << g.id(n) << std::endl;
453 std::cout << ":-)" << std::endl;
454 for (SubGW::EdgeIt e(gw); e!=INVALID; ++e) std::cout << g.id(e) << std::endl;
456 The output of the above code is the following.
462 Note that \c n is of type \c SubGW::NodeIt, but it can be converted to
463 \c Graph::Node that is why \c g.id(n) can be applied.
465 For other examples see also the documentation of NodeSubGraphAdaptor and
470 template<typename _Graph, typename NodeFilterMap,
471 typename EdgeFilterMap, bool checked = true>
472 class SubGraphAdaptor :
473 public IterableGraphExtender<
474 SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap, checked> > {
476 typedef _Graph Graph;
477 typedef IterableGraphExtender<
478 SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap> > Parent;
480 SubGraphAdaptor() { }
482 SubGraphAdaptor(_Graph& _graph, NodeFilterMap& _node_filter_map,
483 EdgeFilterMap& _edge_filter_map) {
485 setNodeFilterMap(_node_filter_map);
486 setEdgeFilterMap(_edge_filter_map);
492 /*! \brief An adaptor for hiding nodes from a graph.
494 \warning Graph adaptors are in even more experimental state than the other
495 parts of the lib. Use them at you own risk.
497 An adaptor for hiding nodes from a graph.
498 This adaptor specializes SubGraphAdaptor in the way that only the node-set
499 can be filtered. In usual case the checked parameter is true, we get the
500 induced subgraph. But if the checked parameter is false then we can only
501 filter only isolated nodes.
504 template<typename Graph, typename NodeFilterMap, bool checked = true>
505 class NodeSubGraphAdaptor :
506 public SubGraphAdaptor<Graph, NodeFilterMap,
507 ConstMap<typename Graph::Edge,bool>, checked> {
509 typedef SubGraphAdaptor<Graph, NodeFilterMap,
510 ConstMap<typename Graph::Edge,bool> > Parent;
512 ConstMap<typename Graph::Edge, bool> const_true_map;
514 NodeSubGraphAdaptor(Graph& _graph, NodeFilterMap& _node_filter_map) :
515 Parent(), const_true_map(true) {
516 Parent::setGraph(_graph);
517 Parent::setNodeFilterMap(_node_filter_map);
518 Parent::setEdgeFilterMap(const_true_map);
523 /*! \brief An adaptor for hiding edges from a graph.
525 \warning Graph adaptors are in even more experimental state than the other
526 parts of the lib. Use them at you own risk.
528 An adaptor for hiding edges from a graph.
529 This adaptor specializes SubGraphAdaptor in the way that only the edge-set
530 can be filtered. The usefulness of this adaptor is demonstrated in the
531 problem of searching a maximum number of edge-disjoint shortest paths
533 two nodes \c s and \c t. Shortest here means being shortest w.r.t.
534 non-negative edge-lengths. Note that
535 the comprehension of the presented solution
536 need's some elementary knowledge from combinatorial optimization.
538 If a single shortest path is to be
539 searched between \c s and \c t, then this can be done easily by
540 applying the Dijkstra algorithm. What happens, if a maximum number of
541 edge-disjoint shortest paths is to be computed. It can be proved that an
542 edge can be in a shortest path if and only if it is tight with respect to
543 the potential function computed by Dijkstra. Moreover, any path containing
544 only such edges is a shortest one. Thus we have to compute a maximum number
545 of edge-disjoint paths between \c s and \c t in the graph which has edge-set
546 all the tight edges. The computation will be demonstrated on the following
547 graph, which is read from the dimacs file \c sub_graph_adaptor_demo.dim.
548 The full source code is available in \ref sub_graph_adaptor_demo.cc.
549 If you are interested in more demo programs, you can use
550 \ref dim_to_dot.cc to generate .dot files from dimacs files.
551 The .dot file of the following figure was generated by
552 the demo program \ref dim_to_dot.cc.
555 digraph lemon_dot_example {
556 node [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
557 n0 [ label="0 (s)" ];
563 n6 [ label="6 (t)" ];
564 edge [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
565 n5 -> n6 [ label="9, length:4" ];
566 n4 -> n6 [ label="8, length:2" ];
567 n3 -> n5 [ label="7, length:1" ];
568 n2 -> n5 [ label="6, length:3" ];
569 n2 -> n6 [ label="5, length:5" ];
570 n2 -> n4 [ label="4, length:2" ];
571 n1 -> n4 [ label="3, length:3" ];
572 n0 -> n3 [ label="2, length:1" ];
573 n0 -> n2 [ label="1, length:2" ];
574 n0 -> n1 [ label="0, length:3" ];
583 readDimacs(std::cin, g, length, s, t);
585 cout << "edges with lengths (of form id, source--length->target): " << endl;
586 for(EdgeIt e(g); e!=INVALID; ++e)
587 cout << g.id(e) << ", " << g.id(g.source(e)) << "--"
588 << length[e] << "->" << g.id(g.target(e)) << endl;
590 cout << "s: " << g.id(s) << " t: " << g.id(t) << endl;
592 Next, the potential function is computed with Dijkstra.
594 typedef Dijkstra<Graph, LengthMap> Dijkstra;
595 Dijkstra dijkstra(g, length);
598 Next, we consrtruct a map which filters the edge-set to the tight edges.
600 typedef TightEdgeFilterMap<Graph, const Dijkstra::DistMap, LengthMap>
602 TightEdgeFilter tight_edge_filter(g, dijkstra.distMap(), length);
604 typedef EdgeSubGraphAdaptor<Graph, TightEdgeFilter> SubGW;
605 SubGW gw(g, tight_edge_filter);
607 Then, the maximum nimber of edge-disjoint \c s-\c t paths are computed
608 with a max flow algorithm Preflow.
610 ConstMap<Edge, int> const_1_map(1);
611 Graph::EdgeMap<int> flow(g, 0);
613 Preflow<SubGW, int, ConstMap<Edge, int>, Graph::EdgeMap<int> >
614 preflow(gw, s, t, const_1_map, flow);
619 cout << "maximum number of edge-disjoint shortest path: "
620 << preflow.flowValue() << endl;
621 cout << "edges of the maximum number of edge-disjoint shortest s-t paths: "
623 for(EdgeIt e(g); e!=INVALID; ++e)
625 cout << " " << g.id(g.source(e)) << "--"
626 << length[e] << "->" << g.id(g.target(e)) << endl;
628 The program has the following (expected :-)) output:
630 edges with lengths (of form id, source--length->target):
642 maximum number of edge-disjoint shortest path: 2
643 edges of the maximum number of edge-disjoint shortest s-t paths:
654 template<typename Graph, typename EdgeFilterMap>
655 class EdgeSubGraphAdaptor :
656 public SubGraphAdaptor<Graph, ConstMap<typename Graph::Node,bool>,
657 EdgeFilterMap, false> {
659 typedef SubGraphAdaptor<Graph, ConstMap<typename Graph::Node,bool>,
660 EdgeFilterMap, false> Parent;
662 ConstMap<typename Graph::Node, bool> const_true_map;
664 EdgeSubGraphAdaptor(Graph& _graph, EdgeFilterMap& _edge_filter_map) :
665 Parent(), const_true_map(true) {
666 Parent::setGraph(_graph);
667 Parent::setNodeFilterMap(const_true_map);
668 Parent::setEdgeFilterMap(_edge_filter_map);
672 template <typename _Graph>
673 class UndirGraphAdaptorBase :
674 public UndirGraphExtender<GraphAdaptorBase<_Graph> > {
676 typedef _Graph Graph;
677 typedef UndirGraphExtender<GraphAdaptorBase<_Graph> > Parent;
679 UndirGraphAdaptorBase() : Parent() { }
681 typedef typename Parent::UndirEdge UndirEdge;
682 typedef typename Parent::Edge Edge;
684 template <typename T>
687 const UndirGraphAdaptorBase<_Graph>* g;
688 template <typename TT> friend class EdgeMap;
689 typename _Graph::template EdgeMap<T> forward_map, backward_map;
694 EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g) : g(&_g),
695 forward_map(*(g->graph)), backward_map(*(g->graph)) { }
697 EdgeMap(const UndirGraphAdaptorBase<_Graph>& _g, T a) : g(&_g),
698 forward_map(*(g->graph), a), backward_map(*(g->graph), a) { }
700 void set(Edge e, T a) {
702 forward_map.set(e, a);
704 backward_map.set(e, a);
707 T operator[](Edge e) const {
709 return forward_map[e];
711 return backward_map[e];
715 template <typename T>
717 template <typename TT> friend class UndirEdgeMap;
718 typename _Graph::template EdgeMap<T> map;
721 typedef UndirEdge Key;
723 UndirEdgeMap(const UndirGraphAdaptorBase<_Graph>& g) :
726 UndirEdgeMap(const UndirGraphAdaptorBase<_Graph>& g, T a) :
727 map(*(g.graph), a) { }
729 void set(UndirEdge e, T a) {
733 T operator[](UndirEdge e) const {
740 /// \brief An undirected graph is made from a directed graph by an adaptor
742 /// Undocumented, untested!!!
743 /// If somebody knows nice demo application, let's polulate it.
745 /// \author Marton Makai
746 template<typename _Graph>
747 class UndirGraphAdaptor :
748 public IterableUndirGraphExtender<
749 UndirGraphAdaptorBase<_Graph> > {
751 typedef _Graph Graph;
752 typedef IterableUndirGraphExtender<
753 UndirGraphAdaptorBase<_Graph> > Parent;
755 UndirGraphAdaptor() { }
757 UndirGraphAdaptor(_Graph& _graph) {
763 template <typename _Graph,
764 typename ForwardFilterMap, typename BackwardFilterMap>
765 class SubBidirGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
767 typedef _Graph Graph;
768 typedef GraphAdaptorBase<_Graph> Parent;
770 ForwardFilterMap* forward_filter;
771 BackwardFilterMap* backward_filter;
772 SubBidirGraphAdaptorBase() : Parent(),
773 forward_filter(0), backward_filter(0) { }
775 void setForwardFilterMap(ForwardFilterMap& _forward_filter) {
776 forward_filter=&_forward_filter;
778 void setBackwardFilterMap(BackwardFilterMap& _backward_filter) {
779 backward_filter=&_backward_filter;
783 // SubGraphAdaptorBase(Graph& _graph,
784 // NodeFilterMap& _node_filter_map,
785 // EdgeFilterMap& _edge_filter_map) :
787 // node_filter_map(&node_filter_map),
788 // edge_filter_map(&edge_filter_map) { }
790 typedef typename Parent::Node Node;
791 typedef typename _Graph::Edge GraphEdge;
792 template <typename T> class EdgeMap;
793 /// SubBidirGraphAdaptorBase<..., ..., ...>::Edge is inherited from
794 /// _Graph::Edge. It contains an extra bool flag which is true
795 /// if and only if the
796 /// edge is the backward version of the original edge.
797 class Edge : public _Graph::Edge {
798 friend class SubBidirGraphAdaptorBase<
799 Graph, ForwardFilterMap, BackwardFilterMap>;
800 template<typename T> friend class EdgeMap;
802 bool backward; //true, iff backward
805 /// \todo =false is needed, or causes problems?
806 /// If \c _backward is false, then we get an edge corresponding to the
807 /// original one, otherwise its oppositely directed pair is obtained.
808 Edge(const typename _Graph::Edge& e, bool _backward/*=false*/) :
809 _Graph::Edge(e), backward(_backward) { }
810 Edge(Invalid i) : _Graph::Edge(i), backward(true) { }
811 bool operator==(const Edge& v) const {
812 return (this->backward==v.backward &&
813 static_cast<typename _Graph::Edge>(*this)==
814 static_cast<typename _Graph::Edge>(v));
816 bool operator!=(const Edge& v) const {
817 return (this->backward!=v.backward ||
818 static_cast<typename _Graph::Edge>(*this)!=
819 static_cast<typename _Graph::Edge>(v));
823 void first(Node& i) const {
827 void first(Edge& i) const {
830 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
831 !(*forward_filter)[i]) Parent::next(i);
832 if (*static_cast<GraphEdge*>(&i)==INVALID) {
835 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
836 !(*backward_filter)[i]) Parent::next(i);
840 void firstIn(Edge& i, const Node& n) const {
841 Parent::firstIn(i, n);
843 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
844 !(*forward_filter)[i]) Parent::nextIn(i);
845 if (*static_cast<GraphEdge*>(&i)==INVALID) {
846 Parent::firstOut(i, n);
848 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
849 !(*backward_filter)[i]) Parent::nextOut(i);
853 void firstOut(Edge& i, const Node& n) const {
854 Parent::firstOut(i, n);
856 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
857 !(*forward_filter)[i]) Parent::nextOut(i);
858 if (*static_cast<GraphEdge*>(&i)==INVALID) {
859 Parent::firstIn(i, n);
861 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
862 !(*backward_filter)[i]) Parent::nextIn(i);
866 void next(Node& i) const {
870 void next(Edge& i) const {
873 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
874 !(*forward_filter)[i]) Parent::next(i);
875 if (*static_cast<GraphEdge*>(&i)==INVALID) {
878 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
879 !(*backward_filter)[i]) Parent::next(i);
883 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
884 !(*backward_filter)[i]) Parent::next(i);
888 void nextIn(Edge& i) const {
890 Node n=Parent::target(i);
892 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
893 !(*forward_filter)[i]) Parent::nextIn(i);
894 if (*static_cast<GraphEdge*>(&i)==INVALID) {
895 Parent::firstOut(i, n);
897 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
898 !(*backward_filter)[i]) Parent::nextOut(i);
902 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
903 !(*backward_filter)[i]) Parent::nextOut(i);
907 void nextOut(Edge& i) const {
909 Node n=Parent::source(i);
911 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
912 !(*forward_filter)[i]) Parent::nextOut(i);
913 if (*static_cast<GraphEdge*>(&i)==INVALID) {
914 Parent::firstIn(i, n);
916 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
917 !(*backward_filter)[i]) Parent::nextIn(i);
921 while (*static_cast<GraphEdge*>(&i)!=INVALID &&
922 !(*backward_filter)[i]) Parent::nextIn(i);
926 Node source(Edge e) const {
927 return ((!e.backward) ? this->graph->source(e) : this->graph->target(e)); }
928 Node target(Edge e) const {
929 return ((!e.backward) ? this->graph->target(e) : this->graph->source(e)); }
931 /// Gives back the opposite edge.
932 Edge opposite(const Edge& e) const {
934 f.backward=!f.backward;
938 /// \warning This is a linear time operation and works only if
939 /// \c Graph::EdgeIt is defined.
941 int edgeNum() const {
944 for (first(e); e!=INVALID; next(e)) ++i;
948 bool forward(const Edge& e) const { return !e.backward; }
949 bool backward(const Edge& e) const { return e.backward; }
951 template <typename T>
952 /// \c SubBidirGraphAdaptorBase<..., ..., ...>::EdgeMap contains two
953 /// _Graph::EdgeMap one for the forward edges and
954 /// one for the backward edges.
956 template <typename TT> friend class EdgeMap;
957 typename _Graph::template EdgeMap<T> forward_map, backward_map;
962 EdgeMap(const SubBidirGraphAdaptorBase<_Graph,
963 ForwardFilterMap, BackwardFilterMap>& g) :
964 forward_map(*(g.graph)), backward_map(*(g.graph)) { }
966 EdgeMap(const SubBidirGraphAdaptorBase<_Graph,
967 ForwardFilterMap, BackwardFilterMap>& g, T a) :
968 forward_map(*(g.graph), a), backward_map(*(g.graph), a) { }
970 void set(Edge e, T a) {
972 forward_map.set(e, a);
974 backward_map.set(e, a);
977 // typename _Graph::template EdgeMap<T>::ConstReference
978 // operator[](Edge e) const {
980 // return forward_map[e];
982 // return backward_map[e];
985 // typename _Graph::template EdgeMap<T>::Reference
986 T operator[](Edge e) const {
988 return forward_map[e];
990 return backward_map[e];
994 forward_map.update();
995 backward_map.update();
1002 ///\brief An adaptor for composing a subgraph of a
1003 /// bidirected graph made from a directed one.
1005 /// An adaptor for composing a subgraph of a
1006 /// bidirected graph made from a directed one.
1008 ///\warning Graph adaptors are in even more experimental state than the other
1009 ///parts of the lib. Use them at you own risk.
1011 /// Let \f$G=(V, A)\f$ be a directed graph and for each directed edge
1012 /// \f$e\in A\f$, let \f$\bar e\f$ denote the edge obtained by
1013 /// reversing its orientation. We are given moreover two bool valued
1014 /// maps on the edge-set,
1015 /// \f$forward\_filter\f$, and \f$backward\_filter\f$.
1016 /// SubBidirGraphAdaptor implements the graph structure with node-set
1017 /// \f$V\f$ and edge-set
1018 /// \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$.
1019 /// The purpose of writing + instead of union is because parallel
1020 /// edges can arise. (Similarly, antiparallel edges also can arise).
1021 /// In other words, a subgraph of the bidirected graph obtained, which
1022 /// is given by orienting the edges of the original graph in both directions.
1023 /// As the oppositely directed edges are logically different,
1024 /// the maps are able to attach different values for them.
1026 /// An example for such a construction is \c RevGraphAdaptor where the
1027 /// forward_filter is everywhere false and the backward_filter is
1028 /// everywhere true. We note that for sake of efficiency,
1029 /// \c RevGraphAdaptor is implemented in a different way.
1030 /// But BidirGraphAdaptor is obtained from
1031 /// SubBidirGraphAdaptor by considering everywhere true
1032 /// valued maps both for forward_filter and backward_filter.
1034 /// The most important application of SubBidirGraphAdaptor
1035 /// is ResGraphAdaptor, which stands for the residual graph in directed
1036 /// flow and circulation problems.
1037 /// As adaptors usually, the SubBidirGraphAdaptor implements the
1038 /// above mentioned graph structure without its physical storage,
1039 /// that is the whole stuff is stored in constant memory.
1040 template<typename _Graph,
1041 typename ForwardFilterMap, typename BackwardFilterMap>
1042 class SubBidirGraphAdaptor :
1043 public IterableGraphExtender<
1044 SubBidirGraphAdaptorBase<_Graph, ForwardFilterMap, BackwardFilterMap> > {
1046 typedef _Graph Graph;
1047 typedef IterableGraphExtender<
1048 SubBidirGraphAdaptorBase<
1049 _Graph, ForwardFilterMap, BackwardFilterMap> > Parent;
1051 SubBidirGraphAdaptor() { }
1053 SubBidirGraphAdaptor(_Graph& _graph, ForwardFilterMap& _forward_filter,
1054 BackwardFilterMap& _backward_filter) {
1056 setForwardFilterMap(_forward_filter);
1057 setBackwardFilterMap(_backward_filter);
1063 ///\brief An adaptor for composing bidirected graph from a directed one.
1065 ///\warning Graph adaptors are in even more experimental state than the other
1066 ///parts of the lib. Use them at you own risk.
1068 /// An adaptor for composing bidirected graph from a directed one.
1069 /// A bidirected graph is composed over the directed one without physical
1070 /// storage. As the oppositely directed edges are logically different ones
1071 /// the maps are able to attach different values for them.
1072 template<typename Graph>
1073 class BidirGraphAdaptor :
1074 public SubBidirGraphAdaptor<
1076 ConstMap<typename Graph::Edge, bool>,
1077 ConstMap<typename Graph::Edge, bool> > {
1079 typedef SubBidirGraphAdaptor<
1081 ConstMap<typename Graph::Edge, bool>,
1082 ConstMap<typename Graph::Edge, bool> > Parent;
1084 ConstMap<typename Graph::Edge, bool> cm;
1086 BidirGraphAdaptor() : Parent(), cm(true) {
1087 Parent::setForwardFilterMap(cm);
1088 Parent::setBackwardFilterMap(cm);
1091 BidirGraphAdaptor(Graph& _graph) : Parent(), cm(true) {
1092 Parent::setGraph(_graph);
1093 Parent::setForwardFilterMap(cm);
1094 Parent::setBackwardFilterMap(cm);
1097 int edgeNum() const {
1098 return 2*this->graph->edgeNum();
1103 template<typename Graph, typename Number,
1104 typename CapacityMap, typename FlowMap>
1105 class ResForwardFilter {
1106 // const Graph* graph;
1107 const CapacityMap* capacity;
1108 const FlowMap* flow;
1110 ResForwardFilter(/*const Graph& _graph, */
1111 const CapacityMap& _capacity, const FlowMap& _flow) :
1112 /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
1113 ResForwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
1114 void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
1115 void setFlow(const FlowMap& _flow) { flow=&_flow; }
1116 bool operator[](const typename Graph::Edge& e) const {
1117 return (Number((*flow)[e]) < Number((*capacity)[e]));
1121 template<typename Graph, typename Number,
1122 typename CapacityMap, typename FlowMap>
1123 class ResBackwardFilter {
1124 const CapacityMap* capacity;
1125 const FlowMap* flow;
1127 ResBackwardFilter(/*const Graph& _graph,*/
1128 const CapacityMap& _capacity, const FlowMap& _flow) :
1129 /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
1130 ResBackwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
1131 void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
1132 void setFlow(const FlowMap& _flow) { flow=&_flow; }
1133 bool operator[](const typename Graph::Edge& e) const {
1134 return (Number(0) < Number((*flow)[e]));
1139 /*! \brief An adaptor for composing the residual graph for directed flow and circulation problems.
1141 An adaptor for composing the residual graph for directed flow and circulation problems.
1142 Let \f$G=(V, A)\f$ be a directed graph and let \f$F\f$ be a
1143 number type. Let moreover
1144 \f$f,c:A\to F\f$, be functions on the edge-set.
1145 In the appications of ResGraphAdaptor, \f$f\f$ usually stands for a flow
1146 and \f$c\f$ for a capacity function.
1147 Suppose that a graph instange \c g of type
1148 \c ListGraph implements \f$G\f$.
1152 Then RevGraphAdaptor implements the graph structure with node-set
1153 \f$V\f$ and edge-set \f$A_{forward}\cup A_{backward}\f$, where
1154 \f$A_{forward}=\{uv : uv\in A, f(uv)<c(uv)\}\f$ and
1155 \f$A_{backward}=\{vu : uv\in A, f(uv)>0\}\f$,
1156 i.e. the so called residual graph.
1157 When we take the union \f$A_{forward}\cup A_{backward}\f$,
1158 multilicities are counted, i.e. if an edge is in both
1159 \f$A_{forward}\f$ and \f$A_{backward}\f$, then in the adaptor it
1161 The following code shows how
1162 such an instance can be constructed.
1164 typedef ListGraph Graph;
1165 Graph::EdgeMap<int> f(g);
1166 Graph::EdgeMap<int> c(g);
1167 ResGraphAdaptor<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> > gw(g);
1169 \author Marton Makai
1171 template<typename Graph, typename Number,
1172 typename CapacityMap, typename FlowMap>
1173 class ResGraphAdaptor :
1174 public SubBidirGraphAdaptor<
1176 ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,
1177 ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > {
1179 typedef SubBidirGraphAdaptor<
1181 ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,
1182 ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > Parent;
1184 const CapacityMap* capacity;
1186 ResForwardFilter<Graph, Number, CapacityMap, FlowMap> forward_filter;
1187 ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> backward_filter;
1188 ResGraphAdaptor() : Parent(),
1189 capacity(0), flow(0) { }
1190 void setCapacityMap(const CapacityMap& _capacity) {
1191 capacity=&_capacity;
1192 forward_filter.setCapacity(_capacity);
1193 backward_filter.setCapacity(_capacity);
1195 void setFlowMap(FlowMap& _flow) {
1197 forward_filter.setFlow(_flow);
1198 backward_filter.setFlow(_flow);
1201 ResGraphAdaptor(Graph& _graph, const CapacityMap& _capacity,
1203 Parent(), capacity(&_capacity), flow(&_flow),
1204 forward_filter(/*_graph,*/ _capacity, _flow),
1205 backward_filter(/*_graph,*/ _capacity, _flow) {
1206 Parent::setGraph(_graph);
1207 Parent::setForwardFilterMap(forward_filter);
1208 Parent::setBackwardFilterMap(backward_filter);
1211 typedef typename Parent::Edge Edge;
1213 void augment(const Edge& e, Number a) const {
1214 if (Parent::forward(e))
1215 flow->set(e, (*flow)[e]+a);
1217 flow->set(e, (*flow)[e]-a);
1220 /// \brief Residual capacity map.
1222 /// In generic residual graphs the residual capacity can be obtained
1226 const ResGraphAdaptor<Graph, Number, CapacityMap, FlowMap>* res_graph;
1228 typedef Number Value;
1230 ResCap(const ResGraphAdaptor<Graph, Number, CapacityMap, FlowMap>&
1231 _res_graph) : res_graph(&_res_graph) { }
1232 Number operator[](const Edge& e) const {
1233 if (res_graph->forward(e))
1234 return (*(res_graph->capacity))[e]-(*(res_graph->flow))[e];
1236 return (*(res_graph->flow))[e];
1240 // KEEP_MAPS(Parent, ResGraphAdaptor);
1245 template <typename _Graph, typename FirstOutEdgesMap>
1246 class ErasingFirstGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
1248 typedef _Graph Graph;
1249 typedef GraphAdaptorBase<_Graph> Parent;
1251 FirstOutEdgesMap* first_out_edges;
1252 ErasingFirstGraphAdaptorBase() : Parent(),
1253 first_out_edges(0) { }
1255 void setFirstOutEdgesMap(FirstOutEdgesMap& _first_out_edges) {
1256 first_out_edges=&_first_out_edges;
1261 typedef typename Parent::Node Node;
1262 typedef typename Parent::Edge Edge;
1264 void firstOut(Edge& i, const Node& n) const {
1265 i=(*first_out_edges)[n];
1268 void erase(const Edge& e) const {
1272 first_out_edges->set(n, f);
1277 /// For blocking flows.
1279 ///\warning Graph adaptors are in even more experimental state than the other
1280 ///parts of the lib. Use them at you own risk.
1282 /// This graph adaptor is used for on-the-fly
1283 /// Dinits blocking flow computations.
1284 /// For each node, an out-edge is stored which is used when the
1286 /// OutEdgeIt& first(OutEdgeIt&, const Node&)
1290 /// \author Marton Makai
1291 template <typename _Graph, typename FirstOutEdgesMap>
1292 class ErasingFirstGraphAdaptor :
1293 public IterableGraphExtender<
1294 ErasingFirstGraphAdaptorBase<_Graph, FirstOutEdgesMap> > {
1296 typedef _Graph Graph;
1297 typedef IterableGraphExtender<
1298 ErasingFirstGraphAdaptorBase<_Graph, FirstOutEdgesMap> > Parent;
1299 ErasingFirstGraphAdaptor(Graph& _graph,
1300 FirstOutEdgesMap& _first_out_edges) {
1302 setFirstOutEdgesMap(_first_out_edges);
1307 template <typename _Graph>
1308 class SplitGraphAdaptorBase
1309 : public GraphAdaptorBase<_Graph> {
1311 typedef GraphAdaptorBase<_Graph> Parent;
1315 template <typename T> class NodeMap;
1316 template <typename T> class EdgeMap;
1319 class Node : public Parent::Node {
1320 friend class SplitGraphAdaptorBase;
1321 template <typename T> friend class NodeMap;
1322 typedef typename Parent::Node NodeParent;
1326 Node(typename Parent::Node _node, bool _entry)
1327 : Parent::Node(_node), entry(_entry) {}
1331 Node(Invalid) : NodeParent(INVALID), entry(true) {}
1333 bool operator==(const Node& node) const {
1334 return NodeParent::operator==(node) && entry == node.entry;
1337 bool operator!=(const Node& node) const {
1338 return !(*this == node);
1341 bool operator<(const Node& node) const {
1342 return NodeParent::operator<(node) ||
1343 (NodeParent::operator==(node) && entry < node.entry);
1347 /// \todo May we want VARIANT/union type
1348 class Edge : public Parent::Edge {
1349 friend class SplitGraphAdaptorBase;
1350 template <typename T> friend class EdgeMap;
1352 typedef typename Parent::Edge EdgeParent;
1353 typedef typename Parent::Node NodeParent;
1356 Edge(const EdgeParent& edge, const NodeParent& node)
1357 : EdgeParent(edge), bind(node) {}
1360 Edge(Invalid) : EdgeParent(INVALID), bind(INVALID) {}
1362 bool operator==(const Edge& edge) const {
1363 return EdgeParent::operator==(edge) && bind == edge.bind;
1366 bool operator!=(const Edge& edge) const {
1367 return !(*this == edge);
1370 bool operator<(const Edge& edge) const {
1371 return EdgeParent::operator<(edge) ||
1372 (EdgeParent::operator==(edge) && bind < edge.bind);
1376 void first(Node& node) const {
1377 Parent::first(node);
1381 void next(Node& node) const {
1390 void first(Edge& edge) const {
1391 Parent::first(edge);
1392 if ((typename Parent::Edge&)edge == INVALID) {
1393 Parent::first(edge.bind);
1395 edge.bind = INVALID;
1399 void next(Edge& edge) const {
1400 if ((typename Parent::Edge&)edge != INVALID) {
1402 if ((typename Parent::Edge&)edge == INVALID) {
1403 Parent::first(edge.bind);
1406 Parent::next(edge.bind);
1410 void firstIn(Edge& edge, const Node& node) const {
1412 Parent::firstIn(edge, node);
1413 edge.bind = INVALID;
1415 (typename Parent::Edge&)edge = INVALID;
1420 void nextIn(Edge& edge) const {
1421 if ((typename Parent::Edge&)edge != INVALID) {
1422 Parent::nextIn(edge);
1424 edge.bind = INVALID;
1428 void firstOut(Edge& edge, const Node& node) const {
1430 Parent::firstOut(edge, node);
1431 edge.bind = INVALID;
1433 (typename Parent::Edge&)edge = INVALID;
1438 void nextOut(Edge& edge) const {
1439 if ((typename Parent::Edge&)edge != INVALID) {
1440 Parent::nextOut(edge);
1442 edge.bind = INVALID;
1446 Node source(const Edge& edge) const {
1447 if ((typename Parent::Edge&)edge != INVALID) {
1448 return Node(Parent::source(edge), false);
1450 return Node(edge.bind, true);
1454 Node target(const Edge& edge) const {
1455 if ((typename Parent::Edge&)edge != INVALID) {
1456 return Node(Parent::target(edge), true);
1458 return Node(edge.bind, false);
1462 static bool entryNode(const Node& node) {
1466 static bool exitNode(const Node& node) {
1470 static Node getEntry(const typename Parent::Node& node) {
1471 return Node(node, true);
1474 static Node getExit(const typename Parent::Node& node) {
1475 return Node(node, false);
1478 static bool originalEdge(const Edge& edge) {
1479 return (typename Parent::Edge&)edge != INVALID;
1482 static bool bindingEdge(const Edge& edge) {
1483 return edge.bind != INVALID;
1486 static Node getBindedNode(const Edge& edge) {
1490 int nodeNum() const {
1491 return Parent::nodeNum() * 2;
1494 typedef CompileTimeAnd<typename Parent::NodeNumTag,
1495 typename Parent::EdgeNumTag> EdgeNumTag;
1497 int edgeNum() const {
1498 return Parent::edgeNum() + Parent::nodeNum();
1501 Edge findEdge(const Node& source, const Node& target,
1502 const Edge& prev = INVALID) const {
1503 if (exitNode(source) && entryNode(target)) {
1504 return Parent::findEdge(source, target, prev);
1506 if (prev == INVALID && entryNode(source) && exitNode(target) &&
1507 (typename Parent::Node&)source == (typename Parent::Node&)target) {
1508 return Edge(INVALID, source);
1515 template <typename T>
1516 class NodeMap : public MapBase<Node, T> {
1517 typedef typename Parent::template NodeMap<T> NodeImpl;
1519 NodeMap(const SplitGraphAdaptorBase& _graph)
1520 : entry(_graph), exit(_graph) {}
1521 NodeMap(const SplitGraphAdaptorBase& _graph, const T& t)
1522 : entry(_graph, t), exit(_graph, t) {}
1524 void set(const Node& key, const T& val) {
1525 if (key.entry) { entry.set(key, val); }
1526 else {exit.set(key, val); }
1529 typename ReferenceMapTraits<NodeImpl>::Reference
1530 operator[](const Node& key) {
1531 if (key.entry) { return entry[key]; }
1532 else { return exit[key]; }
1535 T operator[](const Node& key) const {
1536 if (key.entry) { return entry[key]; }
1537 else { return exit[key]; }
1541 NodeImpl entry, exit;
1544 template <typename T>
1545 class EdgeMap : public MapBase<Edge, T> {
1546 typedef typename Parent::template NodeMap<T> NodeImpl;
1547 typedef typename Parent::template EdgeMap<T> EdgeImpl;
1549 EdgeMap(const SplitGraphAdaptorBase& _graph)
1550 : bind(_graph), orig(_graph) {}
1551 EdgeMap(const SplitGraphAdaptorBase& _graph, const T& t)
1552 : bind(_graph, t), orig(_graph, t) {}
1554 void set(const Edge& key, const T& val) {
1555 if ((typename Parent::Edge&)key != INVALID) { orig.set(key, val); }
1556 else {bind.set(key.bind, val); }
1559 typename ReferenceMapTraits<EdgeImpl>::Reference
1560 operator[](const Edge& key) {
1561 if ((typename Parent::Edge&)key != INVALID) { return orig[key]; }
1562 else {return bind[key.bind]; }
1565 T operator[](const Edge& key) const {
1566 if ((typename Parent::Edge&)key != INVALID) { return orig[key]; }
1567 else {return bind[key.bind]; }
1571 typename Parent::template NodeMap<T> bind;
1572 typename Parent::template EdgeMap<T> orig;
1575 template <typename EntryMap, typename ExitMap>
1576 class CombinedNodeMap : public MapBase<Node, typename EntryMap::Value> {
1578 typedef MapBase<Node, typename EntryMap::Value> Parent;
1580 typedef typename Parent::Key Key;
1581 typedef typename Parent::Value Value;
1583 CombinedNodeMap(EntryMap& _entryMap, ExitMap& _exitMap)
1584 : entryMap(_entryMap), exitMap(_exitMap) {}
1586 Value& operator[](const Key& key) {
1588 return entryMap[key];
1590 return exitMap[key];
1594 Value operator[](const Key& key) const {
1596 return entryMap[key];
1598 return exitMap[key];
1602 void set(const Key& key, const Value& value) {
1604 entryMap.set(key, value);
1606 exitMap.set(key, value);
1617 template <typename EdgeMap, typename NodeMap>
1618 class CombinedEdgeMap : public MapBase<Edge, typename EdgeMap::Value> {
1620 typedef MapBase<Edge, typename EdgeMap::Value> Parent;
1622 typedef typename Parent::Key Key;
1623 typedef typename Parent::Value Value;
1625 CombinedEdgeMap(EdgeMap& _edgeMap, NodeMap& _nodeMap)
1626 : edgeMap(_edgeMap), nodeMap(_nodeMap) {}
1628 void set(const Edge& edge, const Value& val) {
1629 if (SplitGraphAdaptorBase::originalEdge(edge)) {
1630 edgeMap.set(edge, val);
1632 nodeMap.set(SplitGraphAdaptorBase::bindedNode(edge), val);
1636 Value operator[](const Key& edge) const {
1637 if (SplitGraphAdaptorBase::originalEdge(edge)) {
1638 return edgeMap[edge];
1640 return nodeMap[SplitGraphAdaptorBase::bindedNode(edge)];
1644 Value& operator[](const Key& edge) {
1645 if (SplitGraphAdaptorBase::originalEdge(edge)) {
1646 return edgeMap[edge];
1648 return nodeMap[SplitGraphAdaptorBase::bindedNode(edge)];
1659 template <typename _Graph>
1660 class SplitGraphAdaptor
1661 : public IterableGraphExtender<SplitGraphAdaptorBase<_Graph> > {
1663 typedef IterableGraphExtender<SplitGraphAdaptorBase<_Graph> > Parent;
1665 SplitGraphAdaptor(_Graph& graph) {
1666 Parent::setGraph(graph);
1672 template <typename _Graph>
1673 class NewEdgeSetAdaptorBase {
1676 typedef _Graph Graph;
1677 typedef typename Graph::Node Node;
1678 typedef typename Graph::NodeIt NodeIt;
1683 int first_out, first_in;
1684 NodeT() : first_out(-1), first_in(-1) {}
1687 class NodesImpl : protected Graph::template NodeMap<NodeT> {
1689 typedef typename Graph::template NodeMap<NodeT> Parent;
1690 typedef NewEdgeSetAdaptorBase<Graph> Adaptor;
1696 NodesImpl(Adaptor& _adaptor, const Graph& _graph)
1697 : Parent(_graph), adaptor(_adaptor) {}
1699 virtual ~NodesImpl() {}
1701 virtual void build() {
1705 virtual void clear() {
1710 virtual void add(const Node& node) {
1715 virtual void erase(const Node& node) {
1716 adaptor._erase(node);
1717 Parent::erase(node);
1720 NodeT& operator[](const Node& node) {
1721 return Parent::operator[](node);
1724 const NodeT& operator[](const Node& node) const {
1725 return Parent::operator[](node);
1733 Node source, target;
1734 int next_out, next_in;
1735 int prev_out, prev_in;
1736 EdgeT() : prev_out(-1), prev_in(-1) {}
1739 std::vector<EdgeT> edges;
1742 int first_free_edge;
1744 virtual void _clear() = 0;
1745 virtual void _add(const Node& node) = 0;
1746 virtual void _erase(const Node& node) = 0;
1750 void initalize(const Graph& _graph, NodesImpl& _nodes) {
1758 friend class NewEdgeSetAdaptorBase<Graph>;
1760 Edge(int _id) : id(_id) {}
1764 Edge(Invalid) : id(-1) {}
1765 bool operator==(const Edge& edge) const { return id == edge.id; }
1766 bool operator!=(const Edge& edge) const { return id != edge.id; }
1767 bool operator<(const Edge& edge) const { return id < edge.id; }
1770 NewEdgeSetAdaptorBase() : first_edge(-1), first_free_edge(-1) {}
1771 virtual ~NewEdgeSetAdaptorBase() {}
1773 Edge addEdge(const Node& source, const Node& target) {
1775 if (first_free_edge == -1) {
1777 edges.push_back(EdgeT());
1779 n = first_free_edge;
1780 first_free_edge = edges[first_free_edge].next_in;
1782 edges[n].next_in = (*nodes)[target].first_in;
1783 (*nodes)[target].first_in = n;
1784 edges[n].next_out = (*nodes)[source].first_out;
1785 (*nodes)[source].first_out = n;
1786 edges[n].source = source;
1787 edges[n].target = target;
1791 void erase(const Edge& edge) {
1793 if (edges[n].prev_in != -1) {
1794 edges[edges[n].prev_in].next_in = edges[n].next_in;
1796 (*nodes)[edges[n].target].first_in = edges[n].next_in;
1798 if (edges[n].next_in != -1) {
1799 edges[edges[n].next_in].prev_in = edges[n].prev_in;
1802 if (edges[n].prev_out != -1) {
1803 edges[edges[n].prev_out].next_out = edges[n].next_out;
1805 (*nodes)[edges[n].source].first_out = edges[n].next_out;
1807 if (edges[n].next_out != -1) {
1808 edges[edges[n].next_out].prev_out = edges[n].prev_out;
1813 void first(Node& node) const {
1817 void next(Node& node) const {
1821 void first(Edge& edge) const {
1823 for (first(node); node != INVALID && (*nodes)[node].first_in == -1;
1825 edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
1828 void next(Edge& edge) const {
1829 if (edges[edge.id].next_in != -1) {
1830 edge.id = edges[edge.id].next_in;
1832 Node node = edges[edge.id].target;
1833 for (next(node); node != INVALID && (*nodes)[node].first_in == -1;
1835 edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
1839 void firstOut(Edge& edge, const Node& node) const {
1840 edge.id = (*nodes)[node].first_out;
1843 void nextOut(Edge& edge) const {
1844 edge.id = edges[edge.id].next_out;
1847 void firstIn(Edge& edge, const Node& node) const {
1848 edge.id = (*nodes)[node].first_in;
1851 void nextIn(Edge& edge) const {
1852 edge.id = edges[edge.id].next_in;
1855 int id(const Node& node) const { return graph->id(node); }
1856 int id(const Edge& edge) const { return edge.id; }
1858 Node fromId(int id, Node) const { return graph->fromId(id, Node()); }
1859 Edge fromId(int id, Edge) const { return Edge(id); }
1861 int maxId(Node) const { return graph->maxId(Node()); };
1862 int maxId(Edge) const { return edges.size() - 1; }
1864 Node source(const Edge& edge) const { return edges[edge.id].source;}
1865 Node target(const Edge& edge) const { return edges[edge.id].target;}
1870 /// \brief Graph adaptor using a node set of another graph and an
1873 /// This structure can be used to establish another graph over a node set
1874 /// of an existing one. The node iterator will go through the nodes of the
1877 /// \param _Graph The type of the graph which shares its node set with
1878 /// this class. Its interface must conform to the \ref concept::StaticGraph
1879 /// "StaticGraph" concept.
1881 /// In the edge extension and removing it conforms to the
1882 /// \ref concept::ExtendableGraph "ExtendableGraph" concept.
1883 template <typename _Graph>
1884 class NewEdgeSetAdaptor :
1885 public ErasableGraphExtender<
1886 ClearableGraphExtender<
1887 ExtendableGraphExtender<
1888 MappableGraphExtender<
1889 IterableGraphExtender<
1890 AlterableGraphExtender<
1891 NewEdgeSetAdaptorBase<_Graph> > > > > > > {
1895 typedef ErasableGraphExtender<
1896 ClearableGraphExtender<
1897 ExtendableGraphExtender<
1898 MappableGraphExtender<
1899 IterableGraphExtender<
1900 AlterableGraphExtender<
1901 NewEdgeSetAdaptorBase<_Graph> > > > > > > Parent;
1904 typedef typename Parent::Node Node;
1905 typedef typename Parent::Edge Edge;
1909 virtual void _clear() {
1910 Parent::edges.clear();
1911 Parent::first_edge = -1;
1912 Parent::first_free_edge = -1;
1913 Parent::getNotifier(Edge()).clear();
1914 Parent::getNotifier(Node()).clear();
1917 virtual void _add(const Node& node) {
1918 Parent::getNotifier(Node()).add(node);
1921 virtual void _erase(const Node& node) {
1923 Parent::firstOut(edge, node);
1924 while (edge != INVALID) {
1925 Parent::erase(edge);
1926 Parent::firstOut(edge, node);
1929 Parent::firstIn(edge, node);
1930 while (edge != INVALID) {
1931 Parent::erase(edge);
1932 Parent::firstIn(edge, node);
1935 Parent::getNotifier(Node()).erase(node);
1939 typedef typename Parent::NodesImpl NodesImpl;
1945 /// \brief Constructor of the adaptor.
1947 /// Constructor of the adaptor.
1948 NewEdgeSetAdaptor(const _Graph& _graph) : nodes(*this, _graph) {
1949 Parent::initalize(_graph, nodes);
1953 Parent::getNotifier(Edge()).clear();
1955 Parent::edges.clear();
1956 Parent::first_edge = -1;
1957 Parent::first_free_edge = -1;
1962 /// \brief Graph adaptor using a node set of another graph and an
1963 /// own undir edge set.
1965 /// This structure can be used to establish another undirected graph over
1966 /// a node set of an existing one. The node iterator will go through the
1967 /// nodes of the original graph.
1969 /// \param _Graph The type of the graph which shares its node set with
1970 /// this class. Its interface must conform to the \ref concept::StaticGraph
1971 /// "StaticGraph" concept.
1973 /// In the edge extension and removing it conforms to the
1974 /// \ref concept::ExtendableGraph "ExtendableGraph" concept.
1975 template <typename _Graph>
1976 class NewUndirEdgeSetAdaptor :
1977 public ErasableUndirGraphExtender<
1978 ClearableUndirGraphExtender<
1979 ExtendableUndirGraphExtender<
1980 MappableUndirGraphExtender<
1981 IterableUndirGraphExtender<
1982 AlterableUndirGraphExtender<
1984 NewEdgeSetAdaptorBase<_Graph> > > > > > > > {
1988 typedef ErasableUndirGraphExtender<
1989 ClearableUndirGraphExtender<
1990 ExtendableUndirGraphExtender<
1991 MappableUndirGraphExtender<
1992 IterableUndirGraphExtender<
1993 AlterableUndirGraphExtender<
1995 NewEdgeSetAdaptorBase<_Graph> > > > > > > > Parent;
1998 typedef typename Parent::Node Node;
1999 typedef typename Parent::Edge Edge;
2000 typedef typename Parent::UndirEdge UndirEdge;
2004 virtual void _clear() {
2005 Parent::edges.clear();
2006 Parent::first_edge = -1;
2007 Parent::first_free_edge = -1;
2008 Parent::getNotifier(Edge()).clear();
2009 Parent::getNotifier(Node()).clear();
2012 virtual void _add(const Node& node) {
2013 Parent::getNotifier(Node()).add(node);
2016 virtual void _erase(const Node& node) {
2018 Parent::firstOut(edge, node);
2019 while (edge != INVALID) {
2020 Parent::erase(edge);
2021 Parent::firstOut(edge, node);
2024 Parent::firstIn(edge, node);
2025 while (edge != INVALID) {
2026 Parent::erase(edge);
2027 Parent::firstIn(edge, node);
2030 Parent::getNotifier(Node()).erase(node);
2033 typedef typename Parent::NodesImpl NodesImpl;
2040 /// \brief Constructor of the adaptor.
2042 /// Constructor of the adaptor.
2043 NewUndirEdgeSetAdaptor(const _Graph& _graph) : nodes(*this, _graph) {
2044 Parent::initalize(_graph, nodes);
2048 Parent::getNotifier(Edge()).clear();
2049 Parent::getNotifier(UndirEdge()).clear();
2051 Parent::edges.clear();
2052 Parent::first_edge = -1;
2053 Parent::first_free_edge = -1;
2062 #endif //LEMON_GRAPH_ADAPTOR_H