src/lemon/graph_wrapper.h
author alpar
Sat, 05 Feb 2005 20:05:01 +0000
changeset 1125 377e240b050f
parent 1016 18d009b23e42
child 1135 cfccb33ecf7b
permissions -rw-r--r--
A new exception class called UninitializedParameter.
alpar@906
     1
/* -*- C++ -*-
alpar@921
     2
 * src/lemon/graph_wrapper.h - Part of LEMON, a generic C++ optimization library
alpar@906
     3
 *
alpar@906
     4
 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@906
     5
 * (Egervary Combinatorial Optimization Research Group, EGRES).
alpar@906
     6
 *
alpar@906
     7
 * Permission to use, modify and distribute this software is granted
alpar@906
     8
 * provided that this copyright notice appears in all copies. For
alpar@906
     9
 * precise terms see the accompanying LICENSE file.
alpar@906
    10
 *
alpar@906
    11
 * This software is provided "AS IS" with no warranty of any kind,
alpar@906
    12
 * express or implied, and with no claim as to its suitability for any
alpar@906
    13
 * purpose.
alpar@906
    14
 *
alpar@906
    15
 */
alpar@906
    16
alpar@921
    17
#ifndef LEMON_GRAPH_WRAPPER_H
alpar@921
    18
#define LEMON_GRAPH_WRAPPER_H
marci@556
    19
marci@556
    20
///\ingroup gwrappers
marci@556
    21
///\file
marci@556
    22
///\brief Several graph wrappers.
marci@556
    23
///
marci@556
    24
///This file contains several useful graph wrapper functions.
marci@556
    25
///
marci@556
    26
///\author Marton Makai
marci@556
    27
alpar@921
    28
#include <lemon/invalid.h>
alpar@921
    29
#include <lemon/maps.h>
marci@992
    30
#include <lemon/iterable_graph_extender.h>
alpar@921
    31
#include <lemon/map_defines.h>
alpar@774
    32
#include <iostream>
marci@556
    33
alpar@921
    34
