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 and Balazs Dezso
30 #include <lemon/bits/invalid.h>
31 #include <lemon/maps.h>
33 #include <lemon/bits/base_extender.h>
34 #include <lemon/bits/graph_adaptor_extender.h>
35 #include <lemon/bits/graph_extender.h>
37 #include <lemon/tolerance.h>
43 ///\brief Base type for the Graph Adaptors
45 ///Base type for the Graph Adaptors
47 ///This is the base type for most of LEMON graph adaptors.
48 ///This class implements a trivial graph adaptor i.e. it only wraps the
49 ///functions and types of the graph. The purpose of this class is to
50 ///make easier implementing graph adaptors. E.g. if an adaptor is
51 ///considered which differs from the wrapped graph only in some of its
52 ///functions or types, then it can be derived from GraphAdaptor,
54 ///differences should be implemented.
56 ///author Marton Makai
57 template<typename _Graph>
58 class GraphAdaptorBase {
61 typedef GraphAdaptorBase Adaptor;
62 typedef Graph ParentGraph;
66 GraphAdaptorBase() : graph(0) { }
67 void setGraph(Graph& _graph) { graph=&_graph; }
70 GraphAdaptorBase(Graph& _graph) : graph(&_graph) { }
72 typedef typename Graph::Node Node;
73 typedef typename Graph::Edge Edge;
75 void first(Node& i) const { graph->first(i); }
76 void first(Edge& i) const { graph->first(i); }
77 void firstIn(Edge& i, const Node& n) const { graph->firstIn(i, n); }
78 void firstOut(Edge& i, const Node& n ) const { graph->firstOut(i, n); }
80 void next(Node& i) const { graph->next(i); }
81 void next(Edge& i) const { graph->next(i); }
82 void nextIn(Edge& i) const { graph->nextIn(i); }
83 void nextOut(Edge& i) const { graph->nextOut(i); }
85 Node source(const Edge& e) const { return graph->source(e); }
86 Node target(const Edge& e) const { return graph->target(e); }
88 typedef NodeNumTagIndicator<Graph> NodeNumTag;
89 int nodeNum() const { return graph->nodeNum(); }
91 typedef EdgeNumTagIndicator<Graph> EdgeNumTag;
92 int edgeNum() const { return graph->edgeNum(); }
94 typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
95 Edge findEdge(const Node& source, const Node& target,
96 const Edge& prev = INVALID) {
97 return graph->findEdge(source, target, prev);
100 Node addNode() const {
101 return Node(graph->addNode());
104 Edge addEdge(const Node& source, const Node& target) const {
105 return Edge(graph->addEdge(source, target));
108 void erase(const Node& i) const { graph->erase(i); }
109 void erase(const Edge& i) const { graph->erase(i); }
111 void clear() const { graph->clear(); }
113 int id(const Node& v) const { return graph->id(v); }
114 int id(const Edge& e) const { return graph->id(e); }
116 Node fromNodeId(int id) const {
117 return graph->fromNodeId(id);
120 Edge fromEdgeId(int id) const {
121 return graph->fromEdgeId(id);
124 int maxNodeId() const {
125 return graph->maxNodeId();
128 int maxEdgeId() const {
129 return graph->maxEdgeId();
132 typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
134 NodeNotifier& getNotifier(Node) const {
135 return graph->getNotifier(Node());
138 typedef typename ItemSetTraits<Graph, Edge>::ItemNotifier EdgeNotifier;
140 EdgeNotifier& getNotifier(Edge) const {
141 return graph->getNotifier(Edge());
144 template <typename _Value>
145 class NodeMap : public Graph::template NodeMap<_Value> {
148 typedef typename Graph::template NodeMap<_Value> Parent;
150 explicit NodeMap(const Adaptor& ga)
151 : Parent(*ga.graph) {}
153 NodeMap(const Adaptor& ga, const _Value& value)
154 : Parent(*ga.graph, value) { }
156 NodeMap& operator=(const NodeMap& cmap) {
157 return operator=<NodeMap>(cmap);
160 template <typename CMap>
161 NodeMap& operator=(const CMap& cmap) {
162 Parent::operator=(cmap);
168 template <typename _Value>
169 class EdgeMap : public Graph::template EdgeMap<_Value> {
172 typedef typename Graph::template EdgeMap<_Value> Parent;
174 explicit EdgeMap(const Adaptor& ga)
175 : Parent(*ga.graph) {}
177 EdgeMap(const Adaptor& ga, const _Value& value)
178 : Parent(*ga.graph, value) {}
180 EdgeMap& operator=(const EdgeMap& cmap) {
181 return operator=<EdgeMap>(cmap);
184 template <typename CMap>
185 EdgeMap& operator=(const CMap& cmap) {
186 Parent::operator=(cmap);
194 ///\ingroup graph_adaptors
196 ///\brief Trivial Graph Adaptor
198 /// This class is an adaptor which does not change the adapted graph.
199 /// It can be used only to test the graph adaptors.
200 template <typename _Graph>
202 public GraphAdaptorExtender<GraphAdaptorBase<_Graph> > {
204 typedef _Graph Graph;
205 typedef GraphAdaptorExtender<GraphAdaptorBase<_Graph> > Parent;
207 GraphAdaptor() : Parent() { }
210 explicit GraphAdaptor(Graph& _graph) { setGraph(_graph); }
213 /// \brief Just gives back a graph adaptor
215 /// Just gives back a graph adaptor which
216 /// should be provide original graph
217 template<typename Graph>
218 GraphAdaptor<const Graph>
219 graphAdaptor(const Graph& graph) {
220 return GraphAdaptor<const Graph>(graph);
224 template <typename _Graph>
225 class RevGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
227 typedef _Graph Graph;
228 typedef GraphAdaptorBase<_Graph> Parent;
230 RevGraphAdaptorBase() : Parent() { }
232 typedef typename Parent::Node Node;
233 typedef typename Parent::Edge Edge;
235 void firstIn(Edge& i, const Node& n) const { Parent::firstOut(i, n); }
236 void firstOut(Edge& i, const Node& n ) const { Parent::firstIn(i, n); }
238 void nextIn(Edge& i) const { Parent::nextOut(i); }
239 void nextOut(Edge& i) const { Parent::nextIn(i); }
241 Node source(const Edge& e) const { return Parent::target(e); }
242 Node target(const Edge& e) const { return Parent::source(e); }
244 typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
245 Edge findEdge(const Node& source, const Node& target,
246 const Edge& prev = INVALID) {
247 return Parent::findEdge(target, source, prev);
253 ///\ingroup graph_adaptors
255 ///\brief A graph adaptor which reverses the orientation of the edges.
257 /// If \c g is defined as
263 /// RevGraphAdaptor<ListGraph> ga(g);
265 /// implements the graph obtained from \c g by
266 /// reversing the orientation of its edges.
268 /// A good example of using RevGraphAdaptor is to decide that the
269 /// directed graph is wheter strongly connected or not. If from one
270 /// node each node is reachable and from each node is reachable this
271 /// node then and just then the graph is strongly connected. Instead of
272 /// this condition we use a little bit different. From one node each node
273 /// ahould be reachable in the graph and in the reversed graph. Now this
274 /// condition can be checked with the Dfs algorithm class and the
275 /// RevGraphAdaptor algorithm class.
277 /// And look at the code:
280 /// bool stronglyConnected(const Graph& graph) {
281 /// if (NodeIt(graph) == INVALID) return true;
282 /// Dfs<Graph> dfs(graph);
283 /// dfs.run(NodeIt(graph));
284 /// for (NodeIt it(graph); it != INVALID; ++it) {
285 /// if (!dfs.reached(it)) {
289 /// typedef RevGraphAdaptor<const Graph> RGraph;
290 /// RGraph rgraph(graph);
291 /// DfsVisit<RGraph> rdfs(rgraph);
292 /// rdfs.run(NodeIt(graph));
293 /// for (NodeIt it(graph); it != INVALID; ++it) {
294 /// if (!rdfs.reached(it)) {
301 template<typename _Graph>
302 class RevGraphAdaptor :
303 public GraphAdaptorExtender<RevGraphAdaptorBase<_Graph> > {
305 typedef _Graph Graph;
306 typedef GraphAdaptorExtender<
307 RevGraphAdaptorBase<_Graph> > Parent;
309 RevGraphAdaptor() { }
311 explicit RevGraphAdaptor(_Graph& _graph) { setGraph(_graph); }
314 /// \brief Just gives back a reverse graph adaptor
316 /// Just gives back a reverse graph adaptor
317 template<typename Graph>
318 RevGraphAdaptor<const Graph>
319 revGraphAdaptor(const Graph& graph) {
320 return RevGraphAdaptor<const Graph>(graph);
323 template <typename _Graph, typename NodeFilterMap,
324 typename EdgeFilterMap, bool checked = true>
325 class SubGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
327 typedef _Graph Graph;
328 typedef SubGraphAdaptorBase Adaptor;
329 typedef GraphAdaptorBase<_Graph> Parent;
331 NodeFilterMap* node_filter_map;
332 EdgeFilterMap* edge_filter_map;
333 SubGraphAdaptorBase() : Parent(),
334 node_filter_map(0), edge_filter_map(0) { }
336 void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
337 node_filter_map=&_node_filter_map;
339 void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
340 edge_filter_map=&_edge_filter_map;
345 typedef typename Parent::Node Node;
346 typedef typename Parent::Edge Edge;
348 void first(Node& i) const {
350 while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
353 void first(Edge& i) const {
355 while (i!=INVALID && (!(*edge_filter_map)[i]
356 || !(*node_filter_map)[Parent::source(i)]
357 || !(*node_filter_map)[Parent::target(i)])) Parent::next(i);
360 void firstIn(Edge& i, const Node& n) const {
361 Parent::firstIn(i, n);
362 while (i!=INVALID && (!(*edge_filter_map)[i]
363 || !(*node_filter_map)[Parent::source(i)])) Parent::nextIn(i);
366 void firstOut(Edge& i, const Node& n) const {
367 Parent::firstOut(i, n);
368 while (i!=INVALID && (!(*edge_filter_map)[i]
369 || !(*node_filter_map)[Parent::target(i)])) Parent::nextOut(i);
372 void next(Node& i) const {
374 while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
377 void next(Edge& i) const {
379 while (i!=INVALID && (!(*edge_filter_map)[i]
380 || !(*node_filter_map)[Parent::source(i)]
381 || !(*node_filter_map)[Parent::target(i)])) Parent::next(i);
384 void nextIn(Edge& i) const {
386 while (i!=INVALID && (!(*edge_filter_map)[i]
387 || !(*node_filter_map)[Parent::source(i)])) Parent::nextIn(i);
390 void nextOut(Edge& i) const {
392 while (i!=INVALID && (!(*edge_filter_map)[i]
393 || !(*node_filter_map)[Parent::target(i)])) Parent::nextOut(i);
398 /// This function hides \c n in the graph, i.e. the iteration
399 /// jumps over it. This is done by simply setting the value of \c n
400 /// to be false in the corresponding node-map.
401 void hide(const Node& n) const { node_filter_map->set(n, false); }
405 /// This function hides \c e in the graph, i.e. the iteration
406 /// jumps over it. This is done by simply setting the value of \c e
407 /// to be false in the corresponding edge-map.
408 void hide(const Edge& e) const { edge_filter_map->set(e, false); }
412 /// The value of \c n is set to be true in the node-map which stores
413 /// hide information. If \c n was hidden previuosly, then it is shown
415 void unHide(const Node& n) const { node_filter_map->set(n, true); }
419 /// The value of \c e is set to be true in the edge-map which stores
420 /// hide information. If \c e was hidden previuosly, then it is shown
422 void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
424 /// Returns true if \c n is hidden.
428 bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
430 /// Returns true if \c n is hidden.
434 bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
436 typedef False NodeNumTag;
437 typedef False EdgeNumTag;
439 typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
440 Edge findEdge(const Node& source, const Node& target,
441 const Edge& prev = INVALID) {
442 if (!(*node_filter_map)[source] || !(*node_filter_map)[target]) {
445 Edge edge = Parent::findEdge(source, target, prev);
446 while (edge != INVALID && !(*edge_filter_map)[edge]) {
447 edge = Parent::findEdge(source, target, edge);
452 template <typename _Value>
454 : public SubMapExtender<Adaptor,
455 typename Parent::template NodeMap<_Value> >
458 typedef Adaptor Graph;
459 typedef SubMapExtender<Adaptor, typename Parent::
460 template NodeMap<_Value> > Parent;
462 NodeMap(const Graph& graph)
464 NodeMap(const Graph& graph, const _Value& value)
465 : Parent(graph, value) {}
467 NodeMap& operator=(const NodeMap& cmap) {
468 return operator=<NodeMap>(cmap);
471 template <typename CMap>
472 NodeMap& operator=(const CMap& cmap) {
473 Parent::operator=(cmap);
478 template <typename _Value>
480 : public SubMapExtender<Adaptor,
481 typename Parent::template EdgeMap<_Value> >
484 typedef Adaptor Graph;
485 typedef SubMapExtender<Adaptor, typename Parent::
486 template EdgeMap<_Value> > Parent;
488 EdgeMap(const Graph& graph)
490 EdgeMap(const Graph& graph, const _Value& value)
491 : Parent(graph, value) {}
493 EdgeMap& operator=(const EdgeMap& cmap) {
494 return operator=<EdgeMap>(cmap);
497 template <typename CMap>
498 EdgeMap& operator=(const CMap& cmap) {
499 Parent::operator=(cmap);
506 template <typename _Graph, typename NodeFilterMap, typename EdgeFilterMap>
507 class SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap, false>
508 : public GraphAdaptorBase<_Graph> {
510 typedef _Graph Graph;
511 typedef SubGraphAdaptorBase Adaptor;
512 typedef GraphAdaptorBase<_Graph> Parent;
514 NodeFilterMap* node_filter_map;
515 EdgeFilterMap* edge_filter_map;
516 SubGraphAdaptorBase() : Parent(),
517 node_filter_map(0), edge_filter_map(0) { }
519 void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
520 node_filter_map=&_node_filter_map;
522 void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
523 edge_filter_map=&_edge_filter_map;
528 typedef typename Parent::Node Node;
529 typedef typename Parent::Edge Edge;
531 void first(Node& i) const {
533 while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
536 void first(Edge& i) const {
538 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::next(i);
541 void firstIn(Edge& i, const Node& n) const {
542 Parent::firstIn(i, n);
543 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextIn(i);
546 void firstOut(Edge& i, const Node& n) const {
547 Parent::firstOut(i, n);
548 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i);
551 void next(Node& i) const {
553 while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i);
555 void next(Edge& i) const {
557 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::next(i);
559 void nextIn(Edge& i) const {
561 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextIn(i);
564 void nextOut(Edge& i) const {
566 while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i);
571 /// This function hides \c n in the graph, i.e. the iteration
572 /// jumps over it. This is done by simply setting the value of \c n
573 /// to be false in the corresponding node-map.
574 void hide(const Node& n) const { node_filter_map->set(n, false); }
578 /// This function hides \c e in the graph, i.e. the iteration
579 /// jumps over it. This is done by simply setting the value of \c e
580 /// to be false in the corresponding edge-map.
581 void hide(const Edge& e) const { edge_filter_map->set(e, false); }
585 /// The value of \c n is set to be true in the node-map which stores
586 /// hide information. If \c n was hidden previuosly, then it is shown
588 void unHide(const Node& n) const { node_filter_map->set(n, true); }
592 /// The value of \c e is set to be true in the edge-map which stores
593 /// hide information. If \c e was hidden previuosly, then it is shown
595 void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
597 /// Returns true if \c n is hidden.
601 bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
603 /// Returns true if \c n is hidden.
607 bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
609 typedef False NodeNumTag;
610 typedef False EdgeNumTag;
612 typedef FindEdgeTagIndicator<Graph> FindEdgeTag;
613 Edge findEdge(const Node& source, const Node& target,
614 const Edge& prev = INVALID) {
615 if (!(*node_filter_map)[source] || !(*node_filter_map)[target]) {
618 Edge edge = Parent::findEdge(source, target, prev);
619 while (edge != INVALID && !(*edge_filter_map)[edge]) {
620 edge = Parent::findEdge(source, target, edge);
625 template <typename _Value>
627 : public SubMapExtender<Adaptor,
628 typename Parent::template NodeMap<_Value> >
631 typedef Adaptor Graph;
632 typedef SubMapExtender<Adaptor, typename Parent::
633 template NodeMap<_Value> > Parent;
635 NodeMap(const Graph& graph)
637 NodeMap(const Graph& graph, const _Value& value)
638 : Parent(graph, value) {}
640 NodeMap& operator=(const NodeMap& cmap) {
641 return operator=<NodeMap>(cmap);
644 template <typename CMap>
645 NodeMap& operator=(const CMap& cmap) {
646 Parent::operator=(cmap);
651 template <typename _Value>
653 : public SubMapExtender<Adaptor,
654 typename Parent::template EdgeMap<_Value> >
657 typedef Adaptor Graph;
658 typedef SubMapExtender<Adaptor, typename Parent::
659 template EdgeMap<_Value> > Parent;
661 EdgeMap(const Graph& graph)
663 EdgeMap(const Graph& graph, const _Value& value)
664 : Parent(graph, value) {}
666 EdgeMap& operator=(const EdgeMap& cmap) {
667 return operator=<EdgeMap>(cmap);
670 template <typename CMap>
671 EdgeMap& operator=(const CMap& cmap) {
672 Parent::operator=(cmap);
679 /// \ingroup graph_adaptors
681 /// \brief A graph adaptor for hiding nodes and edges from a graph.
683 /// SubGraphAdaptor shows the graph with filtered node-set and
684 /// edge-set. If the \c checked parameter is true then it filters the edgeset
685 /// to do not get invalid edges without source or target.
686 /// Let \f$ G=(V, A) \f$ be a directed graph
687 /// and suppose that the graph instance \c g of type ListGraph
688 /// implements \f$ G \f$.
689 /// Let moreover \f$ b_V \f$ and \f$ b_A \f$ be bool-valued functions resp.
690 /// on the node-set and edge-set.
691 /// SubGraphAdaptor<...>::NodeIt iterates
692 /// on the node-set \f$ \{v\in V : b_V(v)=true\} \f$ and
693 /// SubGraphAdaptor<...>::EdgeIt iterates
694 /// on the edge-set \f$ \{e\in A : b_A(e)=true\} \f$. Similarly,
695 /// SubGraphAdaptor<...>::OutEdgeIt and
696 /// SubGraphAdaptor<...>::InEdgeIt iterates
697 /// only on edges leaving and entering a specific node which have true value.
699 /// If the \c checked template parameter is false then we have to note that
700 /// the node-iterator cares only the filter on the node-set, and the
701 /// edge-iterator cares only the filter on the edge-set.
702 /// This way the edge-map
703 /// should filter all edges which's source or target is filtered by the
706 /// typedef ListGraph Graph;
708 /// typedef Graph::Node Node;
709 /// typedef Graph::Edge Edge;
710 /// Node u=g.addNode(); //node of id 0
711 /// Node v=g.addNode(); //node of id 1
712 /// Node e=g.addEdge(u, v); //edge of id 0
713 /// Node f=g.addEdge(v, u); //edge of id 1
714 /// Graph::NodeMap<bool> nm(g, true);
715 /// nm.set(u, false);
716 /// Graph::EdgeMap<bool> em(g, true);
717 /// em.set(e, false);
718 /// typedef SubGraphAdaptor<Graph, Graph::NodeMap<bool>, Graph::EdgeMap<bool> > SubGA;
719 /// SubGA ga(g, nm, em);
720 /// for (SubGA::NodeIt n(ga); n!=INVALID; ++n) std::cout << g.id(n) << std::endl;
721 /// std::cout << ":-)" << std::endl;
722 /// for (SubGA::EdgeIt e(ga); e!=INVALID; ++e) std::cout << g.id(e) << std::endl;
724 /// The output of the above code is the following.
730 /// Note that \c n is of type \c SubGA::NodeIt, but it can be converted to
731 /// \c Graph::Node that is why \c g.id(n) can be applied.
733 /// For other examples see also the documentation of NodeSubGraphAdaptor and
734 /// EdgeSubGraphAdaptor.
736 /// \author Marton Makai
738 template<typename _Graph, typename NodeFilterMap,
739 typename EdgeFilterMap, bool checked = true>
740 class SubGraphAdaptor :
741 public GraphAdaptorExtender<
742 SubGraphAdaptorBase<_Graph, NodeFilterMap, EdgeFilterMap, checked> > {
744 typedef _Graph Graph;
745 typedef GraphAdaptorExtender< SubGraphAdaptorBase<_Graph, NodeFilterMap,
746 EdgeFilterMap, checked> >
750 SubGraphAdaptor() { }
753 SubGraphAdaptor(_Graph& _graph, NodeFilterMap& _node_filter_map,
754 EdgeFilterMap& _edge_filter_map) {
756 setNodeFilterMap(_node_filter_map);
757 setEdgeFilterMap(_edge_filter_map);
762 /// \brief Just gives back a sub graph adaptor
764 /// Just gives back a sub graph adaptor
765 template<typename Graph, typename NodeFilterMap, typename EdgeFilterMap>
766 SubGraphAdaptor<const Graph, NodeFilterMap, EdgeFilterMap>
767 subGraphAdaptor(const Graph& graph,
768 NodeFilterMap& nfm, EdgeFilterMap& efm) {
769 return SubGraphAdaptor<const Graph, NodeFilterMap, EdgeFilterMap>
773 template<typename Graph, typename NodeFilterMap, typename EdgeFilterMap>
774 SubGraphAdaptor<const Graph, const NodeFilterMap, EdgeFilterMap>
775 subGraphAdaptor(const Graph& graph,
776 NodeFilterMap& nfm, EdgeFilterMap& efm) {
777 return SubGraphAdaptor<const Graph, const NodeFilterMap, EdgeFilterMap>
781 template<typename Graph, typename NodeFilterMap, typename EdgeFilterMap>
782 SubGraphAdaptor<const Graph, NodeFilterMap, const EdgeFilterMap>
783 subGraphAdaptor(const Graph& graph,
784 NodeFilterMap& nfm, EdgeFilterMap& efm) {
785 return SubGraphAdaptor<const Graph, NodeFilterMap, const EdgeFilterMap>
789 template<typename Graph, typename NodeFilterMap, typename EdgeFilterMap>
790 SubGraphAdaptor<const Graph, const NodeFilterMap, const EdgeFilterMap>
791 subGraphAdaptor(const Graph& graph,
792 NodeFilterMap& nfm, EdgeFilterMap& efm) {
793 return SubGraphAdaptor<const Graph, const NodeFilterMap,
794 const EdgeFilterMap>(graph, nfm, efm);
799 ///\ingroup graph_adaptors
801 ///\brief An adaptor for hiding nodes from a graph.
803 ///An adaptor for hiding nodes from a graph.
804 ///This adaptor specializes SubGraphAdaptor in the way that only
806 ///can be filtered. In usual case the checked parameter is true, we get the
807 ///induced subgraph. But if the checked parameter is false then we can only
808 ///filter only isolated nodes.
809 ///\author Marton Makai
810 template<typename Graph, typename NodeFilterMap, bool checked = true>
811 class NodeSubGraphAdaptor :
812 public SubGraphAdaptor<Graph, NodeFilterMap,
813 ConstMap<typename Graph::Edge,bool>, checked> {
816 typedef SubGraphAdaptor<Graph, NodeFilterMap,
817 ConstMap<typename Graph::Edge,bool>, checked >
821 ConstMap<typename Graph::Edge, bool> const_true_map;
823 NodeSubGraphAdaptor() : const_true_map(true) {
824 Parent::setEdgeFilterMap(const_true_map);
829 NodeSubGraphAdaptor(Graph& _graph, NodeFilterMap& _node_filter_map) :
830 Parent(), const_true_map(true) {
831 Parent::setGraph(_graph);
832 Parent::setNodeFilterMap(_node_filter_map);
833 Parent::setEdgeFilterMap(const_true_map);
839 /// \brief Just gives back a node sub graph adaptor
841 /// Just gives back a node sub graph adaptor
842 template<typename Graph, typename NodeFilterMap>
843 NodeSubGraphAdaptor<const Graph, NodeFilterMap>
844 nodeSubGraphAdaptor(const Graph& graph, NodeFilterMap& nfm) {
845 return NodeSubGraphAdaptor<const Graph, NodeFilterMap>(graph, nfm);
848 template<typename Graph, typename NodeFilterMap>
849 NodeSubGraphAdaptor<const Graph, const NodeFilterMap>
850 nodeSubGraphAdaptor(const Graph& graph, const NodeFilterMap& nfm) {
851 return NodeSubGraphAdaptor<const Graph, const NodeFilterMap>(graph, nfm);
854 ///\ingroup graph_adaptors
856 ///\brief An adaptor for hiding edges from a graph.
858 ///An adaptor for hiding edges from a graph.
859 ///This adaptor specializes SubGraphAdaptor in the way that
861 ///can be filtered. The usefulness of this adaptor is demonstrated in the
862 ///problem of searching a maximum number of edge-disjoint shortest paths
864 ///two nodes \c s and \c t. Shortest here means being shortest w.r.t.
865 ///non-negative edge-lengths. Note that
866 ///the comprehension of the presented solution
867 ///need's some elementary knowledge from combinatorial optimization.
869 ///If a single shortest path is to be
870 ///searched between \c s and \c t, then this can be done easily by
871 ///applying the Dijkstra algorithm. What happens, if a maximum number of
872 ///edge-disjoint shortest paths is to be computed. It can be proved that an
873 ///edge can be in a shortest path if and only
874 ///if it is tight with respect to
875 ///the potential function computed by Dijkstra.
876 ///Moreover, any path containing
877 ///only such edges is a shortest one.
878 ///Thus we have to compute a maximum number
879 ///of edge-disjoint paths between \c s and \c t in
880 ///the graph which has edge-set
881 ///all the tight edges. The computation will be demonstrated
883 ///graph, which is read from the dimacs file \c sub_graph_adaptor_demo.dim.
884 ///The full source code is available in \ref sub_graph_adaptor_demo.cc.
885 ///If you are interested in more demo programs, you can use
886 ///\ref dim_to_dot.cc to generate .dot files from dimacs files.
887 ///The .dot file of the following figure was generated by
888 ///the demo program \ref dim_to_dot.cc.
891 ///digraph lemon_dot_example {
892 ///node [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
893 ///n0 [ label="0 (s)" ];
899 ///n6 [ label="6 (t)" ];
900 ///edge [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
901 ///n5 -> n6 [ label="9, length:4" ];
902 ///n4 -> n6 [ label="8, length:2" ];
903 ///n3 -> n5 [ label="7, length:1" ];
904 ///n2 -> n5 [ label="6, length:3" ];
905 ///n2 -> n6 [ label="5, length:5" ];
906 ///n2 -> n4 [ label="4, length:2" ];
907 ///n1 -> n4 [ label="3, length:3" ];
908 ///n0 -> n3 [ label="2, length:1" ];
909 ///n0 -> n2 [ label="1, length:2" ];
910 ///n0 -> n1 [ label="0, length:3" ];
917 ///LengthMap length(g);
919 ///readDimacs(std::cin, g, length, s, t);
921 ///cout << "edges with lengths (of form id, source--length->target): " << endl;
922 ///for(EdgeIt e(g); e!=INVALID; ++e)
923 /// cout << g.id(e) << ", " << g.id(g.source(e)) << "--"
924 /// << length[e] << "->" << g.id(g.target(e)) << endl;
926 ///cout << "s: " << g.id(s) << " t: " << g.id(t) << endl;
928 ///Next, the potential function is computed with Dijkstra.
930 ///typedef Dijkstra<Graph, LengthMap> Dijkstra;
931 ///Dijkstra dijkstra(g, length);
934 ///Next, we consrtruct a map which filters the edge-set to the tight edges.
936 ///typedef TightEdgeFilterMap<Graph, const Dijkstra::DistMap, LengthMap>
938 ///TightEdgeFilter tight_edge_filter(g, dijkstra.distMap(), length);
940 ///typedef EdgeSubGraphAdaptor<Graph, TightEdgeFilter> SubGA;
941 ///SubGA ga(g, tight_edge_filter);
943 ///Then, the maximum nimber of edge-disjoint \c s-\c t paths are computed
944 ///with a max flow algorithm Preflow.
946 ///ConstMap<Edge, int> const_1_map(1);
947 ///Graph::EdgeMap<int> flow(g, 0);
949 ///Preflow<SubGA, int, ConstMap<Edge, int>, Graph::EdgeMap<int> >
950 /// preflow(ga, s, t, const_1_map, flow);
953 ///Last, the output is:
955 ///cout << "maximum number of edge-disjoint shortest path: "
956 /// << preflow.flowValue() << endl;
957 ///cout << "edges of the maximum number of edge-disjoint shortest s-t paths: "
959 ///for(EdgeIt e(g); e!=INVALID; ++e)
961 /// cout << " " << g.id(g.source(e)) << "--"
962 /// << length[e] << "->" << g.id(g.target(e)) << endl;
964 ///The program has the following (expected :-)) output:
966 ///edges with lengths (of form id, source--length->target):
978 ///maximum number of edge-disjoint shortest path: 2
979 ///edges of the maximum number of edge-disjoint shortest s-t paths:
988 ///\author Marton Makai
989 template<typename Graph, typename EdgeFilterMap>
990 class EdgeSubGraphAdaptor :
991 public SubGraphAdaptor<Graph, ConstMap<typename Graph::Node,bool>,
992 EdgeFilterMap, false> {
994 typedef SubGraphAdaptor<Graph, ConstMap<typename Graph::Node,bool>,
995 EdgeFilterMap, false> Parent;
997 ConstMap<typename Graph::Node, bool> const_true_map;
999 EdgeSubGraphAdaptor() : const_true_map(true) {
1000 Parent::setNodeFilterMap(const_true_map);
1005 EdgeSubGraphAdaptor(Graph& _graph, EdgeFilterMap& _edge_filter_map) :
1006 Parent(), const_true_map(true) {
1007 Parent::setGraph(_graph);
1008 Parent::setNodeFilterMap(const_true_map);
1009 Parent::setEdgeFilterMap(_edge_filter_map);
1014 /// \brief Just gives back an edge sub graph adaptor
1016 /// Just gives back an edge sub graph adaptor
1017 template<typename Graph, typename EdgeFilterMap>
1018 EdgeSubGraphAdaptor<const Graph, EdgeFilterMap>
1019 edgeSubGraphAdaptor(const Graph& graph, EdgeFilterMap& efm) {
1020 return EdgeSubGraphAdaptor<const Graph, EdgeFilterMap>(graph, efm);
1023 template<typename Graph, typename EdgeFilterMap>
1024 EdgeSubGraphAdaptor<const Graph, const EdgeFilterMap>
1025 edgeSubGraphAdaptor(const Graph& graph, const EdgeFilterMap& efm) {
1026 return EdgeSubGraphAdaptor<const Graph, const EdgeFilterMap>(graph, efm);
1029 template <typename _Graph>
1030 class UndirGraphAdaptorBase :
1031 public UndirGraphExtender<GraphAdaptorBase<_Graph> > {
1033 typedef _Graph Graph;
1034 typedef UndirGraphAdaptorBase Adaptor;
1035 typedef UndirGraphExtender<GraphAdaptorBase<_Graph> > Parent;
1039 UndirGraphAdaptorBase() : Parent() {}
1043 typedef typename Parent::UEdge UEdge;
1044 typedef typename Parent::Edge Edge;
1048 template <typename _Value>
1052 typedef typename _Graph::template EdgeMap<_Value> MapImpl;
1056 typedef typename MapTraits<MapImpl>::ReferenceMapTag ReferenceMapTag;
1058 typedef _Value Value;
1061 EdgeMapBase(const Adaptor& adaptor) :
1062 forward_map(*adaptor.graph), backward_map(*adaptor.graph) {}
1064 EdgeMapBase(const Adaptor& adaptor, const Value& v)
1065 : forward_map(*adaptor.graph, v), backward_map(*adaptor.graph, v) {}
1067 void set(const Edge& e, const Value& a) {
1068 if (Parent::direction(e)) {
1069 forward_map.set(e, a);
1071 backward_map.set(e, a);
1075 typename MapTraits<MapImpl>::ConstReturnValue operator[](Edge e) const {
1076 if (Parent::direction(e)) {
1077 return forward_map[e];
1079 return backward_map[e];
1083 typename MapTraits<MapImpl>::ReturnValue operator[](Edge e) {
1084 if (Parent::direction(e)) {
1085 return forward_map[e];
1087 return backward_map[e];
1093 MapImpl forward_map, backward_map;
1099 template <typename _Value>
1101 : public SubMapExtender<Adaptor, EdgeMapBase<_Value> >
1104 typedef Adaptor Graph;
1105 typedef SubMapExtender<Adaptor, EdgeMapBase<_Value> > Parent;
1107 EdgeMap(const Graph& graph)
1109 EdgeMap(const Graph& graph, const _Value& value)
1110 : Parent(graph, value) {}
1112 EdgeMap& operator=(const EdgeMap& cmap) {
1113 return operator=<EdgeMap>(cmap);
1116 template <typename CMap>
1117 EdgeMap& operator=(const CMap& cmap) {
1118 Parent::operator=(cmap);
1123 template <typename _Value>
1124 class UEdgeMap : public Graph::template EdgeMap<_Value> {
1127 typedef typename Graph::template EdgeMap<_Value> Parent;
1129 explicit UEdgeMap(const Adaptor& ga)
1130 : Parent(*ga.graph) {}
1132 UEdgeMap(const Adaptor& ga, const _Value& value)
1133 : Parent(*ga.graph, value) {}
1135 UEdgeMap& operator=(const UEdgeMap& cmap) {
1136 return operator=<UEdgeMap>(cmap);
1139 template <typename CMap>
1140 UEdgeMap& operator=(const CMap& cmap) {
1141 Parent::operator=(cmap);
1149 template <typename _Graph, typename Enable = void>
1150 class AlterableUndirGraphAdaptor
1151 : public UGraphAdaptorExtender<UndirGraphAdaptorBase<_Graph> > {
1153 typedef UGraphAdaptorExtender<UndirGraphAdaptorBase<_Graph> > Parent;
1157 AlterableUndirGraphAdaptor() : Parent() {}
1161 typedef typename Parent::EdgeNotifier UEdgeNotifier;
1162 typedef InvalidType EdgeNotifier;
1166 template <typename _Graph>
1167 class AlterableUndirGraphAdaptor<
1169 typename enable_if<typename _Graph::EdgeNotifier::Notifier>::type >
1170 : public UGraphAdaptorExtender<UndirGraphAdaptorBase<_Graph> > {
1173 typedef UGraphAdaptorExtender<UndirGraphAdaptorBase<_Graph> > Parent;
1174 typedef _Graph Graph;
1175 typedef typename _Graph::Edge GraphEdge;
1179 AlterableUndirGraphAdaptor()
1180 : Parent(), edge_notifier(*this), edge_notifier_proxy(*this) {}
1182 void setGraph(_Graph& graph) {
1183 Parent::setGraph(graph);
1184 edge_notifier_proxy.setNotifier(graph.getNotifier(GraphEdge()));
1189 ~AlterableUndirGraphAdaptor() {
1190 edge_notifier.clear();
1193 typedef typename Parent::UEdge UEdge;
1194 typedef typename Parent::Edge Edge;
1196 typedef typename Parent::EdgeNotifier UEdgeNotifier;
1198 using Parent::getNotifier;
1200 typedef AlterationNotifier<AlterableUndirGraphAdaptor,
1202 EdgeNotifier& getNotifier(Edge) const { return edge_notifier; }
1206 class NotifierProxy : public Graph::EdgeNotifier::ObserverBase {
1209 typedef typename Graph::EdgeNotifier::ObserverBase Parent;
1210 typedef AlterableUndirGraphAdaptor AdaptorBase;
1212 NotifierProxy(const AdaptorBase& _adaptor)
1213 : Parent(), adaptor(&_adaptor) {
1216 virtual ~NotifierProxy() {
1217 if (Parent::attached()) {
1222 void setNotifier(typename Graph::EdgeNotifier& notifier) {
1223 Parent::attach(notifier);
1229 virtual void add(const GraphEdge& ge) {
1230 std::vector<Edge> edges;
1231 edges.push_back(AdaptorBase::Parent::direct(ge, true));
1232 edges.push_back(AdaptorBase::Parent::direct(ge, false));
1233 adaptor->getNotifier(Edge()).add(edges);
1235 virtual void add(const std::vector<GraphEdge>& ge) {
1236 std::vector<Edge> edges;
1237 for (int i = 0; i < (int)ge.size(); ++i) {
1238 edges.push_back(AdaptorBase::Parent::direct(ge[i], true));
1239 edges.push_back(AdaptorBase::Parent::direct(ge[i], false));
1241 adaptor->getNotifier(Edge()).add(edges);
1243 virtual void erase(const GraphEdge& ge) {
1244 std::vector<Edge> edges;
1245 edges.push_back(AdaptorBase::Parent::direct(ge, true));
1246 edges.push_back(AdaptorBase::Parent::direct(ge, false));
1247 adaptor->getNotifier(Edge()).erase(edges);
1249 virtual void erase(const std::vector<GraphEdge>& ge) {
1250 std::vector<Edge> edges;
1251 for (int i = 0; i < (int)ge.size(); ++i) {
1252 edges.push_back(AdaptorBase::Parent::direct(ge[i], true));
1253 edges.push_back(AdaptorBase::Parent::direct(ge[i], false));
1255 adaptor->getNotifier(Edge()).erase(edges);
1257 virtual void build() {
1258 adaptor->getNotifier(Edge()).build();
1260 virtual void clear() {
1261 adaptor->getNotifier(Edge()).clear();
1264 const AdaptorBase* adaptor;
1268 mutable EdgeNotifier edge_notifier;
1269 NotifierProxy edge_notifier_proxy;
1274 ///\ingroup graph_adaptors
1276 /// \brief An undirected graph is made from a directed graph by an adaptor
1278 /// Undocumented, untested!!!
1279 /// If somebody knows nice demo application, let's polulate it.
1281 /// \author Marton Makai
1282 template<typename _Graph>
1283 class UndirGraphAdaptor : public AlterableUndirGraphAdaptor<_Graph> {
1285 typedef _Graph Graph;
1286 typedef AlterableUndirGraphAdaptor<_Graph> Parent;
1288 UndirGraphAdaptor() { }
1290 UndirGraphAdaptor(_Graph& _graph) {
1294 template <typename _ForwardMap, typename _BackwardMap>
1295 class CombinedEdgeMap {
1298 typedef _ForwardMap ForwardMap;
1299 typedef _BackwardMap BackwardMap;
1301 typedef typename MapTraits<ForwardMap>::ReferenceMapTag ReferenceMapTag;
1303 typedef typename ForwardMap::Value Value;
1304 typedef typename Parent::Edge Key;
1306 CombinedEdgeMap() : forward_map(0), backward_map(0) {}
1308 CombinedEdgeMap(ForwardMap& _forward_map, BackwardMap& _backward_map)
1309 : forward_map(&_forward_map), backward_map(&_backward_map) {}
1311 void set(const Key& e, const Value& a) {
1312 if (Parent::direction(e)) {
1313 forward_map->set(e, a);
1315 backward_map->set(e, a);
1319 typename MapTraits<ForwardMap>::ConstReturnValue
1320 operator[](const Key& e) const {
1321 if (Parent::direction(e)) {
1322 return (*forward_map)[e];
1324 return (*backward_map)[e];
1328 typename MapTraits<ForwardMap>::ReturnValue
1329 operator[](const Key& e) {
1330 if (Parent::direction(e)) {
1331 return (*forward_map)[e];
1333 return (*backward_map)[e];
1337 void setForwardMap(ForwardMap& _forward_map) {
1338 forward_map = &_forward_map;
1341 void setBackwardMap(BackwardMap& _backward_map) {
1342 backward_map = &_backward_map;
1347 ForwardMap* forward_map;
1348 BackwardMap* backward_map;
1354 /// \brief Just gives back an undir graph adaptor
1356 /// Just gives back an undir graph adaptor
1357 template<typename Graph>
1358 UndirGraphAdaptor<const Graph>
1359 undirGraphAdaptor(const Graph& graph) {
1360 return UndirGraphAdaptor<const Graph>(graph);
1363 template<typename Graph, typename Number,
1364 typename CapacityMap, typename FlowMap,
1365 typename Tolerance = Tolerance<Number> >
1366 class ResForwardFilter {
1367 const CapacityMap* capacity;
1368 const FlowMap* flow;
1369 Tolerance tolerance;
1371 typedef typename Graph::Edge Key;
1374 ResForwardFilter(const CapacityMap& _capacity, const FlowMap& _flow,
1375 const Tolerance& _tolerance = Tolerance())
1376 : capacity(&_capacity), flow(&_flow), tolerance(_tolerance) { }
1378 ResForwardFilter(const Tolerance& _tolerance)
1379 : capacity(0), flow(0), tolerance(_tolerance) { }
1381 void setCapacity(const CapacityMap& _capacity) { capacity = &_capacity; }
1382 void setFlow(const FlowMap& _flow) { flow = &_flow; }
1384 bool operator[](const typename Graph::Edge& e) const {
1385 return tolerance.less((*flow)[e], (*capacity)[e]);
1389 template<typename Graph, typename Number,
1390 typename CapacityMap, typename FlowMap,
1391 typename Tolerance = Tolerance<Number> >
1392 class ResBackwardFilter {
1393 const CapacityMap* capacity;
1394 const FlowMap* flow;
1395 Tolerance tolerance;
1397 typedef typename Graph::Edge Key;
1400 ResBackwardFilter(const CapacityMap& _capacity, const FlowMap& _flow,
1401 const Tolerance& _tolerance = Tolerance())
1402 : capacity(&_capacity), flow(&_flow), tolerance(_tolerance) { }
1403 ResBackwardFilter(const Tolerance& _tolerance = Tolerance())
1404 : capacity(0), flow(0), tolerance(_tolerance) { }
1405 void setCapacity(const CapacityMap& _capacity) { capacity = &_capacity; }
1406 void setFlow(const FlowMap& _flow) { flow = &_flow; }
1407 bool operator[](const typename Graph::Edge& e) const {
1408 return tolerance.less(0, Number((*flow)[e]));
1413 ///\ingroup graph_adaptors
1415 ///\brief An adaptor for composing the residual
1416 ///graph for directed flow and circulation problems.
1418 ///An adaptor for composing the residual graph for directed flow and
1419 ///circulation problems. Let \f$ G=(V, A) \f$ be a directed graph
1420 ///and let \f$ F \f$ be a number type. Let moreover \f$ f,c:A\to F \f$,
1421 ///be functions on the edge-set.
1423 ///In the appications of ResGraphAdaptor, \f$ f \f$ usually stands
1424 ///for a flow and \f$ c \f$ for a capacity function. Suppose that a
1425 ///graph instange \c g of type \c ListGraph implements \f$ G \f$.
1431 ///Then RevGraphAdaptor implements the graph structure with node-set
1432 /// \f$ V \f$ and edge-set \f$ A_{forward}\cup A_{backward} \f$,
1433 ///where \f$ A_{forward}=\{uv : uv\in A, f(uv)<c(uv)\} \f$ and
1434 /// \f$ A_{backward}=\{vu : uv\in A, f(uv)>0\} \f$, i.e. the so called
1435 ///residual graph. When we take the union
1436 /// \f$ A_{forward}\cup A_{backward} \f$, multilicities are counted, i.e.
1437 ///if an edge is in both \f$ A_{forward} \f$ and \f$ A_{backward} \f$,
1438 ///then in the adaptor it appears twice. The following code shows how
1439 ///such an instance can be constructed.
1442 /// typedef ListGraph Graph;
1443 /// Graph::EdgeMap<int> f(g);
1444 /// Graph::EdgeMap<int> c(g);
1445 /// ResGraphAdaptor<Graph, int, Graph::EdgeMap<int>, Graph::EdgeMap<int> > ga(g);
1447 ///\author Marton Makai
1449 template<typename Graph, typename Number,
1450 typename CapacityMap, typename FlowMap,
1451 typename Tolerance = Tolerance<Number> >
1452 class ResGraphAdaptor :
1453 public EdgeSubGraphAdaptor<
1454 UndirGraphAdaptor<const Graph>,
1455 typename UndirGraphAdaptor<const Graph>::template CombinedEdgeMap<
1456 ResForwardFilter<const Graph, Number, CapacityMap, FlowMap>,
1457 ResBackwardFilter<const Graph, Number, CapacityMap, FlowMap> > > {
1460 typedef UndirGraphAdaptor<const Graph> UGraph;
1462 typedef ResForwardFilter<const Graph, Number, CapacityMap, FlowMap>
1465 typedef ResBackwardFilter<const Graph, Number, CapacityMap, FlowMap>
1468 typedef typename UGraph::
1469 template CombinedEdgeMap<ForwardFilter, BackwardFilter>
1472 typedef EdgeSubGraphAdaptor<UGraph, EdgeFilter> Parent;
1476 const CapacityMap* capacity;
1480 ForwardFilter forward_filter;
1481 BackwardFilter backward_filter;
1482 EdgeFilter edge_filter;
1484 void setCapacityMap(const CapacityMap& _capacity) {
1485 capacity=&_capacity;
1486 forward_filter.setCapacity(_capacity);
1487 backward_filter.setCapacity(_capacity);
1490 void setFlowMap(FlowMap& _flow) {
1492 forward_filter.setFlow(_flow);
1493 backward_filter.setFlow(_flow);
1498 /// \brief Constructor of the residual graph.
1500 /// Constructor of the residual graph. The parameters are the graph type,
1501 /// the flow map, the capacity map and a tolerance object.
1502 ResGraphAdaptor(const Graph& _graph, const CapacityMap& _capacity,
1503 FlowMap& _flow, const Tolerance& _tolerance = Tolerance())
1504 : Parent(), capacity(&_capacity), flow(&_flow), ugraph(_graph),
1505 forward_filter(_capacity, _flow, _tolerance),
1506 backward_filter(_capacity, _flow, _tolerance),
1507 edge_filter(forward_filter, backward_filter)
1509 Parent::setGraph(ugraph);
1510 Parent::setEdgeFilterMap(edge_filter);
1513 typedef typename Parent::Edge Edge;
1515 /// \brief Gives back the residual capacity of the edge.
1517 /// Gives back the residual capacity of the edge.
1518 Number rescap(const Edge& edge) const {
1519 if (UGraph::direction(edge)) {
1520 return (*capacity)[edge]-(*flow)[edge];
1522 return (*flow)[edge];
1526 /// \brief Augment on the given edge in the residual graph.
1528 /// Augment on the given edge in the residual graph. It increase
1529 /// or decrease the flow on the original edge depend on the direction
1530 /// of the residual edge.
1531 void augment(const Edge& e, Number a) const {
1532 if (UGraph::direction(e)) {
1533 flow->set(e, (*flow)[e] + a);
1535 flow->set(e, (*flow)[e] - a);
1539 /// \brief Returns the direction of the edge.
1541 /// Returns true when the edge is same oriented as the original edge.
1542 static bool forward(const Edge& e) {
1543 return UGraph::direction(e);
1546 /// \brief Returns the direction of the edge.
1548 /// Returns true when the edge is opposite oriented as the original edge.
1549 static bool backward(const Edge& e) {
1550 return !UGraph::direction(e);
1553 /// \brief Gives back the forward oriented residual edge.
1555 /// Gives back the forward oriented residual edge.
1556 static Edge forward(const typename Graph::Edge& e) {
1557 return UGraph::direct(e, true);
1560 /// \brief Gives back the backward oriented residual edge.
1562 /// Gives back the backward oriented residual edge.
1563 static Edge backward(const typename Graph::Edge& e) {
1564 return UGraph::direct(e, false);
1567 /// \brief Residual capacity map.
1569 /// In generic residual graphs the residual capacity can be obtained
1573 const ResGraphAdaptor* res_graph;
1575 typedef Number Value;
1577 ResCap(const ResGraphAdaptor& _res_graph)
1578 : res_graph(&_res_graph) {}
1580 Number operator[](const Edge& e) const {
1581 return res_graph->rescap(e);
1590 template <typename _Graph, typename FirstOutEdgesMap>
1591 class ErasingFirstGraphAdaptorBase : public GraphAdaptorBase<_Graph> {
1593 typedef _Graph Graph;
1594 typedef GraphAdaptorBase<_Graph> Parent;
1596 FirstOutEdgesMap* first_out_edges;
1597 ErasingFirstGraphAdaptorBase() : Parent(),
1598 first_out_edges(0) { }
1600 void setFirstOutEdgesMap(FirstOutEdgesMap& _first_out_edges) {
1601 first_out_edges=&_first_out_edges;
1606 typedef typename Parent::Node Node;
1607 typedef typename Parent::Edge Edge;
1609 void firstOut(Edge& i, const Node& n) const {
1610 i=(*first_out_edges)[n];
1613 void erase(const Edge& e) const {
1617 first_out_edges->set(n, f);
1622 ///\ingroup graph_adaptors
1624 ///\brief For blocking flows.
1626 ///This graph adaptor is used for on-the-fly
1627 ///Dinits blocking flow computations.
1628 ///For each node, an out-edge is stored which is used when the
1630 ///OutEdgeIt& first(OutEdgeIt&, const Node&)
1634 ///\author Marton Makai
1636 template <typename _Graph, typename FirstOutEdgesMap>
1637 class ErasingFirstGraphAdaptor :
1638 public GraphAdaptorExtender<
1639 ErasingFirstGraphAdaptorBase<_Graph, FirstOutEdgesMap> > {
1641 typedef _Graph Graph;
1642 typedef GraphAdaptorExtender<
1643 ErasingFirstGraphAdaptorBase<_Graph, FirstOutEdgesMap> > Parent;
1644 ErasingFirstGraphAdaptor(Graph& _graph,
1645 FirstOutEdgesMap& _first_out_edges) {
1647 setFirstOutEdgesMap(_first_out_edges);
1652 /// \brief Base class for split graph adaptor
1654 /// Base class of split graph adaptor. In most case you do not need to
1655 /// use it directly but the documented member functions of this class can
1656 /// be used with the SplitGraphAdaptor class.
1657 /// \sa SplitGraphAdaptor
1658 template <typename _Graph>
1659 class SplitGraphAdaptorBase
1660 : public GraphAdaptorBase<const _Graph> {
1663 typedef _Graph Graph;
1665 typedef GraphAdaptorBase<const _Graph> Parent;
1667 typedef typename Graph::Node GraphNode;
1668 typedef typename Graph::Edge GraphEdge;
1673 template <typename T> class NodeMap;
1674 template <typename T> class EdgeMap;
1677 class Node : public GraphNode {
1678 friend class SplitGraphAdaptorBase;
1679 template <typename T> friend class NodeMap;
1683 Node(GraphNode _node, bool _in_node)
1684 : GraphNode(_node), in_node(_in_node) {}
1689 Node(Invalid) : GraphNode(INVALID), in_node(true) {}
1691 bool operator==(const Node& node) const {
1692 return GraphNode::operator==(node) && in_node == node.in_node;
1695 bool operator!=(const Node& node) const {
1696 return !(*this == node);
1699 bool operator<(const Node& node) const {
1700 return GraphNode::operator<(node) ||
1701 (GraphNode::operator==(node) && in_node < node.in_node);
1706 friend class SplitGraphAdaptorBase;
1707 template <typename T> friend class EdgeMap;
1709 typedef BiVariant<GraphEdge, GraphNode> EdgeImpl;
1711 explicit Edge(const GraphEdge& edge) : item(edge) {}
1712 explicit Edge(const GraphNode& node) : item(node) {}
1718 Edge(Invalid) : item(GraphEdge(INVALID)) {}
1720 bool operator==(const Edge& edge) const {
1721 if (item.firstState()) {
1722 if (edge.item.firstState()) {
1723 return item.first() == edge.item.first();
1726 if (edge.item.secondState()) {
1727 return item.second() == edge.item.second();
1733 bool operator!=(const Edge& edge) const {
1734 return !(*this == edge);
1737 bool operator<(const Edge& edge) const {
1738 if (item.firstState()) {
1739 if (edge.item.firstState()) {
1740 return item.first() < edge.item.first();
1744 if (edge.item.secondState()) {
1745 return item.second() < edge.item.second();
1751 operator GraphEdge() const { return item.first(); }
1752 operator GraphNode() const { return item.second(); }
1756 void first(Node& node) const {
1757 Parent::first(node);
1758 node.in_node = true;
1761 void next(Node& node) const {
1763 node.in_node = false;
1765 node.in_node = true;
1770 void first(Edge& edge) const {
1771 edge.item.setSecond();
1772 Parent::first(edge.item.second());
1773 if (edge.item.second() == INVALID) {
1774 edge.item.setFirst();
1775 Parent::first(edge.item.first());
1779 void next(Edge& edge) const {
1780 if (edge.item.secondState()) {
1781 Parent::next(edge.item.second());
1782 if (edge.item.second() == INVALID) {
1783 edge.item.setFirst();
1784 Parent::first(edge.item.first());
1787 Parent::next(edge.item.first());
1791 void firstOut(Edge& edge, const Node& node) const {
1793 edge.item.setSecond(node);
1795 edge.item.setFirst();
1796 Parent::firstOut(edge.item.first(), node);
1800 void nextOut(Edge& edge) const {
1801 if (!edge.item.firstState()) {
1802 edge.item.setFirst(INVALID);
1804 Parent::nextOut(edge.item.first());
1808 void firstIn(Edge& edge, const Node& node) const {
1809 if (!node.in_node) {
1810 edge.item.setSecond(node);
1812 edge.item.setFirst();
1813 Parent::firstIn(edge.item.first(), node);
1817 void nextIn(Edge& edge) const {
1818 if (!edge.item.firstState()) {
1819 edge.item.setFirst(INVALID);
1821 Parent::nextIn(edge.item.first());
1825 Node source(const Edge& edge) const {
1826 if (edge.item.firstState()) {
1827 return Node(Parent::source(edge.item.first()), false);
1829 return Node(edge.item.second(), true);
1833 Node target(const Edge& edge) const {
1834 if (edge.item.firstState()) {
1835 return Node(Parent::target(edge.item.first()), true);
1837 return Node(edge.item.second(), false);
1841 int id(const Node& node) const {
1842 return (Parent::id(node) << 1) | (node.in_node ? 0 : 1);
1844 Node nodeFromId(int id) const {
1845 return Node(Parent::nodeFromId(id >> 1), (id & 1) == 0);
1847 int maxNodeId() const {
1848 return 2 * Parent::maxNodeId() + 1;
1851 int id(const Edge& edge) const {
1852 if (edge.item.firstState()) {
1853 return Parent::id(edge.item.first()) << 1;
1855 return (Parent::id(edge.item.second()) << 1) | 1;
1858 Edge edgeFromId(int id) const {
1859 if ((id & 1) == 0) {
1860 return Edge(Parent::edgeFromId(id >> 1));
1862 return Edge(Parent::nodeFromId(id >> 1));
1865 int maxEdgeId() const {
1866 return std::max(Parent::maxNodeId() << 1,
1867 (Parent::maxEdgeId() << 1) | 1);
1870 /// \brief Returns true when the node is in-node.
1872 /// Returns true when the node is in-node.
1873 static bool inNode(const Node& node) {
1874 return node.in_node;
1877 /// \brief Returns true when the node is out-node.
1879 /// Returns true when the node is out-node.
1880 static bool outNode(const Node& node) {
1881 return !node.in_node;
1884 /// \brief Returns true when the edge is edge in the original graph.
1886 /// Returns true when the edge is edge in the original graph.
1887 static bool origEdge(const Edge& edge) {
1888 return edge.item.firstState();
1891 /// \brief Returns true when the edge binds an in-node and an out-node.
1893 /// Returns true when the edge binds an in-node and an out-node.
1894 static bool bindEdge(const Edge& edge) {
1895 return edge.item.secondState();
1898 /// \brief Gives back the in-node created from the \c node.
1900 /// Gives back the in-node created from the \c node.
1901 static Node inNode(const GraphNode& node) {
1902 return Node(node, true);
1905 /// \brief Gives back the out-node created from the \c node.
1907 /// Gives back the out-node created from the \c node.
1908 static Node outNode(const GraphNode& node) {
1909 return Node(node, false);
1912 /// \brief Gives back the edge binds the two part of the node.
1914 /// Gives back the edge binds the two part of the node.
1915 static Edge edge(const GraphNode& node) {
1919 /// \brief Gives back the edge of the original edge.
1921 /// Gives back the edge of the original edge.
1922 static Edge edge(const GraphEdge& edge) {
1926 typedef True NodeNumTag;
1928 int nodeNum() const {
1929 return 2 * countNodes(*Parent::graph);
1932 typedef True EdgeNumTag;
1934 int edgeNum() const {
1935 return countEdges(*Parent::graph) + countNodes(*Parent::graph);
1938 typedef True FindEdgeTag;
1940 Edge findEdge(const Node& source, const Node& target,
1941 const Edge& prev = INVALID) const {
1942 if (inNode(source)) {
1943 if (outNode(target)) {
1944 if ((GraphNode&)source == (GraphNode&)target && prev == INVALID) {
1945 return Edge(source);
1949 if (inNode(target)) {
1950 return Edge(findEdge(*Parent::graph, source, target, prev));
1956 template <typename T>
1957 class NodeMap : public MapBase<Node, T> {
1958 typedef typename Parent::template NodeMap<T> NodeImpl;
1960 NodeMap(const SplitGraphAdaptorBase& _graph)
1961 : inNodeMap(_graph), outNodeMap(_graph) {}
1962 NodeMap(const SplitGraphAdaptorBase& _graph, const T& t)
1963 : inNodeMap(_graph, t), outNodeMap(_graph, t) {}
1965 void set(const Node& key, const T& val) {
1966 if (SplitGraphAdaptorBase::inNode(key)) { inNodeMap.set(key, val); }
1967 else {outNodeMap.set(key, val); }
1970 typename MapTraits<NodeImpl>::ReturnValue
1971 operator[](const Node& key) {
1972 if (SplitGraphAdaptorBase::inNode(key)) { return inNodeMap[key]; }
1973 else { return outNodeMap[key]; }
1976 typename MapTraits<NodeImpl>::ConstReturnValue
1977 operator[](const Node& key) const {
1978 if (SplitGraphAdaptorBase::inNode(key)) { return inNodeMap[key]; }
1979 else { return outNodeMap[key]; }
1983 NodeImpl inNodeMap, outNodeMap;
1986 template <typename T>
1987 class EdgeMap : public MapBase<Edge, T> {
1988 typedef typename Parent::template EdgeMap<T> EdgeMapImpl;
1989 typedef typename Parent::template NodeMap<T> NodeMapImpl;
1992 EdgeMap(const SplitGraphAdaptorBase& _graph)
1993 : edge_map(_graph), node_map(_graph) {}
1994 EdgeMap(const SplitGraphAdaptorBase& _graph, const T& t)
1995 : edge_map(_graph, t), node_map(_graph, t) {}
1997 void set(const Edge& key, const T& val) {
1998 if (SplitGraphAdaptorBase::origEdge(key)) {
1999 edge_map.set(key.item.first(), val);
2001 node_map.set(key.item.second(), val);
2005 typename MapTraits<EdgeMapImpl>::ReturnValue
2006 operator[](const Edge& key) {
2007 if (SplitGraphAdaptorBase::origEdge(key)) {
2008 return edge_map[key.item.first()];
2010 return node_map[key.item.second()];
2014 typename MapTraits<EdgeMapImpl>::ConstReturnValue
2015 operator[](const Edge& key) const {
2016 if (SplitGraphAdaptorBase::origEdge(key)) {
2017 return edge_map[key.item.first()];
2019 return node_map[key.item.second()];
2024 typename Parent::template EdgeMap<T> edge_map;
2025 typename Parent::template NodeMap<T> node_map;
2031 template <typename _Graph, typename NodeEnable = void,
2032 typename EdgeEnable = void>
2033 class AlterableSplitGraphAdaptor
2034 : public GraphAdaptorExtender<SplitGraphAdaptorBase<_Graph> > {
2037 typedef GraphAdaptorExtender<SplitGraphAdaptorBase<_Graph> > Parent;
2038 typedef _Graph Graph;
2040 typedef typename Graph::Node GraphNode;
2041 typedef typename Graph::Node GraphEdge;
2045 AlterableSplitGraphAdaptor() : Parent() {}
2049 typedef InvalidType NodeNotifier;
2050 typedef InvalidType EdgeNotifier;
2054 template <typename _Graph, typename EdgeEnable>
2055 class AlterableSplitGraphAdaptor<
2057 typename enable_if<typename _Graph::NodeNotifier::Notifier>::type,
2059 : public GraphAdaptorExtender<SplitGraphAdaptorBase<_Graph> > {
2062 typedef GraphAdaptorExtender<SplitGraphAdaptorBase<_Graph> > Parent;
2063 typedef _Graph Graph;
2065 typedef typename Graph::Node GraphNode;
2066 typedef typename Graph::Edge GraphEdge;
2068 typedef typename Parent::Node Node;
2069 typedef typename Parent::Edge Edge;
2073 AlterableSplitGraphAdaptor()
2074 : Parent(), node_notifier(*this), node_notifier_proxy(*this) {}
2076 void setGraph(_Graph& graph) {
2077 Parent::setGraph(graph);
2078 node_notifier_proxy.setNotifier(graph.getNotifier(GraphNode()));
2083 ~AlterableSplitGraphAdaptor() {
2084 node_notifier.clear();
2087 typedef AlterationNotifier<AlterableSplitGraphAdaptor, Node> NodeNotifier;
2088 typedef InvalidType EdgeNotifier;
2090 NodeNotifier& getNotifier(Node) const { return node_notifier; }
2094 class NodeNotifierProxy : public Graph::NodeNotifier::ObserverBase {
2097 typedef typename Graph::NodeNotifier::ObserverBase Parent;
2098 typedef AlterableSplitGraphAdaptor AdaptorBase;
2100 NodeNotifierProxy(const AdaptorBase& _adaptor)
2101 : Parent(), adaptor(&_adaptor) {
2104 virtual ~NodeNotifierProxy() {
2105 if (Parent::attached()) {
2110 void setNotifier(typename Graph::NodeNotifier& graph_notifier) {
2111 Parent::attach(graph_notifier);
2117 virtual void add(const GraphNode& gn) {
2118 std::vector<Node> nodes;
2119 nodes.push_back(AdaptorBase::Parent::inNode(gn));
2120 nodes.push_back(AdaptorBase::Parent::outNode(gn));
2121 adaptor->getNotifier(Node()).add(nodes);
2124 virtual void add(const std::vector<GraphNode>& gn) {
2125 std::vector<Node> nodes;
2126 for (int i = 0; i < (int)gn.size(); ++i) {
2127 nodes.push_back(AdaptorBase::Parent::inNode(gn[i]));
2128 nodes.push_back(AdaptorBase::Parent::outNode(gn[i]));
2130 adaptor->getNotifier(Node()).add(nodes);
2133 virtual void erase(const GraphNode& gn) {
2134 std::vector<Node> nodes;
2135 nodes.push_back(AdaptorBase::Parent::inNode(gn));
2136 nodes.push_back(AdaptorBase::Parent::outNode(gn));
2137 adaptor->getNotifier(Node()).erase(nodes);
2140 virtual void erase(const std::vector<GraphNode>& gn) {
2141 std::vector<Node> nodes;
2142 for (int i = 0; i < (int)gn.size(); ++i) {
2143 nodes.push_back(AdaptorBase::Parent::inNode(gn[i]));
2144 nodes.push_back(AdaptorBase::Parent::outNode(gn[i]));
2146 adaptor->getNotifier(Node()).erase(nodes);
2148 virtual void build() {
2149 adaptor->getNotifier(Node()).build();
2151 virtual void clear() {
2152 adaptor->getNotifier(Node()).clear();
2155 const AdaptorBase* adaptor;
2159 mutable NodeNotifier node_notifier;
2161 NodeNotifierProxy node_notifier_proxy;
2165 template <typename _Graph>
2166 class AlterableSplitGraphAdaptor<
2168 typename enable_if<typename _Graph::NodeNotifier::Notifier>::type,
2169 typename enable_if<typename _Graph::EdgeNotifier::Notifier>::type>
2170 : public GraphAdaptorExtender<SplitGraphAdaptorBase<_Graph> > {
2173 typedef GraphAdaptorExtender<SplitGraphAdaptorBase<_Graph> > Parent;
2174 typedef _Graph Graph;
2176 typedef typename Graph::Node GraphNode;
2177 typedef typename Graph::Edge GraphEdge;
2179 typedef typename Parent::Node Node;
2180 typedef typename Parent::Edge Edge;
2184 AlterableSplitGraphAdaptor()
2185 : Parent(), node_notifier(*this), edge_notifier(*this),
2186 node_notifier_proxy(*this), edge_notifier_proxy(*this) {}
2188 void setGraph(_Graph& graph) {
2189 Parent::setGraph(graph);
2190 node_notifier_proxy.setNotifier(graph.getNotifier(GraphNode()));
2191 edge_notifier_proxy.setNotifier(graph.getNotifier(GraphEdge()));
2196 ~AlterableSplitGraphAdaptor() {
2197 node_notifier.clear();
2198 edge_notifier.clear();
2201 typedef AlterationNotifier<AlterableSplitGraphAdaptor, Node> NodeNotifier;
2202 typedef AlterationNotifier<AlterableSplitGraphAdaptor, Edge> EdgeNotifier;
2204 NodeNotifier& getNotifier(Node) const { return node_notifier; }
2205 EdgeNotifier& getNotifier(Edge) const { return edge_notifier; }
2209 class NodeNotifierProxy : public Graph::NodeNotifier::ObserverBase {
2212 typedef typename Graph::NodeNotifier::ObserverBase Parent;
2213 typedef AlterableSplitGraphAdaptor AdaptorBase;
2215 NodeNotifierProxy(const AdaptorBase& _adaptor)
2216 : Parent(), adaptor(&_adaptor) {
2219 virtual ~NodeNotifierProxy() {
2220 if (Parent::attached()) {
2225 void setNotifier(typename Graph::NodeNotifier& graph_notifier) {
2226 Parent::attach(graph_notifier);
2232 virtual void add(const GraphNode& gn) {
2233 std::vector<Node> nodes;
2234 nodes.push_back(AdaptorBase::Parent::inNode(gn));
2235 nodes.push_back(AdaptorBase::Parent::outNode(gn));
2236 adaptor->getNotifier(Node()).add(nodes);
2237 adaptor->getNotifier(Edge()).add(AdaptorBase::Parent::edge(gn));
2239 virtual void add(const std::vector<GraphNode>& gn) {
2240 std::vector<Node> nodes;
2241 std::vector<Edge> edges;
2242 for (int i = 0; i < (int)gn.size(); ++i) {
2243 edges.push_back(AdaptorBase::Parent::edge(gn[i]));
2244 nodes.push_back(AdaptorBase::Parent::inNode(gn[i]));
2245 nodes.push_back(AdaptorBase::Parent::outNode(gn[i]));
2247 adaptor->getNotifier(Node()).add(nodes);
2248 adaptor->getNotifier(Edge()).add(edges);
2250 virtual void erase(const GraphNode& gn) {
2251 adaptor->getNotifier(Edge()).erase(AdaptorBase::Parent::edge(gn));
2252 std::vector<Node> nodes;
2253 nodes.push_back(AdaptorBase::Parent::inNode(gn));
2254 nodes.push_back(AdaptorBase::Parent::outNode(gn));
2255 adaptor->getNotifier(Node()).erase(nodes);
2257 virtual void erase(const std::vector<GraphNode>& gn) {
2258 std::vector<Node> nodes;
2259 std::vector<Edge> edges;
2260 for (int i = 0; i < (int)gn.size(); ++i) {
2261 edges.push_back(AdaptorBase::Parent::edge(gn[i]));
2262 nodes.push_back(AdaptorBase::Parent::inNode(gn[i]));
2263 nodes.push_back(AdaptorBase::Parent::outNode(gn[i]));
2265 adaptor->getNotifier(Edge()).erase(edges);
2266 adaptor->getNotifier(Node()).erase(nodes);
2268 virtual void build() {
2269 std::vector<Edge> edges;
2270 const typename Parent::Notifier* notifier = Parent::getNotifier();
2272 for (notifier->first(it); it != INVALID; notifier->next(it)) {
2273 edges.push_back(AdaptorBase::Parent::edge(it));
2275 adaptor->getNotifier(Node()).build();
2276 adaptor->getNotifier(Edge()).add(edges);
2278 virtual void clear() {
2279 std::vector<Edge> edges;
2280 const typename Parent::Notifier* notifier = Parent::getNotifier();
2282 for (notifier->first(it); it != INVALID; notifier->next(it)) {
2283 edges.push_back(AdaptorBase::Parent::edge(it));
2285 adaptor->getNotifier(Edge()).erase(edges);
2286 adaptor->getNotifier(Node()).clear();
2289 const AdaptorBase* adaptor;
2292 class EdgeNotifierProxy : public Graph::EdgeNotifier::ObserverBase {
2295 typedef typename Graph::EdgeNotifier::ObserverBase Parent;
2296 typedef AlterableSplitGraphAdaptor AdaptorBase;
2298 EdgeNotifierProxy(const AdaptorBase& _adaptor)
2299 : Parent(), adaptor(&_adaptor) {
2302 virtual ~EdgeNotifierProxy() {
2303 if (Parent::attached()) {
2308 void setNotifier(typename Graph::EdgeNotifier& graph_notifier) {
2309 Parent::attach(graph_notifier);
2315 virtual void add(const GraphEdge& ge) {
2316 adaptor->getNotifier(Edge()).add(AdaptorBase::edge(ge));
2318 virtual void add(const std::vector<GraphEdge>& ge) {
2319 std::vector<Edge> edges;
2320 for (int i = 0; i < (int)ge.size(); ++i) {
2321 edges.push_back(AdaptorBase::edge(ge[i]));
2323 adaptor->getNotifier(Edge()).add(edges);
2325 virtual void erase(const GraphEdge& ge) {
2326 adaptor->getNotifier(Edge()).erase(AdaptorBase::edge(ge));
2328 virtual void erase(const std::vector<GraphEdge>& ge) {
2329 std::vector<Edge> edges;
2330 for (int i = 0; i < (int)ge.size(); ++i) {
2331 edges.push_back(AdaptorBase::edge(ge[i]));
2333 adaptor->getNotifier(Edge()).erase(edges);
2335 virtual void build() {
2336 std::vector<Edge> edges;
2337 const typename Parent::Notifier* notifier = Parent::getNotifier();
2339 for (notifier->first(it); it != INVALID; notifier->next(it)) {
2340 edges.push_back(AdaptorBase::Parent::edge(it));
2342 adaptor->getNotifier(Edge()).add(edges);
2344 virtual void clear() {
2345 std::vector<Edge> edges;
2346 const typename Parent::Notifier* notifier = Parent::getNotifier();
2348 for (notifier->first(it); it != INVALID; notifier->next(it)) {
2349 edges.push_back(AdaptorBase::Parent::edge(it));
2351 adaptor->getNotifier(Edge()).erase(edges);
2354 const AdaptorBase* adaptor;
2358 mutable NodeNotifier node_notifier;
2359 mutable EdgeNotifier edge_notifier;
2361 NodeNotifierProxy node_notifier_proxy;
2362 EdgeNotifierProxy edge_notifier_proxy;
2366 /// \ingroup graph_adaptors
2368 /// \brief Split graph adaptor class
2370 /// This is an graph adaptor which splits all node into an in-node
2371 /// and an out-node. Formaly, the adaptor replaces each \f$ u \f$
2372 /// node in the graph with two node, \f$ u_{in} \f$ node and
2373 /// \f$ u_{out} \f$ node. If there is an \f$ (v, u) \f$ edge in the
2374 /// original graph the new target of the edge will be \f$ u_{in} \f$ and
2375 /// similarly the source of the original \f$ (u, v) \f$ edge will be
2376 /// \f$ u_{out} \f$. The adaptor will add for each node in the
2377 /// original graph an additional edge which will connect
2378 /// \f$ (u_{in}, u_{out}) \f$.
2380 /// The aim of this class is to run algorithm with node costs if the
2381 /// algorithm can use directly just edge costs. In this case we should use
2382 /// a \c SplitGraphAdaptor and set the node cost of the graph to the
2383 /// bind edge in the adapted graph.
2385 /// By example a maximum flow algoritm can compute how many edge
2386 /// disjoint paths are in the graph. But we would like to know how
2387 /// many node disjoint paths are in the graph. First we have to
2388 /// adapt the graph with the \c SplitGraphAdaptor. Then run the flow
2389 /// algorithm on the adapted graph. The bottleneck of the flow will
2390 /// be the bind edges which bounds the flow with the count of the
2391 /// node disjoint paths.
2395 /// typedef SplitGraphAdaptor<SmartGraph> SGraph;
2397 /// SGraph sgraph(graph);
2399 /// typedef ConstMap<SGraph::Edge, int> SCapacity;
2400 /// SCapacity scapacity(1);
2402 /// SGraph::EdgeMap<int> sflow(sgraph);
2404 /// Preflow<SGraph, int, SCapacity>
2405 /// spreflow(sgraph, SGraph::outNode(source),SGraph::inNode(target),
2406 /// scapacity, sflow);
2412 /// The result of the mamixum flow on the original graph
2413 /// shows the next figure:
2415 /// \image html edge_disjoint.png
2416 /// \image latex edge_disjoint.eps "Edge disjoint paths" width=\textwidth
2418 /// And the maximum flow on the adapted graph:
2420 /// \image html node_disjoint.png
2421 /// \image latex node_disjoint.eps "Node disjoint paths" width=\textwidth
2423 /// The second solution contains just 3 disjoint paths while the first 4.
2424 /// The full code can be found in the \ref disjoint_paths_demo.cc demo file.
2426 /// This graph adaptor is fully conform to the
2427 /// \ref concept::Graph "Graph" concept and
2428 /// contains some additional member functions and types. The
2429 /// documentation of some member functions may be found just in the
2430 /// SplitGraphAdaptorBase class.
2432 /// \sa SplitGraphAdaptorBase
2433 template <typename _Graph>
2434 class SplitGraphAdaptor : public AlterableSplitGraphAdaptor<_Graph> {
2436 typedef AlterableSplitGraphAdaptor<_Graph> Parent;
2438 typedef typename Parent::Node Node;
2439 typedef typename Parent::Edge Edge;
2441 /// \brief Constructor of the adaptor.
2443 /// Constructor of the adaptor.
2444 SplitGraphAdaptor(_Graph& graph) {
2445 Parent::setGraph(graph);
2448 /// \brief NodeMap combined from two original NodeMap
2450 /// This class adapt two of the original graph NodeMap to
2451 /// get a node map on the adapted graph.
2452 template <typename InNodeMap, typename OutNodeMap>
2453 class CombinedNodeMap {
2457 typedef typename InNodeMap::Value Value;
2459 /// \brief Constructor
2462 CombinedNodeMap(InNodeMap& _inNodeMap, OutNodeMap& _outNodeMap)
2463 : inNodeMap(_inNodeMap), outNodeMap(_outNodeMap) {}
2465 /// \brief The subscript operator.
2467 /// The subscript operator.
2468 Value& operator[](const Key& key) {
2469 if (Parent::inNode(key)) {
2470 return inNodeMap[key];
2472 return outNodeMap[key];
2476 /// \brief The const subscript operator.
2478 /// The const subscript operator.
2479 Value operator[](const Key& key) const {
2480 if (Parent::inNode(key)) {
2481 return inNodeMap[key];
2483 return outNodeMap[key];
2487 /// \brief The setter function of the map.
2489 /// The setter function of the map.
2490 void set(const Key& key, const Value& value) {
2491 if (Parent::inNode(key)) {
2492 inNodeMap.set(key, value);
2494 outNodeMap.set(key, value);
2500 InNodeMap& inNodeMap;
2501 OutNodeMap& outNodeMap;
2506 /// \brief Just gives back a combined node map.
2508 /// Just gives back a combined node map.
2509 template <typename InNodeMap, typename OutNodeMap>
2510 static CombinedNodeMap<InNodeMap, OutNodeMap>
2511 combinedNodeMap(InNodeMap& in_map, OutNodeMap& out_map) {
2512 return CombinedNodeMap<InNodeMap, OutNodeMap>(in_map, out_map);
2515 template <typename InNodeMap, typename OutNodeMap>
2516 static CombinedNodeMap<const InNodeMap, OutNodeMap>
2517 combinedNodeMap(const InNodeMap& in_map, OutNodeMap& out_map) {
2518 return CombinedNodeMap<const InNodeMap, OutNodeMap>(in_map, out_map);
2521 template <typename InNodeMap, typename OutNodeMap>
2522 static CombinedNodeMap<InNodeMap, const OutNodeMap>
2523 combinedNodeMap(InNodeMap& in_map, const OutNodeMap& out_map) {
2524 return CombinedNodeMap<InNodeMap, const OutNodeMap>(in_map, out_map);
2527 template <typename InNodeMap, typename OutNodeMap>
2528 static CombinedNodeMap<const InNodeMap, const OutNodeMap>
2529 combinedNodeMap(const InNodeMap& in_map, const OutNodeMap& out_map) {
2530 return CombinedNodeMap<const InNodeMap,
2531 const OutNodeMap>(in_map, out_map);
2534 /// \brief EdgeMap combined from an original EdgeMap and NodeMap
2536 /// This class adapt an original graph EdgeMap and NodeMap to
2537 /// get an edge map on the adapted graph.
2538 template <typename GraphEdgeMap, typename GraphNodeMap>
2539 class CombinedEdgeMap
2540 : public MapBase<Edge, typename GraphEdgeMap::Value> {
2542 typedef MapBase<Edge, typename GraphEdgeMap::Value> Parent;
2544 typedef typename Parent::Key Key;
2545 typedef typename Parent::Value Value;
2547 /// \brief Constructor
2550 CombinedEdgeMap(GraphEdgeMap& _edge_map, GraphNodeMap& _node_map)
2551 : edge_map(_edge_map), node_map(_node_map) {}
2553 /// \brief The subscript operator.
2555 /// The subscript operator.
2556 void set(const Edge& edge, const Value& val) {
2557 if (Parent::origEdge(edge)) {
2558 edge_map.set(edge, val);
2560 node_map.set(edge, val);
2564 /// \brief The const subscript operator.
2566 /// The const subscript operator.
2567 Value operator[](const Key& edge) const {
2568 if (Parent::origEdge(edge)) {
2569 return edge_map[edge];
2571 return node_map[edge];
2575 /// \brief The const subscript operator.
2577 /// The const subscript operator.
2578 Value& operator[](const Key& edge) {
2579 if (Parent::origEdge(edge)) {
2580 return edge_map[edge];
2582 return node_map[edge];
2587 GraphEdgeMap& edge_map;
2588 GraphNodeMap& node_map;
2591 /// \brief Just gives back a combined edge map.
2593 /// Just gives back a combined edge map.
2594 template <typename GraphEdgeMap, typename GraphNodeMap>
2595 static CombinedEdgeMap<GraphEdgeMap, GraphNodeMap>
2596 combinedEdgeMap(GraphEdgeMap& edge_map, GraphNodeMap& node_map) {
2597 return CombinedEdgeMap<GraphEdgeMap, GraphNodeMap>(edge_map, node_map);
2600 template <typename GraphEdgeMap, typename GraphNodeMap>
2601 static CombinedEdgeMap<const GraphEdgeMap, GraphNodeMap>
2602 combinedEdgeMap(const GraphEdgeMap& edge_map, GraphNodeMap& node_map) {
2603 return CombinedEdgeMap<const GraphEdgeMap,
2604 GraphNodeMap>(edge_map, node_map);
2607 template <typename GraphEdgeMap, typename GraphNodeMap>
2608 static CombinedEdgeMap<GraphEdgeMap, const GraphNodeMap>
2609 combinedEdgeMap(GraphEdgeMap& edge_map, const GraphNodeMap& node_map) {
2610 return CombinedEdgeMap<GraphEdgeMap,
2611 const GraphNodeMap>(edge_map, node_map);
2614 template <typename GraphEdgeMap, typename GraphNodeMap>
2615 static CombinedEdgeMap<const GraphEdgeMap, const GraphNodeMap>
2616 combinedEdgeMap(const GraphEdgeMap& edge_map,
2617 const GraphNodeMap& node_map) {
2618 return CombinedEdgeMap<const GraphEdgeMap,
2619 const GraphNodeMap>(edge_map, node_map);
2624 /// \brief Just gives back a split graph adaptor
2626 /// Just gives back a split graph adaptor
2627 template<typename Graph>
2628 SplitGraphAdaptor<Graph>
2629 splitGraphAdaptor(const Graph& graph) {
2630 return SplitGraphAdaptor<Graph>(graph);
2636 #endif //LEMON_GRAPH_ADAPTOR_H