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