src/hugo/graph_wrapper.h
author alpar
Fri, 07 May 2004 06:35:02 +0000
changeset 566 14355e502338
parent 561 a10e6f1769e2
child 569 3b6afd33c221
permissions -rw-r--r--
Exit with correct return value
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@556
    14
//#include <iter_map.h>
marci@556
    15
marci@556
    16
namespace hugo {
marci@556
    17
marci@556
    18
  // Graph wrappers
marci@556
    19
marci@556
    20
  /// \addtogroup gwrappers
marci@556
    21
  /// A main parts of HUGOlib are the different graph structures, 
marci@556
    22
  /// generic graph algorithms, graph concepts which couple these, and 
marci@556
    23
  /// graph wrappers. While the previous ones are more or less clear, the 
marci@556
    24
  /// latter notion needs further explanation.
marci@556
    25
  /// Graph wrappers are graph classes which serve for considering graph 
marci@556
    26
  /// structures in different ways. A short example makes the notion much 
marci@556
    27
  /// clearer. 
marci@556
    28
  /// Suppose that we have an instance \c g of a directed graph
marci@556
    29
  /// type say \c ListGraph and an algorithm 
marci@556
    30
  /// \code template<typename Graph> int algorithm(const Graph&); \endcode 
marci@556
    31
  /// is needed to run on the reversely oriented graph. 
marci@556
    32
  /// It may be expensive (in time or in memory usage) to copy 
marci@556
    33
  /// \c g with the reverse orientation. 
marci@556
    34
  /// Thus, a wrapper class
marci@556
    35
  /// \code template<typename Graph> class RevGraphWrapper; \endcode is used. 
marci@556
    36
  /// The code looks as follows
marci@556
    37
  /// \code
marci@556
    38
  /// ListGraph g;
marci@556
    39
  /// RevGraphWrapper<ListGraph> rgw(g);
marci@556
    40
  /// int result=algorithm(rgw);
marci@556
    41
  /// \endcode
marci@556
    42
  /// After running the algorithm, the original graph \c g 
marci@556
    43
  /// remains untouched. Thus the graph wrapper used above is to consider the 
marci@556
    44
  /// original graph with reverse orientation. 
marci@556
    45
  /// This techniques gives rise to an elegant code, and 
marci@556
    46
  /// based on stable graph wrappers, complex algorithms can be 
marci@556
    47
  /// implemented easily. 
marci@556
    48
  /// In flow, circulation and bipartite matching problems, the residual 
marci@556
    49
  /// graph is of particular importance. Combining a wrapper implementing 
marci@556
    50
  /// this, shortest path algorithms and minimum mean cycle algorithms, 
marci@556
    51
  /// a range of weighted and cardinality optimization algorithms can be 
marci@556
    52
  /// obtained. For lack of space, for other examples, 
marci@556
    53
  /// the interested user is referred to the detailed documentation of graph 
marci@556
    54
  /// wrappers. 
marci@556
    55
  /// The behavior of graph wrappers can be very different. Some of them keep 
marci@556
    56
  /// capabilities of the original graph while in other cases this would be 
marci@556
    57
  /// meaningless. This means that the concepts that they are a model of depend 
marci@556
    58
  /// on the graph wrapper, and the wrapped graph(s). 
marci@556
    59
  /// If an edge of \c rgw is deleted, this is carried out by 
marci@556
    60
  /// deleting the corresponding edge of \c g. But for a residual 
marci@556
    61
  /// graph, this operation has no sense. 
marci@556
    62
  /// Let we stand one more example here to simplify your work. 
marci@556
    63
  /// wrapper class
marci@556
    64
  /// \code template<typename Graph> class RevGraphWrapper; \endcode 
marci@556
    65
  /// has constructor 
marci@556
    66
  /// <tt> RevGraphWrapper(Graph& _g)</tt>. 
marci@556
    67
  /// This means that in a situation, 
marci@556
    68
  /// when a <tt> const ListGraph& </tt> reference to a graph is given, 
marci@556
    69
  /// then it have to be instantiated with <tt>Graph=const ListGraph</tt>.
marci@556
    70
  /// \code
marci@556
    71
  /// int algorithm1(const ListGraph& g) {
marci@556
    72
  ///   RevGraphWrapper<const ListGraph> rgw(g);
marci@556
    73
  ///   return algorithm2(rgw);
marci@556
    74
  /// }
marci@556
    75
  /// \endcode
marci@556
    76
marci@556
    77
  /// \addtogroup gwrappers
marci@556
    78
  /// @{
marci@556
    79
marci@556
    80
  ///Base type for the Graph Wrappers
marci@556
    81
marci@556
    82
  ///This is the base type for the Graph Wrappers.
marci@556
    83
  ///\todo Some more docs... 
marci@556
    84
  ///
marci@556
    85
  ///\author Marton Makai
marci@556
    86
 
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) { }
marci@556
    99
//     Graph& getGraph() const { return *graph; }
marci@556
   100
 
marci@556
   101
//    typedef typename Graph::Node Node;
marci@556
   102
    class Node : public Graph::Node {
marci@556
   103
      friend class GraphWrapper<Graph>;
marci@556
   104
    public:
marci@556
   105
      Node() { }
marci@556
   106
      Node(const typename Graph::Node& _n) : Graph::Node(_n) { }
marci@556
   107
      Node(const Invalid& i) : Graph::Node(i) { }
marci@556
   108
    };
marci@556
   109
    class NodeIt { 
marci@556
   110
      friend class GraphWrapper<Graph>;
marci@556
   111
      typename Graph::NodeIt n;
marci@556
   112
     public:
marci@556
   113
      NodeIt() { }
marci@556
   114
      NodeIt(const typename Graph::NodeIt& _n) : n(_n) { }
marci@556
   115
      NodeIt(const Invalid& i) : n(i) { }
marci@556
   116
      NodeIt(const GraphWrapper<Graph>& _G) : n(*(_G.graph)) { }
marci@556
   117
      operator Node() const { return Node(typename Graph::Node(n)); }
marci@556
   118
    };
marci@556
   119
//    typedef typename Graph::Edge Edge;
marci@556
   120
    class Edge : public Graph::Edge {
marci@556
   121
      friend class GraphWrapper<Graph>;
marci@556
   122
    public:
marci@556
   123
      Edge() { }
marci@556
   124
      Edge(const typename Graph::Edge& _e) : Graph::Edge(_e) { }
marci@556
   125
      Edge(const Invalid& i) : Graph::Edge(i) { }
marci@556
   126
    };
