COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/marci/bipartite_graph_wrapper.h @ 500:1a45623b4796

Last change on this file since 500:1a45623b4796 was 500:1a45623b4796, checked in by marci, 20 years ago

misc

File size: 22.6 KB
RevLine 
[174]1// -*- c++ -*-
[496]2#ifndef HUGO_BIPARTITE_GRAPH_WRAPPER_H
3#define HUGO_BIPARTITE_GRAPH_WRAPPER_H
[76]4
[491]5///\ingroup gwrappers
[457]6///\file
7///\brief Several graph wrappers.
8///
9///This file contains several useful graph wrapper functions.
10///
11///\author Marton Makai
12
[174]13#include <invalid.h>
[368]14#include <iter_map.h>
[496]15#include <graph_wrapper.h>
[174]16
[105]17namespace hugo {
[76]18
[368]19  /// A wrapper for composing a bipartite graph.
[371]20  /// \c _graph have to be a reference to a graph of type \c Graph
21  /// and \c _s_false_t_true_map is an \c IterableBoolMap
[368]22  /// reference containing the elements for the
[371]23  /// color classes S and T. \c _graph is to be referred to an undirected
24  /// graph or a directed graph with edges oriented from S to T.
[457]25  ///
26  ///\author Marton Makai
[368]27  template<typename Graph>
28  class BipartiteGraphWrapper : public GraphWrapper<Graph> {
[497]29  protected:
[389]30    typedef IterableBoolMap< typename Graph::template NodeMap<int> >
31    SFalseTTrueMap;
[368]32    SFalseTTrueMap* s_false_t_true_map;
[393]33
[499]34    BipartiteGraphWrapper() : GraphWrapper<Graph>() { }
[497]35    void setSFalseTTrueMap(SFalseTTrueMap& _s_false_t_true_map) {
[499]36      s_false_t_true_map=&_s_false_t_true_map;
[497]37    }
38
[368]39  public:
[409]40    //marci
41    //FIXME vhogy igy kellene, csak az en forditom nem eszi meg
42    //static const bool S_CLASS=false;
43    //static const bool T_CLASS=true;
[379]44   
[409]45    bool S_CLASS;
46    bool T_CLASS;
47
[368]48    BipartiteGraphWrapper(Graph& _graph, SFalseTTrueMap& _s_false_t_true_map)
[500]49      : GraphWrapper<Graph>(_graph),
50        s_false_t_true_map(&_s_false_t_true_map),
51        S_CLASS(false), T_CLASS(true) { }
[368]52    typedef typename GraphWrapper<Graph>::Node Node;
53    //using GraphWrapper<Graph>::NodeIt;
54    typedef typename GraphWrapper<Graph>::Edge Edge;
55    //using GraphWrapper<Graph>::EdgeIt;
[393]56    class ClassNodeIt;
57    friend class ClassNodeIt;
58    class OutEdgeIt;
59    friend class OutEdgeIt;
60    class InEdgeIt;
61    friend class InEdgeIt;
[379]62    class ClassNodeIt {
[393]63      friend class BipartiteGraphWrapper<Graph>;
64    protected:
[368]65      Node n;
66    public:
[379]67      ClassNodeIt() { }
68      ClassNodeIt(const Invalid& i) : n(i) { }
69      ClassNodeIt(const BipartiteGraphWrapper<Graph>& _G, bool _class) {
70        _G.s_false_t_true_map->first(n, _class);
[368]71      }
[381]72      //FIXME needed in new concept, important here
73      ClassNodeIt(const Node& _n) : n(_n) { }
[368]74      operator Node() const { return n; }
75    };
[379]76//     class SNodeIt {
77//       Node n;
78//     public:
79//       SNodeIt() { }
80//       SNodeIt(const Invalid& i) : n(i) { }
81//       SNodeIt(const BipartiteGraphWrapper<Graph>& _G) {
82//      _G.s_false_t_true_map->first(n, false);
83//       }
84//       operator Node() const { return n; }
85//     };
86//     class TNodeIt {
87//       Node n;
88//     public:
89//       TNodeIt() { }
90//       TNodeIt(const Invalid& i) : n(i) { }
91//       TNodeIt(const BipartiteGraphWrapper<Graph>& _G) {
92//      _G.s_false_t_true_map->first(n, true);
93//       }
94//       operator Node() const { return n; }
95//     };
[368]96    class OutEdgeIt {
[393]97      friend class BipartiteGraphWrapper<Graph>;
98    protected:
[368]99      typename Graph::OutEdgeIt e;
100    public:
101      OutEdgeIt() { }
102      OutEdgeIt(const Invalid& i) : e(i) { }
103      OutEdgeIt(const BipartiteGraphWrapper<Graph>& _G, const Node& _n) {
104        if (!(*(_G.s_false_t_true_map))[_n])
[379]105          e=typename Graph::OutEdgeIt(*(_G.graph), typename Graph::Node(_n));
[368]106        else
107          e=INVALID;
108      }
109      operator Edge() const { return Edge(typename Graph::Edge(e)); }
110    };
111    class InEdgeIt {
[393]112      friend class BipartiteGraphWrapper<Graph>;
113    protected:
[368]114      typename Graph::InEdgeIt e;
115    public:
116      InEdgeIt() { }
117      InEdgeIt(const Invalid& i) : e(i) { }
118      InEdgeIt(const BipartiteGraphWrapper<Graph>& _G, const Node& _n) {
119        if ((*(_G.s_false_t_true_map))[_n])
[379]120          e=typename Graph::InEdgeIt(*(_G.graph), typename Graph::Node(_n));
[368]121        else
122          e=INVALID;
123      }
124      operator Edge() const { return Edge(typename Graph::Edge(e)); }
125    };
126
127    using GraphWrapper<Graph>::first;
[379]128    ClassNodeIt& first(ClassNodeIt& n, bool _class) const {
[393]129      n=ClassNodeIt(*this, _class) ; return n; }
[379]130//    SNodeIt& first(SNodeIt& n) const { n=SNodeIt(*this); return n; }
131//    TNodeIt& first(TNodeIt& n) const { n=TNodeIt(*this); return n; }
132    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const {
133      i=OutEdgeIt(*this, p); return i;
134    }
135    InEdgeIt& first(InEdgeIt& i, const Node& p) const {
136      i=InEdgeIt(*this, p); return i;
137    }
[368]138
139    using GraphWrapper<Graph>::next;
[379]140    ClassNodeIt& next(ClassNodeIt& n) const {
[393]141      this->s_false_t_true_map->next(n.n); return n;
[368]142    }
[379]143//     SNodeIt& next(SNodeIt& n) const {
144//       this->s_false_t_true_map->next(n); return n;
145//     }
146//     TNodeIt& next(TNodeIt& n) const {
147//       this->s_false_t_true_map->next(n); return n;
148//     }
[389]149    OutEdgeIt& next(OutEdgeIt& i) const { this->graph->next(i.e); return i; }
150    InEdgeIt& next(InEdgeIt& i) const { this->graph->next(i.e); return i; }
[368]151
152    Node tail(const Edge& e) {
153      if (!(*(this->s_false_t_true_map))[this->graph->tail(e)])
154        return Node(this->graph->tail(e));
155      else
156        return Node(this->graph->head(e));     
157    }
158    Node head(const Edge& e) {
159      if (!(*(this->s_false_t_true_map))[this->graph->tail(e)])
160        return Node(this->graph->head(e));
161      else
162        return Node(this->graph->tail(e));     
163    }
164
165    Node aNode(const OutEdgeIt& e) const {
166      return Node(this->graph->aNode(e.e));
167    }
168    Node aNode(const InEdgeIt& e) const {
169      return Node(this->graph->aNode(e.e));
170    }
171    Node bNode(const OutEdgeIt& e) const {
172      return Node(this->graph->bNode(e.e));
173    }
174    Node bNode(const InEdgeIt& e) const {
175      return Node(this->graph->bNode(e.e));
176    }
[379]177
178    bool inSClass(const Node& n) const {
[381]179      return !(*(this->s_false_t_true_map))[n];
[379]180    }
181    bool inTClass(const Node& n) const {
[381]182      return (*(this->s_false_t_true_map))[n];
[379]183    }
[368]184  };
185
[497]186  ///\bug Do not use this while the bipartitemap augmentation
187  /// does not work well.
188  template<typename Graph>
189  class BipartiteGraph : public BipartiteGraphWrapper<Graph> {
190    typedef IterableBoolMap< typename Graph::template NodeMap<int> >
191    SFalseTTrueMap;
192    typedef BipartiteGraphWrapper<Graph> Parent;
193  protected:
194    Graph gr;
195    typename Graph::template NodeMap<int> bipartite_map;
196    SFalseTTrueMap s_false_t_true_map;
197  public:
198    typedef typename Parent::Node Node;
199    typedef typename Parent::Edge Edge;
[499]200    BipartiteGraph() : BipartiteGraphWrapper<Graph>(),
[500]201                       gr(), bipartite_map(gr, -1),
[497]202                       s_false_t_true_map(bipartite_map) {
203      Parent::setGraph(gr);
[499]204      Parent::setSFalseTTrueMap(s_false_t_true_map);
[497]205    }
206
207    /// the \c bool parameter which can be \c S_Class or \c T_Class shows
208    /// the color class where the new node is to be inserted.
[498]209    Node addNode(bool b) {
210      Node n=Parent::graph->addNode();
211      bipartite_map.update();
212      s_false_t_true_map.insert(n, b);
213      return n;
214    }
[497]215
216    /// A new edge is inserted.
217    ///\pre \c tail have to be in \c S_Class and \c head in \c T_Class.
[498]218    Edge addEdge(const Node& tail, const Node& head) {
219      return Parent::graph->addEdge(tail, head);
220    }
[497]221
[498]222    void erase(const Node& n) {
223      s_false_t_true_map.remove(n);
224      Parent::graph->erase(n);
225    }
226    void erase(const Edge& e) {
227      Parent::graph->erase(e);
228    }
[497]229   
230    void clear() {
231      FOR_EACH_LOC(typename Parent::EdgeIt, e, G) erase(e);
232      FOR_EACH_LOC(typename Parent::NodeIt, n, G) erase(n);
233    }
234  };
235
236
[435]237  template<typename Graph>
238  class stGraphWrapper;
239
240//   template<typename Graph>
241//   std::ostream&
242//   operator<<(std::ostream& os, const typename stGraphWrapper<Graph>::Node& i) {
243//     os << "(node: " << typename Graph::Node(i) << " spec: " << i.spec <<")";
244//     return os;
245//   }
246//   template<typename Graph>
247//   std::ostream&
248//   operator<<(std::ostream& os, const typename stGraphWrapper<Graph>::Edge& i) {
249//     os << "(edge: " << typename Graph::Edge(i) << " spec: " << i.spec <<
250//       " node: " << i.n << ")";
251//     return os;
252//   }
[341]253
[379]254  /// experimentral, do not try it.
255  /// It eats a bipartite graph, oriented from S to T.
256  /// Such one can be made e.g. by the above wrapper.
[457]257  ///
258  ///\author Marton Makai
[379]259  template<typename Graph>
260  class stGraphWrapper : public GraphWrapper<Graph> {
261  public:
262    class Node;
[381]263    friend class Node;
[379]264//GN, int
265//0 normalis, 1 s, 2, true, ez az iteralasi sorrend,
266//es a vege a false azaz (invalid, 3)   
267    class NodeIt;
[381]268    friend class NodeIt;
[379]269//GNI, int
270    class Edge;
[381]271    friend class Edge;
[379]272//GE, int, GN
273//0 normalis, 1 s->vmi, 2 vmi->t, ez a sorrend,
274//invalid: (invalid, 3, invalid)
275    class OutEdgeIt;
[381]276    friend class OutEdgeIt;
[379]277//GO, int, GNI
278//normalis pontbol (first, 0, invalid), ..., (invalid, 2, vmi), ... (invalid, 3, invalid)
279//s-bol (invalid, 1, first), ... (invalid, 3, invalid)
280//t-bol (invalid, 3, invalid)
281    class InEdgeIt;
[381]282    friend class InEdgeIt;
[379]283//GI, int, GNI
284//normalis pontbol (first, 0, invalid), ..., (invalid, 1, vmi), ... (invalid, 3, invalid)
285//s-be (invalid, 3, invalid)
286//t-be (invalid, 2, first), ... (invalid, 3, invalid)
287    class EdgeIt;
[381]288    friend class EdgeIt;
[379]289//(first, 0, invalid) ...
290//(invalid, 1, vmi)
291//(invalid, 2, vmi)
292//invalid, 3, invalid)
293    template <typename T> class NodeMap;
[409]294    template <typename T, typename Parent> class EdgeMap;
[341]295
[379]296//    template <typename T> friend class NodeMap;
297//    template <typename T> friend class EdgeMap;
[341]298
[379]299    const Node S_NODE;
300    const Node T_NODE;
[341]301
[379]302    static const bool S_CLASS=false;
303    static const bool T_CLASS=true;
[341]304
[379]305    stGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) ,
306                                    S_NODE(INVALID, 1),
307                                    T_NODE(INVALID, 2) { }
[341]308
[435]309   
310//    std::ostream&
311//    operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Node& i);
312//    friend std::ostream&
313//    operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Node& i);
314//    friend std::ostream&
315//    operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Edge& i);
316
[379]317    class Node : public Graph::Node {
318    protected:
319      friend class GraphWrapper<Graph>;
320      friend class stGraphWrapper<Graph>;
[389]321      template <typename T> friend class NodeMap;
[380]322      friend class Edge;
323      friend class OutEdgeIt;
324      friend class InEdgeIt;
325      friend class EdgeIt;
[379]326      int spec;
327    public:
328      Node() { }
329      Node(const typename Graph::Node& _n, int _spec=0) :
330        Graph::Node(_n), spec(_spec) { }
331      Node(const Invalid& i) : Graph::Node(i), spec(3) { }
332      friend bool operator==(const Node& u, const Node& v) {
333        return (u.spec==v.spec &&
334                static_cast<typename Graph::Node>(u)==
335                static_cast<typename Graph::Node>(v));
336      }
337      friend bool operator!=(const Node& u, const Node& v) {
338        return (v.spec!=u.spec ||
339                static_cast<typename Graph::Node>(u)!=
340                static_cast<typename Graph::Node>(v));
[409]341      }
[435]342//      template<typename G>
343//      friend std::ostream&
344//      operator<<(std::ostream& os, const typename stGraphWrapper<G>::Node& i);
345      friend std::ostream& operator<< (std::ostream& os, const Node& i);
[379]346      int getSpec() const { return spec; }
347    };
[409]348
[379]349    class NodeIt {
350      friend class GraphWrapper<Graph>;
351      friend class stGraphWrapper<Graph>;
352      typename Graph::NodeIt n;
353      int spec;
354     public:
355      NodeIt() { }
356      NodeIt(const typename Graph::NodeIt& _n, int _spec) :
357        n(_n), spec(_spec) { }
358      NodeIt(const Invalid& i) : n(i), spec(3) { }
[381]359      NodeIt(const stGraphWrapper<Graph>& _G) : n(*(_G.graph)), spec(0) {
[409]360        if (!_G.graph->valid(n)) spec=1;
[379]361      }
362      operator Node() const { return Node(n, spec); }
363    };
[409]364
[379]365    class Edge : public Graph::Edge {
366      friend class GraphWrapper<Graph>;
367      friend class stGraphWrapper<Graph>;
[409]368      template <typename T, typename Parent> friend class EdgeMap;
[379]369      int spec;
370      typename Graph::Node n;
371    public:
372      Edge() { }
373      Edge(const typename Graph::Edge& _e, int _spec,
374           const typename Graph::Node& _n) :
375        Graph::Edge(_e), spec(_spec), n(_n) {
376      }
377      Edge(const Invalid& i) : Graph::Edge(i), spec(3), n(i) { }
378      friend bool operator==(const Edge& u, const Edge& v) {
379        return (u.spec==v.spec &&
380                static_cast<typename Graph::Edge>(u)==
381                static_cast<typename Graph::Edge>(v) &&
382                u.n==v.n);
383      }
384      friend bool operator!=(const Edge& u, const Edge& v) {
385        return (v.spec!=u.spec ||
386                static_cast<typename Graph::Edge>(u)!=
387                static_cast<typename Graph::Edge>(v) ||
388                u.n!=v.n);
389      }
[435]390//      template<typename G>
391//      friend std::ostream&
392//      operator<<(std::ostream& os, const typename stGraphWrapper<G>::Edge& i);
393      friend std::ostream& operator<< (std::ostream& os, const Edge& i);
[379]394      int getSpec() const { return spec; }
395    };
[409]396
[379]397    class OutEdgeIt {
398      friend class GraphWrapper<Graph>;
399      friend class stGraphWrapper<Graph>;
400      typename Graph::OutEdgeIt e;
401      int spec;
402      typename Graph::ClassNodeIt n;
403    public:
404      OutEdgeIt() { }
405      OutEdgeIt(const typename Graph::OutEdgeIt& _e, int _spec,
406                const typename Graph::ClassNodeIt& _n) :
407        e(_e), spec(_spec), n(_n) {
408      }
409      OutEdgeIt(const Invalid& i) : e(i), spec(3), n(i) { }
[381]410      OutEdgeIt(const stGraphWrapper<Graph>& _G, const Node& _n) {
[379]411        switch (_n.spec) {
412          case 0 :
[381]413            if (_G.graph->inSClass(_n)) { //S, van normalis kiel
[379]414              e=typename Graph::OutEdgeIt(*(_G.graph),
415                                          typename Graph::Node(_n));
416              spec=0;
417              n=INVALID;
418              if (!_G.graph->valid(e)) spec=3;
419            } else { //T, specko kiel van
420              e=INVALID;
421              spec=2;
422              n=_n;
423            }
424            break;
425          case 1:
426            e=INVALID;
427            spec=1;
428            _G.graph->first(n, S_CLASS); //s->vmi;
429            if (!_G.graph->valid(n)) spec=3; //Ha S ures
430            break;
431          case 2:
432            e=INVALID;
433            spec=3;
434            n=INVALID;
435            break;
436        }
437      }
438      operator Edge() const { return Edge(e, spec, n); }
439    };
[409]440
[379]441    class InEdgeIt {
442      friend class GraphWrapper<Graph>;
443      friend class stGraphWrapper<Graph>;
444      typename Graph::InEdgeIt e;
445      int spec;
446      typename Graph::ClassNodeIt n;
447    public:
448      InEdgeIt() { }
449      InEdgeIt(const typename Graph::InEdgeIt& _e, int _spec,
450               const typename Graph::ClassNodeIt& _n) :
451        e(_e), spec(_spec), n(_n) {
452      }
453      InEdgeIt(const Invalid& i) : e(i), spec(3), n(i) { }
[381]454      InEdgeIt(const stGraphWrapper<Graph>& _G, const Node& _n) {
[379]455        switch (_n.spec) {
456          case 0 :
[381]457            if (_G.graph->inTClass(_n)) { //T, van normalis beel
[379]458              e=typename Graph::InEdgeIt(*(_G.graph),
459                                         typename Graph::Node(_n));
460              spec=0;
461              n=INVALID;
462              if (!_G.graph->valid(e)) spec=3;
463            } else { //S, specko beel van
464              e=INVALID;
465              spec=1;
466              n=_n;
467            }
468            break;
469          case 1:
470            e=INVALID;
471            spec=3;
472            n=INVALID;
[409]473            break;
[379]474          case 2:
475            e=INVALID;
[409]476            spec=2;
[379]477            _G.graph->first(n, T_CLASS); //vmi->t;
478            if (!_G.graph->valid(n)) spec=3; //Ha T ures
479            break;
480        }
481      }
482      operator Edge() const { return Edge(e, spec, n); }
483    };
[409]484
[379]485    class EdgeIt {
486      friend class GraphWrapper<Graph>;
487      friend class stGraphWrapper<Graph>;
488      typename Graph::EdgeIt e;
489      int spec;
490      typename Graph::ClassNodeIt n;
491    public:
492      EdgeIt() { }
493      EdgeIt(const typename Graph::EdgeIt& _e, int _spec,
494             const typename Graph::ClassNodeIt& _n) :
495        e(_e), spec(_spec), n(_n) { }
496      EdgeIt(const Invalid& i) : e(i), spec(3), n(i) { }
[381]497      EdgeIt(const stGraphWrapper<Graph>& _G) :
[379]498        e(*(_G.graph)), spec(0), n(INVALID) {
499        if (!_G.graph->valid(e)) {
500          spec=1;
501          _G.graph->first(n, S_CLASS);
502          if (!_G.graph->valid(n)) { //Ha S ures
503            spec=2;
504            _G.graph->first(n, T_CLASS);
505            if (!_G.graph->valid(n)) { //Ha T ures
506              spec=3;
507            }
508          }
509        }
510      }
511      operator Edge() const { return Edge(e, spec, n); }
512    };
[341]513   
[379]514    NodeIt& first(NodeIt& i) const {
515      i=NodeIt(*this); return i;
516    }
517    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const {
518      i=OutEdgeIt(*this, p); return i;
519    }
520    InEdgeIt& first(InEdgeIt& i, const Node& p) const {
521      i=InEdgeIt(*this, p); return i;
522    }
523    EdgeIt& first(EdgeIt& i) const {
524      i=EdgeIt(*this); return i;
525    }
[341]526
[379]527    NodeIt& next(NodeIt& i) const {
528      switch (i.spec) {
529        case 0:
[389]530          this->graph->next(i.n);
531          if (!this->graph->valid(i.n)) {
[379]532            i.spec=1;
533          }
534          break;
535        case 1:
536          i.spec=2;
537          break;
538        case 2:
539          i.spec=3;
540          break;
541      }
542      return i;
543    }
544    OutEdgeIt& next(OutEdgeIt& i) const {
[393]545      typename Graph::Node v;
[379]546      switch (i.spec) {
547        case 0: //normal edge
[409]548          v=this->graph->aNode(i.e);
[389]549          this->graph->next(i.e);
550          if (!this->graph->valid(i.e)) { //Az igazi elek vegere ertunk
551            if (this->graph->inSClass(v)) { //S, nincs kiel
[379]552              i.spec=3;
553              i.n=INVALID;
554            } else { //T, van kiel
555              i.spec=2;
556              i.n=v;
557            }
558          }
559          break;
560        case 1: //s->vmi
[389]561          this->graph->next(i.n);
562          if (!this->graph->valid(i.n)) i.spec=3;
[379]563          break;
564        case 2: //vmi->t
565          i.spec=3;
566          i.n=INVALID;
567          break;
568      }
569      return i;
570    }
571    InEdgeIt& next(InEdgeIt& i) const {
[393]572      typename Graph::Node v;
[379]573      switch (i.spec) {
574        case 0: //normal edge
[393]575          v=this->graph->aNode(i.e);
[389]576          this->graph->next(i.e);
577          if (!this->graph->valid(i.e)) { //Az igazi elek vegere ertunk
578            if (this->graph->inTClass(v)) { //S, nincs beel
[379]579              i.spec=3;
580              i.n=INVALID;
581            } else { //S, van beel
582              i.spec=1;
583              i.n=v;
584            }
585          }
586          break;
587        case 1: //s->vmi
588          i.spec=3;
589          i.n=INVALID;
590          break;
591        case 2: //vmi->t
[389]592          this->graph->next(i.n);
593          if (!this->graph->valid(i.n)) i.spec=3;
[379]594          break;
595      }
596      return i;
597    }
[341]598
[379]599    EdgeIt& next(EdgeIt& i) const {
600      switch (i.spec) {
601        case 0:
[389]602          this->graph->next(i.e);
603          if (!this->graph->valid(i.e)) {
[379]604            i.spec=1;
[389]605            this->graph->first(i.n, S_CLASS);
606            if (!this->graph->valid(i.n)) {
[379]607              i.spec=2;
[389]608              this->graph->first(i.n, T_CLASS);
609              if (!this->graph->valid(i.n)) i.spec=3;
[379]610            }
611          }
612          break;
613        case 1:
[389]614          this->graph->next(i.n);
615          if (!this->graph->valid(i.n)) {
[379]616            i.spec=2;
[389]617            this->graph->first(i.n, T_CLASS);
618            if (!this->graph->valid(i.n)) i.spec=3;
[379]619          }
620          break;
621        case 2:
[389]622          this->graph->next(i.n);
623          if (!this->graph->valid(i.n)) i.spec=3;
[379]624          break;
625      }
626      return i;
627    }   
[341]628
[379]629    Node tail(const Edge& e) const {
630      switch (e.spec) {
[393]631      case 0:
632        return Node(this->graph->tail(e));
633        break;
634      case 1:
635        return S_NODE;
636        break;
637      case 2:
638      default:
639        return Node(e.n);
640        break;
[379]641      }
642    }
643    Node head(const Edge& e) const {
644      switch (e.spec) {
[393]645      case 0:
646        return Node(this->graph->head(e));
647        break;
648      case 1:
649        return Node(e.n);
650        break;
651      case 2:
652      default:
653        return T_NODE;
654        break;
[379]655      }
656    }
[341]657
[379]658    bool valid(const Node& n) const { return (n.spec<3); }
659    bool valid(const Edge& e) const { return (e.spec<3); }
660
[409]661    int nodeNum() const { return this->graph->nodeNum()+2; }
662    int edgeNum() const {
663      return this->graph->edgeNum()+this->graph->nodeNum();
664    }
[341]665 
[379]666    Node aNode(const OutEdgeIt& e) const { return tail(e); }
667    Node aNode(const InEdgeIt& e) const { return head(e); }
668    Node bNode(const OutEdgeIt& e) const { return head(e); }
669    Node bNode(const InEdgeIt& e) const { return tail(e); }
[409]670
671    void addNode() const { }
672    void addEdge() const { }
673   
[389]674//    Node addNode() const { return Node(this->graph->addNode()); }
[379]675//    Edge addEdge(const Node& tail, const Node& head) const {
[389]676//      return Edge(this->graph->addEdge(tail, head)); }
[341]677
[389]678//    void erase(const Node& i) const { this->graph->erase(i); }
679//    void erase(const Edge& i) const { this->graph->erase(i); }
[341]680 
[389]681//    void clear() const { this->graph->clear(); }
[341]682   
[389]683    template<typename T> class NodeMap : public GraphWrapper<Graph>::template NodeMap<T> {
684      typedef typename GraphWrapper<Graph>::template NodeMap<T> Parent;
[379]685      T s_value, t_value;
686    public:
[409]687      NodeMap(const stGraphWrapper<Graph>& _G) :  Parent(_G),
688                                                  s_value(),
689                                                  t_value() { }
[389]690      NodeMap(const stGraphWrapper<Graph>& _G, T a) : Parent(_G, a),
691                                                      s_value(a),
692                                                      t_value(a) { }
[379]693      T operator[](const Node& n) const {
694        switch (n.spec) {
[393]695        case 0:
696          return Parent::operator[](n);
697          break;
698        case 1:
699          return s_value;
700          break;
701        case 2:
702        default:
703          return t_value;
704          break;
[379]705        }
706      }
707      void set(const Node& n, T t) {
708        switch (n.spec) {
[393]709        case 0:
710          GraphWrapper<Graph>::template NodeMap<T>::set(n, t);
711          break;
712        case 1:
713          s_value=t;
714          break;
715        case 2:
716        default:
717          t_value=t;
718          break;
[379]719        }
720      }
721    };
[341]722
[409]723    template<typename T,
724             typename Parent=
725             typename GraphWrapper<Graph>::template EdgeMap<T> >
726    class EdgeMap : public Parent {
727      //typedef typename GraphWrapper<Graph>::template EdgeMap<T> Parent;
[389]728      typename GraphWrapper<Graph>::template NodeMap<T> node_value;
[379]729    public:
[393]730      EdgeMap(const stGraphWrapper<Graph>& _G) : Parent(_G),
731                                                 node_value(_G) { }
[389]732      EdgeMap(const stGraphWrapper<Graph>& _G, T a) : Parent(_G, a),
733                                                      node_value(_G, a) { }
[379]734      T operator[](const Edge& e) const {
735        switch (e.spec) {
[393]736        case 0:
737          return Parent::operator[](e);
738          break;
739        case 1:
740          return node_value[e.n];
741          break;
742        case 2:
743        default:
744          return node_value[e.n];
745          break;
[379]746        }
747      }
748      void set(const Edge& e, T t) {
749        switch (e.spec) {
[393]750        case 0:
[409]751          Parent::set(e, t);
[393]752          break;
753        case 1:
754          node_value.set(e.n, t);
755          break;
756        case 2:
757        default:
758          node_value.set(e.n, t);
759          break;
[379]760        }
761      }
762    };
[409]763
764//     template<typename T> class EdgeMap : public GraphWrapper<Graph>::template EdgeMap<T> {
765//       typedef typename GraphWrapper<Graph>::template EdgeMap<T> Parent;
766//       typename GraphWrapper<Graph>::template NodeMap<T> node_value;
767//     public:
768//       EdgeMap(const stGraphWrapper<Graph>& _G) : Parent(_G),
769//                                               node_value(_G) { }
770//       EdgeMap(const stGraphWrapper<Graph>& _G, T a) : Parent(_G, a),
771//                                                    node_value(_G, a) { }
772//       T operator[](const Edge& e) const {
773//      switch (e.spec) {
774//      case 0:
775//        return Parent::operator[](e);
776//        break;
777//      case 1:
778//        return node_value[e.n];
779//        break;
780//      case 2:
781//      default:
782//        return node_value[e.n];
783//        break;
784//      }
785//       }
786//       void set(const Edge& e, T t) {
787//      switch (e.spec) {
788//      case 0:
789//        GraphWrapper<Graph>::template EdgeMap<T>::set(e, t);
790//        break;
791//      case 1:
792//        node_value.set(e.n, t);
793//        break;
794//      case 2:
795//      default:
796//        node_value.set(e.n, t);
797//        break;
798//      }
799//       }
800//     };
801
[435]802//  template<typename G>
803    friend std::ostream&
804    operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Node& i) {
[409]805      os << "(node: " << typename Graph::Node(i) << " spec: " << i.spec <<")";
806      return os;
807    }
[435]808//  template<typename G>
809    friend std::ostream&
810    operator<<(std::ostream& os, const /*typename stGraphWrapper<Graph>::*/Edge& i) {
[409]811      os << "(edge: " << typename Graph::Edge(i) << " spec: " << i.spec <<
812        " node: " << i.n << ")";
813      return os;
814    }
815
[379]816  };
817
[406]818  ///@}
[341]819
[105]820} //namespace hugo
[76]821
[406]822
[259]823#endif //HUGO_GRAPH_WRAPPER_H
[76]824
Note: See TracBrowser for help on using the repository browser.