src/hugo/graph_wrapper.h
author marci
Thu, 06 May 2004 17:45:12 +0000
changeset 559 82a8f2bc5758
child 560 5adcef1d7bcc
permissions -rw-r--r--
A max bipartite matching class in src/work/marci/max_bipartite_matching.h
which can be used for computing maximum cardinality ordinary matching, b-matching and capacitated b-matching.
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@556
   439
    ///\todo
marci@556
   440
    ///Some doki, please.
marci@556
   441
    void hide(const Node& n) const { node_filter_map->set(n, false); }
marci@556
   442
    ///\todo
marci@556
   443
    ///Some doki, please.
marci@556
   444
    void hide(const Edge& e) const { edge_filter_map->set(e, false); }
marci@556
   445
marci@556
   446
    ///\todo
marci@556
   447
    ///Some doki, please.
marci@556
   448
    void unHide(const Node& n) const { node_filter_map->set(n, true); }
marci@556
   449
    ///\todo
marci@556
   450
    ///Some doki, please.
marci@556
   451
    void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
marci@556
   452
marci@556
   453
    ///\todo
marci@556
   454
    ///Some doki, please.
marci@556
   455
    bool hidden(const Node& n) const { return (*node_filter_map)[n]; }
marci@556
   456
    ///\todo
marci@556
   457
    ///Some doki, please.
marci@556
   458
    bool hidden(const Edge& e) const { return (*edge_filter_map)[e]; }
marci@556
   459
  };
marci@556
   460
marci@556
   461
  /// A wrapper for forgetting the orientation of a graph.
marci@556
   462
marci@556
   463
  /// A wrapper for getting an undirected graph by forgetting
marci@556
   464
  /// the orientation of a directed one.
marci@556
   465
  template<typename Graph>
marci@556
   466
  class UndirGraphWrapper : public GraphWrapper<Graph> {
marci@556
   467
  protected:
marci@556
   468
    UndirGraphWrapper() : GraphWrapper<Graph>() { }
marci@556
   469
    
marci@556
   470
  public:
marci@556
   471
    typedef typename GraphWrapper<Graph>::Node Node;
marci@556
   472
    typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
marci@556
   473
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@556
   474
    typedef typename GraphWrapper<Graph>::EdgeIt EdgeIt;
marci@556
   475
marci@556
   476
    UndirGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }  
marci@556
   477
marci@556
   478
    class OutEdgeIt {
marci@556
   479
      friend class UndirGraphWrapper<Graph>;
marci@556
   480
      bool out_or_in; //true iff out
marci@556
   481
      typename Graph::OutEdgeIt out;
marci@556
   482
      typename Graph::InEdgeIt in;
marci@556
   483
    public:
marci@556
   484
      OutEdgeIt() { }
marci@556
   485
      OutEdgeIt(const Invalid& i) : Edge(i) { }
marci@556
   486
      OutEdgeIt(const UndirGraphWrapper<Graph>& _G, const Node& _n) {
marci@556
   487
	out_or_in=true; _G.graph->first(out, _n);
marci@556
   488
	if (!(_G.graph->valid(out))) { out_or_in=false; _G.graph->first(in, _n);	}
marci@556
   489
      } 
marci@556
   490
      operator Edge() const { 
marci@556
   491
	if (out_or_in) return Edge(out); else return Edge(in); 
marci@556
   492
      }
marci@556
   493
    };
marci@556
   494
marci@556
   495
//FIXME InEdgeIt
marci@556
   496
    typedef OutEdgeIt InEdgeIt; 
marci@556
   497
marci@556
   498
    using GraphWrapper<Graph>::first;
marci@556
   499
//     NodeIt& first(NodeIt& i) const { 
marci@556
   500
//       i=NodeIt(*this); return i;
marci@556
   501
//     }
marci@556
   502
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   503
      i=OutEdgeIt(*this, p); return i;
marci@556
   504
    }
marci@556
   505
//FIXME
marci@556
   506
//     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
   507
//       i=InEdgeIt(*this, p); return i;
marci@556
   508
//     }
marci@556
   509
//     EdgeIt& first(EdgeIt& i) const { 
marci@556
   510