marci@556
   127
    class OutEdgeIt { 
marci@556
   128
      friend class GraphWrapper<Graph>;
marci@556
   129
      typename Graph::OutEdgeIt e;
marci@556
   130
    public:
marci@556
   131
      OutEdgeIt() { }
marci@556
   132
      OutEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@556
   133
      OutEdgeIt(const Invalid& i) : e(i) { }
marci@556
   134
      OutEdgeIt(const GraphWrapper<Graph>& _G, const Node& _n) : 
marci@556
   135
	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@556
   136
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@556
   137
    };
marci@556
   138
    class InEdgeIt { 
marci@556
   139
      friend class GraphWrapper<Graph>;
marci@556
   140
      typename Graph::InEdgeIt e;
marci@556
   141
    public:
marci@556
   142
      InEdgeIt() { }
marci@556
   143
      InEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@556
   144
      InEdgeIt(const Invalid& i) : e(i) { }
marci@556
   145
      InEdgeIt(const GraphWrapper<Graph>& _G, const Node& _n) : 
marci@556
   146
	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@556
   147
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@556
   148
    };
marci@556
   149
    //typedef typename Graph::SymEdgeIt SymEdgeIt;
marci@556
   150
    class EdgeIt { 
marci@556
   151
      friend class GraphWrapper<Graph>;
marci@556
   152
      typename Graph::EdgeIt e;
marci@556
   153
    public:
marci@556
   154
      EdgeIt() { }
marci@556
   155
      EdgeIt(const typename Graph::EdgeIt& _e) : e(_e) { }
marci@556
   156
      EdgeIt(const Invalid& i) : e(i) { }
marci@556
   157
      EdgeIt(const GraphWrapper<Graph>& _G) : e(*(_G.graph)) { }
marci@556
   158
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@556
   159
    };
marci@556
   160
   
marci@556
   161
    NodeIt& first(NodeIt& i) const { 
marci@556
   162
      i=NodeIt(*this); return i;
marci@556
   163
    }
marci@556
   164
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   165
      i=OutEdgeIt(*this, p); return i;
marci@556
   166
    }
marci@556
   167
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
   168
      i=InEdgeIt(*this, p); return i;
marci@556
   169
    }
marci@556
   170
    EdgeIt& first(EdgeIt& i) const { 
marci@556
   171
      i=EdgeIt(*this); return i;
marci@556
   172
    }
marci@556
   173
marci@556
   174
    NodeIt& next(NodeIt& i) const { graph->next(i.n); return i; }
marci@556
   175
    OutEdgeIt& next(OutEdgeIt& i) const { graph->next(i.e); return i; }
marci@556
   176
    InEdgeIt& next(InEdgeIt& i) const { graph->next(i.e); return i; }
marci@556
   177
    EdgeIt& next(EdgeIt& i) const { graph->next(i.e); return i; }    
marci@556
   178
marci@556
   179
    Node tail(const Edge& e) const { 
marci@556
   180
      return Node(graph->tail(static_cast<typename Graph::Edge>(e))); }
marci@556
   181
    Node head(const Edge& e) const { 
marci@556
   182
      return Node(graph->head(static_cast<typename Graph::Edge>(e))); }
marci@556
   183
marci@556
   184
    bool valid(const Node& n) const { 
marci@556
   185
      return graph->valid(static_cast<typename Graph::Node>(n)); }
marci@556
   186
    bool valid(const Edge& e) const { 
marci@556
   187
      return graph->valid(static_cast<typename Graph::Edge>(e)); }
marci@556
   188
marci@556
   189
    int nodeNum() const { return graph->nodeNum(); }
marci@556
   190
    int edgeNum() const { return graph->edgeNum(); }
marci@556
   191
  
marci@556
   192
    Node aNode(const OutEdgeIt& e) const { return Node(graph->aNode(e.e)); }
marci@556
   193
    Node aNode(const InEdgeIt& e) const { return Node(graph->aNode(e.e)); }
marci@556
   194
    Node bNode(const OutEdgeIt& e) const { return Node(graph->bNode(e.e)); }
marci@556
   195
    Node bNode(const InEdgeIt& e) const { return Node(graph->bNode(e.e)); }
marci@556
   196
  
marci@556
   197
    Node addNode() const { return Node(graph->addNode()); }
marci@556
   198
    Edge addEdge(const Node& tail, const Node& head) const { 
marci@556
   199
      return Edge(graph->addEdge(tail, head)); }
marci@556
   200
marci@556
   201
    void erase(const Node& i) const { graph->erase(i); }
marci@556
   202
    void erase(const Edge& i) const { graph->erase(i); }
marci@556
   203
  
marci@556
   204
    void clear() const { graph->clear(); }
marci@556
   205
    
marci@556
   206
    template<typename T> class NodeMap : public Graph::template NodeMap<T> { 
marci@556
   207
      typedef typename Graph::template NodeMap<T> Parent;
marci@556
   208
    public:
marci@556
   209
      NodeMap(const GraphWrapper<Graph>& _G) :  Parent(*(_G.graph)) { }
marci@556
   210
      NodeMap(const GraphWrapper<Graph>& _G, T a) : Parent(*(_G.graph), a) { }
marci@556
   211
    };
marci@556
   212
marci@556
   213
    template<typename T> class EdgeMap : public Graph::template EdgeMap<T> { 
marci@556
   214
      typedef typename Graph::template EdgeMap<T> Parent;
marci@556
   215
    public:
marci@556
   216
      EdgeMap(const GraphWrapper<Graph>& _G) : Parent(*(_G.graph)) { }
marci@556
   217
      EdgeMap(const GraphWrapper<Graph>& _G, T a) : Parent(*(_G.graph), a) { }
marci@556
   218
    };
marci@556
   219
  };
marci@556
   220
marci@556
   221
  /// A graph wrapper which reverses the orientation of the edges.
marci@556
   222
marci@556
   223
  /// A graph wrapper which reverses the orientation of the edges.
marci@556
   224
  ///
marci@556
   225
  ///\author Marton Makai
marci@556
   226
  template<typename Graph>
marci@556
   227
  class RevGraphWrapper : public GraphWrapper<Graph> {
marci@556
   228
  protected:
marci@556
   229
    RevGraphWrapper() : GraphWrapper<Graph>(0) { }
marci@556
   230
  public:
marci@556
   231
    RevGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }  
marci@556
   232
marci@556
   233
    typedef typename GraphWrapper<Graph>::Node Node;
marci@556
   234
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@556
   235
    //If Graph::OutEdgeIt is not defined
marci@556
   236
    //and we do not want to use RevGraphWrapper::InEdgeIt,
marci@556
   237
    //the typdef techinque does not work.
marci@556
   238
    //Unfortunately all the typedefs are instantiated in templates.
marci@556
   239
    //typedef typename GraphWrapper<Graph>::OutEdgeIt InEdgeIt;
