COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/hugo/graph_wrapper.h @ 920:2d6c8075d9d0

Last change on this file since 920:2d6c8075d9d0 was 911:89a4fbb99cad, checked in by Alpar Juttner, 20 years ago

Fix many doxygen command bugs.

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