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