marci@556
   240
    //typedef typename GraphWrapper<Graph>::InEdgeIt OutEdgeIt;
marci@556
   241
marci@556
   242
    class OutEdgeIt { 
marci@556
   243
      friend class GraphWrapper<Graph>;
marci@556
   244
      friend class RevGraphWrapper<Graph>;
marci@556
   245
      typename Graph::InEdgeIt e;
marci@556
   246
    public:
marci@556
   247
      OutEdgeIt() { }
marci@556
   248
      OutEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@556
   249
      OutEdgeIt(const Invalid& i) : e(i) { }
marci@556
   250
      OutEdgeIt(const RevGraphWrapper<Graph>& _G, const Node& _n) : 
marci@556
   251
	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@556
   252
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@556
   253
    };
marci@556
   254
    class InEdgeIt { 
marci@556
   255
      friend class GraphWrapper<Graph>;
marci@556
   256
      friend class RevGraphWrapper<Graph>;
marci@556
   257
      typename Graph::OutEdgeIt e;
marci@556
   258
    public:
marci@556
   259
      InEdgeIt() { }
marci@556
   260
      InEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@556
   261
      InEdgeIt(const Invalid& i) : e(i) { }
marci@556
   262
      InEdgeIt(const RevGraphWrapper<Graph>& _G, const Node& _n) : 
marci@556
   263
	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@556
   264
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@556
   265
    };
marci@556
   266
marci@556
   267
    using GraphWrapper<Graph>::first;
marci@556
   268
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   269
      i=OutEdgeIt(*this, p); return i;
marci@556
   270
    }
marci@556
   271
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
   272
      i=InEdgeIt(*this, p); return i;
marci@556
   273
    }
marci@556
   274
marci@556
   275
    using GraphWrapper<Graph>::next;
marci@556
   276
    OutEdgeIt& next(OutEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@556
   277
    InEdgeIt& next(InEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@556
   278
marci@556
   279
    Node aNode(const OutEdgeIt& e) const { 
marci@556
   280
      return Node(this->graph->aNode(e.e)); }
marci@556
   281
    Node aNode(const InEdgeIt& e) const { 
marci@556
   282
      return Node(this->graph->aNode(e.e)); }
marci@556
   283
    Node bNode(const OutEdgeIt& e) const { 
marci@556
   284
      return Node(this->graph->bNode(e.e)); }
marci@556
   285
    Node bNode(const InEdgeIt& e) const { 
marci@556
   286
      return Node(this->graph->bNode(e.e)); }
marci@556
   287
marci@556
   288
    Node tail(const Edge& e) const { 
marci@556
   289
      return GraphWrapper<Graph>::head(e); }
marci@556
   290
    Node head(const Edge& e) const { 
marci@556
   291
      return GraphWrapper<Graph>::tail(e); }
marci@556
   292
marci@556
   293
  };
marci@556
   294
marci@556
   295
  /// Wrapper for hiding nodes and edges from a graph.
marci@556
   296
  
marci@556
   297
  /// This wrapper shows a graph with filtered node-set and 
marci@556
   298
  /// edge-set. The quick brown fox iterator jumps over 
marci@556
   299
  /// the lazy dog nodes or edges if the values for them are false 
marci@556
   300
  /// in the bool maps. 
marci@556
   301
  ///
marci@556
   302
  ///\author Marton Makai
marci@556
   303
  template<typename Graph, typename NodeFilterMap, 
marci@556
   304
	   typename EdgeFilterMap>
marci@556
   305
  class SubGraphWrapper : public GraphWrapper<Graph> {
marci@556
   306
  protected:
marci@556
   307
    NodeFilterMap* node_filter_map;
marci@556
   308
    EdgeFilterMap* edge_filter_map;
marci@556
   309
marci@556
   310
    SubGraphWrapper() : GraphWrapper<Graph>(0), 
marci@556
   311
			node_filter_map(0), edge_filter_map(0) { }
marci@556
   312
    void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
marci@556
   313
      node_filter_map=&_node_filter_map;
marci@556
   314
    }
marci@556
   315
    void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
marci@556
   316
      edge_filter_map=&_edge_filter_map;
marci@556
   317
    }
marci@556
   318
    
marci@556
   319
  public:
marci@556
   320
marci@556
   321
    SubGraphWrapper(Graph& _graph, NodeFilterMap& _node_filter_map, 
marci@556
   322
		    EdgeFilterMap& _edge_filter_map) : 
marci@556
   323
      GraphWrapper<Graph>(_graph), node_filter_map(&_node_filter_map), 
marci@556
   324
      edge_filter_map(&_edge_filter_map) { }  
marci@556
   325
marci@556
   326
    typedef typename GraphWrapper<Graph>::Node Node;
marci@556
   327
    class NodeIt { 
marci@556
   328
      friend class GraphWrapper<Graph>;
marci@556
   329
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@556
   330
      typename Graph::NodeIt n;
marci@556
   331
     public:
marci@556
   332
      NodeIt() { }
marci@556
   333
      NodeIt(const typename Graph::NodeIt& _n) : n(_n) { }
marci@556
   334
      NodeIt(const Invalid& i) : n(i) { }
marci@556
   335
      NodeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _G) : 
marci@556
   336
	n(*(_G.graph)) { 
marci@556
   337
	while (_G.graph->valid(n) && !(*(_G.node_filter_map))[n]) 
marci@556
   338
	  _G.graph->next(n);
marci@556
   339
      }
marci@556
   340
      operator Node() const { return Node(typename Graph::Node(n)); }
marci@556
   341
    };
marci@556
   342
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@556
   343
    class OutEdgeIt { 
marci@556
   344
      friend class GraphWrapper<Graph>;
marci@556
   345
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@556
   346
      typename Graph::OutEdgeIt e;
marci@556
   347
    public:
marci@556
   348
      OutEdgeIt() { }
marci@556
   349
      OutEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@556
   350
      OutEdgeIt(const Invalid& i) : e(i) { }
marci@556
   351
      OutEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _G, 
marci@556
   352
		const Node& _n) : 
marci@556
   353
	e(*(_G.graph), typename Graph::Node(_n)) { 
marci@556
   354
      	while (_G.graph->valid(e) && !(*(_G.edge_filter_map))[e]) 
marci@556
   355
	  _G.graph->next(e);
marci@556
   356
      }
marci@556
   357
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@556
   358
    };
marci@556
   359
    class InEdgeIt { 
marci@556
   360
      friend class GraphWrapper<Graph>;
marci@556
   361
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@556
   362
      typename Graph::InEdgeIt e;
marci@556
   363
    public:
marci@556
   364
      InEdgeIt() { }
marci@556
   365
      InEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@556
   366
      InEdgeIt(const Invalid& i) : e(i) { }
marci@556
   367
      InEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _G, 
marci@556
   368
	       const Node& _n) : 
