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