//       i=EdgeIt(*this); return i;
marci@556
   511
//     }
marci@556
   512
marci@556
   513
    using GraphWrapper<Graph>::next;
marci@556
   514
//     NodeIt& next(NodeIt& n) const {
marci@556
   515
//       GraphWrapper<Graph>::next(n);
marci@556
   516
//       return n;
marci@556
   517
//     }
marci@556
   518
    OutEdgeIt& next(OutEdgeIt& e) const {
marci@556
   519
      if (e.out_or_in) {
marci@556
   520
	typename Graph::Node n=this->graph->tail(e.out);
marci@556
   521
	this->graph->next(e.out);
marci@556
   522
	if (!this->graph->valid(e.out)) { 
marci@556
   523
	  e.out_or_in=false; this->graph->first(e.in, n); }
marci@556
   524
      } else {
marci@556
   525
	this->graph->next(e.in);
marci@556
   526
      }
marci@556
   527
      return e;
marci@556
   528
    }
marci@556
   529
    //FIXME InEdgeIt
marci@556
   530
//     EdgeIt& next(EdgeIt& e) const {
marci@556
   531
//       GraphWrapper<Graph>::next(n);
marci@556
   532
// //      graph->next(e.e);
marci@556
   533
//       return e;
marci@556
   534
//     }
marci@556
   535
marci@556
   536
    Node aNode(const OutEdgeIt& e) const { 
marci@556
   537
      if (e.out_or_in) return this->graph->tail(e); else 
marci@556
   538
	return this->graph->head(e); }
marci@556
   539
    Node bNode(const OutEdgeIt& e) const { 
marci@556
   540
      if (e.out_or_in) return this->graph->head(e); else 
marci@556
   541
	return this->graph->tail(e); }
marci@556
   542
  };
marci@556
   543
  
marci@556
   544
marci@556
   545
marci@556
   546
  /// An undirected graph template
marci@556
   547
  template<typename Graph>
marci@556
   548
  class UndirGraph : public UndirGraphWrapper<Graph> {
marci@556
   549
    typedef UndirGraphWrapper<Graph> Parent;
marci@556
   550
  protected:
marci@556
   551
    Graph gr;
marci@556
   552
  public:
marci@556
   553
    UndirGraph() : UndirGraphWrapper<Graph>() { 
marci@556
   554
      Parent::setGraph(gr); 
marci@556
   555
    }
marci@556
   556
  };
marci@556
   557
marci@556
   558
  
marci@556
   559
marci@556
   560
  /// A wrapper for composing the residual graph for directed flow and circulation problems.
marci@556
   561
marci@556
   562
  /// A wrapper for composing the residual graph for directed flow and circulation problems.
marci@556
   563
  template<typename Graph, typename Number, 
marci@556
   564
	   typename CapacityMap, typename FlowMap>