marci@556
   369
	e(*(_G.graph), typename Graph::Node(_n)) { 
marci@556
   370
      	while (_G.graph->valid(e) && !(*(_G.edge_filter_map))[e]) 
marci@556
   371
	  _G.graph->next(e);
marci@556
   372
      }
marci@556
   373
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@556
   374
    };
marci@556
   375
    //typedef typename Graph::SymEdgeIt SymEdgeIt;
marci@556
   376
    class EdgeIt { 
marci@556
   377
      friend class GraphWrapper<Graph>;
marci@556
   378
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@556
   379
      typename Graph::EdgeIt e;
marci@556
   380
    public:
marci@556
   381
      EdgeIt() { }
marci@556
   382
      EdgeIt(const typename Graph::EdgeIt& _e) : e(_e) { }
marci@556
   383
      EdgeIt(const Invalid& i) : e(i) { }
marci@556
   384
      EdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _G) : 
marci@556
   385
	e(*(_G.graph)) { 
marci@556
   386
      	while (_G.graph->valid(e) && !(*(_G.edge_filter_map))[e]) 
marci@556
   387
	  _G.graph->next(e);
marci@556
   388
      }
marci@556
   389
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@556
   390
    };
marci@556
   391
marci@556
   392
    NodeIt& first(NodeIt& i) const { 
marci@556
   393
      i=NodeIt(*this); return i;
marci@556
   394
    }
marci@556
   395
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   396
      i=OutEdgeIt(*this, p); return i;
marci@556
   397
    }
marci@556
   398
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
   399
      i=InEdgeIt(*this, p); return i;
marci@556
   400
    }
marci@556
   401
    EdgeIt& first(EdgeIt& i) const { 
marci@556
   402
      i=EdgeIt(*this); return i;
marci@556
   403
    }
marci@556
   404
    
marci@556
   405
    NodeIt& next(NodeIt& i) const {
marci@556
   406
      this->graph->next(i.n); 
marci@556
   407
      while (this->graph->valid(i) && !(*node_filter_map)[i.n]) { 
marci@556
   408
	this->graph->next(i.n); }
marci@556
   409
      return i;
marci@556
   410
    }
marci@556
   411
    OutEdgeIt& next(OutEdgeIt& i) const {
marci@556
   412
      this->graph->next(i.e); 
marci@556
   413
      while (this->graph->valid(i) && !(*edge_filter_map)[i.e]) { 
marci@556
   414
	this->graph->next(i.e); }
marci@556
   415
      return i;
marci@556
   416
    }
marci@556
   417
    InEdgeIt& next(InEdgeIt& i) const {
marci@556
   418
      this->graph->next(i.e); 
marci@556
   419
      while (this->graph->valid(i) && !(*edge_filter_map)[i.e]) { 
marci@556
   420
	this->graph->next(i.e); }
marci@556
   421
      return i;
marci@556
   422
    }
marci@556
   423
    EdgeIt& next(EdgeIt& i) const {
marci@556
   424
      this->graph->next(i.e); 
marci@556
   425
      while (this->graph->valid(i) && !(*edge_filter_map)[i.e]) { 
marci@556
   426
	this->graph->next(i.e); }
marci@556
   427
      return i;
marci@556
   428
    }
marci@556
   429
marci@556
   430
    Node aNode(const OutEdgeIt& e) const { 
marci@556
   431
      return Node(this->graph->aNode(e.e)); }
marci@556
   432
    Node aNode(const InEdgeIt& e) const { 
marci@556
   433
      return Node(this->graph->aNode(e.e)); }
marci@556
   434
    Node bNode(const OutEdgeIt& e) const { 
marci@556
   435
      return Node(this->graph->bNode(e.e)); }
marci@556
   436
    Node bNode(const InEdgeIt& e) const { 
marci@556
   437
      return Node(this->graph->bNode(e.e)); }
marci@556
   438
marci@561
   439
    /// This function hides \c n in the graph, i.e. the iteration 
marci@561
   440
    /// jumps over it. This is done by simply setting the value of \c n  
marci@561
   441
    /// to be false in the corresponding node-map.
marci@556
   442
    void hide(const Node& n) const { node_filter_map->set(n, false); }
marci@561
   443
marci@561
   444
    /// This function hides \c e in the graph, i.e. the iteration 
marci@561
   445
    /// jumps over it. This is done by simply setting the value of \c e  
marci@561
   446
    /// to be false in the corresponding edge-map.
marci@556
   447
    void hide(const Edge& e) const { edge_filter_map->set(e, false); }
marci@556
   448
marci@561
   449
    /// The value of \c n is set to be true in the node-map which stores 
marci@561
   450
    /// hide information. If \c n was hidden previuosly, then it is shown 
marci@561
   451
    /// again
marci@561
   452
     void unHide(const Node& n) const { node_filter_map->set(n, true); }
marci@561
   453
marci@561
   454
    /// The value of \c e is set to be true in the edge-map which stores 
marci@561
   455
    /// hide information. If \c e was hidden previuosly, then it is shown 
marci@561
   456
    /// again
marci@556
   457
    void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
marci@556
   458
marci@561
   459
    /// Returns true if \c n is hidden.
marci@561
   460
    bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
marci@561
   461
marci@561
   462
    /// Returns true if \c n is hidden.
marci@561
   463
    bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
marci@556
   464
  };
marci@556
   465
marci@556
   466
  /// A wrapper for forgetting the orientation of a graph.
marci@556
   467
marci@556
   468
  /// A wrapper for getting an undirected graph by forgetting
marci@556
   469
  /// the orientation of a directed one.
marci@556
   470
  template<typename Graph>
marci@556
   471
  class UndirGraphWrapper : public GraphWrapper<Graph> {
marci@556
   472
  protected:
marci@556
   473
    UndirGraphWrapper() : GraphWrapper<Graph>() { }
marci@556
   474
    
marci@556
   475
  public:
marci@556
   476
    typedef typename GraphWrapper<Graph>::Node Node;
marci@556
   477
    typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
marci@556
   478
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@556
   479
    typedef typename GraphWrapper<Graph>::EdgeIt EdgeIt;
marci@556
   480
marci@556
   481
    UndirGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }  
marci@556
   482
