COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/undir_graph_extender.h @ 986:e997802b855c

Last change on this file since 986:e997802b855c was 986:e997802b855c, checked in by Alpar Juttner, 19 years ago

Naming changes:

  • head -> target
  • tail -> source
File size: 4.7 KB
RevLine 
[962]1/* -*- C++ -*-
2 *
3 * src/lemon/undir_graph_extender.h - Part of LEMON, a generic C++
4 * optimization library
5 *
6 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi
7 * Kutatocsoport (Egervary Combinatorial Optimization Research Group,
8 * EGRES).
9 *
10 * Permission to use, modify and distribute this software is granted
11 * provided that this copyright notice appears in all copies. For
12 * precise terms see the accompanying LICENSE file.
13 *
14 * This software is provided "AS IS" with no warranty of any kind,
15 * express or implied, and with no claim as to its suitability for any
16 * purpose.
17 *
18 */
19
20#ifndef LEMON_UNDIR_GRAPH_EXTENDER_H
21#define LEMON_UNDIR_GRAPH_EXTENDER_H
22
23#include <lemon/invalid.h>
24
25namespace lemon {
26
27  template <typename _Base>
28  class UndirGraphExtender : public _Base {
29    typedef _Base Parent;
30    typedef UndirGraphExtender Graph;
31
32  public:
33
34    typedef typename Parent::Edge UndirEdge;
35    typedef typename Parent::Node Node;
36
37    class Edge : public UndirEdge {
[978]38      friend class UndirGraphExtender;
[962]39
40    protected:
41      // FIXME: Marci use opposite logic in his graph wrappers. It would
42      // be reasonable to syncronize...
43      bool forward;
44
45    public:
46      Edge() {}
47      /// Construct a direct edge from undirect edge and a direction.
48      Edge(const UndirEdge &ue, bool _forward) :
49        UndirEdge(ue), forward(_forward) {}
50      /// Invalid edge constructor
51      Edge(Invalid i) : UndirEdge(i), forward(false) {}
52
53      bool operator==(const Edge &that) const {
54        return forward==that.forward && UndirEdge(*this)==UndirEdge(that);
55      }
56      bool operator!=(const Edge &that) const {
57        return forward!=that.forward || UndirEdge(*this)!=UndirEdge(that);
58      }
59      bool operator<(const Edge &that) const {
60        return forward<that.forward ||
61          (!(that.forward<forward) && UndirEdge(*this)<UndirEdge(that));
62      }
63    };
64
65
66    /// \brief Returns the Edge of opposite direction.
67    ///
68    /// \bug Is this a good name for this? Or "reverse" is better?
69    Edge opposite(const Edge &e) const {
70      return Edge(e,!e.forward);
71    }
72
[986]73    /// Source of the given Edge.
74    Node source(const Edge &e) const {
75      return e.forward ? Parent::source(e) : Parent::target(e);
[962]76    }
77
[986]78    /// \todo Shouldn't the "source" of an undirected edge be called "aNode"
[962]79    /// or something???
[986]80    using Parent::source;
[962]81
[986]82    /// Target of the given Edge.
83    Node target(const Edge &e) const {
84      return e.forward ? Parent::target(e) : Parent::source(e);
[962]85    }
86
[986]87    /// \todo Shouldn't the "target" of an undirected edge be called "bNode"
[962]88    /// or something???
[986]89    using Parent::target;
[962]90
91    /// Returns whether the given directed edge is same orientation as the
92    /// corresponding undirected edge.
93    ///
94    /// \todo reference to the corresponding point of the undirected graph
95    /// concept. "What does the direction of an undirected edge mean?"
96    bool forward(const Edge &e) const { return e.forward; }
97
98    Node oppsiteNode(const Node &n, const Edge &e) const {
[986]99      if( n == Parent::source(e))
100        return Parent::target(e);
101      else if( n == Parent::target(e))
102        return Parent::source(e);
[962]103      else
104        return INVALID;
105    }
106
107
108    using Parent::first;
109    void first(Edge &e) const {
110      Parent::first(e);
111      e.forward=true;
112    }
113
114    using Parent::next;
115    void next(Edge &e) const {
116      if( e.forward ) {
117        e.forward = false;
118      }
119      else {
120        Parent::next(e);
121        e.forward = true;
122      }
123    }
124
125    void firstOut(Edge &e, const Node &n) const {
126      Parent::firstOut(e,n);
127      if( UndirEdge(e) != INVALID ) {
128        e.forward = true;
129      }
130      else {
131        Parent::firstIn(e,n);
132        e.forward = false;
133      }
134    }
135    void firstIn(Edge &e, const Node &n) const {
136      Parent::firstIn(e,n);
137      if( UndirEdge(e) != INVALID ) {
138        e.forward = true;
139      }
140      else {
141        Parent::firstOut(e,n);
142        e.forward = false;
143      }
144    }
145
146    void nextOut(Edge &e) const {
147      if( e.forward ) {
148        Parent::nextOut(e);
149        if( UndirEdge(e) == INVALID ) {
[986]150          Parent::firstIn(e, Parent::source(e));
[962]151          e.forward = false;
152        }
153      }
154      else {
155        Parent::nextIn(e);
156      }
157    }
158    void nextIn(Edge &e) const {
159      if( e.forward ) {
160        Parent::nextIn(e);
161        if( UndirEdge(e) == INVALID ) {
[986]162          Parent::firstOut(e, Parent::target(e));
[962]163          e.forward = false;
164        }
165      }
166      else {
167        Parent::nextOut(e);
168      }
169    }
170
171    // Miscellaneous stuff:
172
173    /// \todo these methods (id, maxEdgeId) should be moved into separate
174    /// Extender
175
176    using Parent::id;
177
178    int id(const Edge &e) const {
[981]179      return 2 * Parent::id(e) + int(e.forward);
[962]180    }
181
[981]182    int maxId(Edge = INVALID) const {
183      return 2 * Parent::maxId(typename Parent::Edge()) + 1;
[962]184    }
[981]185    int maxId(UndirEdge = INVALID) const {
186      return Parent::maxId(typename Parent::Edge());
[962]187    }
188
189  };
190
191}
192
193#endif // LEMON_UNDIR_GRAPH_EXTENDER_H
Note: See TracBrowser for help on using the repository browser.