marci@556
   565
  class ResGraphWrapper : public GraphWrapper<Graph> {
marci@556
   566
  protected:
marci@556
   567
    const CapacityMap* capacity;
marci@556
   568
    FlowMap* flow;
marci@556
   569
marci@556
   570
    ResGraphWrapper() : GraphWrapper<Graph>(0), 
marci@556
   571
			capacity(0), flow(0) { }
marci@556
   572
    void setCapacityMap(const CapacityMap& _capacity_map) {
marci@556
   573
      capacity_map=&_capacity_map;
marci@556
   574
    }
marci@556
   575
    void setFlowMap(FlowMap& _flow) {
marci@556
   576
      flow=&_flow;
marci@556
   577
    }
marci@556
   578
marci@556
   579
  public:
marci@556
   580
marci@556
   581
    ResGraphWrapper(Graph& _graph, const CapacityMap& _capacity, 
marci@556
   582
		    FlowMap& _flow) : 
marci@556
   583
      GraphWrapper<Graph>(_graph), capacity(&_capacity), flow(&_flow) { }
marci@556
   584
marci@556
   585
    class Edge; 
marci@556
   586
    class OutEdgeIt; 
marci@556
   587
    friend class Edge; 
marci@556
   588
    friend class OutEdgeIt; 
marci@556
   589
marci@556
   590
    typedef typename GraphWrapper<Graph>::Node Node;
marci@556
   591
    typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
marci@556
   592
    class Edge : public Graph::Edge {
marci@556
   593
      friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@556
   594
    protected:
marci@556
   595
      bool forward; //true, iff forward
marci@556
   596
//      typename Graph::Edge e;
marci@556
   597
    public:
marci@556
   598
      Edge() { }
marci@556
   599
      Edge(const typename Graph::Edge& _e, bool _forward) : 
marci@556
   600
	Graph::Edge(_e), forward(_forward) { }
marci@556
   601
      Edge(const Invalid& i) : Graph::Edge(i), forward(false) { }
marci@556
   602
//the unique invalid iterator
marci@556
   603
      friend bool operator==(const Edge& u, const Edge& v) { 
marci@556
   604
	return (v.forward==u.forward && 
marci@556
   605
		static_cast<typename Graph::Edge>(u)==
marci@556
   606
		static_cast<typename Graph::Edge>(v));
marci@556
   607
      } 
marci@556
   608
      friend bool operator!=(const Edge& u, const Edge& v) { 
marci@556
   609
	return (v.forward!=u.forward || 
marci@556
   610
		static_cast<typename Graph::Edge>(u)!=
marci@556
   611
		static_cast<typename Graph::Edge>(v));
marci@556
   612
      } 
marci@556
   613
    };
marci@556
   614
marci@556
   615
    class OutEdgeIt {
marci@556
   616
      friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@556
   617
    protected:
marci@556
   618
      typename Graph::OutEdgeIt out;
marci@556
   619
      typename Graph::InEdgeIt in;
marci@556
   620
      bool forward;
marci@556
   621
    public:
marci@556
   622
      OutEdgeIt() { }
marci@556
   623
      //FIXME
marci@556
   624
//      OutEdgeIt(const Edge& e) : Edge(e) { }
marci@556
   625
      OutEdgeIt(const Invalid& i) : out(i), in(i), forward(false) { }
marci@556
   626
//the unique invalid iterator
marci@556
   627
      OutEdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG, Node v) { 
marci@556
   628
	forward=true;
marci@556
   629
	resG.graph->first(out, v);
marci@556
   630
	while( resG.graph->valid(out) && !(resG.resCap(*this)>0) ) { resG.graph->next(out); }
marci@556
   631
	if (!resG.graph->valid(out)) {
marci@556
   632
	  forward=false;
marci@556
   633
	  resG.graph->first(in, v);
marci@556
   634
	  while( resG.graph->valid(in) && !(resG.resCap(*this)>0) ) { resG.graph->next(in); }
marci@556
   635
	}
marci@556
   636
      }
marci@556
   637
      operator Edge() const { 
marci@556
   638
//	Edge e;
marci@556
   639
//	e.forward=this->forward;
marci@556
   640
//	if (this->forward) e=out; else e=in;
marci@556
   641
//	return e;
marci@556
   642
	if (this->forward) 
marci@556
   643
	  return Edge(out, this->forward); 
marci@556
   644
	else 
marci@556
   645
	  return Edge(in, this->forward);
marci@556
   646
      }
marci@556
   647
    };
marci@556
   648
marci@556
   649
    class InEdgeIt {
marci@556
   650
      friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@556
   651
    protected:
marci@556
   652
      typename Graph::OutEdgeIt out;
marci@556
   653
      typename Graph::InEdgeIt in;
marci@556
   654
      bool forward;
marci@556
   655
    public:
marci@556
   656
      InEdgeIt() { }
marci@556
   657
      //FIXME
marci@556
   658
//      OutEdgeIt(const Edge& e) : Edge(e) { }
marci@556
   659
      InEdgeIt(const Invalid& i) : out(i), in(i), forward(false) { }
marci@556
   660
//the unique invalid iterator
marci@556
   661
      InEdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG, Node v) { 
marci@556
   662
	forward=true;
marci@556
   663
	resG.graph->first(in, v);
marci@556
   664
	while( resG.graph->valid(in) && !(resG.resCap(*this)>0) ) { resG.graph->next(in); }
marci@556
   665
	if (!resG.graph->valid(in)) {
marci@556
   666
	  forward=false;
marci@556
   667
	  resG.graph->first(out, v);
marci@556
   668
	  while( resG.graph->valid(out) && !(resG.resCap(*this)>0) ) { resG.graph->next(out); }
marci@556
   669
	}
marci@556
   670
      }