marci@556
   483
    class OutEdgeIt {
marci@556
   484
      friend class UndirGraphWrapper<Graph>;
marci@556
   485
      bool out_or_in; //true iff out
marci@556
   486
      typename Graph::OutEdgeIt out;
marci@556
   487
      typename Graph::InEdgeIt in;
marci@556
   488
    public:
marci@556
   489
      OutEdgeIt() { }
marci@556
   490
      OutEdgeIt(const Invalid& i) : Edge(i) { }
marci@556
   491
      OutEdgeIt(const UndirGraphWrapper<Graph>& _G, const Node& _n) {
marci@556
   492
	out_or_in=true; _G.graph->first(out, _n);
marci@556
   493
	if (!(_G.graph->valid(out))) { out_or_in=false; _G.graph->first(in, _n);	}
marci@556
   494
      } 
marci@556
   495
      operator Edge() const { 
marci@556
   496
	if (out_or_in) return Edge(out); else return Edge(in); 
marci@556
   497
      }
marci@556
   498
    };
marci@556
   499
marci@556
   500
//FIXME InEdgeIt
marci@556
   501
    typedef OutEdgeIt InEdgeIt; 
marci@556
   502
marci@556
   503
    using GraphWrapper<Graph>::first;
marci@556
   504
//     NodeIt& first(NodeIt& i) const { 
marci@556
   505
//       i=NodeIt(*this); return i;
marci@556
   506
//     }
marci@556
   507
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   508
      i=OutEdgeIt(*this, p); return i;
marci@556
   509
    }
marci@556
   510
//FIXME
marci@556
   511
//     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
   512
//       i=InEdgeIt(*this, p); return i;
marci@556
   513
//     }
marci@556
   514
//     EdgeIt& first(EdgeIt& i) const { 
marci@556
   515
//       i=EdgeIt(*this); return i;
marci@556
   516
//     }
marci@556
   517
marci@556
   518
    using GraphWrapper<Graph>::next;
marci@556
   519
//     NodeIt& next(NodeIt& n) const {
marci@556
   520
//       GraphWrapper<Graph>::next(n);
marci@556
   521
//       return n;
marci@556
   522
//     }
marci@556
   523
    OutEdgeIt& next(OutEdgeIt& e) const {
marci@556
   524
      if (e.out_or_in) {
marci@556
   525
	typename Graph::Node n=this->graph->tail(e.out);
marci@556
   526
	this->graph->next(e.out);
marci@556
   527
	if (!this->graph->valid(e.out)) { 
marci@556
   528
	  e.out_or_in=false; this->graph->first(e.in, n); }
marci@556
   529
      } else {
marci@556
   530
	this->graph->next(e.in);
marci@556
   531
      }
marci@556
   532
      return e;
marci@556
   533
    }
marci@556
   534
    //FIXME InEdgeIt
marci@556
   535
//     EdgeIt& next(EdgeIt& e) const {
marci@556
   536
//       GraphWrapper<Graph>::next(n);
marci@556
   537
// //      graph->next(e.e);
marci@556
   538
//       return e;
marci@556
   539
//     }
marci@556
   540
marci@556
   541
    Node aNode(const OutEdgeIt& e) const { 
marci@556
   542
      if (e.out_or_in) return this->graph->tail(e); else 
marci@556
   543
	return this->graph->head(e); }
marci@556
   544
    Node bNode(const OutEdgeIt& e) const { 
marci@556
   545
      if (e.out_or_in) return this->graph->head(e); else 
marci@556
   546
	return this->graph->tail(e); }
marci@556
   547
  };
marci@556
   548
  
marci@556
   549
marci@556
   550
marci@556
   551
  /// An undirected graph template
marci@556
   552
  template<typename Graph>
marci@556
   553
  class UndirGraph : public UndirGraphWrapper<Graph> {
marci@556
   554
    typedef UndirGraphWrapper<Graph> Parent;
marci@556
   555
  protected:
marci@556
   556
    Graph gr;
marci@556
   557
  public:
marci@556
   558
    UndirGraph() : UndirGraphWrapper<Graph>() { 
marci@556
   559
      Parent::setGraph(gr); 
marci@556
   560
    }
marci@556
   561
  };
marci@556
   562
marci@556
   563
  
marci@556
   564
marci@556
   565
  /// A wrapper for composing the residual graph for directed flow and circulation problems.
marci@556
   566
marci@556
   567
  /// A wrapper for composing the residual graph for directed flow and circulation problems.
marci@556
   568
  template<typename Graph, typename Number, 
marci@556
   569
	   typename CapacityMap, typename FlowMap>
marci@556
   570
  class ResGraphWrapper : public GraphWrapper<Graph> {
marci@556
   571
  protected:
marci@556
   572
    const CapacityMap* capacity;
marci@556
   573
    FlowMap* flow;
marci@556
   574
marci@556
   575
    ResGraphWrapper() : GraphWrapper<Graph>(0), 
marci@556
   576
			capacity(0), flow(0) { }
marci@560
   577
    void setCapacityMap(const CapacityMap& _capacity) {
marci@560
   578
      capacity=&_capacity;
marci@556
   579
    }
marci@556
   580
    void setFlowMap(FlowMap& _flow) {
marci@556
   581
      flow=&_flow;
marci@556
   582
    }
marci@556
   583
marci@556
   584
  public:
marci@556
   585
marci@556
   586
    ResGraphWrapper(Graph& _graph, const CapacityMap& _capacity, 
marci@556
   587
		    FlowMap& _flow) : 
marci@556
   588
      GraphWrapper<Graph>(_graph), capacity(&_capacity), flow(&_flow) { }
marci@556
   589
marci@556
   590
    class Edge; 
marci@556
   591
    class OutEdgeIt; 
marci@556
   592
    friend class Edge; 
marci@556
   593
    friend class OutEdgeIt; 
marci@556
   594
marci@556
   595
    typedef typename GraphWrapper<Graph>::Node Node;
marci@556
   596
    typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
marci@556
   597
    class Edge : public Graph::Edge {
marci@556
   598
      friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@556
   599
    protected:
marci@565
   600
      bool backward; //true, iff backward
marci@556
   601
//      typename Graph::Edge e;
marci@556
   602
    public:
marci@556
   603
      Edge() { }
marci@565
   604
      Edge(const typename Graph::Edge& _e, bool _backward) : 
marci@565
   605
	Graph::Edge(_e), backward(_backward) { }
marci@565
   606
      Edge(const Invalid& i) : Graph::Edge(i), backward(true) { }
marci@556
   607
//the unique invalid iterator
marci@556
   608
      friend bool operator==(const Edge& u, const Edge& v) { 
marci@565
   609
	return (v.backward==u.backward && 
marci@556
   610
		static_cast<typename Graph::Edge>(u)==
marci@556
   611
		static_cast<typename Graph::Edge>(v));
marci@556
   612
      } 
marci@556
   613
      friend bool operator!=(const Edge& u, const Edge& v) { 
marci@565
   614
	return (v.backward!=u.backward || 
marci@556
   615
		static_cast<typename Graph::Edge>(u)!=
marci@556
   616
		static_cast<typename Graph::Edge>(v));
marci@556
   617
      } 
marci@556
   618
    };
marci@556
   619
marci@556
   620
    class OutEdgeIt {
marci@556
   621
      friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@556
   622
    protected:
marci@556
   623
      typename Graph::OutEdgeIt out;
marci@556
   624
      typename Graph::InEdgeIt in;
marci@565
   625
      bool backward;
marci@556
   626
    public:
marci@556
   627
      OutEdgeIt() { }
marci@556
   628
      //FIXME
marci@556
   629
//      OutEdgeIt(const Edge& e) : Edge(e) { }
marci@565
   630
      OutEdgeIt(const Invalid& i) : out(i), in(i), backward(true) { }
marci@556
   631
//the unique invalid iterator
marci@556
   632
      OutEdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG, Node v) { 
marci@565
   633
	backward=false;
marci@556
   634
	resG.graph->first(out, v);
marci@556
   635
	while( resG.graph->valid(out) && !(resG.resCap(*this)>0) ) { resG.graph->next(out); }
marci@556
   636
	if (!resG.graph->valid(out)) {
marci@565
   637
	  backward=true;
marci@556
   638
	  resG.graph->first(in, v);
marci@556
   639
	  while( resG.graph->valid(in) && !(resG.resCap(*this)>0) ) { resG.graph->next(in); }
marci@556
   640
	}
marci@556
   641
      }
marci@556
   642
      operator Edge() const { 
marci@556
   643
//	Edge e;
marci@556
   644
//	e.forward=this->forward;
marci@556
   645
//	if (this->forward) e=out; else e=in;
marci@556
   646
//	return e;
marci@565
   647
	if (this->backward) 
marci@565
   648
	  return Edge(in, this->backward); 
marci@556
   649
	else 
marci@565
   650
	  return Edge(out, this->backward);
marci@556
   651
      }
marci@556
   652
    };
