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