marci@556
   671
      operator Edge() const { 
marci@556
   672
//	Edge e;
marci@556
   673
//	e.forward=this->forward;
marci@556
   674
//	if (this->forward) e=out; else e=in;
marci@556
   675
//	return e;
marci@556
   676
	if (this->forward) 
marci@556
   677
	  return Edge(in, this->forward); 
marci@556
   678
	else 
marci@556
   679
	  return Edge(out, this->forward);
marci@556
   680
      }
marci@556
   681
    };
marci@556
   682
marci@556
   683
    class EdgeIt {
marci@556
   684
      friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@556
   685
    protected:
marci@556
   686
      typename Graph::EdgeIt e;
marci@556
   687
      bool forward;
marci@556
   688
    public:
marci@556
   689
      EdgeIt() { }
marci@556
   690
      EdgeIt(const Invalid& i) : e(i), forward(false) { }
marci@556
   691
      EdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG) { 
marci@556
   692
	forward=true;
marci@556
   693
	resG.graph->first(e);
marci@556
   694
	while (resG.graph->valid(e) && !(resG.resCap(*this)>0)) resG.graph->next(e);
marci@556
   695
	if (!resG.graph->valid(e)) {
marci@556
   696
	  forward=false;
marci@556
   697
	  resG.graph->first(e);
marci@556
   698
	  while (resG.graph->valid(e) && !(resG.resCap(*this)>0)) resG.graph->next(e);
marci@556
   699
	}
marci@556
   700
      }
marci@556
   701
      operator Edge() const { 
marci@556
   702
	return Edge(e, this->forward);
marci@556
   703
      }
marci@556
   704
    };
marci@556
   705
marci@556
   706
    using GraphWrapper<Graph>::first;
marci@556
   707
//     NodeIt& first(NodeIt& i) const { 
marci@556
   708
//       i=NodeIt(*this); return i;
marci@556
   709
//     }
marci@556
   710
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   711
      i=OutEdgeIt(*this, p); return i;
marci@556
   712
    }
marci@556
   713
//    FIXME not tested
marci@556
   714
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
   715
      i=InEdgeIt(*this, p); return i;
marci@556
   716
    }
marci@556
   717
    EdgeIt& first(EdgeIt& i) const { 
marci@556
   718
      i=EdgeIt(*this); return i;
marci@556
   719
    }
marci@556
   720
  
marci@556
   721
    using GraphWrapper<Graph>::next;
marci@556
   722