marci@556
   653
marci@556
   654
    class InEdgeIt {
marci@556
   655
      friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@556
   656
    protected:
marci@556
   657
      typename Graph::OutEdgeIt out;
marci@556
   658
      typename Graph::InEdgeIt in;
marci@565
   659
      bool backward;
marci@556
   660
    public:
marci@556
   661
      InEdgeIt() { }
marci@556
   662
      //FIXME
marci@556
   663
//      OutEdgeIt(const Edge& e) : Edge(e) { }
marci@565
   664
      InEdgeIt(const Invalid& i) : out(i), in(i), backward(true) { }
marci@556
   665
//the unique invalid iterator
marci@556
   666
      InEdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG, Node v) { 
marci@565
   667
	backward=false;
marci@556
   668
	resG.graph->first(in, v);
marci@556
   669
	while( resG.graph->valid(in) && !(resG.resCap(*this)>0) ) { resG.graph->next(in); }
marci@556
   670
	if (!resG.graph->valid(in)) {
marci@565
   671
	  backward=true;
marci@556
   672
	  resG.graph->first(out, v);
marci@556
   673
	  while( resG.graph->valid(out) && !(resG.resCap(*this)>0) ) { resG.graph->next(out); }
marci@556
   674
	}
marci@556
   675
      }
marci@556
   676
      operator Edge() const { 
marci@556
   677
//	Edge e;
marci@556
   678
//	e.forward=this->forward;
marci@556
   679
//	if (this->forward) e=out; else e=in;
marci@556
   680
//	return e;
marci@565
   681
	if (this->backward) 
marci@565
   682
	  return Edge(out, this->backward); 
marci@556
   683
	else 
marci@565
   684
	  return Edge(in, this->backward);
marci@556
   685
      }
marci@556
   686
    };
marci@556
   687
marci@556
   688
    class EdgeIt {
marci@556
   689
      friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@556
   690
    protected:
marci@556
   691
      typename Graph::EdgeIt e;
marci@565
   692
      bool backward;
marci@556
   693
    public:
marci@556
   694
      EdgeIt() { }
marci@565
   695
      EdgeIt(const Invalid& i) : e(i), backward(true) { }
marci@556
   696
      EdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG) { 
marci@565
   697
	backward=false;
marci@556
   698
	resG.graph->first(e);
marci@556
   699
	while (resG.graph->valid(e) && !(resG.resCap(*this)>0)) resG.graph->next(e);
marci@556
   700
	if (!resG.graph->valid(e)) {
marci@565
   701
	  backward=true;
marci@556
   702
	  resG.graph->first(e);
marci@556
   703
	  while (resG.graph->valid(e) && !(resG.resCap(*this)>0)) resG.graph->next(e);
marci@556
   704
	}
marci@556
   705
      }
marci@556
   706
      operator Edge() const { 
marci@565
   707
	return Edge(e, this->backward);
marci@556
   708
      }
marci@556
   709
    };
marci@556
   710
marci@556
   711
    using GraphWrapper<Graph>::first;
marci@556
   712
//     NodeIt& first(NodeIt& i) const { 
marci@556
   713
//       i=NodeIt(*this); return i;
marci@556
   714
//     }
marci@556
   715
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   716
      i=OutEdgeIt(*this, p); return i;
marci@556
   717
    }
marci@556
   718
//    FIXME not tested
marci@556
   719
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
   720
      i=InEdgeIt(*this, p); return i;
marci@556
   721
    }
marci@556
   722
    EdgeIt& first(EdgeIt& i) const { 
marci@556
   723
      i=EdgeIt(*this); return i;
marci@556
   724
    }
marci@556
   725
  
marci@556
   726
    using GraphWrapper<Graph>::next;
marci@556
   727
//    NodeIt& next(NodeIt& n) const { GraphWrapper<Graph>::next(n); return n; }
marci@556
   728
    OutEdgeIt& next(OutEdgeIt& e) const { 
marci@565
   729
      if (!e.backward) {
marci@556
   730
	Node v=this->graph->aNode(e.out);
marci@556
   731
	this->graph->next(e.out);
marci@556
   732
	while( this->graph->valid(e.out) && !(resCap(e)>0) ) { 
marci@556
   733
	  this->graph->next(e.out); }
marci@556
   734
	if (!this->graph->valid(e.out)) {
marci@565
   735
	  e.backward=true;
marci@556
   736
	  this->graph->first(e.in, v); 
marci@556
   737
	  while( this->graph->valid(e.in) && !(resCap(e)>0) ) { 
marci@556
   738
	    this->graph->next(e.in); }
marci@556
   739
	}
marci@556
   740
      } else {
marci@556
   741
	this->graph->next(e.in);
marci@556
   742
	while( this->graph->valid(e.in) && !(resCap(e)>0) ) { 
marci@556
   743
	  this->graph->next(e.in); } 
marci@556
   744
      }
marci@556
   745
      return e;
marci@556
   746
    }