namespace lemon {
marci@556
    35
marci@556
    36
  // Graph wrappers
marci@556
    37
marci@1004
    38
  /*! \addtogroup gwrappers
marci@1004
    39
    The main parts of LEMON are the different graph structures, 
marci@1004
    40
    generic graph algorithms, graph concepts which couple these, and 
marci@1004
    41
    graph wrappers. While the previous ones are more or less clear, the 
marci@1004
    42
    latter notion needs further explanation.
marci@1004
    43
    Graph wrappers are graph classes which serve for considering graph 
marci@1004
    44
    structures in different ways. A short example makes the notion much 
marci@1004
    45
    clearer. 
marci@1004
    46
    Suppose that we have an instance \c g of a directed graph
marci@1004
    47
    type say \c ListGraph and an algorithm 
marci@1004
    48
    \code template<typename Graph> int algorithm(const Graph&); \endcode 
marci@1004
    49
    is needed to run on the reversely oriented graph. 
marci@1004
    50
    It may be expensive (in time or in memory usage) to copy 
marci@1004
    51
    \c g with the reverse orientation. 
marci@1004
    52
    Thus, a wrapper class
marci@1004
    53
    \code template<typename Graph> class RevGraphWrapper; \endcode is used. 
marci@1004
    54
    The code looks as follows
marci@1004
    55
    \code
marci@1004
    56
    ListGraph g;
marci@1004
    57
    RevGraphWrapper<ListGraph> rgw(g);
marci@1004
    58
    int result=algorithm(rgw);
marci@1004
    59
    \endcode
marci@1004
    60
    After running the algorithm, the original graph \c g 
marci@1004
    61
    remains untouched. Thus the graph wrapper used above is to consider the 
marci@1004
    62
    original graph with reverse orientation. 
marci@1004
    63
    This techniques gives rise to an elegant code, and 
marci@1004
    64
    based on stable graph wrappers, complex algorithms can be 
marci@1004
    65
    implemented easily. 
marci@1004
    66
    In flow, circulation and bipartite matching problems, the residual 
marci@1004
    67
    graph is of particular importance. Combining a wrapper implementing 
marci@1004
    68
    this, shortest path algorithms and minimum mean cycle algorithms, 
marci@1004
    69
    a range of weighted and cardinality optimization algorithms can be 
marci@1004
    70
    obtained. For lack of space, for other examples, 
marci@1004
    71
    the interested user is referred to the detailed documentation of graph 
marci@1004
    72
    wrappers. 
marci@1004
    73
    The behavior of graph wrappers can be very different. Some of them keep 
marci@1004
    74
    capabilities of the original graph while in other cases this would be 
marci@1004
    75
    meaningless. This means that the concepts that they are a model of depend 
marci@1004
    76
    on the graph wrapper, and the wrapped graph(s). 
marci@1004
    77
    If an edge of \c rgw is deleted, this is carried out by 
marci@1004
    78
    deleting the corresponding edge of \c g. But for a residual 
marci@1004
    79
    graph, this operation has no sense. 
marci@1004
    80
    Let we stand one more example here to simplify your work. 
marci@1004
    81
    wrapper class
marci@1004
    82
    \code template<typename Graph> class RevGraphWrapper; \endcode 
marci@1004
    83
    has constructor 
marci@1004
    84
    <tt> RevGraphWrapper(Graph& _g)</tt>. 
marci@1004
    85
    This means that in a situation, 
marci@1004
    86
    when a <tt> const ListGraph& </tt> reference to a graph is given, 
marci@1004
    87
    then it have to be instantiated with <tt>Graph=const ListGraph</tt>.
marci@1004
    88
    \code
marci@1004
    89
    int algorithm1(const ListGraph& g) {
marci@1004
    90
    RevGraphWrapper<const ListGraph> rgw(g);
marci@1004
    91
    return algorithm2(rgw);
marci@1004
    92
    }
marci@1004
    93
    \endcode
marci@556
    94
marci@1004
    95
    \addtogroup gwrappers
marci@1004
    96
    @{
marci@556
    97
marci@1004
    98
    Base type for the Graph Wrappers
marci@556
    99
marci@1004
   100
    \warning Graph wrappers are in even more experimental state than the other
marci@1004
   101
    parts of the lib. Use them at you own risk.
marci@1004
   102
  
marci@1004
   103
    This is the base type for most of LEMON graph wrappers. 
marci@1004
   104
    This class implements a trivial graph wrapper i.e. it only wraps the 
marci@1004
   105
    functions and types of the graph. The purpose of this class is to 
marci@1004
   106
    make easier implementing graph wrappers. E.g. if a wrapper is 
marci@1004
   107
    considered which differs from the wrapped graph only in some of its 
marci@1004
   108
    functions or types, then it can be derived from GraphWrapper, and only the 
marci@1004
   109
    differences should be implemented.
marci@1004
   110
  
marci@1004
   111
    \author Marton Makai 
marci@1004
   112
  */
marci@970
   113
  template<typename _Graph>
marci@970
   114
  class GraphWrapperBase {
marci@970
   115
  public:
marci@970
   116
    typedef _Graph Graph;
marci@970
   117
    /// \todo Is it needed?
marci@970
   118
    typedef Graph BaseGraph;
marci@970
   119
    typedef Graph ParentGraph;
marci@970
   120
marci@556
   121
  protected:
marci@556
   122
    Graph* graph;
marci@970
   123
    GraphWrapperBase() : graph(0) { }
marci@556
   124
    void setGraph(Graph& _graph) { graph=&_graph; }
marci@556
   125
marci@556
   126
  public:
marci@970
   127
    GraphWrapperBase(Graph& _graph) : graph(&_graph) { }
marci@556
   128
 
alpar@774
   129
    typedef typename Graph::Node Node;
alpar@774
   130
    typedef typename Graph::Edge Edge;
marci@556
   131
   
marci@970
   132
    void first(Node& i) const { graph->first(i); }
marci@970
   133
    void first(Edge& i) const { graph->first(i); }
marci@970
   134
    void firstIn(Edge& i, const Node& n) const { graph->firstIn(i, n); }
marci@970
   135
    void firstOut(Edge& i, const Node& n ) const { graph->firstOut(i, n); }
marci@556
   136
marci@970
   137
    void next(Node& i) const { graph->next(i); }
marci@970
   138
    void next(Edge& i) const { graph->next(i); }
marci@970
   139
    void nextIn(Edge& i) const { graph->nextIn(i); }
marci@970
   140
    void nextOut(Edge& i) const { graph->nextOut(i); }
marci@970
   141
alpar@986
   142
    Node source(const Edge& e) const { return graph->source(e); }
alpar@986
   143
    Node target(const Edge& e) const { return graph->target(e); }
marci@556
   144
marci@556
   145
    int nodeNum() const { return graph->nodeNum(); }
marci@556
   146
    int edgeNum() const { return graph->edgeNum(); }
marci@556
   147
  
marci@556
   148
    Node addNode() const { return Node(graph->addNode()); }
alpar@986
   149
    Edge addEdge(const Node& source, const Node& target) const { 
alpar@986
   150
      return Edge(graph->addEdge(source, target)); }
marci@556
   151
marci@556
   152
    void erase(const Node& i) const { graph->erase(i); }
marci@556
   153
    void erase(const Edge& i) const { graph->erase(i); }
marci@556
   154
  
marci@556
   155
    void clear() const { graph->clear(); }
marci@556
   156
    
alpar@736
   157
    bool forward(const Edge& e) const { return graph->forward(e); }
alpar@736
   158
    bool backward(const Edge& e) const { return graph->backward(e); }
marci@739
   159
marci@739
   160
    int id(const Node& v) const { return graph->id(v); }
marci@739
   161
    int id(const Edge& e) const { return graph->id(e); }
marci@650
   162
    
marci@738
   163
    Edge opposite(const Edge& e) const { return Edge(graph->opposite(e)); }
marci@650
   164
marci@970
   165
    template <typename _Value>
marci@970
   166
    class NodeMap : public _Graph::template NodeMap<_Value> {
marci@970
   167
    public:
marci@970
   168
      typedef typename _Graph::template NodeMap<_Value> Parent;
marci@970
   169
      NodeMap(const GraphWrapperBase<_Graph>& gw) : Parent(*gw.graph) { }
marci@970
   170
      NodeMap(const GraphWrapperBase<_Graph>& gw, const _Value& value)
marci@970
   171
      : Parent(*gw.graph, value) { }
marci@970
   172
    };
marci@556
   173
marci@970
   174
    template <typename _Value>
marci@970
   175
    class EdgeMap : public _Graph::template EdgeMap<_Value> {
marci@970
   176
    public:
marci@970
   177
      typedef typename _Graph::template EdgeMap<_Value> Parent;
marci@970
   178
      EdgeMap(const GraphWrapperBase<_Graph>& gw) : Parent(*gw.graph) { }
marci@970
   179
      EdgeMap(const GraphWrapperBase<_Graph>& gw, const _Value& value)
marci@970
   180
      : Parent(*gw.graph, value) { }
marci@970
   181
    };
deba@877
   182
marci@556
   183
  };
marci@556
   184
marci@970
   185
  template <typename _Graph>
marci@970
   186
  class GraphWrapper :
marci@970
   187
    public IterableGraphExtender<GraphWrapperBase<_Graph> > { 
marci@970
   188
  public:
marci@970
   189
    typedef _Graph Graph;
marci@970
   190
    typedef IterableGraphExtender<GraphWrapperBase<_Graph> > Parent;
marci@970
   191
  protected:
marci@970
   192
    GraphWrapper() : Parent() { }
marci@569
   193
marci@970
   194
  public:
marci@970
   195
    GraphWrapper(Graph& _graph) { setGraph(_graph); }
marci@970
   196
  };
marci@569
   197
marci@997
   198
  template <typename _Graph>
marci@997
   199
  class RevGraphWrapperBase : public GraphWrapperBase<_Graph> {
marci@997
   200
  public:
marci@997
   201
    typedef _Graph Graph;
marci@997
   202
    typedef GraphWrapperBase<_Graph> Parent;
marci@997
   203
  protected:
marci@997
   204
    RevGraphWrapperBase() : Parent() { }
marci@997
   205
  public:
marci@997
   206
    typedef typename Parent::Node Node;
marci@997
   207
    typedef typename Parent::Edge Edge;
marci@997
   208
marci@997
   209
    using Parent::first;
marci@997
   210
    void firstIn(Edge& i, const Node& n) const { Parent::firstOut(i, n); }
marci@997
   211
    void firstOut(Edge& i, const Node& n ) const { Parent::firstIn(i, n); }
marci@997
   212
marci@997
   213
    using Parent::next;
marci@997
   214
    void nextIn(Edge& i) const { Parent::nextOut(i); }
marci@997
   215
    void nextOut(Edge& i) const { Parent::nextIn(i); }
marci@997
   216
marci@997
   217
    Node source(const Edge& e) const { return Parent::target(e); }
marci@997
   218
    Node target(const Edge& e) const { return Parent::source(e); }
marci@997
   219
  };
marci@997
   220
    
marci@997
   221
marci@556
   222
  /// A graph wrapper which reverses the orientation of the edges.
marci@556
   223
alpar@879
   224
  ///\warning Graph wrappers are in even more experimental state than the other
alpar@879
   225
  ///parts of the lib. Use them at you own risk.
alpar@879
   226
  ///
marci@923
   227
  /// Let \f$G=(V, A)\f$ be a directed graph and 
marci@923
   228
  /// suppose that a graph instange \c g of type 
marci@923
   229
  /// \c ListGraph implements \f$G\f$.
marci@923
   230
  /// \code
marci@923
   231
  /// ListGraph g;
marci@923
   232
  /// \endcode
marci@923
   233
  /// For each directed edge 
marci@923
   234
  /// \f$e\in A\f$, let \f$\bar e\f$ denote the edge obtained by 
marci@923
   235
  /// reversing its orientation. 
marci@923
   236
  /// Then RevGraphWrapper implements the graph structure with node-set 
marci@923
   237
  /// \f$V\f$ and edge-set 
marci@923
   238
  /// \f$\{\bar e : e\in A \}\f$, i.e. the graph obtained from \f$G\f$ be 
marci@923
   239
  /// reversing the orientation of its edges. The following code shows how 
marci@923
   240
  /// such an instance can be constructed.
marci@923
   241
  /// \code
marci@923
   242
  /// RevGraphWrapper<ListGraph> gw(g);
marci@923
   243
  /// \endcode
marci@556
   244
  ///\author Marton Makai
marci@997
   245
  template<typename _Graph>
marci@997
   246
  class RevGraphWrapper : 
marci@997
   247
    public IterableGraphExtender<RevGraphWrapperBase<_Graph> > {
marci@650
   248
  public:
marci@997
   249
    typedef _Graph Graph;
marci@997
   250
    typedef IterableGraphExtender<
marci@997
   251
      RevGraphWrapperBase<_Graph> > Parent;
marci@556
   252
  protected:
marci@997
   253
    RevGraphWrapper() { }
marci@556
   254
  public:
marci@997
   255
    RevGraphWrapper(_Graph& _graph) { setGraph(_graph); }
marci@997
   256
  };
marci@556
   257
marci@992
   258
  
marci@992
   259
  template <typename _Graph, typename NodeFilterMap, typename EdgeFilterMap>
marci@992
   260
  class SubGraphWrapperBase : public GraphWrapperBase<_Graph> {
marci@992
   261
  public:
marci@992
   262
    typedef _Graph Graph;
marci@992
   263
    typedef GraphWrapperBase<_Graph> Parent;
marci@992
   264
  protected:
marci@992
   265
    NodeFilterMap* node_filter_map;
marci@992
   266
    EdgeFilterMap* edge_filter_map;
marci@992
   267
    SubGraphWrapperBase() : Parent(), 
marci@992
   268
			    node_filter_map(0), edge_filter_map(0) { }
marci@775
   269
marci@992
   270
    void setNodeFilterMap(NodeFilterMap& _node_filter_map) {
marci@992
   271
      node_filter_map=&_node_filter_map;
marci@992
   272
    }
marci@992
   273
    void setEdgeFilterMap(EdgeFilterMap& _edge_filter_map) {
marci@992
   274
      edge_filter_map=&_edge_filter_map;
marci@992
   275
    }
marci@992
   276
marci@992
   277
  public:
marci@992
   278
//     SubGraphWrapperBase(Graph& _graph, 
marci@992
   279
// 			NodeFilterMap& _node_filter_map, 
marci@992
   280
// 			EdgeFilterMap& _edge_filter_map) : 
marci@992
   281
//       Parent(&_graph), 
marci@992
   282
//       node_filter_map(&node_filter_map), 
marci@992
   283
//       edge_filter_map(&edge_filter_map) { }
marci@992
   284
marci@992
   285
    typedef typename Parent::Node Node;
marci@992
   286
    typedef typename Parent::Edge Edge;
marci@992
   287
marci@992
   288
    void first(Node& i) const { 
marci@992
   289
      Parent::first(i); 
marci@992
   290
      while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i); 
marci@992
   291
    }
marci@992
   292
    void first(Edge& i) const { 
marci@992
   293
      Parent::first(i); 
marci@992
   294
      while (i!=INVALID && !(*edge_filter_map)[i]) Parent::next(i); 
marci@992
   295
    }
marci@992
   296
    void firstIn(Edge& i, const Node& n) const { 
marci@992
   297
      Parent::firstIn(i, n); 
marci@992
   298
      while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextIn(i); 
marci@992
   299
    }
marci@992
   300
    void firstOut(Edge& i, const Node& n) const { 
marci@992
   301
      Parent::firstOut(i, n); 
marci@992
   302
      while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i); 
marci@992
   303
    }
marci@992
   304