//    NodeIt& next(NodeIt& n) const { GraphWrapper<Graph>::next(n); return n; }
marci@556
   723
    OutEdgeIt& next(OutEdgeIt& e) const { 
marci@556
   724
      if (e.forward) {
marci@556
   725
	Node v=this->graph->aNode(e.out);
marci@556
   726
	this->graph->next(e.out);
marci@556
   727
	while( this->graph->valid(e.out) && !(resCap(e)>0) ) { 
marci@556
   728
	  this->graph->next(e.out); }
marci@556
   729
	if (!this->graph->valid(e.out)) {
marci@556
   730
	  e.forward=false;
marci@556
   731
	  this->graph->first(e.in, v); 
marci@556
   732
	  while( this->graph->valid(e.in) && !(resCap(e)>0) ) { 
marci@556
   733
	    this->graph->next(e.in); }
marci@556
   734
	}
marci@556
   735
      } else {
marci@556
   736
	this->graph->next(e.in);
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
      return e;
marci@556
   741
    }
marci@556
   742
//     FIXME Not tested
marci@556
   743
    InEdgeIt& next(InEdgeIt& e) const { 
marci@556
   744
      if (e.forward) {
marci@556
   745
	Node v=this->graph->aNode(e.in);
marci@556
   746
	this->graph->next(e.in);
marci@556
   747
	while( this->graph->valid(e.in) && !(resCap(e)>0) ) { 
marci@556
   748
	  this->graph->next(e.in); }
marci@556
   749
	if (!this->graph->valid(e.in)) {
marci@556
   750
	  e.forward=false;
marci@556
   751
	  this->graph->first(e.out, v); 
marci@556
   752
	  while( this->graph->valid(e.out) && !(resCap(e)>0) ) { 
marci@556
   753
	    this->graph->next(e.out); }
marci@556
   754
	}
marci@556
   755
      } else {
marci@556
   756
	this->graph->next(e.out);
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
      return e;
marci@556
   761
    }
marci@556
   762
    EdgeIt& next(EdgeIt& e) const {
marci@556
   763
      if (e.forward) {
marci@556
   764
	this->graph->next(e.e);
marci@556
   765
	while( this->graph->valid(e.e) && !(resCap(e)>0) ) { 
marci@556
   766
	  this->graph->next(e.e); }
marci@556
   767
	if (!this->graph->valid(e.e)) {
marci@556
   768
	  e.forward=false;
marci@556
   769
	  this->graph->first(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
	}
marci@556
   773
      } else {
marci@556
   774
	this->graph->next(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
      return e;
marci@556
   779
    }
marci@556
   780
marci@556
   781
    Node tail(Edge e) const { 
marci@556
   782
      return ((e.forward) ? this->graph->tail(e) : this->graph->head(e)); }
marci@556
   783
    Node head(Edge e) const { 
marci@556
   784
      return ((e.forward) ? this->graph->head(e) : this->graph->tail(e)); }
marci@556
   785
marci@556
   786
    Node aNode(OutEdgeIt e) const { 
marci@556
   787
      return ((e.forward) ? this->graph->aNode(e.out) : 
marci@556
   788
	      this->graph->aNode(e.in)); }
marci@556
   789
    Node bNode(OutEdgeIt e) const { 
marci@556
   790
      return ((e.forward) ? this->graph->bNode(e.out) : 
marci@556
   791
	      this->graph->bNode(e.in)); }
marci@556
   792
marci@556
   793
    Node aNode(InEdgeIt e) const { 
marci@556
   794
      return ((e.forward) ? this->graph->aNode(e.in) : 
marci@556
   795
	      this->graph->aNode(e.out)); }
marci@556
   796
    Node bNode(InEdgeIt e) const { 
marci@556
   797
      return ((e.forward) ? this->graph->bNode(e.in) : 
marci@556
   798
	      this->graph->bNode(e.out)); }
marci@556
   799
marci@556
   800
//    int nodeNum() const { return graph->nodeNum(); }
marci@556
   801
    //FIXME
marci@556
   802
    void edgeNum() const { }
marci@556
   803
    //int edgeNum() const { return graph->edgeNum(); }
marci@556
   804
marci@556
   805
marci@556
   806
//    int id(Node v) const { return graph->id(v); }
marci@556
   807
marci@556
   808
    bool valid(Node n) const { return GraphWrapper<Graph>::valid(n); }
marci@556
   809
    bool valid(Edge e) const { 
marci@556
   810
      return this->graph->valid(e);
marci@556
   811
	//return e.forward ? graph->valid(e.out) : graph->valid(e.in); 
marci@556
   812
    }
marci@556
   813
marci@556
   814
    bool forward(const Edge& e) const { return e.forward; }
marci@556
   815
    bool backward(const Edge& e) const { return !e.forward; }
marci@556
   816
marci@556
   817
    void augment(const Edge& e, Number a) const {
marci@556
   818
      if (e.forward)  
marci@556
   819
// 	flow->set(e.out, flow->get(e.out)+a);
marci@556
   820
	flow->set(e, (*flow)[e]+a);
marci@556
   821
      else  
marci@556
   822
// 	flow->set(e.in, flow->get(e.in)-a);
marci@556
   823
	flow->set(e, (*flow)[e]-a);
marci@556
   824
    }
marci@556
   825
marci@556
   826
    Number resCap(const Edge& e) const { 
marci@556
   827
      if (e.forward) 
marci@556
   828
//	return (capacity->get(e.out)-flow->get(e.out)); 
marci@556
   829
	return ((*capacity)[e]-(*flow)[e]); 
marci@556
   830
      else 
marci@556
   831
//	return (flow->get(e.in)); 
marci@556
   832
	return ((*flow)[e]); 
marci@556
   833
    }
marci@556
   834
marci@556
   835
//     Number resCap(typename Graph::OutEdgeIt out) const { 
marci@556
   836
// //      return (capacity->get(out)-flow->get(out)); 
marci@556
   837
//       return ((*capacity)[out]-(*flow)[out]); 
marci@556
   838
//     }
marci@556
   839
    
marci@556
   840
//     Number resCap(typename Graph::InEdgeIt in) const { 
marci@556
   841
// //      return (flow->get(in)); 
marci@556
   842
//       return ((*flow)[in]); 
marci@556
   843
//     }
marci@556
   844
marci@556
   845
    template <typename T>
marci@556
   846
    class EdgeMap {
marci@556
   847
      typename Graph::template EdgeMap<T> forward_map, backward_map; 
marci@556
   848
    public:
marci@556
   849
      EdgeMap(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G) : forward_map(*(_G.graph)), backward_map(*(_G.graph)) { }
marci@556
   850
      EdgeMap(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G, T a) : forward_map(*(_G.graph), a), backward_map(*(_G.graph), a) { }
marci@556
   851
      void set(Edge e, T a) { 
marci@556
   852
	if (e.forward) 
marci@556
   853
	  forward_map.set(e.out, a); 
marci@556
   854
	else 
marci@556
   855
	  backward_map.set(e.in, a); 
marci@556
   856
      }
marci@556
   857
      T operator[](Edge e) const { 
marci@556
   858
	if (e.forward) 
marci@556
   859
	  return forward_map[e.out]; 
marci@556
   860
	else 
marci@556
   861
	  return backward_map[e.in]; 
marci@556
   862
      }
marci@556
   863
//       T get(Edge e) const { 
marci@556
   864
// 	if (e.out_or_in) 
marci@556
   865
// 	  return forward_map.get(e.out); 
marci@556
   866
// 	else 
marci@556
   867
// 	  return backward_map.get(e.in); 
marci@556
   868
//       }
marci@556
   869
    };
marci@556
   870
  };
marci@556
   871
marci@556
   872
  /// ErasingFirstGraphWrapper for blocking flows.
marci@556
   873
marci@556
   874
  /// ErasingFirstGraphWrapper for blocking flows.
marci@556
   875
  ///
marci@556
   876
  ///\author Marton Makai
marci@556
   877
  template<typename Graph, typename FirstOutEdgesMap>
marci@556
   878
  class ErasingFirstGraphWrapper : public GraphWrapper<Graph> {
marci@556
   879
  protected:
marci@556
   880
    FirstOutEdgesMap* first_out_edges;
marci@556
   881
  public:
marci@556
   882
    ErasingFirstGraphWrapper(Graph& _graph, 
marci@556
   883
			     FirstOutEdgesMap& _first_out_edges) : 
marci@556
   884
      GraphWrapper<Graph>(_graph), first_out_edges(&_first_out_edges) { }  
marci@556
   885
marci@556
   886
    typedef typename GraphWrapper<Graph>::Node Node;
marci@556
   887
//     class NodeIt { 
marci@556
   888
//       friend class GraphWrapper<Graph>;
marci@556
   889
//       friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@556
   890
//       typename Graph::NodeIt n;
marci@556
   891
//      public:
marci@556
   892
//       NodeIt() { }
marci@556
   893
//       NodeIt(const typename Graph::NodeIt& _n) : n(_n) { }
marci@556
   894
//       NodeIt(const Invalid& i) : n(i) { }
marci@556
   895
//       NodeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G) : 
marci@556
   896
// 	n(*(_G.graph)) { }
marci@556
   897
//       operator Node() const { return Node(typename Graph::Node(n)); }
marci@556
   898
//     };
marci@556
   899
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@556
   900
    class OutEdgeIt { 
marci@556
   901
      friend class GraphWrapper<Graph>;
marci@556
   902
      friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@556
   903
//      typedef typename Graph::OutEdgeIt GraphOutEdgeIt;
marci@556
   904
      typename Graph::OutEdgeIt e;
marci@556
   905
    public:
marci@556
   906
      OutEdgeIt() { }
marci@556
   907
      OutEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@556
   908
      OutEdgeIt(const Invalid& i) : e(i) { }
marci@556
   909
      OutEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G, 
marci@556
   910
		const Node& _n) : 
marci@556
   911
	e((*_G.first_out_edges)[_n]) { }
marci@556
   912
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@556
   913
    };
marci@556
   914
    class InEdgeIt { 
marci@556
   915
      friend class GraphWrapper<Graph>;
marci@556
   916
      friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@556
   917
//      typedef typename Graph::InEdgeIt GraphInEdgeIt;
marci@556
   918
      typename Graph::InEdgeIt e;
marci@556
   919
    public:
marci@556
   920
      InEdgeIt() { }
marci@556
   921
      InEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@556
   922
      InEdgeIt(const Invalid& i) : e(i) { }
marci@556
   923
      InEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G, 
marci@556
   924
	       const Node& _n) : 
marci@556
   925
	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@556
   926
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@556
   927
    };
marci@556
   928
    //typedef typename Graph::SymEdgeIt SymEdgeIt;
marci@556
   929
    class EdgeIt { 
marci@556
   930
      friend class GraphWrapper<Graph>;
marci@556
   931
      friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@556
   932
//      typedef typename Graph::EdgeIt GraphEdgeIt;
marci@556
   933
      typename Graph::EdgeIt e;
marci@556
   934
    public:
marci@556
   935
      EdgeIt() { }
marci@556
   936
      EdgeIt(const typename Graph::EdgeIt& _e) : e(_e) { }
marci@556
   937
      EdgeIt(const Invalid& i) : e(i) { }
marci@556
   938
      EdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G) : 
marci@556
   939
	e(*(_G.graph)) { }
marci@556
   940
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@556
   941
    };
marci@556
   942
marci@556
   943
    using GraphWrapper<Graph>::first;
marci@556
   944
//     NodeIt& first(NodeIt& i) const { 
marci@556
   945
//       i=NodeIt(*this); return i;
marci@556
   946
//     }
marci@556
   947
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   948
      i=OutEdgeIt(*this, p); return i;
marci@556
   949
    }
marci@556
   950
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@556
   951
      i=InEdgeIt(*this, p); return i;
marci@556
   952
    }
