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