marci@556
   747
//     FIXME Not tested
marci@556
   748
    InEdgeIt& next(InEdgeIt& e) const { 
marci@565
   749
      if (!e.backward) {
marci@556
   750
	Node v=this->graph->aNode(e.in);
marci@556
   751
	this->graph->next(e.in);
marci@556
   752
	while( this->graph->valid(e.in) && !(resCap(e)>0) ) { 
marci@556
   753
	  this->graph->next(e.in); }
marci@556
   754
	if (!this->graph->valid(e.in)) {
marci@565
   755
	  e.backward=true;
marci@556
   756
	  this->graph->first(e.out, v); 
marci@556
   757
	  while( this->graph->valid(e.out) && !(resCap(e)>0) ) { 
marci@556
   758
	    this->graph->next(e.out); }
marci@556
   759
	}
marci@556
   760
      } else {
marci@556
   761
	this->graph->next(e.out);
marci@556
   762
	while( this->graph->valid(e.out) && !(resCap(e)>0) ) { 
marci@556
   763
	  this->graph->next(e.out); } 
marci@556
   764
      }
marci@556
   765
      return e;
marci@556
   766
    }
marci@556
   767
    EdgeIt& next(EdgeIt& e) const {
marci@565
   768
      if (!e.backward) {
marci@556
   769
	this->graph->next(e.e);
marci@556
   770
	while( this->graph->valid(e.e) && !(resCap(e)>0) ) { 
marci@556
   771
	  this->graph->next(e.e); }
marci@556
   772
	if (!this->graph->valid(e.e)) {
marci@565
   773
	  e.backward=true;
marci@556
   774
	  this->graph->first(e.e); 
marci@556
   775
	  while( this->graph->valid(e.e) && !(resCap(e)>0) ) { 
marci@556
   776
	    this->graph->next(e.e); }
marci@556
   777
	}
marci@556
   778
      } else {
marci@556
   779
	this->graph->next(e.e);
marci@556
   780
	while( this->graph->valid(e.e) && !(resCap(e)>0) ) { 
marci@556
   781
	  this->graph->next(e.e); } 
marci@556
   782
      }
marci@556
   783
      return e;
marci@556
   784
    }
marci@556
   785
marci@556
   786
    Node tail(Edge e) const { 
marci@565
   787
      return ((!e.backward) ? this->graph->tail(e) : this->graph->head(e)); }
marci@556
   788
    Node head(Edge e) const { 
marci@565
   789
      return ((!e.backward) ? this->graph->head(e) : this->graph->tail(e)); }
marci@556
   790
marci@556
   791
    Node aNode(OutEdgeIt e) const { 
marci@565
   792
      return ((!e.backward) ? this->graph->aNode(e.out) : 
marci@556
   793
	      this->graph->aNode(e.in)); }
marci@556
   794
    Node bNode(OutEdgeIt e) const { 
marci@565
   795
      return ((!e.backward) ? this->graph->bNode(e.out) : 
marci@556
   796
	      this->graph->bNode(e.in)); }
marci@556
   797
marci@556
   798
    Node aNode(InEdgeIt e) const { 
marci@565
   799
      return ((!e.backward) ? this->graph->aNode(e.in) : 
marci@556
   800
	      this->graph->aNode(e.out)); }
marci@556
   801
    Node bNode(InEdgeIt e) const { 
marci@565
   802
      return ((!e.backward) ? this->graph->bNode(e.in) : 
marci@556
   803
	      this->graph->bNode(e.out)); }
marci@556
   804
marci@556
   805
//    int nodeNum() const { return graph->nodeNum(); }
marci@556
   806
    //FIXME
marci@556
   807
    void edgeNum() const { }
marci@556
   808
    //int edgeNum() const { return graph->edgeNum(); }
marci@556
   809
marci@556
   810
marci@556
   811
//    int id(Node v) const { return graph->id(v); }
marci@556
   812
marci@556
   813
    bool valid(Node n) const { return GraphWrapper<Graph>::valid(n); }
marci@556
   814
    bool valid(Edge e) const { 
marci@556
   815
      return this->graph->valid(e);
marci@556
   816
	//return e.forward ? graph->valid(e.out) : graph->valid(e.in); 
marci@556
   817
    }
marci@556
   818
marci@565
   819
    bool forward(const Edge& e) const { return !e.backward; }
marci@565
   820
    bool backward(const Edge& e) const { return e.backward; }
marci@556
   821
marci@556
   822
    void augment(const Edge& e, Number a) const {
marci@565
   823
      if (!e.backward)  
marci@556
   824
// 	flow->set(e.out, flow->get(e.out)+a);
marci@556
   825
	flow->set(e, (*flow)[e]+a);
marci@556
   826
      else  
marci@556
   827
// 	flow->set(e.in, flow->get(e.in)-a);
marci@556
   828
	flow->set(e, (*flow)[e]-a);
marci@556
   829
    }
marci@556
   830
marci@556
   831
    Number resCap(const Edge& e) const { 
marci@565
   832
      if (!e.backward) 
marci@556
   833
//	return (capacity->get(e.out)-flow->get(e.out)); 
marci@556
   834
	return ((*capacity)[e]-(*flow)[e]); 
marci@556
   835
      else 
marci@556
   836
//	return (flow->get(e.in)); 
marci@556
   837
	return ((*flow)[e]); 
marci@556
   838
    }
marci@556
   839
marci@556
   840
//     Number resCap(typename Graph::OutEdgeIt out) const { 
marci@556
   841
// //      return (capacity->get(out)-flow->get(out)); 
marci@556
   842
//       return ((*capacity)[out]-(*flow)[out]); 
marci@556
   843
//     }
marci@556
   844
    
marci@556
   845
//     Number resCap(typename Graph::InEdgeIt in) const { 
marci@556
   846
// //      return (flow->get(in)); 
marci@556
   847
//       return ((*flow)[in]); 
marci@556
   848
//     }
marci@556
   849
marci@556
   850
    template <typename T>
marci@556
   851
    class EdgeMap {
marci@556
   852
      typename Graph::template EdgeMap<T> forward_map, backward_map; 
marci@556
   853
    public:
marci@556
   854
      EdgeMap(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G) : forward_map(*(_G.graph)), backward_map(*(_G.graph)) { }
marci@556
   855
      EdgeMap(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G, T a) : forward_map(*(_G.graph), a), backward_map(*(_G.graph), a) { }
marci@556
   856
      void set(Edge e, T a) { 
marci@565
   857
	if (!e.backward) 
marci@556
   858
	  forward_map.set(e.out, a); 
marci@556
   859
	else 
marci@556
   860
	  backward_map.set(e.in, a); 
marci@556
   861
      }
marci@556
   862
      T operator[](Edge e) const { 
marci@565
   863
	if (!e.backward) 
marci@556
   864
	  return forward_map[e.out]; 
marci@556
   865
	else 
marci@556
   866
	  return backward_map[e.in]; 
marci@556
   867
      }
marci@556
   868
//       T get(Edge e) const { 
marci@556
   869
// 	if (e.out_or_in) 
marci@556
   870
// 	  return forward_map.get(e.out); 
marci@556
   871
// 	else 
marci@556
   872
// 	  return backward_map.get(e.in); 
marci@556
   873
//       }
marci@556
   874
    };
