COIN-OR::LEMON - Graph Library

Changeset 1172:37338ae42a2b in lemon-0.x for doc/gwrappers.dox


Ignore:
Timestamp:
02/23/05 23:00:05 (19 years ago)
Author:
marci
Branch:
default
Phase:
public
Convert:
svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@1578
Message:

graphwrapper dox. everybody is asked to read doxygen.log

File:
1 copied

Legend:

Unmodified
Added
Removed
  • doc/gwrappers.dox

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