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