marci@556
   875
  };
marci@556
   876
marci@556
   877
  /// ErasingFirstGraphWrapper for blocking flows.
marci@556
   878
marci@556
   879
  /// ErasingFirstGraphWrapper for blocking flows.
marci@556
   880
  ///
marci@556
   881
  ///\author Marton Makai
marci@556
   882
  template<typename Graph, typename FirstOutEdgesMap>
marci@556
   883
  class ErasingFirstGraphWrapper : public GraphWrapper<Graph> {
marci@556
   884
  protected:
marci@556
   885
    FirstOutEdgesMap* first_out_edges;
marci@556
   886
  public:
marci@556
   887
    ErasingFirstGraphWrapper(Graph& _graph, 
marci@556
   888
			     FirstOutEdgesMap& _first_out_edges) : 
marci@556
   889
      GraphWrapper<Graph>(_graph), first_out_edges(&_first_out_edges) { }  
marci@556
   890
marci@556
   891
    typedef typename GraphWrapper<Graph>::Node Node;
marci@556
   892
//     class NodeIt { 
marci@556
   893
//       friend class GraphWrapper<Graph>;
marci@556
   894
//       friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@556
   895
//       typename Graph::NodeIt n;
marci@556
   896
//      public:
marci@556
   897
//       NodeIt() { }
marci@556
   898
//       NodeIt(const typename Graph::NodeIt& _n) : n(_n) { }
marci@556
   899
//       NodeIt(const Invalid& i) : n(i) { }
marci@556
   900
//       NodeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G) : 
marci@556
   901
// 	n(*(_G.graph)) { }
marci@556
   902
//       operator Node() const { return Node(typename Graph::Node(n)); }
marci@556
   903
//     };
marci@556
   904
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@556
   905
    class OutEdgeIt { 
marci@556
   906
      friend class GraphWrapper<Graph>;
marci@556
   907
      friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@556
   908
//      typedef typename Graph::OutEdgeIt GraphOutEdgeIt;
marci@556
   909
      typename Graph::OutEdgeIt e;
marci@556
   910
    public:
marci@556
   911
      OutEdgeIt() { }
marci@556
   912
      OutEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@556
   913
      OutEdgeIt(const Invalid& i) : e(i) { }
marci@556
   914
      OutEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G, 
marci@556
   915
		const Node& _n) : 
marci@556
   916
	e((*_G.first_out_edges)[_n]) { }
marci@556
   917
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@556
   918
    };
marci@556
   919
    class InEdgeIt { 
marci@556
   920
      friend class GraphWrapper<Graph>;
marci@556
   921
      friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@556
   922
//      typedef typename Graph::InEdgeIt GraphInEdgeIt;
marci@556
   923
      typename Graph::InEdgeIt e;
marci@556
   924
    public:
marci@556
   925
      InEdgeIt() { }
marci@556
   926
      InEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@556
   927
      InEdgeIt(const Invalid& i) : e(i) { }
marci@556
   928
      InEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G, 
marci@556
   929
	       const Node& _n) : 
marci@556
   930
	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@556
   931
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@556
   932
    };
marci@556
   933
    //typedef typename Graph::SymEdgeIt SymEdgeIt;
marci@556
   934
    class EdgeIt { 
marci@556
   935
      friend class GraphWrapper<Graph>;
marci@556
   936
      friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@556
   937
//      typedef typename Graph::EdgeIt GraphEdgeIt;
marci@556
   938
      typename Graph::EdgeIt e;
marci@556
   939
    public:
marci@556
   940
      EdgeIt() { }
marci@556
   941
      EdgeIt(const typename Graph::EdgeIt& _e) : e(_e) { }
marci@556
   942
      EdgeIt(const Invalid& i) : e(i) { }
marci@556
   943
      EdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G) : 
marci@556
   944
	e(*(_G.graph)) { }
marci@556
   945
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@556
   946
    };
marci@556
   947
marci@556
   948
    using GraphWrapper<Graph>::first;
marci@556
   949
//     NodeIt& first(NodeIt& i) const { 
marci@556
   950
//       i=NodeIt(*this); return i;
marci@556
   951
//     }
marci@556
   952
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   953
      i=OutEdgeIt(*this, p); return i;
marci@556
   954
    }
marci@556
   955
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
   956
      i=InEdgeIt(*this, p); return i;
marci@556
   957
    }
marci@556
   958
    EdgeIt& first(EdgeIt& i) const { 
marci@556
   959
      i=EdgeIt(*this); return i;
marci@556
   960
    }
marci@556
   961
marci@556
   962
    using GraphWrapper<Graph>::next;
marci@556
   963
//    NodeIt& next(NodeIt& i) const { graph->next(i.n); return i; }
marci@556
   964
    OutEdgeIt& next(OutEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@556
   965
    InEdgeIt& next(InEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@556
   966
    EdgeIt& next(EdgeIt& i) const { this->graph->next(i.e); return i; }    
marci@556
   967
    
marci@556
   968
    Node aNode(const OutEdgeIt& e) const { 
marci@556
   969
      return Node(this->graph->aNode(e.e)); }
marci@556
   970
    Node aNode(const InEdgeIt& e) const { 
marci@556
   971
      return Node(this->graph->aNode(e.e)); }
marci@556
   972
    Node bNode(const OutEdgeIt& e) const { 
marci@556
   973
      return Node(this->graph->bNode(e.e)); }
marci@556
   974
    Node bNode(const InEdgeIt& e) const { 
marci@556
   975
      return Node(this->graph->bNode(e.e)); }
marci@556
   976
marci@556
   977
    void erase(const OutEdgeIt& e) const {
marci@556
   978
      OutEdgeIt f=e;
marci@556
   979
      this->next(f);
marci@556
   980
      first_out_edges->set(this->tail(e), f.e);
marci@556
   981
    }
marci@556
   982
  };
marci@556
   983
marci@556
   984
  ///@}
marci@556
   985
marci@556
   986
} //namespace hugo
marci@556
   987
marci@556
   988
marci@556
   989
#endif //HUGO_GRAPH_WRAPPER_H
marci@556
   990