marci@556
   953
    EdgeIt& first(EdgeIt& i) const { 
marci@556
   954
      i=EdgeIt(*this); return i;
marci@556
   955
    }
marci@556
   956
marci@556
   957
    using GraphWrapper<Graph>::next;
marci@556
   958
//    NodeIt& next(NodeIt& i) const { graph->next(i.n); return i; }
marci@556
   959
    OutEdgeIt& next(OutEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@556
   960
    InEdgeIt& next(InEdgeIt& i) const { this->graph->next(i.e); return i; }
marci@556
   961
    EdgeIt& next(EdgeIt& i) const { this->graph->next(i.e); return i; }    
marci@556
   962
    
marci@556
   963
    Node aNode(const OutEdgeIt& e) const { 
marci@556
   964
      return Node(this->graph->aNode(e.e)); }
marci@556
   965
    Node aNode(const InEdgeIt& e) const { 
marci@556
   966
      return Node(this->graph->aNode(e.e)); }
marci@556
   967
    Node bNode(const OutEdgeIt& e) const { 
marci@556
   968
      return Node(this->graph->bNode(e.e)); }
marci@556
   969
    Node bNode(const InEdgeIt& e) const { 
marci@556
   970
      return Node(this->graph->bNode(e.e)); }
marci@556
   971
marci@556
   972
    void erase(const OutEdgeIt& e) const {
marci@556
   973
      OutEdgeIt f=e;
marci@556
   974
      this->next(f);
marci@556
   975
      first_out_edges->set(this->tail(e), f.e);
marci@556
   976
    }
marci@556
   977
  };
marci@556
   978
marci@556
   979
  ///@}
marci@556
   980
marci@556
   981
} //namespace hugo
marci@556
   982
marci@556
   983
marci@556
   984
#endif //HUGO_GRAPH_WRAPPER_H
marci@556
   985