marci@992
   305
    void next(Node& i) const { 
marci@992
   306
      Parent::next(i); 
marci@992
   307
      while (i!=INVALID && !(*node_filter_map)[i]) Parent::next(i); 
marci@992
   308
    }
marci@992
   309
    void next(Edge& i) const { 
marci@992
   310
      Parent::next(i); 
marci@992
   311
      while (i!=INVALID && !(*edge_filter_map)[i]) Parent::next(i); 
marci@992
   312
    }
marci@992
   313
    void nextIn(Edge& i) const { 
marci@992
   314
      Parent::nextIn(i); 
marci@992
   315
      while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextIn(i); 
marci@992
   316
    }
marci@992
   317
    void nextOut(Edge& i) const { 
marci@992
   318
      Parent::nextOut(i); 
marci@992
   319
      while (i!=INVALID && !(*edge_filter_map)[i]) Parent::nextOut(i); 
marci@992
   320
    }
marci@992
   321
marci@992
   322
    /// This function hides \c n in the graph, i.e. the iteration 
marci@992
   323
    /// jumps over it. This is done by simply setting the value of \c n  
marci@992
   324
    /// to be false in the corresponding node-map.
marci@992
   325
    void hide(const Node& n) const { node_filter_map->set(n, false); }
marci@992
   326
marci@992
   327
    /// This function hides \c e in the graph, i.e. the iteration 
marci@992
   328
    /// jumps over it. This is done by simply setting the value of \c e  
marci@992
   329
    /// to be false in the corresponding edge-map.
marci@992
   330
    void hide(const Edge& e) const { edge_filter_map->set(e, false); }
marci@992
   331
marci@992
   332
    /// The value of \c n is set to be true in the node-map which stores 
marci@992
   333
    /// hide information. If \c n was hidden previuosly, then it is shown 
marci@992
   334
    /// again
marci@992
   335
     void unHide(const Node& n) const { node_filter_map->set(n, true); }
marci@992
   336
marci@992
   337
    /// The value of \c e is set to be true in the edge-map which stores 
marci@992
   338
    /// hide information. If \c e was hidden previuosly, then it is shown 
marci@992
   339
    /// again
marci@992
   340
    void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
marci@992
   341
marci@992
   342
    /// Returns true if \c n is hidden.
marci@992
   343
    bool hidden(const Node& n) const { return !(*node_filter_map)[n]; }
marci@992
   344
marci@992
   345
    /// Returns true if \c n is hidden.
marci@992
   346
    bool hidden(const Edge& e) const { return !(*edge_filter_map)[e]; }
marci@992
   347
marci@992
   348
    /// \warning This is a linear time operation and works only if s
marci@992
   349
    /// \c Graph::NodeIt is defined.
marci@992
   350
    /// \todo assign tags.
marci@992
   351
    int nodeNum() const { 
marci@992
   352
      int i=0;
marci@992
   353
      Node n;
marci@992
   354
      for (first(n); n!=INVALID; next(n)) ++i;
marci@992
   355
      return i; 
marci@992
   356
    }
marci@992
   357
marci@992
   358
    /// \warning This is a linear time operation and works only if 
marci@992
   359
    /// \c Graph::EdgeIt is defined.
marci@992
   360
    /// \todo assign tags.
marci@992
   361
    int edgeNum() const { 
marci@992
   362
      int i=0;
marci@992
   363
      Edge e;
marci@992
   364
      for (first(e); e!=INVALID; next(e)) ++i;
marci@992
   365
      return i; 
marci@992
   366
    }
marci@992
   367
marci@992
   368
marci@992
   369
  };
marci@775
   370
marci@930
   371
  /*! \brief A graph wrapper for hiding nodes and edges from a graph.
marci@556
   372
  
marci@930
   373
  \warning Graph wrappers are in even more experimental state than the other
marci@930
   374
  parts of the lib. Use them at you own risk.
marci@930
   375
  
marci@930
   376
  This wrapper shows a graph with filtered node-set and 
marci@930
   377
  edge-set. 
marci@930
   378
  Given a bool-valued map on the node-set and one on 
marci@930
   379
  the edge-set of the graph, the iterators show only the objects 
marci@930
   380
  having true value. We have to note that this does not mean that an 
marci@930
   381
  induced subgraph is obtained, the node-iterator cares only the filter 
marci@930
   382
  on the node-set, and the edge-iterators care only the filter on the 
marci@930
   383
  edge-set.
marci@930
   384
  \code
marci@930
   385
  typedef SmartGraph Graph;
marci@930
   386
  Graph g;
marci@930
   387
  typedef Graph::Node Node;
marci@930
   388
  typedef Graph::Edge Edge;
marci@930
   389
  Node u=g.addNode(); //node of id 0
marci@930
   390
  Node v=g.addNode(); //node of id 1
marci@930
   391
  Node e=g.addEdge(u, v); //edge of id 0
marci@930
   392
  Node f=g.addEdge(v, u); //edge of id 1
marci@930
   393
  Graph::NodeMap<bool> nm(g, true);
marci@930
   394
  nm.set(u, false);
marci@930
   395
  Graph::EdgeMap<bool> em(g, true);
marci@930
   396
  em.set(e, false);
marci@930
   397
  typedef SubGraphWrapper<Graph, Graph::NodeMap<bool>, Graph::EdgeMap<bool> > SubGW;
marci@930
   398
  SubGW gw(g, nm, em);
marci@930
   399
  for (SubGW::NodeIt n(gw); n!=INVALID; ++n) std::cout << g.id(n) << std::endl;
marci@930
   400
  std::cout << ":-)" << std::endl;
marci@930
   401
  for (SubGW::EdgeIt e(gw); e!=INVALID; ++e) std::cout << g.id(e) << std::endl;
marci@930
   402
  \endcode
marci@930
   403
  The output of the above code is the following.
marci@930
   404
  \code
marci@930
   405
  1
marci@930
   406
  :-)
marci@930
   407
  1
marci@930
   408
  \endcode
marci@930
   409
  Note that \c n is of type \c SubGW::NodeIt, but it can be converted to
marci@930
   410
  \c Graph::Node that is why \c g.id(n) can be applied.
marci@930
   411
marci@933
   412
  For other examples see also the documentation of NodeSubGraphWrapper and 
marci@933
   413
  EdgeSubGraphWrapper.
marci@930
   414
marci@930
   415
  \author Marton Makai
marci@930
   416
  */
marci@992
   417
  template<typename _Graph, typename NodeFilterMap, 
marci@556
   418
	   typename EdgeFilterMap>
marci@992
   419
  class SubGraphWrapper : 
marci@992
   420
    public IterableGraphExtender<
marci@992
   421
    SubGraphWrapperBase<_Graph, NodeFilterMap, EdgeFilterMap> > {
marci@650
   422
  public:
marci@992
   423
    typedef _Graph Graph;
marci@992
   424
    typedef IterableGraphExtender<
marci@992
   425
      SubGraphWrapperBase<_Graph, NodeFilterMap, EdgeFilterMap> > Parent;
marci@556
   426
  protected:
marci@992
   427
    SubGraphWrapper() { }
marci@992
   428
  public:
marci@992
   429
    SubGraphWrapper(_Graph& _graph, NodeFilterMap& _node_filter_map, 
marci@992
   430
		    EdgeFilterMap& _edge_filter_map) { 
marci@992
   431
      setGraph(_graph);
marci@992
   432
      setNodeFilterMap(_node_filter_map);
marci@992
   433
      setEdgeFilterMap(_edge_filter_map);
marci@992
   434
    }
marci@992
   435
  };
marci@556
   436
marci@556
   437
marci@569
   438
marci@933
   439
  /*! \brief A wrapper for hiding nodes from a graph.
marci@933
   440
marci@933
   441
  \warning Graph wrappers are in even more experimental state than the other
marci@933
   442
  parts of the lib. Use them at you own risk.
marci@933
   443
  
marci@933
   444
  A wrapper for hiding nodes from a graph.
marci@933
   445
  This wrapper specializes SubGraphWrapper in the way that only the node-set 
marci@933
   446
  can be filtered. Note that this does not mean of considering induced 
marci@933
   447
  subgraph, the edge-iterators consider the original edge-set.
marci@933
   448
  \author Marton Makai
marci@933
   449
  */
marci@933
   450
  template<typename Graph, typename NodeFilterMap>
marci@933
   451
  class NodeSubGraphWrapper : 
marci@933
   452
    public SubGraphWrapper<Graph, NodeFilterMap, 
