src/hugo/graph_wrapper.h
author marci
Mon, 27 Sep 2004 18:11:27 +0000
changeset 910 5a89cacf17f1
parent 906 17f31d280385
child 911 89a4fbb99cad
permissions -rw-r--r--
minor corrections
     1 /* -*- C++ -*-
     2  * src/hugo/graph_wrapper.h - Part of HUGOlib, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Combinatorial Optimization Research Group, EGRES).
     6  *
     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.
    10  *
    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
    13  * purpose.
    14  *
    15  */
    16 
    17 #ifndef HUGO_GRAPH_WRAPPER_H
    18 #define HUGO_GRAPH_WRAPPER_H
    19 
    20 ///\ingroup gwrappers
    21 ///\file
    22 ///\brief Several graph wrappers.
    23 ///
    24 ///This file contains several useful graph wrapper functions.
    25 ///
    26 ///\author Marton Makai
    27 
    28 #include <hugo/invalid.h>
    29 #include <hugo/maps.h>
    30 #include <hugo/map_defines.h>
    31 #include <iostream>
    32 
    33 namespace hugo {
    34 
    35   // Graph wrappers
    36 
    37   /// \addtogroup gwrappers
    38   /// A main parts of HUGOlib are the different graph structures, 
    39   /// generic graph algorithms, graph concepts which couple these, and 
    40   /// graph wrappers. While the previous ones are more or less clear, the 
    41   /// latter notion needs further explanation.
    42   /// Graph wrappers are graph classes which serve for considering graph 
    43   /// structures in different ways. A short example makes the notion much 
    44   /// clearer. 
    45   /// Suppose that we have an instance \c g of a directed graph
    46   /// type say \c ListGraph and an algorithm 
    47   /// \code template<typename Graph> int algorithm(const Graph&); \endcode 
    48   /// is needed to run on the reversely oriented graph. 
    49   /// It may be expensive (in time or in memory usage) to copy 
    50   /// \c g with the reverse orientation. 
    51   /// Thus, a wrapper class
    52   /// \code template<typename Graph> class RevGraphWrapper; \endcode is used. 
    53   /// The code looks as follows
    54   /// \code
    55   /// ListGraph g;
    56   /// RevGraphWrapper<ListGraph> rgw(g);
    57   /// int result=algorithm(rgw);
    58   /// \endcode
    59   /// After running the algorithm, the original graph \c g 
    60   /// remains untouched. Thus the graph wrapper used above is to consider the 
    61   /// original graph with reverse orientation. 
    62   /// This techniques gives rise to an elegant code, and 
    63   /// based on stable graph wrappers, complex algorithms can be 
    64   /// implemented easily. 
    65   /// In flow, circulation and bipartite matching problems, the residual 
    66   /// graph is of particular importance. Combining a wrapper implementing 
    67   /// this, shortest path algorithms and minimum mean cycle algorithms, 
    68   /// a range of weighted and cardinality optimization algorithms can be 
    69   /// obtained. For lack of space, for other examples, 
    70   /// the interested user is referred to the detailed documentation of graph 
    71   /// wrappers. 
    72   /// The behavior of graph wrappers can be very different. Some of them keep 
    73   /// capabilities of the original graph while in other cases this would be 
    74   /// meaningless. This means that the concepts that they are a model of depend 
    75   /// on the graph wrapper, and the wrapped graph(s). 
    76   /// If an edge of \c rgw is deleted, this is carried out by 
    77   /// deleting the corresponding edge of \c g. But for a residual 
    78   /// graph, this operation has no sense. 
    79   /// Let we stand one more example here to simplify your work. 
    80   /// wrapper class
    81   /// \code template<typename Graph> class RevGraphWrapper; \endcode 
    82   /// has constructor 
    83   /// <tt> RevGraphWrapper(Graph& _g)</tt>. 
    84   /// This means that in a situation, 
    85   /// when a <tt> const ListGraph& </tt> reference to a graph is given, 
    86   /// then it have to be instantiated with <tt>Graph=const ListGraph</tt>.
    87   /// \code
    88   /// int algorithm1(const ListGraph& g) {
    89   ///   RevGraphWrapper<const ListGraph> rgw(g);
    90   ///   return algorithm2(rgw);
    91   /// }
    92   /// \endcode
    93 
    94   /// \addtogroup gwrappers
    95   /// @{
    96 
    97   ///Base type for the Graph Wrappers
    98 
    99   ///\warning Graph wrappers are in even more experimental state than the other
   100   ///parts of the lib. Use them at you own risk.
   101   ///
   102   ///This is the base type for the Graph Wrappers.
   103   ///\todo Some more docs... 
   104   ///
   105   ///\author Marton Makai 
   106   template<typename Graph>
   107   class GraphWrapper {
   108   protected:
   109     Graph* graph;
   110     GraphWrapper() : graph(0) { }
   111     void setGraph(Graph& _graph) { graph=&_graph; }
   112 
   113   public:
   114     typedef Graph BaseGraph;
   115     typedef Graph ParentGraph;
   116 
   117     GraphWrapper(Graph& _graph) : graph(&_graph) { }
   118     GraphWrapper(const GraphWrapper<Graph>& gw) : graph(gw.graph) { }
   119  
   120     typedef typename Graph::Node Node;
   121     class NodeIt : public Node { 
   122       const GraphWrapper<Graph>* gw;
   123       friend class GraphWrapper<Graph>;
   124      public:
   125       NodeIt() { }
   126       NodeIt(Invalid i) : Node(i) { }
   127       NodeIt(const GraphWrapper<Graph>& _gw) : 
   128 	Node(typename Graph::NodeIt(*(_gw.graph))), gw(&_gw) { }
   129       NodeIt(const GraphWrapper<Graph>& _gw, const Node& n) : 
   130 	Node(n), gw(&_gw) { }
   131       NodeIt& operator++() { 
   132 	*(static_cast<Node*>(this))=
   133 	  ++(typename Graph::NodeIt(*(gw->graph), *this));
   134 	return *this; 
   135       }
   136     };
   137     typedef typename Graph::Edge Edge;
   138     class OutEdgeIt : public Edge { 
   139       const GraphWrapper<Graph>* gw;
   140       friend class GraphWrapper<Graph>;
   141      public:
   142       OutEdgeIt() { }
   143       OutEdgeIt(Invalid i) : Edge(i) { }
   144       OutEdgeIt(const GraphWrapper<Graph>& _gw, const Node& n) : 
   145 	Edge(typename Graph::OutEdgeIt(*(_gw.graph), n)), gw(&_gw) { }
   146       OutEdgeIt(const GraphWrapper<Graph>& _gw, const Edge& e) : 
   147 	Edge(e), gw(&_gw) { }
   148       OutEdgeIt& operator++() { 
   149 	*(static_cast<Edge*>(this))=
   150 	  ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
   151 	return *this; 
   152       }
   153     };
   154     class InEdgeIt : public Edge { 
   155       const GraphWrapper<Graph>* gw;
   156       friend class GraphWrapper<Graph>;
   157      public:
   158       InEdgeIt() { }
   159       InEdgeIt(Invalid i) : Edge(i) { }
   160       InEdgeIt(const GraphWrapper<Graph>& _gw, const Node& n) : 
   161 	Edge(typename Graph::InEdgeIt(*(_gw.graph), n)), gw(&_gw) { }
   162       InEdgeIt(const GraphWrapper<Graph>& _gw, const Edge& e) : 
   163 	Edge(e), gw(&_gw) { }
   164       InEdgeIt& operator++() { 
   165 	*(static_cast<Edge*>(this))=
   166 	  ++(typename Graph::InEdgeIt(*(gw->graph), *this));
   167 	return *this; 
   168       }
   169     };
   170     class EdgeIt : public Edge { 
   171       const GraphWrapper<Graph>* gw;
   172       friend class GraphWrapper<Graph>;
   173      public:
   174       EdgeIt() { }
   175       EdgeIt(Invalid i) : Edge(i) { }
   176       EdgeIt(const GraphWrapper<Graph>& _gw) : 
   177 	Edge(typename Graph::EdgeIt(*(_gw.graph))), gw(&_gw) { }
   178       EdgeIt(const GraphWrapper<Graph>& _gw, const Edge& e) : 
   179 	Edge(e), gw(&_gw) { }
   180       EdgeIt& operator++() { 
   181 	*(static_cast<Edge*>(this))=
   182 	  ++(typename Graph::EdgeIt(*(gw->graph), *this));
   183 	return *this; 
   184       }
   185     };
   186    
   187     NodeIt& first(NodeIt& i) const { 
   188       i=NodeIt(*this); return i;
   189     }
   190     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
   191       i=OutEdgeIt(*this, p); return i;
   192     }
   193     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
   194       i=InEdgeIt(*this, p); return i;
   195     }
   196     EdgeIt& first(EdgeIt& i) const { 
   197       i=EdgeIt(*this); return i;
   198     }
   199 
   200     Node tail(const Edge& e) const { 
   201       return Node(graph->tail(static_cast<typename Graph::Edge>(e))); }
   202     Node head(const Edge& e) const { 
   203       return Node(graph->head(static_cast<typename Graph::Edge>(e))); }
   204 
   205     int nodeNum() const { return graph->nodeNum(); }
   206     int edgeNum() const { return graph->edgeNum(); }
   207   
   208     Node addNode() const { return Node(graph->addNode()); }
   209     Edge addEdge(const Node& tail, const Node& head) const { 
   210       return Edge(graph->addEdge(tail, head)); }
   211 
   212     void erase(const Node& i) const { graph->erase(i); }
   213     void erase(const Edge& i) const { graph->erase(i); }
   214   
   215     void clear() const { graph->clear(); }
   216     
   217     bool forward(const Edge& e) const { return graph->forward(e); }
   218     bool backward(const Edge& e) const { return graph->backward(e); }
   219 
   220     int id(const Node& v) const { return graph->id(v); }
   221     int id(const Edge& e) const { return graph->id(e); }
   222     
   223     Edge opposite(const Edge& e) const { return Edge(graph->opposite(e)); }
   224 
   225 
   226     IMPORT_NODE_MAP(Graph, *(gw.graph), GraphWrapper, gw);    
   227     IMPORT_EDGE_MAP(Graph, *(gw.graph), GraphWrapper, gw);
   228     
   229 
   230   };
   231 
   232 
   233 
   234   /// A graph wrapper which reverses the orientation of the edges.
   235 
   236   ///\warning Graph wrappers are in even more experimental state than the other
   237   ///parts of the lib. Use them at you own risk.
   238   ///
   239   /// A graph wrapper which reverses the orientation of the edges.
   240   /// Thus \c Graph have to be a directed graph type.
   241   ///
   242   ///\author Marton Makai
   243   template<typename Graph>
   244   class RevGraphWrapper : public GraphWrapper<Graph> {
   245   public:
   246     typedef GraphWrapper<Graph> Parent; 
   247   protected:
   248     RevGraphWrapper() : GraphWrapper<Graph>() { }
   249   public:
   250     RevGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }  
   251     RevGraphWrapper(const RevGraphWrapper<Graph>& gw) : Parent(gw) { }
   252 
   253     typedef typename GraphWrapper<Graph>::Node Node;
   254     typedef typename GraphWrapper<Graph>::Edge Edge;
   255     //remark: OutEdgeIt and InEdgeIt cannot be typedef-ed to each other
   256     //because this does not work is some of them are not defined in the 
   257     //original graph. The problem with this is that typedef-ed stuff 
   258     //are instantiated in c++.
   259     class OutEdgeIt : public Edge { 
   260       const RevGraphWrapper<Graph>* gw;
   261       friend class GraphWrapper<Graph>;
   262      public:
   263       OutEdgeIt() { }
   264       OutEdgeIt(Invalid i) : Edge(i) { }
   265       OutEdgeIt(const RevGraphWrapper<Graph>& _gw, const Node& n) : 
   266 	Edge(typename Graph::InEdgeIt(*(_gw.graph), n)), gw(&_gw) { }
   267       OutEdgeIt(const RevGraphWrapper<Graph>& _gw, const Edge& e) : 
   268 	Edge(e), gw(&_gw) { }
   269       OutEdgeIt& operator++() { 
   270 	*(static_cast<Edge*>(this))=
   271 	  ++(typename Graph::InEdgeIt(*(gw->graph), *this));
   272 	return *this; 
   273       }
   274     };
   275     class InEdgeIt : public Edge { 
   276       const RevGraphWrapper<Graph>* gw;
   277       friend class GraphWrapper<Graph>;
   278      public:
   279       InEdgeIt() { }
   280       InEdgeIt(Invalid i) : Edge(i) { }
   281       InEdgeIt(const RevGraphWrapper<Graph>& _gw, const Node& n) : 
   282 	Edge(typename Graph::OutEdgeIt(*(_gw.graph), n)), gw(&_gw) { }
   283       InEdgeIt(const RevGraphWrapper<Graph>& _gw, const Edge& e) : 
   284 	Edge(e), gw(&_gw) { }
   285       InEdgeIt& operator++() { 
   286 	*(static_cast<Edge*>(this))=
   287 	  ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
   288 	return *this; 
   289       }
   290     };
   291 
   292     using GraphWrapper<Graph>::first;
   293     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
   294       i=OutEdgeIt(*this, p); return i;
   295     }
   296     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
   297       i=InEdgeIt(*this, p); return i;
   298     }
   299 
   300     Node tail(const Edge& e) const { 
   301       return GraphWrapper<Graph>::head(e); }
   302     Node head(const Edge& e) const { 
   303       return GraphWrapper<Graph>::tail(e); }
   304 
   305     //    KEEP_MAPS(Parent, RevGraphWrapper);
   306 
   307   };
   308 
   309 
   310 
   311   /// A graph wrapper for hiding nodes and edges from a graph.
   312   
   313   ///\warning Graph wrappers are in even more experimental state than the other
   314   ///parts of the lib. Use them at you own risk.
   315   ///
   316   /// This wrapper shows a graph with filtered node-set and 
   317   /// edge-set. Given a bool-valued map on the node-set and one on 
   318   /// the edge-set of the graphs, the iterators show only the objects 
   319   /// having true value. 
   320   /// The quick brown fox iterators jump over 
   321   /// the lazy dog nodes or edges if their values for are false in the 
   322   /// corresponding bool maps. 
   323   ///
   324   ///\author Marton Makai
   325   template<typename Graph, typename NodeFilterMap, 
   326 	   typename EdgeFilterMap>
   327   class SubGraphWrapper : public GraphWrapper<Graph> {
   328   public:
   329     typedef GraphWrapper<Graph> Parent;
   330   protected:
   331     NodeFilterMap* node_filter_map;
   332     EdgeFilterMap* edge_filter_map;
   333 
   334     SubGraphWrapper() : GraphWrapper<Graph>(), 
   335 			node_filter_map(0), edge_filter_map(0) { }
   336     void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
   337       node_filter_map=&_node_filter_map;
   338     }
   339     void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
   340       edge_filter_map=&_edge_filter_map;
   341     }
   342     
   343   public:
   344     SubGraphWrapper(Graph& _graph, NodeFilterMap& _node_filter_map, 
   345 		    EdgeFilterMap& _edge_filter_map) : 
   346       GraphWrapper<Graph>(_graph), node_filter_map(&_node_filter_map), 
   347       edge_filter_map(&_edge_filter_map) { }  
   348 
   349     typedef typename GraphWrapper<Graph>::Node Node;
   350     class NodeIt : public Node { 
   351       const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>* gw;
   352       friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
   353     public:
   354       NodeIt() { }
   355       NodeIt(Invalid i) : Node(i) { }
   356       NodeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw) : 
   357 	Node(typename Graph::NodeIt(*(_gw.graph))), gw(&_gw) { 
   358 	while (*static_cast<Node*>(this)!=INVALID && 
   359 	       !(*(gw->node_filter_map))[*this]) 
   360 	  *(static_cast<Node*>(this))=
   361 	    ++(typename Graph::NodeIt(*(gw->graph), *this));
   362       }
   363       NodeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, 
   364 	     const Node& n) : 
   365 	Node(n), gw(&_gw) { }
   366       NodeIt& operator++() { 
   367 	*(static_cast<Node*>(this))=
   368 	  ++(typename Graph::NodeIt(*(gw->graph), *this));
   369 	while (*static_cast<Node*>(this)!=INVALID && 
   370 	       !(*(gw->node_filter_map))[*this]) 
   371 	  *(static_cast<Node*>(this))=
   372 	    ++(typename Graph::NodeIt(*(gw->graph), *this));
   373 	return *this; 
   374       }
   375     };
   376     typedef typename GraphWrapper<Graph>::Edge Edge;
   377     class OutEdgeIt : public Edge { 
   378       const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>* gw;
   379       friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
   380     public:
   381       OutEdgeIt() { }
   382       OutEdgeIt(Invalid i) : Edge(i) { }
   383       OutEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, const Node& n) : 
   384 	Edge(typename Graph::OutEdgeIt(*(_gw.graph), n)), gw(&_gw) { 
   385 	while (*static_cast<Edge*>(this)!=INVALID && 
   386 	       !(*(gw->edge_filter_map))[*this]) 
   387 	  *(static_cast<Edge*>(this))=
   388 	    ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
   389       }
   390       OutEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, 
   391 	     const Edge& e) : 
   392 	Edge(e), gw(&_gw) { }
   393       OutEdgeIt& operator++() { 
   394 	*(static_cast<Edge*>(this))=
   395 	  ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
   396 	while (*static_cast<Edge*>(this)!=INVALID && 
   397 	       !(*(gw->edge_filter_map))[*this]) 
   398 	  *(static_cast<Edge*>(this))=
   399 	    ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
   400 	return *this; 
   401       }
   402     };
   403     class InEdgeIt : public Edge { 
   404       const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>* gw;
   405       friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
   406     public:
   407       InEdgeIt() { }
   408       //      InEdgeIt(const InEdgeIt& e) : Edge(e), gw(e.gw) { }
   409       InEdgeIt(Invalid i) : Edge(i) { }
   410       InEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, const Node& n) : 
   411 	Edge(typename Graph::InEdgeIt(*(_gw.graph), n)), gw(&_gw) { 
   412 	while (*static_cast<Edge*>(this)!=INVALID && 
   413 	       !(*(gw->edge_filter_map))[*this]) 
   414 	  *(static_cast<Edge*>(this))=
   415 	    ++(typename Graph::InEdgeIt(*(gw->graph), *this));
   416       }
   417       InEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, 
   418 	     const Edge& e) : 
   419 	Edge(e), gw(&_gw) { }
   420       InEdgeIt& operator++() { 
   421 	*(static_cast<Edge*>(this))=
   422 	  ++(typename Graph::InEdgeIt(*(gw->graph), *this));
   423 	while (*static_cast<Edge*>(this)!=INVALID && 
   424 	       !(*(gw->edge_filter_map))[*this]) 
   425 	  *(static_cast<Edge*>(this))=
   426 	    ++(typename Graph::InEdgeIt(*(gw->graph), *this));
   427 	return *this; 
   428       }
   429     };
   430     class EdgeIt : public Edge { 
   431       const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>* gw;
   432       friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
   433     public:
   434       EdgeIt() { }
   435       EdgeIt(Invalid i) : Edge(i) { }
   436       EdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw) : 
   437 	Edge(typename Graph::EdgeIt(*(_gw.graph))), gw(&_gw) { 
   438 	while (*static_cast<Edge*>(this)!=INVALID && 
   439 	       !(*(gw->edge_filter_map))[*this]) 
   440 	  *(static_cast<Edge*>(this))=
   441 	    ++(typename Graph::EdgeIt(*(gw->graph), *this));
   442       }
   443       EdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _gw, 
   444 	     const Edge& e) : 
   445 	Edge(e), gw(&_gw) { }
   446       EdgeIt& operator++() { 
   447 	*(static_cast<Edge*>(this))=
   448 	  ++(typename Graph::EdgeIt(*(gw->graph), *this));
   449 	while (*static_cast<Edge*>(this)!=INVALID && 
   450 	       !(*(gw->edge_filter_map))[*this]) 
   451 	  *(static_cast<Edge*>(this))=
   452 	    ++(typename Graph::EdgeIt(*(gw->graph), *this));
   453 	return *this; 
   454       }
   455     };
   456 
   457     NodeIt& first(NodeIt& i) const { 
   458       i=NodeIt(*this); return i;
   459     }
   460     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
   461       i=OutEdgeIt(*this, p); return i;
   462     }
   463     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
   464       i=InEdgeIt(*this, p); return i;
   465     }
   466     EdgeIt& first(EdgeIt& i) const { 
   467       i=EdgeIt(*this); return i;
   468     }
   469     
   470     /// This function hides \c n in the graph, i.e. the iteration 
   471     /// jumps over it. This is done by simply setting the value of \c n  
   472     /// to be false in the corresponding node-map.
   473     void hide(const Node& n) const { node_filter_map->set(n, false); }
   474 
   475     /// This function hides \c e in the graph, i.e. the iteration 
   476     /// jumps over it. This is done by simply setting the value of \c e  
   477     /// to be false in the corresponding edge-map.
   478     void hide(const Edge& e) const { edge_filter_map->set(e, false); }
   479 
   480     /// The value of \c n is set to be true in the node-map which stores 
   481     /// hide information. If \c n was hidden previuosly, then it is shown 
   482     /// again
   483      void unHide(const Node& n) const { node_filter_map->set(n, true); }
   484 
   485     /// The value of \c e is set to be true in the edge-map which stores 
   486     /// hide information. If \c e was hidden previuosly, then it is shown 
   487     /// again
   488     void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
   489 
   490     /// Returns true if \c n is hidden.
   491     bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
   492 
   493     /// Returns true if \c n is hidden.
   494     bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
   495 
   496     /// \warning This is a linear time operation and works only if 
   497     /// \c Graph::NodeIt is defined.
   498     int nodeNum() const { 
   499       int i=0;
   500       for (NodeIt n(*this); n!=INVALID; ++n) ++i;
   501       return i; 
   502     }
   503 
   504     /// \warning This is a linear time operation and works only if 
   505     /// \c Graph::EdgeIt is defined.
   506     int edgeNum() const { 
   507       int i=0;
   508       for (EdgeIt e(*this); e!=INVALID; ++e) ++i;
   509       return i; 
   510     }
   511 
   512     //    KEEP_MAPS(Parent, SubGraphWrapper);
   513   };
   514 
   515 
   516 
   517   template<typename Graph>
   518   class UndirGraphWrapper : public GraphWrapper<Graph> {
   519   public:
   520     typedef GraphWrapper<Graph> Parent; 
   521   protected:
   522     UndirGraphWrapper() : GraphWrapper<Graph>() { }
   523     
   524   public:
   525     typedef typename GraphWrapper<Graph>::Node Node;
   526     typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
   527     typedef typename GraphWrapper<Graph>::Edge Edge;
   528     typedef typename GraphWrapper<Graph>::EdgeIt EdgeIt;
   529 
   530     UndirGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }  
   531 
   532     class OutEdgeIt {
   533       friend class UndirGraphWrapper<Graph>;
   534       bool out_or_in; //true iff out
   535       typename Graph::OutEdgeIt out;
   536       typename Graph::InEdgeIt in;
   537     public:
   538       OutEdgeIt() { }
   539       OutEdgeIt(const Invalid& i) : Edge(i) { }
   540       OutEdgeIt(const UndirGraphWrapper<Graph>& _G, const Node& _n) {
   541 	out_or_in=true; _G.graph->first(out, _n);
   542 	if (!(_G.graph->valid(out))) { out_or_in=false; _G.graph->first(in, _n);	}
   543       } 
   544       operator Edge() const { 
   545 	if (out_or_in) return Edge(out); else return Edge(in); 
   546       }
   547     };
   548 
   549     typedef OutEdgeIt InEdgeIt; 
   550 
   551     using GraphWrapper<Graph>::first;
   552     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
   553       i=OutEdgeIt(*this, p); return i;
   554     }
   555 
   556     using GraphWrapper<Graph>::next;
   557 
   558     OutEdgeIt& next(OutEdgeIt& e) const {
   559       if (e.out_or_in) {
   560 	typename Graph::Node n=this->graph->tail(e.out);
   561 	this->graph->next(e.out);
   562 	if (!this->graph->valid(e.out)) { 
   563 	  e.out_or_in=false; this->graph->first(e.in, n); }
   564       } else {
   565 	this->graph->next(e.in);
   566       }
   567       return e;
   568     }
   569 
   570     Node aNode(const OutEdgeIt& e) const { 
   571       if (e.out_or_in) return this->graph->tail(e); else 
   572 	return this->graph->head(e); }
   573     Node bNode(const OutEdgeIt& e) const { 
   574       if (e.out_or_in) return this->graph->head(e); else 
   575 	return this->graph->tail(e); }
   576 
   577     //    KEEP_MAPS(Parent, UndirGraphWrapper);
   578 
   579   };
   580   
   581 //   /// \brief An undirected graph template.
   582 //   ///
   583 //   ///\warning Graph wrappers are in even more experimental state than the other
   584 //   ///parts of the lib. Use them at your own risk.
   585 //   ///
   586 //   /// An undirected graph template.
   587 //   /// This class works as an undirected graph and a directed graph of 
   588 //   /// class \c Graph is used for the physical storage.
   589 //   /// \ingroup graphs
   590   template<typename Graph>
   591   class UndirGraph : public UndirGraphWrapper<Graph> {
   592     typedef UndirGraphWrapper<Graph> Parent;
   593   protected:
   594     Graph gr;
   595   public:
   596     UndirGraph() : UndirGraphWrapper<Graph>() { 
   597       Parent::setGraph(gr); 
   598     }
   599 
   600     //    KEEP_MAPS(Parent, UndirGraph);
   601   };
   602 
   603 
   604 
   605   ///\brief A wrapper for composing a subgraph of a 
   606   /// bidirected graph made from a directed one. 
   607   ///
   608   ///\warning Graph wrappers are in even more experimental state than the other
   609   ///parts of the lib. Use them at you own risk.
   610   ///
   611   /// Suppose that for a directed graph $G=(V, A)$, 
   612   /// two bool valued maps on the edge-set, 
   613   /// $forward_filter$, and $backward_filter$ 
   614   /// is given, and we are dealing with the directed graph
   615   /// a $G'=(V, \{uv : uv\in A \mbox{ and } forward_filter(uv) \mbox{ is true}\}+\{vu : uv\in A \mbox{ and } backward_filter(uv) \mbox{ is true}\})$. 
   616   /// The purpose of writing + instead of union is because parallel 
   617   /// edges can arose. 
   618   /// In other words, a subgraph of the bidirected graph obtained, which 
   619   /// is given by orienting the edges of the original graph in both directions.
   620   /// An example for such a construction is the \c RevGraphWrapper where the 
   621   /// forward_filter is everywhere false and the backward_filter is 
   622   /// everywhere true. We note that for sake of efficiency, 
   623   /// \c RevGraphWrapper is implemented in a different way. 
   624   /// But BidirGraphWrapper is obtained from 
   625   /// SubBidirGraphWrapper by considering everywhere true 
   626   /// valued maps both for forward_filter and backward_filter. 
   627   /// Finally, one of the most important applications of SubBidirGraphWrapper 
   628   /// is ResGraphWrapper, which stands for the residual graph in directed 
   629   /// flow and circulation problems. 
   630   /// As wrappers usually, the SubBidirGraphWrapper implements the 
   631   /// above mentioned graph structure without its physical storage, 
   632   /// that is the whole stuff eats constant memory. 
   633   /// As the oppositely directed edges are logically different, 
   634   /// the maps are able to attach different values for them. 
   635   template<typename Graph, 
   636 	   typename ForwardFilterMap, typename BackwardFilterMap>
   637   class SubBidirGraphWrapper : public GraphWrapper<Graph> {
   638   public:
   639     typedef GraphWrapper<Graph> Parent; 
   640   protected:
   641     ForwardFilterMap* forward_filter;
   642     BackwardFilterMap* backward_filter;
   643 
   644     SubBidirGraphWrapper() : GraphWrapper<Graph>() { }
   645     void setForwardFilterMap(ForwardFilterMap& _forward_filter) {
   646       forward_filter=&_forward_filter;
   647     }
   648     void setBackwardFilterMap(BackwardFilterMap& _backward_filter) {
   649       backward_filter=&_backward_filter;
   650     }
   651 
   652   public:
   653 
   654     SubBidirGraphWrapper(Graph& _graph, ForwardFilterMap& _forward_filter, 
   655 			 BackwardFilterMap& _backward_filter) : 
   656       GraphWrapper<Graph>(_graph), 
   657       forward_filter(&_forward_filter), backward_filter(&_backward_filter) { }
   658     SubBidirGraphWrapper(const SubBidirGraphWrapper<Graph, 
   659 			 ForwardFilterMap, BackwardFilterMap>& gw) : 
   660       Parent(gw), 
   661       forward_filter(gw.forward_filter), 
   662       backward_filter(gw.backward_filter) { }
   663 
   664     class Edge; 
   665     class OutEdgeIt; 
   666     friend class Edge; 
   667     friend class OutEdgeIt; 
   668 
   669     template<typename T> class EdgeMap;
   670 
   671     typedef typename GraphWrapper<Graph>::Node Node;
   672 
   673     typedef typename Graph::Edge GraphEdge;
   674     /// SubBidirGraphWrapper<..., ..., ...>::Edge is inherited from 
   675     /// Graph::Edge. It contains an extra bool flag which is true 
   676     /// if and only if the 
   677     /// edge is the backward version of the original edge.
   678     class Edge : public Graph::Edge {
   679       friend class SubBidirGraphWrapper<Graph, 
   680 					ForwardFilterMap, BackwardFilterMap>;
   681       template<typename T> friend class EdgeMap;
   682     protected:
   683       bool backward; //true, iff backward
   684     public:
   685       Edge() { }
   686       /// \todo =false is needed, or causes problems?
   687       /// If \c _backward is false, then we get an edge corresponding to the 
   688       /// original one, otherwise its oppositely directed pair is obtained.
   689       Edge(const typename Graph::Edge& e, bool _backward/*=false*/) : 
   690 	Graph::Edge(e), backward(_backward) { }
   691       Edge(Invalid i) : Graph::Edge(i), backward(true) { }
   692       bool operator==(const Edge& v) const { 
   693 	return (this->backward==v.backward && 
   694 		static_cast<typename Graph::Edge>(*this)==
   695 		static_cast<typename Graph::Edge>(v));
   696       } 
   697       bool operator!=(const Edge& v) const { 
   698 	return (this->backward!=v.backward || 
   699 		static_cast<typename Graph::Edge>(*this)!=
   700 		static_cast<typename Graph::Edge>(v));
   701       }
   702     };
   703 
   704     class OutEdgeIt : public Edge {
   705       friend class SubBidirGraphWrapper<Graph, 
   706 					ForwardFilterMap, BackwardFilterMap>;
   707     protected:
   708       const SubBidirGraphWrapper<Graph, 
   709 				 ForwardFilterMap, BackwardFilterMap>* gw;
   710     public:
   711       OutEdgeIt() { }
   712       OutEdgeIt(Invalid i) : Edge(i) { }
   713       OutEdgeIt(const SubBidirGraphWrapper<Graph, 
   714 		ForwardFilterMap, BackwardFilterMap>& _gw, const Node& n) : 
   715 	Edge(typename Graph::OutEdgeIt(*(_gw.graph), n), false), gw(&_gw) { 
   716 	while (*static_cast<GraphEdge*>(this)!=INVALID && 
   717 	       !(*(gw->forward_filter))[*this]) 
   718 	  *(static_cast<GraphEdge*>(this))=
   719 	    ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
   720 	if (*static_cast<GraphEdge*>(this)==INVALID) {
   721 	  *static_cast<Edge*>(this)=
   722 	    Edge(typename Graph::InEdgeIt(*(_gw.graph), n), true);
   723 	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
   724 		 !(*(gw->backward_filter))[*this]) 
   725 	    *(static_cast<GraphEdge*>(this))=
   726 	      ++(typename Graph::InEdgeIt(*(gw->graph), *this));
   727 	}
   728       }
   729       OutEdgeIt(const SubBidirGraphWrapper<Graph, 
   730 		ForwardFilterMap, BackwardFilterMap>& _gw, const Edge& e) : 
   731 	Edge(e), gw(&_gw) { }
   732       OutEdgeIt& operator++() { 
   733 	if (!this->backward) {
   734 	  Node n=gw->tail(*this);
   735 	  *(static_cast<GraphEdge*>(this))=
   736 	    ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
   737 	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
   738 		 !(*(gw->forward_filter))[*this]) 
   739 	    *(static_cast<GraphEdge*>(this))=
   740 	      ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
   741 	  if (*static_cast<GraphEdge*>(this)==INVALID) {
   742 	    *static_cast<Edge*>(this)=
   743 	      Edge(typename Graph::InEdgeIt(*(gw->graph), n), true);
   744 	    while (*static_cast<GraphEdge*>(this)!=INVALID && 
   745 		   !(*(gw->backward_filter))[*this]) 
   746 	      *(static_cast<GraphEdge*>(this))=
   747 		++(typename Graph::InEdgeIt(*(gw->graph), *this));
   748 	  }
   749 	} else {
   750 	  *(static_cast<GraphEdge*>(this))=
   751 	    ++(typename Graph::InEdgeIt(*(gw->graph), *this));
   752 	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
   753 		 !(*(gw->backward_filter))[*this]) 
   754 	    *(static_cast<GraphEdge*>(this))=
   755 	      ++(typename Graph::InEdgeIt(*(gw->graph), *this));
   756 	}
   757 	return *this;
   758       }
   759     };
   760 
   761     class InEdgeIt : public Edge {
   762       friend class SubBidirGraphWrapper<Graph, 
   763 					ForwardFilterMap, BackwardFilterMap>;
   764     protected:
   765       const SubBidirGraphWrapper<Graph, 
   766 				 ForwardFilterMap, BackwardFilterMap>* gw;
   767     public:
   768       InEdgeIt() { }
   769       InEdgeIt(Invalid i) : Edge(i) { }
   770       InEdgeIt(const SubBidirGraphWrapper<Graph, 
   771 	       ForwardFilterMap, BackwardFilterMap>& _gw, const Node& n) : 
   772 	Edge(typename Graph::InEdgeIt(*(_gw.graph), n), false), gw(&_gw) { 
   773 	while (*static_cast<GraphEdge*>(this)!=INVALID && 
   774 	       !(*(gw->forward_filter))[*this]) 
   775 	  *(static_cast<GraphEdge*>(this))=
   776 	    ++(typename Graph::InEdgeIt(*(gw->graph), *this));
   777 	if (*static_cast<GraphEdge*>(this)==INVALID) {
   778 	  *static_cast<Edge*>(this)=
   779 	    Edge(typename Graph::OutEdgeIt(*(_gw.graph), n), true);
   780 	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
   781 		 !(*(gw->backward_filter))[*this]) 
   782 	    *(static_cast<GraphEdge*>(this))=
   783 	      ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
   784 	}
   785       }
   786       InEdgeIt(const SubBidirGraphWrapper<Graph, 
   787 	       ForwardFilterMap, BackwardFilterMap>& _gw, const Edge& e) : 
   788 	Edge(e), gw(&_gw) { }
   789       InEdgeIt& operator++() { 
   790 	if (!this->backward) {
   791 	  Node n=gw->tail(*this);
   792 	  *(static_cast<GraphEdge*>(this))=
   793 	    ++(typename Graph::InEdgeIt(*(gw->graph), *this));
   794 	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
   795 		 !(*(gw->forward_filter))[*this]) 
   796 	    *(static_cast<GraphEdge*>(this))=
   797 	      ++(typename Graph::InEdgeIt(*(gw->graph), *this));
   798 	  if (*static_cast<GraphEdge*>(this)==INVALID) {
   799 	    *static_cast<Edge*>(this)=
   800 	      Edge(typename Graph::OutEdgeIt(*(gw->graph), n), true);
   801 	    while (*static_cast<GraphEdge*>(this)!=INVALID && 
   802 		   !(*(gw->backward_filter))[*this]) 
   803 	      *(static_cast<GraphEdge*>(this))=
   804 		++(typename Graph::OutEdgeIt(*(gw->graph), *this));
   805 	  }
   806 	} else {
   807 	  *(static_cast<GraphEdge*>(this))=
   808 	    ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
   809 	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
   810 		 !(*(gw->backward_filter))[*this]) 
   811 	    *(static_cast<GraphEdge*>(this))=
   812 	      ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
   813 	}
   814 	return *this;
   815       }
   816     };
   817 
   818     class EdgeIt : public Edge {
   819       friend class SubBidirGraphWrapper<Graph, 
   820 					ForwardFilterMap, BackwardFilterMap>;
   821     protected:
   822       const SubBidirGraphWrapper<Graph, 
   823 				 ForwardFilterMap, BackwardFilterMap>* gw;
   824     public:
   825       EdgeIt() { }
   826       EdgeIt(Invalid i) : Edge(i) { }
   827       EdgeIt(const SubBidirGraphWrapper<Graph, 
   828 	     ForwardFilterMap, BackwardFilterMap>& _gw) : 
   829 	Edge(typename Graph::EdgeIt(*(_gw.graph)), false), gw(&_gw) { 
   830 	while (*static_cast<GraphEdge*>(this)!=INVALID && 
   831 	       !(*(gw->forward_filter))[*this]) 
   832 	  *(static_cast<GraphEdge*>(this))=
   833 	    ++(typename Graph::EdgeIt(*(gw->graph), *this));
   834 	if (*static_cast<GraphEdge*>(this)==INVALID) {
   835 	  *static_cast<Edge*>(this)=
   836 	    Edge(typename Graph::EdgeIt(*(_gw.graph)), true);
   837 	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
   838 		 !(*(gw->backward_filter))[*this]) 
   839 	    *(static_cast<GraphEdge*>(this))=
   840 	      ++(typename Graph::EdgeIt(*(gw->graph), *this));
   841 	}
   842       }
   843       EdgeIt(const SubBidirGraphWrapper<Graph, 
   844 	     ForwardFilterMap, BackwardFilterMap>& _gw, const Edge& e) : 
   845 	Edge(e), gw(&_gw) { }
   846       EdgeIt& operator++() { 
   847 	if (!this->backward) {
   848 	  *(static_cast<GraphEdge*>(this))=
   849 	    ++(typename Graph::EdgeIt(*(gw->graph), *this));
   850 	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
   851 		 !(*(gw->forward_filter))[*this]) 
   852 	    *(static_cast<GraphEdge*>(this))=
   853 	      ++(typename Graph::EdgeIt(*(gw->graph), *this));
   854 	  if (*static_cast<GraphEdge*>(this)==INVALID) {
   855 	    *static_cast<Edge*>(this)=
   856 	      Edge(typename Graph::EdgeIt(*(gw->graph)), true);
   857 	    while (*static_cast<GraphEdge*>(this)!=INVALID && 
   858 		   !(*(gw->backward_filter))[*this]) 
   859 	      *(static_cast<GraphEdge*>(this))=
   860 		++(typename Graph::EdgeIt(*(gw->graph), *this));
   861 	  }
   862 	} else {
   863 	  *(static_cast<GraphEdge*>(this))=
   864 	    ++(typename Graph::EdgeIt(*(gw->graph), *this));
   865 	  while (*static_cast<GraphEdge*>(this)!=INVALID && 
   866 		 !(*(gw->backward_filter))[*this]) 
   867 	    *(static_cast<GraphEdge*>(this))=
   868 	      ++(typename Graph::EdgeIt(*(gw->graph), *this));
   869 	}
   870 	return *this;
   871       }
   872     };
   873 
   874     using GraphWrapper<Graph>::first;
   875     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
   876       i=OutEdgeIt(*this, p); return i;
   877     }
   878     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
   879       i=InEdgeIt(*this, p); return i;
   880     }
   881     EdgeIt& first(EdgeIt& i) const { 
   882       i=EdgeIt(*this); return i;
   883     }
   884   
   885 
   886     Node tail(Edge e) const { 
   887       return ((!e.backward) ? this->graph->tail(e) : this->graph->head(e)); }
   888     Node head(Edge e) const { 
   889       return ((!e.backward) ? this->graph->head(e) : this->graph->tail(e)); }
   890 
   891     /// Gives back the opposite edge.
   892     Edge opposite(const Edge& e) const { 
   893       Edge f=e;
   894       f.backward=!f.backward;
   895       return f;
   896     }
   897 
   898     /// \warning This is a linear time operation and works only if 
   899     /// \c Graph::EdgeIt is defined.
   900     int edgeNum() const { 
   901       int i=0;
   902       for (EdgeIt e(*this); e!=INVALID; ++e) ++i;
   903       return i; 
   904     }
   905 
   906     bool forward(const Edge& e) const { return !e.backward; }
   907     bool backward(const Edge& e) const { return e.backward; }
   908 
   909 
   910     template <typename T>
   911     /// \c SubBidirGraphWrapper<..., ..., ...>::EdgeMap contains two 
   912     /// Graph::EdgeMap one for the forward edges and 
   913     /// one for the backward edges.
   914     class EdgeMap {
   915       template <typename TT> friend class EdgeMap;
   916       typename Graph::template EdgeMap<T> forward_map, backward_map; 
   917     public:
   918       typedef T ValueType;
   919       typedef Edge KeyType;
   920 
   921       EdgeMap(const SubBidirGraphWrapper<Graph, 
   922 	      ForwardFilterMap, BackwardFilterMap>& g) : 
   923 	forward_map(*(g.graph)), backward_map(*(g.graph)) { }
   924 
   925       EdgeMap(const SubBidirGraphWrapper<Graph, 
   926 	      ForwardFilterMap, BackwardFilterMap>& g, T a) : 
   927 	forward_map(*(g.graph), a), backward_map(*(g.graph), a) { }
   928 
   929       template <typename TT>
   930       EdgeMap(const EdgeMap<TT>& copy) 
   931 	: forward_map(copy.forward_map), backward_map(copy.backward_map) {}
   932 
   933       template <typename TT>
   934       EdgeMap& operator=(const EdgeMap<TT>& copy) {
   935 	forward_map = copy.forward_map;
   936 	backward_map = copy.backward_map;
   937 	return *this;
   938       }
   939       
   940       void set(Edge e, T a) { 
   941 	if (!e.backward) 
   942 	  forward_map.set(e, a); 
   943 	else 
   944 	  backward_map.set(e, a); 
   945       }
   946 
   947       typename Graph::template EdgeMap<T>::ConstReferenceType 
   948       operator[](Edge e) const { 
   949 	if (!e.backward) 
   950 	  return forward_map[e]; 
   951 	else 
   952 	  return backward_map[e]; 
   953       }
   954 
   955       typename Graph::template EdgeMap<T>::ReferenceType 
   956       operator[](Edge e) { 
   957 	if (!e.backward) 
   958 	  return forward_map[e]; 
   959 	else 
   960 	  return backward_map[e]; 
   961       }
   962 
   963       void update() { 
   964 	forward_map.update(); 
   965 	backward_map.update();
   966       }
   967     };
   968 
   969 
   970     //    KEEP_NODE_MAP(Parent, SubBidirGraphWrapper);
   971 
   972   };
   973 
   974 
   975   ///\brief A wrapper for composing bidirected graph from a directed one. 
   976   ///
   977   ///\warning Graph wrappers are in even more experimental state than the other
   978   ///parts of the lib. Use them at you own risk.
   979   ///
   980   /// A wrapper for composing bidirected graph from a directed one. 
   981   /// A bidirected graph is composed over the directed one without physical 
   982   /// storage. As the oppositely directed edges are logically different ones 
   983   /// the maps are able to attach different values for them.
   984   template<typename Graph>
   985   class BidirGraphWrapper : 
   986     public SubBidirGraphWrapper<
   987     Graph, 
   988     ConstMap<typename Graph::Edge, bool>, 
   989     ConstMap<typename Graph::Edge, bool> > {
   990   public:
   991     typedef  SubBidirGraphWrapper<
   992       Graph, 
   993       ConstMap<typename Graph::Edge, bool>, 
   994       ConstMap<typename Graph::Edge, bool> > Parent; 
   995   protected:
   996     ConstMap<typename Graph::Edge, bool> cm;
   997 
   998     BidirGraphWrapper() : Parent(), cm(true) { 
   999       Parent::setForwardFilterMap(cm);
  1000       Parent::setBackwardFilterMap(cm);
  1001     }
  1002   public:
  1003     BidirGraphWrapper(Graph& _graph) : Parent() { 
  1004       Parent::setGraph(_graph);
  1005       Parent::setForwardFilterMap(cm);
  1006       Parent::setBackwardFilterMap(cm);
  1007     }
  1008 
  1009     int edgeNum() const { 
  1010       return 2*this->graph->edgeNum();
  1011     }
  1012     //    KEEP_MAPS(Parent, BidirGraphWrapper);
  1013   };
  1014 
  1015 
  1016   /// \brief A bidirected graph template.
  1017   ///
  1018   ///\warning Graph wrappers are in even more experimental state than the other
  1019   ///parts of the lib. Use them at you own risk.
  1020   ///
  1021   /// A bidirected graph template.
  1022   /// Such a bidirected graph stores each pair of oppositely directed edges 
  1023   /// ones in the memory, i.e. a directed graph of type 
  1024   /// \c Graph is used for that.
  1025   /// As the oppositely directed edges are logically different ones 
  1026   /// the maps are able to attach different values for them.
  1027   /// \ingroup graphs
  1028   template<typename Graph>
  1029   class BidirGraph : public BidirGraphWrapper<Graph> {
  1030   public:
  1031     typedef UndirGraphWrapper<Graph> Parent;
  1032   protected:
  1033     Graph gr;
  1034   public:
  1035     BidirGraph() : BidirGraphWrapper<Graph>() { 
  1036       Parent::setGraph(gr); 
  1037     }
  1038     //    KEEP_MAPS(Parent, BidirGraph);
  1039   };
  1040 
  1041 
  1042 
  1043   template<typename Graph, typename Number,
  1044 	   typename CapacityMap, typename FlowMap>
  1045   class ResForwardFilter {
  1046     //    const Graph* graph;
  1047     const CapacityMap* capacity;
  1048     const FlowMap* flow;
  1049   public:
  1050     ResForwardFilter(/*const Graph& _graph, */
  1051 		     const CapacityMap& _capacity, const FlowMap& _flow) :
  1052       /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
  1053     ResForwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
  1054     void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
  1055     void setFlow(const FlowMap& _flow) { flow=&_flow; }
  1056     bool operator[](const typename Graph::Edge& e) const {
  1057       return (Number((*flow)[e]) < Number((*capacity)[e]));
  1058     }
  1059   };
  1060 
  1061   template<typename Graph, typename Number,
  1062 	   typename CapacityMap, typename FlowMap>
  1063   class ResBackwardFilter {
  1064     const CapacityMap* capacity;
  1065     const FlowMap* flow;
  1066   public:
  1067     ResBackwardFilter(/*const Graph& _graph,*/ 
  1068 		      const CapacityMap& _capacity, const FlowMap& _flow) :
  1069       /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
  1070     ResBackwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
  1071     void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
  1072     void setFlow(const FlowMap& _flow) { flow=&_flow; }
  1073     bool operator[](const typename Graph::Edge& e) const {
  1074       return (Number(0) < Number((*flow)[e]));
  1075     }
  1076   };
  1077 
  1078   
  1079   /// A wrapper for composing the residual graph for directed flow and circulation problems.
  1080 
  1081   ///\warning Graph wrappers are in even more experimental state than the other
  1082   ///parts of the lib. Use them at you own risk.
  1083   ///
  1084   /// A wrapper for composing the residual graph for directed flow and circulation problems.
  1085   template<typename Graph, typename Number, 
  1086 	   typename CapacityMap, typename FlowMap>
  1087   class ResGraphWrapper : 
  1088     public SubBidirGraphWrapper< 
  1089     Graph, 
  1090     ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,  
  1091     ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > {
  1092   public:
  1093     typedef SubBidirGraphWrapper< 
  1094       Graph, 
  1095       ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,  
  1096       ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > Parent;
  1097   protected:
  1098     const CapacityMap* capacity;
  1099     FlowMap* flow;
  1100     ResForwardFilter<Graph, Number, CapacityMap, FlowMap> forward_filter;
  1101     ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> backward_filter;
  1102     ResGraphWrapper() : Parent(), 
  1103  			capacity(0), flow(0) { }
  1104     void setCapacityMap(const CapacityMap& _capacity) {
  1105       capacity=&_capacity;
  1106       forward_filter.setCapacity(_capacity);
  1107       backward_filter.setCapacity(_capacity);
  1108     }
  1109     void setFlowMap(FlowMap& _flow) {
  1110       flow=&_flow;
  1111       forward_filter.setFlow(_flow);
  1112       backward_filter.setFlow(_flow);
  1113     }
  1114   public:
  1115     ResGraphWrapper(Graph& _graph, const CapacityMap& _capacity, 
  1116 		       FlowMap& _flow) : 
  1117       Parent(), capacity(&_capacity), flow(&_flow), 
  1118       forward_filter(/*_graph,*/ _capacity, _flow), 
  1119       backward_filter(/*_graph,*/ _capacity, _flow) {
  1120       Parent::setGraph(_graph);
  1121       Parent::setForwardFilterMap(forward_filter);
  1122       Parent::setBackwardFilterMap(backward_filter);
  1123     }
  1124 
  1125     typedef typename Parent::Edge Edge;
  1126 
  1127     void augment(const Edge& e, Number a) const {
  1128       if (Parent::forward(e))  
  1129 	flow->set(e, (*flow)[e]+a);
  1130       else  
  1131 	flow->set(e, (*flow)[e]-a);
  1132     }
  1133 
  1134     /// \brief Residual capacity map.
  1135     ///
  1136     /// In generic residual graphs the residual capacity can be obtained 
  1137     /// as a map. 
  1138     class ResCap {
  1139     protected:
  1140       const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>* res_graph;
  1141     public:
  1142       typedef Number ValueType;
  1143       typedef Edge KeyType;
  1144       ResCap(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& 
  1145 	     _res_graph) : res_graph(&_res_graph) { }
  1146       Number operator[](const Edge& e) const { 
  1147 	if (res_graph->forward(e)) 
  1148 	  return (*(res_graph->capacity))[e]-(*(res_graph->flow))[e]; 
  1149 	else 
  1150 	  return (*(res_graph->flow))[e]; 
  1151       }
  1152     };
  1153 
  1154     //    KEEP_MAPS(Parent, ResGraphWrapper);
  1155   };
  1156 
  1157 
  1158   /// For blocking flows.
  1159 
  1160   ///\warning Graph wrappers are in even more experimental state than the other
  1161   ///parts of the lib. Use them at you own risk.
  1162   ///
  1163   /// This graph wrapper is used for on-the-fly 
  1164   /// Dinits blocking flow computations.
  1165   /// For each node, an out-edge is stored which is used when the 
  1166   /// \code 
  1167   /// OutEdgeIt& first(OutEdgeIt&, const Node&)
  1168   /// \endcode
  1169   /// is called. 
  1170   ///
  1171   /// \author Marton Makai
  1172   template<typename Graph, typename FirstOutEdgesMap>
  1173   class ErasingFirstGraphWrapper : public GraphWrapper<Graph> {
  1174   public:
  1175     typedef GraphWrapper<Graph> Parent; 
  1176   protected:
  1177     FirstOutEdgesMap* first_out_edges;
  1178   public:
  1179     ErasingFirstGraphWrapper(Graph& _graph, 
  1180 			     FirstOutEdgesMap& _first_out_edges) : 
  1181       GraphWrapper<Graph>(_graph), first_out_edges(&_first_out_edges) { }  
  1182 
  1183     typedef typename GraphWrapper<Graph>::Node Node;
  1184     typedef typename GraphWrapper<Graph>::Edge Edge;
  1185     class OutEdgeIt : public Edge { 
  1186       friend class GraphWrapper<Graph>;
  1187       friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
  1188       const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>* gw;
  1189     public:
  1190       OutEdgeIt() { }
  1191       OutEdgeIt(Invalid i) : Edge(i) { }
  1192       OutEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _gw, 
  1193 		const Node& n) : 
  1194 	Edge((*(_gw.first_out_edges))[n]), gw(&_gw) { }
  1195       OutEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _gw, 
  1196 		const Edge& e) : 
  1197 	Edge(e), gw(&_gw) { }
  1198       OutEdgeIt& operator++() { 
  1199 	*(static_cast<Edge*>(this))=
  1200 	  ++(typename Graph::OutEdgeIt(*(gw->graph), *this));
  1201 	return *this; 
  1202       }
  1203     };
  1204 
  1205     using GraphWrapper<Graph>::first;
  1206     OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
  1207       i=OutEdgeIt(*this, p); return i;
  1208     }
  1209     void erase(const Edge& e) const {
  1210       Node n=tail(e);
  1211       typename Graph::OutEdgeIt f(*Parent::graph, n);
  1212       ++f;
  1213       first_out_edges->set(n, f);
  1214     }
  1215 
  1216     //    KEEP_MAPS(Parent, ErasingFirstGraphWrapper);
  1217   };
  1218 
  1219   ///@}
  1220 
  1221 } //namespace hugo
  1222 
  1223 #endif //HUGO_GRAPH_WRAPPER_H
  1224