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