marci@933
   453
			   ConstMap<typename Graph::Edge,bool> > {
marci@933
   454
  public:
marci@933
   455
    typedef SubGraphWrapper<Graph, NodeFilterMap, 
marci@933
   456
			    ConstMap<typename Graph::Edge,bool> > Parent;
marci@933
   457
  protected:
marci@933
   458
    ConstMap<typename Graph::Edge, bool> const_true_map;
marci@933
   459
  public:
marci@933
   460
    NodeSubGraphWrapper(Graph& _graph, NodeFilterMap& _node_filter_map) : 
marci@933
   461
      Parent(), const_true_map(true) { 
marci@933
   462
      Parent::setGraph(_graph);
marci@933
   463
      Parent::setNodeFilterMap(_node_filter_map);
marci@933
   464
      Parent::setEdgeFilterMap(const_true_map);
marci@933
   465
    }
marci@933
   466
  };
marci@933
   467
marci@933
   468
marci@932
   469
  /*! \brief A wrapper for hiding edges from a graph.
marci@932
   470
marci@932
   471
  \warning Graph wrappers are in even more experimental state than the other
marci@932
   472
  parts of the lib. Use them at you own risk.
marci@932
   473
  
marci@932
   474
  A wrapper for hiding edges from a graph.
marci@932
   475
  This wrapper specializes SubGraphWrapper in the way that only the edge-set 
marci@933
   476
  can be filtered. The usefulness of this wrapper is demonstrated in the 
marci@933
   477
  problem of searching a maximum number of edge-disjoint shortest paths 
marci@933
   478
  between 
marci@933
   479
  two nodes \c s and \c t. Shortest here means being shortest w.r.t. 
marci@933
   480
  non-negative edge-lengths. Note that 
marci@933
   481
  the comprehension of the presented solution 
marci@933
   482
  need's some knowledge from elementary combinatorial optimization. 
marci@933
   483
marci@933
   484
  If a single shortest path is to be 
marci@933
   485
  searched between two nodes \c s and \c t, then this can be done easily by 
marci@933
   486
  applying the Dijkstra algorithm class. What happens, if a maximum number of 
marci@933
   487
  edge-disjoint shortest paths is to be computed. It can be proved that an 
marci@933
   488
  edge can be in a shortest path if and only if it is tight with respect to 
marci@933
   489
  the potential function computed by Dijkstra. Moreover, any path containing 
marci@933
   490
  only such edges is a shortest one. Thus we have to compute a maximum number 
marci@933
   491
  of edge-disjoint paths between \c s and \c t in the graph which has edge-set 
marci@933
   492
  all the tight edges. The computation will be demonstrated on the following 
marci@933
   493
  graph, which is read from a dimacs file.
marci@933
   494
  
marci@933
   495
  \dot
marci@933
   496
  digraph lemon_dot_example {
marci@933
   497
  node [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
marci@933
   498
  n0 [ label="0 (s)" ];
marci@933
   499
  n1 [ label="1" ];
marci@933
   500
  n2 [ label="2" ];
marci@933
   501
  n3 [ label="3" ];
marci@933
   502
  n4 [ label="4" ];
marci@933
   503
  n5 [ label="5" ];
marci@933
   504
  n6 [ label="6 (t)" ];
marci@933
   505
  edge [ shape=ellipse, fontname=Helvetica, fontsize=10 ];
marci@933
   506
  n5 ->  n6 [ label="9, length:4" ];
marci@933
   507
  n4 ->  n6 [ label="8, length:2" ];
marci@933
   508
  n3 ->  n5 [ label="7, length:1" ];
marci@933
   509
  n2 ->  n5 [ label="6, length:3" ];
marci@933
   510
  n2 ->  n6 [ label="5, length:5" ];
marci@933
   511
  n2 ->  n4 [ label="4, length:2" ];
marci@933
   512
  n1 ->  n4 [ label="3, length:3" ];
marci@933
   513
  n0 ->  n3 [ label="2, length:1" ];
marci@933
   514
  n0 ->  n2 [ label="1, length:2" ];
marci@933
   515
  n0 ->  n1 [ label="0, length:3" ];
marci@933
   516
  }
marci@933
   517
  \enddot
marci@933
   518
marci@933
   519
  \code
marci@933
   520
  Graph g;
marci@933
   521
  Node s, t;
marci@933
   522
  LengthMap length(g);
marci@933
   523
marci@933
   524
  readDimacs(std::cin, g, length, s, t);
marci@933
   525
alpar@986
   526
  cout << "edges with lengths (of form id, source--length->target): " << endl;
marci@933
   527
  for(EdgeIt e(g); e!=INVALID; ++e) 
alpar@986
   528
    cout << g.id(e) << ", " << g.id(g.source(e)) << "--" 
alpar@986
   529
         << length[e] << "->" << g.id(g.target(e)) << endl;
marci@933
   530
marci@933
   531
  cout << "s: " << g.id(s) << " t: " << g.id(t) << endl;
marci@933
   532
  \endcode
marci@933
   533
  Next, the potential function is computed with Dijkstra.
marci@933
   534
  \code
marci@933
   535
  typedef Dijkstra<Graph, LengthMap> Dijkstra;
marci@933
   536
  Dijkstra dijkstra(g, length);
marci@933
   537
  dijkstra.run(s);
marci@933
   538
  \endcode
marci@933
   539
  Next, we consrtruct a map which filters the edge-set to the tight edges.
marci@933
   540
  \code
marci@933
   541
  typedef TightEdgeFilterMap<Graph, const Dijkstra::DistMap, LengthMap> 
marci@933
   542
    TightEdgeFilter;
marci@933
   543
  TightEdgeFilter tight_edge_filter(g, dijkstra.distMap(), length);
marci@933
   544
  
marci@933
   545
  typedef EdgeSubGraphWrapper<Graph, TightEdgeFilter> SubGW;
marci@933
   546
  SubGW gw(g, tight_edge_filter);
marci@933
   547
  \endcode
marci@933
   548
  Then, the maximum nimber of edge-disjoint \c s-\c t paths are computed 
marci@933
   549
  with a max flow algorithm Preflow.
marci@933
   550
  \code
marci@933
   551
  ConstMap<Edge, int> const_1_map(1);
marci@933
   552
  Graph::EdgeMap<int> flow(g, 0);
marci@933
   553
marci@933
   554
  Preflow<SubGW, int, ConstMap<Edge, int>, Graph::EdgeMap<int> > 
marci@933
   555
    preflow(gw, s, t, const_1_map, flow);
marci@933
   556
  preflow.run();
marci@933
   557
  \endcode
marci@933
   558
  Last, the output is:
marci@933
   559
  \code  
marci@933
   560
  cout << "maximum number of edge-disjoint shortest path: " 
marci@933
   561
       << preflow.flowValue() << endl;
marci@933
   562
  cout << "edges of the maximum number of edge-disjoint shortest s-t paths: " 
marci@933
   563
       << endl;
marci@933
   564
  for(EdgeIt e(g); e!=INVALID; ++e) 
marci@933
   565
    if (flow[e])
alpar@986
   566
      cout << " " << g.id(g.source(e)) << "--" 
alpar@986
   567
	   << length[e] << "->" << g.id(g.target(e)) << endl;
marci@933
   568
  \endcode
marci@933
   569
  The program has the following (expected :-)) output:
marci@933
   570
  \code
alpar@986
   571
  edges with lengths (of form id, source--length->target):
marci@933
   572
   9, 5--4->6
marci@933
   573
   8, 4--2->6
marci@933
   574
   7, 3--1->5
marci@933
   575
   6, 2--3->5
marci@933
   576
   5, 2--5->6
marci@933
   577
   4, 2--2->4
marci@933
   578
   3, 1--3->4
marci@933
   579
   2, 0--1->3
marci@933
   580
   1, 0--2->2
marci@933
   581
   0, 0--3->1
marci@933
   582
  s: 0 t: 6
marci@933
   583
  maximum number of edge-disjoint shortest path: 2
marci@933
   584
  edges of the maximum number of edge-disjoint shortest s-t paths:
marci@933
   585
   9, 5--4->6
marci@933
   586
   8, 4--2->6
marci@933
   587
   7, 3--1->5
marci@933
   588
   4, 2--2->4
marci@933
   589
   2, 0--1->3
marci@933
   590
   1, 0--2->2
marci@933
   591
  \endcode
marci@933
   592
marci@932
   593
  \author Marton Makai
marci@932
   594
  */
marci@932
   595
  template<typename Graph, typename EdgeFilterMap>
marci@932
   596
  class EdgeSubGraphWrapper : 
marci@932
   597
    public SubGraphWrapper<Graph, ConstMap<typename Graph::Node,bool>, 
marci@932
   598
			   EdgeFilterMap> {
marci@932
   599
  public:
marci@932
   600
    typedef SubGraphWrapper<Graph, ConstMap<typename Graph::Node,bool>, 
marci@932
   601
			    EdgeFilterMap> Parent;
marci@932
   602
  protected:
marci@932
   603
    ConstMap<typename Graph::Node, bool> const_true_map;
marci@932
   604
  public:
marci@932
   605
    EdgeSubGraphWrapper(Graph& _graph, EdgeFilterMap& _edge_filter_map) : 
marci@932
   606
      Parent(), const_true_map(true) { 
marci@932
   607
      Parent::setGraph(_graph);
marci@932
   608
      Parent::setNodeFilterMap(const_true_map);
marci@932
   609
      Parent::setEdgeFilterMap(_edge_filter_map);
marci@932
   610
    }
marci@932
   611
  };
marci@932
   612
marci@569
   613
marci@556
   614
  template<typename Graph>
marci@556
   615
  class UndirGraphWrapper : public GraphWrapper<Graph> {
marci@650
   616
  public:
marci@650
   617
    typedef GraphWrapper<Graph> Parent; 
marci@556
   618
  protected:
marci@556
   619
    UndirGraphWrapper() : GraphWrapper<Graph>() { }
marci@556
   620
    
marci@556
   621
  public:
marci@556
   622
    typedef typename GraphWrapper<Graph>::Node Node;
marci@556
   623
    typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
marci@556
   624
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@556
   625
    typedef typename GraphWrapper<Graph>::EdgeIt EdgeIt;
marci@556
   626
marci@556
   627
    UndirGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }  
marci@556
   628
marci@556
   629
    class OutEdgeIt {
marci@556
   630
      friend class UndirGraphWrapper<Graph>;
marci@556
   631
      bool out_or_in; //true iff out
marci@556
   632
      typename Graph::OutEdgeIt out;
marci@556
   633
      typename Graph::InEdgeIt in;
marci@556
   634
    public:
marci@556
   635
      OutEdgeIt() { }
marci@556
   636
      OutEdgeIt(const Invalid& i) : Edge(i) { }
marci@556
   637
      OutEdgeIt(const UndirGraphWrapper<Graph>& _G, const Node& _n) {
marci@556
   638
	out_or_in=true; _G.graph->first(out, _n);
marci@556
   639
	if (!(_G.graph->valid(out))) { out_or_in=false; _G.graph->first(in, _n);	}
marci@556
   640
      } 
marci@556
   641
      operator Edge() const { 
marci@556
   642
	if (out_or_in) return Edge(out); else return Edge(in); 
marci@556
   643
      }
marci@556
   644
    };
marci@556
   645
marci@556
   646
    typedef OutEdgeIt InEdgeIt; 
marci@556
   647
marci@556
   648
    using GraphWrapper<Graph>::first;
marci@556
   649
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@556
   650
      i=OutEdgeIt(*this, p); return i;
marci@556
   651
    }
marci@556
   652
marci@556
   653
    using GraphWrapper<Graph>::next;
alpar@878
   654
marci@556
   655
    OutEdgeIt& next(OutEdgeIt& e) const {
marci@556
   656
      if (e.out_or_in) {
alpar@986
   657
	typename Graph::Node n=this->graph->source(e.out);
marci@556
   658
	this->graph->next(e.out);
marci@556
   659
	if (!this->graph->valid(e.out)) { 
marci@556
   660
	  e.out_or_in=false; this->graph->first(e.in, n); }
marci@556
   661
      } else {
marci@556
   662
	this->graph->next(e.in);
marci@556
   663
      }
marci@556
   664
      return e;
marci@556
   665
    }
marci@556
   666
marci@556
   667
    Node aNode(const OutEdgeIt& e) const { 
alpar@986
   668
      if (e.out_or_in) return this->graph->source(e); else 
alpar@986
   669
	return this->graph->target(e); }
marci@556
   670
    Node bNode(const OutEdgeIt& e) const { 
alpar@986
   671
      if (e.out_or_in) return this->graph->target(e); else 
alpar@986
   672
	return this->graph->source(e); }
deba@877
   673
deba@891
   674
    //    KEEP_MAPS(Parent, UndirGraphWrapper);
deba@877
   675
marci@556
   676
  };
marci@556
   677
  
marci@910
   678
//   /// \brief An undirected graph template.
marci@910
   679
//   ///
marci@910
   680
//   ///\warning Graph wrappers are in even more experimental state than the other
marci@910
   681
//   ///parts of the lib. Use them at your own risk.
marci@910
   682
//   ///
marci@910
   683
//   /// An undirected graph template.
marci@910
   684
//   /// This class works as an undirected graph and a directed graph of 
marci@910
   685
//   /// class \c Graph is used for the physical storage.
marci@910
   686
//   /// \ingroup graphs
marci@556
   687
  template<typename Graph>
marci@556
   688
  class UndirGraph : public UndirGraphWrapper<Graph> {
marci@556
   689
    typedef UndirGraphWrapper<Graph> Parent;
marci@556
   690
  protected:
marci@556
   691
    Graph gr;
marci@556
   692
  public:
marci@556
   693
    UndirGraph() : UndirGraphWrapper<Graph>() { 
marci@556
   694
      Parent::setGraph(gr); 
marci@556
   695
    }
deba@877
   696
deba@891
   697
    //    KEEP_MAPS(Parent, UndirGraph);
marci@556
   698
  };
marci@556
   699
marci@992
   700
  
marci@992
   701
  template <typename _Graph, 
marci@992
   702
	    typename ForwardFilterMap, typename BackwardFilterMap>
marci@992
   703
  class SubBidirGraphWrapperBase : public GraphWrapperBase<_Graph> {
marci@992
   704
  public:
marci@992
   705
    typedef _Graph Graph;
marci@992
   706
    typedef GraphWrapperBase<_Graph> Parent;
marci@992
   707
  protected:
marci@992
   708
    ForwardFilterMap* forward_filter;
marci@992
   709
    BackwardFilterMap* backward_filter;
marci@992
   710
    SubBidirGraphWrapperBase() : Parent(), 
marci@992
   711
				 forward_filter(0), backward_filter(0) { }
marci@992
   712
marci@992
   713
    void setForwardFilterMap(ForwardFilterMap& _forward_filter) {
marci@992
   714
      forward_filter=&_forward_filter;
marci@992
   715
    }
marci@992
   716
    void setBackwardFilterMap(BackwardFilterMap& _backward_filter) {
marci@992
   717
      backward_filter=&_backward_filter;
marci@992
   718
    }
marci@992
   719
marci@992
   720
  public:
marci@992
   721
//     SubGraphWrapperBase(Graph& _graph, 
marci@992
   722
// 			NodeFilterMap& _node_filter_map, 
marci@992
   723
// 			EdgeFilterMap& _edge_filter_map) : 
marci@992
   724
//       Parent(&_graph), 
marci@992
   725
//       node_filter_map(&node_filter_map), 
marci@992
   726
//       edge_filter_map(&edge_filter_map) { }
marci@992
   727
marci@992
   728
    typedef typename Parent::Node Node;
marci@992
   729
    typedef typename _Graph::Edge GraphEdge;
marci@992
   730
    template <typename T> class EdgeMap;
marci@992
   731
    /// SubBidirGraphWrapperBase<..., ..., ...>::Edge is inherited from 
marci@992
   732
    /// _Graph::Edge. It contains an extra bool flag which is true 
marci@992
   733
    /// if and only if the 
marci@992
   734
    /// edge is the backward version of the original edge.
marci@992
   735
    class Edge : public _Graph::Edge {
marci@992
   736
      friend class SubBidirGraphWrapperBase<
marci@992
   737
	Graph, ForwardFilterMap, BackwardFilterMap>;
marci@992
   738
      template<typename T> friend class EdgeMap;
marci@992
   739
    protected:
marci@992
   740
      bool backward; //true, iff backward
marci@992
   741
    public:
marci@992
   742
      Edge() { }
marci@992
   743
      /// \todo =false is needed, or causes problems?
marci@992
   744
      /// If \c _backward is false, then we get an edge corresponding to the 
marci@992
   745
      /// original one, otherwise its oppositely directed pair is obtained.
marci@992
   746
      Edge(const typename _Graph::Edge& e, bool _backward/*=false*/) : 
marci@992
   747
	_Graph::Edge(e), backward(_backward) { }
marci@992
   748
      Edge(Invalid i) : _Graph::Edge(i), backward(true) { }
marci@992
   749
      bool operator==(const Edge& v) const { 
marci@992
   750
	return (this->backward==v.backward && 
marci@992
   751
		static_cast<typename _Graph::Edge>(*this)==
marci@992
   752
		static_cast<typename _Graph::Edge>(v));
marci@992
   753
      } 
marci@992
   754
      bool operator!=(const Edge& v) const { 
marci@992
   755
	return (this->backward!=v.backward || 
marci@992
   756
		static_cast<typename _Graph::Edge>(*this)!=
marci@992
   757
		static_cast<typename _Graph::Edge>(v));
marci@992
   758
      }
marci@992
   759
    };
marci@992
   760
marci@992
   761
    void first(Node& i) const { 
marci@992
   762
      Parent::first(i); 
marci@992
   763
    }
marci@992
   764
marci@992
   765
    void first(Edge& i) const { 
marci@992
   766
      Parent::first(i); 
marci@992
   767
      i.backward=false;
marci@992
   768
      while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   769
	     !(*forward_filter)[i]) Parent::next(i);
marci@992
   770
      if (*static_cast<GraphEdge*>(&i)==INVALID) {
marci@992
   771
	Parent::first(i); 
marci@992
   772
	i.backward=true;
marci@992
   773
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   774
	       !(*backward_filter)[i]) Parent::next(i);
marci@992
   775
      }
marci@992
   776
    }
marci@992
   777
marci@992
   778
    void firstIn(Edge& i, const Node& n) const { 
marci@992
   779
      Parent::firstIn(i, n); 
marci@992
   780
      i.backward=false;
marci@992
   781
      while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   782
	     !(*forward_filter)[i]) Parent::nextOut(i);
marci@992
   783
      if (*static_cast<GraphEdge*>(&i)==INVALID) {
marci@992
   784
	Parent::firstOut(i, n); 
marci@992
   785
	i.backward=true;
marci@992
   786
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   787
	       !(*backward_filter)[i]) Parent::nextOut(i);
marci@992
   788
      }
marci@992
   789
    }
marci@992
   790
marci@992
   791
    void firstOut(Edge& i, const Node& n) const { 
marci@992
   792
      Parent::firstOut(i, n); 
marci@992
   793
      i.backward=false;
marci@992
   794
      while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   795
	     !(*forward_filter)[i]) Parent::nextOut(i);
marci@992
   796
      if (*static_cast<GraphEdge*>(&i)==INVALID) {
marci@992
   797
	Parent::firstIn(i, n); 
marci@992
   798
	i.backward=true;
marci@992
   799
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   800
	       !(*backward_filter)[i]) Parent::nextIn(i);
marci@992
   801
      }
marci@992
   802
    }
marci@992
   803
marci@992
   804
    void next(Node& i) const { 
marci@992
   805
      Parent::next(i); 
marci@992
   806
    }
marci@992
   807
marci@992
   808
    void next(Edge& i) const { 
marci@992
   809
      if (!(i.backward)) {
marci@992
   810
	Parent::next(i);
marci@992
   811
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   812
	       !(*forward_filter)[i]) Parent::next(i);
marci@992
   813
	if (*static_cast<GraphEdge*>(&i)==INVALID) {
marci@992
   814
	  Parent::first(i); 
marci@992
   815
	  i.backward=true;
marci@992
   816
	  while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   817
		 !(*backward_filter)[i]) Parent::next(i);
marci@992
   818
	}
marci@992
   819
      } else {
marci@992
   820
	Parent::next(i);
marci@992
   821
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   822
	       !(*backward_filter)[i]) Parent::next(i);
marci@992
   823
      }
marci@992
   824
    }
marci@992
   825
marci@992
   826
    void nextIn(Edge& i) const { 
marci@992
   827
      if (!(i.backward)) {
marci@992
   828
	Node n=Parent::target(i);
marci@992
   829
	Parent::nextIn(i);
marci@992
   830
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   831
	       !(*forward_filter)[i]) Parent::nextIn(i);
marci@992
   832
	if (*static_cast<GraphEdge*>(&i)==INVALID) {
marci@992
   833
	  Parent::firstOut(i, n); 
marci@992
   834
	  i.backward=true;
marci@992
   835
	  while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   836
		 !(*backward_filter)[i]) Parent::nextOut(i);
marci@992
   837
	}
marci@992
   838
      } else {
marci@992
   839
	Parent::nextOut(i);
marci@992
   840
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   841
	       !(*backward_filter)[i]) Parent::nextOut(i);
marci@992
   842
      }
marci@992
   843
    }
marci@992
   844
marci@992
   845
    void nextOut(Edge& i) const { 
marci@992
   846
      if (!(i.backward)) {
marci@992
   847
	Node n=Parent::source(i);
marci@992
   848
	Parent::nextOut(i);
marci@992
   849
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   850
	       !(*forward_filter)[i]) Parent::nextOut(i);
marci@992
   851
	if (*static_cast<GraphEdge*>(&i)==INVALID) {
marci@992
   852
	  Parent::firstIn(i, n); 
marci@992
   853
	  i.backward=true;
marci@992
   854
	  while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   855
		 !(*backward_filter)[i]) Parent::nextIn(i);
marci@992
   856
	}
marci@992
   857
      } else {
marci@992
   858
	Parent::nextIn(i);
marci@992
   859
	while (*static_cast<GraphEdge*>(&i)!=INVALID && 
marci@992
   860
	       !(*backward_filter)[i]) Parent::nextIn(i);
marci@992
   861
      }
marci@992
   862
    }
marci@992
   863
marci@992
   864
    Node source(Edge e) const { 
marci@992
   865
      return ((!e.backward) ? this->graph->source(e) : this->graph->target(e)); }
marci@992
   866
    Node target(Edge e) const { 
marci@992
   867
      return ((!e.backward) ? this->graph->target(e) : this->graph->source(e)); }
marci@992
   868
marci@992
   869
    /// Gives back the opposite edge.
marci@992
   870
    Edge opposite(const Edge& e) const { 
marci@992
   871
      Edge f=e;
marci@992
   872
      f.backward=!f.backward;
marci@992
   873
      return f;
marci@992
   874
    }
marci@992
   875
marci@992
   876
    /// \warning This is a linear time operation and works only if 
marci@992
   877
    /// \c Graph::EdgeIt is defined.
marci@992
   878
    /// \todo hmm
marci@992
   879
    int edgeNum() const { 
marci@992
   880
      int i=0;
marci@992
   881
      Edge e;
marci@992
   882
      for (first(e); e!=INVALID; next(e)) ++i;
marci@992
   883
      return i; 
marci@992
   884
    }
marci@992
   885
marci@992
   886
    bool forward(const Edge& e) const { return !e.backward; }
marci@992
   887
    bool backward(const Edge& e) const { return e.backward; }
marci@992
   888
marci@992
   889
    template <typename T>
marci@992
   890
    /// \c SubBidirGraphWrapperBase<..., ..., ...>::EdgeMap contains two 
marci@992
   891
    /// _Graph::EdgeMap one for the forward edges and 
marci@992
   892
    /// one for the backward edges.
marci@992
   893
    class EdgeMap {
marci@992
   894
      template <typename TT> friend class EdgeMap;
marci@992
   895
      typename _Graph::template EdgeMap<T> forward_map, backward_map; 
marci@992
   896
    public:
marci@992
   897
      typedef T Value;
marci@992
   898
      typedef Edge Key;
marci@992
   899
marci@992
   900
      EdgeMap(const SubBidirGraphWrapperBase<_Graph, 
marci@992
   901
	      ForwardFilterMap, BackwardFilterMap>& g) : 
marci@992
   902
	forward_map(*(g.graph)), backward_map(*(g.graph)) { }
marci@992
   903
marci@992
   904
      EdgeMap(const SubBidirGraphWrapperBase<_Graph, 
marci@992
   905
	      ForwardFilterMap, BackwardFilterMap>& g, T a) : 
marci@992
   906
	forward_map(*(g.graph), a), backward_map(*(g.graph), a) { }
marci@992
   907
      
marci@992
   908
      void set(Edge e, T a) { 
marci@992
   909
	if (!e.backward) 
marci@992
   910
	  forward_map.set(e, a); 
marci@992
   911
	else 
marci@992
   912
	  backward_map.set(e, a); 
marci@992
   913
      }
marci@992
   914
marci@992
   915
//       typename _Graph::template EdgeMap<T>::ConstReference 
marci@992
   916
//       operator[](Edge e) const { 
marci@992
   917
// 	if (!e.backward) 
marci@992
   918
// 	  return forward_map[e]; 
marci@992
   919
// 	else 
marci@992
   920
// 	  return backward_map[e]; 
marci@992
   921
//       }
marci@992
   922
marci@992
   923
//      typename _Graph::template EdgeMap<T>::Reference 
marci@1016
   924
      T operator[](Edge e) const { 
marci@992
   925
	if (!e.backward) 
marci@992
   926
	  return forward_map[e]; 
marci@992
   927
	else 
marci@992
   928
	  return backward_map[e]; 
marci@992
   929
      }
marci@992
   930
marci@992
   931
      void update() { 
marci@992
   932
	forward_map.update(); 
marci@992
   933
	backward_map.update();
marci@992
   934
      }
marci@992
   935
    };
marci@992
   936
marci@992
   937
  };
marci@569
   938
marci@650
   939
marci@650
   940
  ///\brief A wrapper for composing a subgraph of a 
marci@792
   941
  /// bidirected graph made from a directed one. 
marci@612
   942
  ///
alpar@911
   943
  /// A wrapper for composing a subgraph of a 
alpar@911
   944
  /// bidirected graph made from a directed one. 
alpar@911
   945
  ///
alpar@879
   946
  ///\warning Graph wrappers are in even more experimental state than the other
alpar@879
   947
  ///parts of the lib. Use them at you own risk.
alpar@879
   948
  ///
marci@923
   949
  /// Let \f$G=(V, A)\f$ be a directed graph and for each directed edge 
marci@923
   950
  /// \f$e\in A\f$, let \f$\bar e\f$ denote the edge obtained by
marci@923
   951
  /// reversing its orientation. We are given moreover two bool valued 
marci@923
   952
  /// maps on the edge-set, 
marci@923
   953
  /// \f$forward\_filter\f$, and \f$backward\_filter\f$. 
marci@923
   954
  /// SubBidirGraphWrapper implements the graph structure with node-set 
marci@923
   955
  /// \f$V\f$ and edge-set 
marci@923
   956
  /// \f$\{e : e\in A \mbox{ and } forward\_filter(e) \mbox{ is true}\}+\{\bar e : e\in A \mbox{ and } backward\_filter(e) \mbox{ is true}\}\f$. 
marci@792
   957
  /// The purpose of writing + instead of union is because parallel 
marci@923
   958
  /// edges can arise. (Similarly, antiparallel edges also can arise).
marci@792
   959
  /// In other words, a subgraph of the bidirected graph obtained, which 
marci@792
   960
  /// is given by orienting the edges of the original graph in both directions.
marci@923
   961
  /// As the oppositely directed edges are logically different, 
marci@923
   962
  /// the maps are able to attach different values for them. 
marci@923
   963
  ///
marci@923
   964
  /// An example for such a construction is \c RevGraphWrapper where the 
marci@792
   965
  /// forward_filter is everywhere false and the backward_filter is 
marci@792
   966
  /// everywhere true. We note that for sake of efficiency, 
marci@792
   967
  /// \c RevGraphWrapper is implemented in a different way. 
marci@792
   968
  /// But BidirGraphWrapper is obtained from 
marci@792
   969
  /// SubBidirGraphWrapper by considering everywhere true 
marci@910
   970
  /// valued maps both for forward_filter and backward_filter. 
marci@792
   971
  /// Finally, one of the most important applications of SubBidirGraphWrapper 
marci@792
   972
  /// is ResGraphWrapper, which stands for the residual graph in directed 
marci@792
   973
  /// flow and circulation problems. 
marci@792
   974
  /// As wrappers usually, the SubBidirGraphWrapper implements the 
marci@792
   975
  /// above mentioned graph structure without its physical storage, 
marci@923
   976
  /// that is the whole stuff is stored in constant memory. 
marci@992
   977
  template<typename _Graph, 
marci@650
   978
	   typename ForwardFilterMap, typename BackwardFilterMap>
marci@992
   979
  class SubBidirGraphWrapper : 
marci@992
   980
    public IterableGraphExtender<
marci@992
   981
    SubBidirGraphWrapperBase<_Graph, ForwardFilterMap, BackwardFilterMap> > {
marci@650
   982
  public:
marci@992
   983
    typedef _Graph Graph;
marci@992
   984
    typedef IterableGraphExtender<
marci@992
   985
      SubBidirGraphWrapperBase<
marci@992
   986
      _Graph, ForwardFilterMap, BackwardFilterMap> > Parent;
marci@569
   987
  protected:
marci@992
   988
    SubBidirGraphWrapper() { }
marci@992
   989
  public:
marci@992
   990
    SubBidirGraphWrapper(_Graph& _graph, ForwardFilterMap& _forward_filter, 
marci@992
   991
			 BackwardFilterMap& _backward_filter) { 
marci@992
   992
      setGraph(_graph);
marci@992
   993
      setForwardFilterMap(_forward_filter);
marci@992
   994
      setBackwardFilterMap(_backward_filter);
marci@992
   995
    }
marci@992
   996
  };
marci@650
   997
marci@569
   998
marci@650
   999
marci@650
  1000
  ///\brief A wrapper for composing bidirected graph from a directed one. 
marci@650
  1001
  ///
alpar@879
  1002
  ///\warning Graph wrappers are in even more experimental state than the other
alpar@879
  1003
  ///parts of the lib. Use them at you own risk.
alpar@879
  1004
  ///
marci@650
  1005
  /// A wrapper for composing bidirected graph from a directed one. 
marci@650
  1006
  /// A bidirected graph is composed over the directed one without physical 
marci@650
  1007
  /// storage. As the oppositely directed edges are logically different ones 
marci@650
  1008
  /// the maps are able to attach different values for them.
marci@650
  1009
  template<typename Graph>
marci@650
  1010
  class BidirGraphWrapper : 
marci@650
  1011
    public SubBidirGraphWrapper<
marci@650
  1012
    Graph, 
marci@650
  1013
    ConstMap<typename Graph::Edge, bool>, 
marci@650
  1014
    ConstMap<typename Graph::Edge, bool> > {
marci@650
  1015
  public:
marci@650
  1016
    typedef  SubBidirGraphWrapper<
marci@650
  1017
      Graph, 
marci@650
  1018
      ConstMap<typename Graph::Edge, bool>, 
marci@650
  1019
      ConstMap<typename Graph::Edge, bool> > Parent; 
marci@650
  1020
  protected:
marci@650
  1021
    ConstMap<typename Graph::Edge, bool> cm;
marci@650
  1022
marci@655
  1023
    BidirGraphWrapper() : Parent(), cm(true) { 
marci@655
  1024
      Parent::setForwardFilterMap(cm);
marci@655
  1025
      Parent::setBackwardFilterMap(cm);
marci@655
  1026
    }
marci@650
  1027
  public:
marci@650
  1028
    BidirGraphWrapper(Graph& _graph) : Parent() { 
marci@650
  1029
      Parent::setGraph(_graph);
marci@650
  1030
      Parent::setForwardFilterMap(cm);
marci@650
  1031
      Parent::setBackwardFilterMap(cm);
marci@650
  1032
    }
marci@738
  1033
marci@738
  1034
    int edgeNum() const { 
marci@738
  1035
      return 2*this->graph->edgeNum();
marci@738
  1036
    }
deba@891
  1037
    //    KEEP_MAPS(Parent, BidirGraphWrapper);
marci@650
  1038
  };
marci@650
  1039
marci@650
  1040
marci@612
  1041
  /// \brief A bidirected graph template.
marci@612
  1042
  ///
alpar@879
  1043
  ///\warning Graph wrappers are in even more experimental state than the other
alpar@879
  1044
  ///parts of the lib. Use them at you own risk.
alpar@879
  1045
  ///
marci@612
  1046
  /// A bidirected graph template.
marci@612
  1047
  /// Such a bidirected graph stores each pair of oppositely directed edges 
marci@612
  1048
  /// ones in the memory, i.e. a directed graph of type 
marci@612
  1049
  /// \c Graph is used for that.
marci@612
  1050
  /// As the oppositely directed edges are logically different ones 
marci@612
  1051
  /// the maps are able to attach different values for them.
marci@612
  1052
  /// \ingroup graphs
marci@612
  1053
  template<typename Graph>
marci@612
  1054
  class BidirGraph : public BidirGraphWrapper<Graph> {
marci@650
  1055
  public:
marci@612
  1056
    typedef UndirGraphWrapper<Graph> Parent;
marci@612
  1057
  protected:
marci@612
  1058
    Graph gr;
marci@612
  1059
  public:
marci@612
  1060
    BidirGraph() : BidirGraphWrapper<Graph>() { 
marci@612
  1061
      Parent::setGraph(gr); 
marci@612
  1062
    }
deba@891
  1063
    //    KEEP_MAPS(Parent, BidirGraph);
marci@612
  1064
  };
marci@569
  1065
marci@556
  1066
marci@650
  1067
marci@650
  1068
  template<typename Graph, typename Number,
marci@650
  1069
	   typename CapacityMap, typename FlowMap>
marci@658
  1070
  class ResForwardFilter {
marci@658
  1071
    //    const Graph* graph;
marci@650
  1072
    const CapacityMap* capacity;
marci@650
  1073
    const FlowMap* flow;
marci@650
  1074
  public:
marci@658
  1075
    ResForwardFilter(/*const Graph& _graph, */
marci@658
  1076
		     const CapacityMap& _capacity, const FlowMap& _flow) :
marci@658
  1077
      /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
marci@658
  1078
    ResForwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
marci@656
  1079
    void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
marci@656
  1080
    void setFlow(const FlowMap& _flow) { flow=&_flow; }
marci@650
  1081
    bool operator[](const typename Graph::Edge& e) const {
marci@738
  1082
      return (Number((*flow)[e]) < Number((*capacity)[e]));
marci@650
  1083
    }
marci@650
  1084
  };
marci@650
  1085
marci@650
  1086
  template<typename Graph, typename Number,
marci@650
  1087
	   typename CapacityMap, typename FlowMap>
marci@658
  1088
  class ResBackwardFilter {
marci@650
  1089
    const CapacityMap* capacity;
marci@650
  1090
    const FlowMap* flow;
marci@650
  1091
  public:
marci@658
  1092
    ResBackwardFilter(/*const Graph& _graph,*/ 
marci@658
  1093
		      const CapacityMap& _capacity, const FlowMap& _flow) :
marci@658
  1094
      /*graph(&_graph),*/ capacity(&_capacity), flow(&_flow) { }
marci@658
  1095
    ResBackwardFilter() : /*graph(0),*/ capacity(0), flow(0) { }
marci@656
  1096
    void setCapacity(const CapacityMap& _capacity) { capacity=&_capacity; }
marci@656
  1097
    void setFlow(const FlowMap& _flow) { flow=&_flow; }
marci@650
  1098
    bool operator[](const typename Graph::Edge& e) const {
marci@738
  1099
      return (Number(0) < Number((*flow)[e]));
marci@650
  1100
    }
marci@650
  1101
  };
marci@650
  1102
marci@653
  1103
  
marci@653
  1104
  /// A wrapper for composing the residual graph for directed flow and circulation problems.
marci@650
  1105
alpar@879
  1106
  ///\warning Graph wrappers are in even more experimental state than the other
alpar@879
  1107
  ///parts of the lib. Use them at you own risk.
alpar@879
  1108
  ///
marci@653
  1109
  /// A wrapper for composing the residual graph for directed flow and circulation problems.
marci@650
  1110
  template<typename Graph, typename Number, 
marci@650
  1111
	   typename CapacityMap, typename FlowMap>
marci@653
  1112
  class ResGraphWrapper : 
marci@650
  1113
    public SubBidirGraphWrapper< 
marci@650
  1114
    Graph, 
marci@658
  1115
    ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,  
marci@658
  1116
    ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > {
marci@650
  1117
  public:
marci@650
  1118
    typedef SubBidirGraphWrapper< 
marci@650
  1119
      Graph, 
marci@658
  1120
      ResForwardFilter<Graph, Number, CapacityMap, FlowMap>,  
marci@658
  1121
      ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> > Parent;
marci@650
  1122
  protected:
marci@650
  1123
    const CapacityMap* capacity;
marci@650
  1124
    FlowMap* flow;
marci@658
  1125
    ResForwardFilter<Graph, Number, CapacityMap, FlowMap> forward_filter;
marci@658
  1126
    ResBackwardFilter<Graph, Number, CapacityMap, FlowMap> backward_filter;
marci@658
  1127
    ResGraphWrapper() : Parent(), 
marci@658
  1128
 			capacity(0), flow(0) { }
marci@658
  1129
    void setCapacityMap(const CapacityMap& _capacity) {
marci@658
  1130
      capacity=&_capacity;
marci@658
  1131
      forward_filter.setCapacity(_capacity);
marci@658
  1132
      backward_filter.setCapacity(_capacity);
marci@658
  1133
    }
marci@658
  1134
    void setFlowMap(FlowMap& _flow) {
marci@658
  1135
      flow=&_flow;
marci@658
  1136
      forward_filter.setFlow(_flow);
marci@658
  1137
      backward_filter.setFlow(_flow);
marci@658
  1138
    }
marci@650
  1139
  public:
marci@653
  1140
    ResGraphWrapper(Graph& _graph, const CapacityMap& _capacity, 
marci@650
  1141
		       FlowMap& _flow) : 
marci@650
  1142
      Parent(), capacity(&_capacity), flow(&_flow), 
marci@658
  1143
      forward_filter(/*_graph,*/ _capacity, _flow), 
marci@658
  1144
      backward_filter(/*_graph,*/ _capacity, _flow) {
marci@650
  1145
      Parent::setGraph(_graph);
marci@650
  1146
      Parent::setForwardFilterMap(forward_filter);
marci@650
  1147
      Parent::setBackwardFilterMap(backward_filter);
marci@650
  1148
    }
marci@650
  1149
marci@660
  1150
    typedef typename Parent::Edge Edge;
marci@660
  1151
marci@660
  1152
    void augment(const Edge& e, Number a) const {
marci@650
  1153
      if (Parent::forward(e))  
marci@650
  1154
	flow->set(e, (*flow)[e]+a);
marci@650
  1155
      else  
marci@650
  1156
	flow->set(e, (*flow)[e]-a);
marci@650
  1157
    }
marci@650
  1158
marci@660
  1159
    /// \brief Residual capacity map.
marci@660
  1160
    ///
marci@910
  1161
    /// In generic residual graphs the residual capacity can be obtained 
marci@910
  1162
    /// as a map. 
marci@660
  1163
    class ResCap {
marci@660
  1164
    protected:
marci@660
  1165
      const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>* res_graph;
marci@660
  1166
    public:
alpar@987
  1167
      typedef Number Value;
alpar@987
  1168
      typedef Edge Key;
marci@888
  1169
      ResCap(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& 
marci@888
  1170
	     _res_graph) : res_graph(&_res_graph) { }
marci@660
  1171
      Number operator[](const Edge& e) const { 
marci@660
  1172
	if (res_graph->forward(e)) 
marci@660
  1173
	  return (*(res_graph->capacity))[e]-(*(res_graph->flow))[e]; 
marci@660
  1174
	else 
marci@660
  1175
	  return (*(res_graph->flow))[e]; 
marci@660
  1176
      }
marci@660
  1177
    };
marci@660
  1178
deba@891
  1179
    //    KEEP_MAPS(Parent, ResGraphWrapper);
marci@650
  1180
  };
marci@650
  1181
marci@650
  1182
marci@998
  1183
marci@998
  1184
  template <typename _Graph, typename FirstOutEdgesMap>
marci@998
  1185
  class ErasingFirstGraphWrapperBase : public GraphWrapperBase<_Graph> {
marci@998
  1186
  public:
marci@998
  1187
    typedef _Graph Graph;
marci@998
  1188
    typedef GraphWrapperBase<_Graph> Parent;
marci@998
  1189
  protected:
marci@998
  1190
    FirstOutEdgesMap* first_out_edges;
marci@998
  1191
    ErasingFirstGraphWrapperBase() : Parent(), 
marci@998
  1192
				     first_out_edges(0) { }
marci@998
  1193
marci@998
  1194
    void setFirstOutEdgesMap(FirstOutEdgesMap& _first_out_edges) {
marci@998
  1195
      first_out_edges=&_first_out_edges;
marci@998
  1196
    }
marci@998
  1197
marci@998
  1198
  public:
marci@998
  1199
marci@998
  1200
    typedef typename Parent::Node Node;
marci@998
  1201
    typedef typename Parent::Edge Edge;
marci@998
  1202
marci@998
  1203
    void firstOut(Edge& i, const Node& n) const { 
marci@998
  1204
      i=(*first_out_edges)[n];
marci@998
  1205
    }
marci@998
  1206
marci@998
  1207
    void erase(const Edge& e) const {
marci@998
  1208
      Node n=source(e);
marci@998
  1209
      Edge f=e;
marci@998
  1210
      Parent::nextOut(f);
marci@998
  1211
      first_out_edges->set(n, f);
marci@998
  1212
    }    
marci@998
  1213
  };
marci@998
  1214
marci@998
  1215
marci@612
  1216
  /// For blocking flows.
marci@556
  1217
alpar@879
  1218
  ///\warning Graph wrappers are in even more experimental state than the other
alpar@879
  1219
  ///parts of the lib. Use them at you own risk.
alpar@879
  1220
  ///
marci@792
  1221
  /// This graph wrapper is used for on-the-fly 
marci@792
  1222
  /// Dinits blocking flow computations.
marci@612
  1223
  /// For each node, an out-edge is stored which is used when the 
marci@612
  1224
  /// \code 
marci@612
  1225
  /// OutEdgeIt& first(OutEdgeIt&, const Node&)
marci@612
  1226
  /// \endcode
marci@612
  1227
  /// is called. 
marci@556
  1228
  ///
marci@792
  1229
  /// \author Marton Makai
marci@998
  1230
  template <typename _Graph, typename FirstOutEdgesMap>
marci@998
  1231
  class ErasingFirstGraphWrapper : 
marci@998
  1232
    public IterableGraphExtender<
marci@998
  1233
    ErasingFirstGraphWrapperBase<_Graph, FirstOutEdgesMap> > {
marci@650
  1234
  public:
marci@998
  1235
    typedef _Graph Graph;
marci@998
  1236
    typedef IterableGraphExtender<
marci@998
  1237
      ErasingFirstGraphWrapperBase<_Graph, FirstOutEdgesMap> > Parent;
marci@556
  1238
    ErasingFirstGraphWrapper(Graph& _graph, 
marci@998
  1239
			     FirstOutEdgesMap& _first_out_edges) { 
marci@998
  1240
      setGraph(_graph);
marci@998
  1241
      setFirstOutEdgesMap(_first_out_edges);
marci@998
  1242
    } 
marci@1019
  1243
marci@998
  1244
  };
marci@556
  1245
marci@556
  1246
  ///@}
marci@556
  1247
alpar@921
  1248
} //namespace lemon
marci@556
  1249
alpar@921
  1250
#endif //LEMON_GRAPH_WRAPPER_H
marci@556
  1251