COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/work/alpar/smart_graph.h @ 177:924f9555711d

Last change on this file since 177:924f9555711d was 177:924f9555711d, checked in by Alpar Juttner, 16 years ago

Marci's changes accepted.

File size: 10.8 KB
Line 
1// -*- mode:C++ -*-
2
3#ifndef SMART_GRAPH_H
4#define SMART_GRAPH_H
5
6#include <vector>
7#include <limits.h>
8
9#include <invalid.h>
10
11namespace hugo {
12
13  class SmartGraph {
14
15    struct NodeT
16    {
17      int first_in,first_out;     
18      NodeT() : first_in(-1), first_out(-1) {}
19    };
20    struct EdgeT
21    {
22      int head, tail, next_in, next_out;     
23      //FIXME: is this necessary?
24      EdgeT() : next_in(-1), next_out(-1) {} 
25    };
26
27    std::vector<NodeT> nodes;
28
29    std::vector<EdgeT> edges;
30   
31    template <typename Key> class DynMapBase
32    {
33    protected:
34      SmartGraph* G;
35    public:
36      virtual void add(const Key k) = NULL;
37      virtual void erase(const Key k) = NULL;
38      DynMapBase(const SmartGraph &_G) : G(&_G) {}
39      virtual ~DynMapBase() {}
40      friend class SmartGraph;
41    };
42  public:
43    template <typename T> class DynEdgeMap;
44    template <typename T> class DynEdgeMap;
45
46    class Node;
47    class Edge;
48
49  protected:
50    mutable std::vector<DynMapBase<Node> * > dyn_node_maps;
51    mutable std::vector<DynMapBase<Edge> * > dyn_edge_maps;
52   
53  public:
54
55    class NodeIt;
56    class EdgeIt;
57    class OutEdgeIt;
58    class InEdgeIt;
59   
60    //     class Node { int n; };
61    //     class NodeIt : public Node { };
62    //     class Edge { int n; };
63    //     class EdgeIt : public Edge {};
64    //     class OutEdgeIt : public Edge {};
65    //     class InEdgeIt : public Edge {};
66    //     class SymEdge;
67   
68    template <typename T> class NodeMap;
69    template <typename T> class EdgeMap;
70   
71  public:
72
73    /* default constructor */
74
75    SmartGraph() : nodes(), edges() { }
76    SmartGraph(const SmartGraph &_g) : nodes(_g.nodes), edges(_g.edges) { }
77   
78    ~SmartGraph()
79    {
80      for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
81          i!=dyn_node_maps.end(); ++i) (**i).G=NULL;
82      for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
83          i!=dyn_edge_maps.end(); ++i) (**i).G=NULL;
84    }
85
86    int nodeNum() const { return nodes.size(); }  //FIXME: What is this?
87    int edgeNum() const { return edges.size(); }  //FIXME: What is this?
88
89    int maxNodeId() const { return nodes.size(); }  //FIXME: What is this?
90    int maxEdgeId() const { return edges.size(); }  //FIXME: What is this?
91
92   
93    Node tail(Edge e) const { return edges[e.n].tail; }
94    Node head(Edge e) const { return edges[e.n].head; }
95
96    // Marci
97    Node aNode(OutEdgeIt e) const { return edges[e.n].tail; }
98    Node aNode(InEdgeIt e) const { return edges[e.n].head; }
99//     //Node aNode(const SymEdge& e) const { return e.aNode(); }
100
101    // Marci
102    Node bNode(OutEdgeIt e) const { return edges[e.n].head; }
103    Node bNode(InEdgeIt e) const { return edges[e.n].tail; }
104//     //Node bNode(const SymEdge& e) const { return e.bNode(); }
105
106    NodeIt& first(NodeIt& v) const {
107      v=NodeIt(*this); return v; }
108    EdgeIt& first(EdgeIt& e) const {
109      e=EdgeIt(*this); return e; }
110    OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
111      e=OutEdgeIt(*this,v); return e; }
112    InEdgeIt& first(InEdgeIt& e, const Node v) const {
113      e=InEdgeIt(*this,v); return e; }
114
115    template< typename It >
116    It first() const { It e; first(e); return e; }
117
118    template< typename It >
119    It first(Node v) const { It e; first(e,v); return e; }
120
121    bool valid(Edge e) const { return e.n!=-1; }
122    bool valid(Node n) const { return n.n!=-1; }
123   
124    void setInvalid(Edge &e) { e.n=-1; }
125    void setInvalid(Node &n) { n.n=-1; }
126   
127    template <typename It> It getNext(It it) const
128    { It tmp(it); return next(tmp); }
129
130    NodeIt& next(NodeIt& it) const {
131      it.n=(it.n+2)%(nodes.size()+1)-1;
132      return it;
133    }
134    OutEdgeIt& next(OutEdgeIt& it) const
135    { it.n=edges[it.n].next_out; return it; }
136    InEdgeIt& next(InEdgeIt& it) const
137    { it.n=edges[it.n].next_in; return it; }
138    EdgeIt& next(EdgeIt& it) const { --it.n; return it; }
139
140    int id(Node v) const { return v.n; }
141    int id(Edge e) const { return e.n; }
142
143    Node addNode() {
144      Node n; n.n=nodes.size();
145      nodes.push_back(NodeT()); //FIXME: Hmmm...
146
147      for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
148          i!=dyn_node_maps.end(); ++i) (**i).add(n.n);
149
150      return n;
151    }
152   
153    Edge addEdge(Node u, Node v) {
154      Edge e; e.n=edges.size(); edges.push_back(EdgeT()); //FIXME: Hmmm...
155      edges[e.n].tail=u.n; edges[e.n].head=v.n;
156      edges[e.n].next_out=nodes[u.n].first_out;
157      edges[e.n].next_in=nodes[v.n].first_in;
158      nodes[u.n].first_out=nodes[v.n].first_in=e.n;
159
160      for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
161          i!=dyn_edge_maps.end(); ++i) (**i).add(e);
162
163      return e;
164    }
165
166    void clear() {nodes.clear();edges.clear();}
167
168    class Node {
169      friend class SmartGraph;
170      template <typename T> friend class NodeMap;
171      template <typename T> friend class DynNodeMap;
172     
173      friend class Edge;
174      friend class OutEdgeIt;
175      friend class InEdgeIt;
176      friend class SymEdge;
177
178    protected:
179      int n;
180      friend int SmartGraph::id(Node v) const;
181      Node(int nn) {n=nn;}
182    public:
183      Node() {}
184      Node (Invalid i) { n=-1; }
185      bool operator==(const Node i) const {return n==i.n;}
186      bool operator!=(const Node i) const {return n!=i.n;}
187      bool operator<(const Node i) const {return n<i.n;}
188    };
189   
190    class NodeIt : public Node {
191      friend class SmartGraph;
192    public:
193      NodeIt(const SmartGraph& G) : Node(G.nodes.size()?0:-1) { }
194      NodeIt() : Node() { }
195    };
196
197    class Edge {
198      friend class SmartGraph;
199      template <typename T> friend class EdgeMap;
200      template <typename T> friend class DynEdgeMap;
201     
202      friend class Node;
203      friend class NodeIt;
204    protected:
205      int n;
206      friend int SmartGraph::id(Edge e) const;
207
208      Edge(int nn) {n=nn;}
209    public:
210      Edge() { }
211      Edge (Invalid) { n=-1; }
212      bool operator==(const Edge i) const {return n==i.n;}
213      bool operator!=(const Edge i) const {return n!=i.n;}
214      bool operator<(const Edge i) const {return n<i.n;}
215    };
216   
217    class EdgeIt : public Edge {
218      friend class SmartGraph;
219    public:
220      EdgeIt(const SmartGraph& G) : Edge(G.edges.size()-1) { }
221      EdgeIt (Invalid i) : Edge(i) { }
222      EdgeIt() : Edge() { }
223    };
224   
225    class OutEdgeIt : public Edge {
226      friend class SmartGraph;
227    public:
228      OutEdgeIt() : Edge() { }
229      OutEdgeIt (Invalid i) : Edge(i) { }
230
231      OutEdgeIt(const SmartGraph& G,const Node v)
232        : Edge(G.nodes[v.n].first_out) {}
233    };
234   
235    class InEdgeIt : public Edge {
236      friend class SmartGraph;
237    public:
238      InEdgeIt() : Edge() { }
239      InEdgeIt (Invalid i) : Edge(i) { }
240      InEdgeIt(const SmartGraph& G,Node v) :Edge(G.nodes[v.n].first_in){}
241    };
242
243    // Map types
244
245    template <typename T>
246    class NodeMap {
247      const SmartGraph& G;
248      std::vector<T> container;
249    public:
250      typedef T ValueType;
251      typedef Node KeyType;
252      NodeMap(const SmartGraph& _G) : G(_G), container(G.maxNodeId()) { }
253      NodeMap(const SmartGraph& _G, T a) :
254        G(_G), container(G.maxNodeId(), a) { }
255      void set(Node n, T a) { container[n.n]=a; }
256      T get(Node n) const { return container[n.n]; }
257      T& operator[](Node n) { return container[n.n]; }
258      const T& operator[](Node n) const { return container[n.n]; }
259      void update() { container.resize(G.maxNodeId()); }
260      void update(T a) { container.resize(G.maxNodeId(), a); }
261    };
262
263    template <typename T>
264    class EdgeMap {
265      const SmartGraph& G;
266      std::vector<T> container;
267    public:
268      typedef T ValueType;
269      typedef Edge KeyType;
270      EdgeMap(const SmartGraph& _G) : G(_G), container(G.maxEdgeId()) { }
271      EdgeMap(const SmartGraph& _G, T a) :
272        G(_G), container(G.maxEdgeId(), a) { }
273      void set(Edge e, T a) { container[e.n]=a; }
274      T get(Edge e) const { return container[e.n]; }
275      T& operator[](Edge e) { return container[e.n]; }
276      const T& operator[](Edge e) const { return container[e.n]; }
277      void update() { container.resize(G.maxEdgeId()); }
278      void update(T a) { container.resize(G.maxEdgeId(), a); }
279    };
280
281    template <typename T> class DynNodeMap : public DynMapBase<Node>
282    {
283      std::vector<T> container;
284
285    public:
286      typedef T ValueType;
287      typedef Node KeyType;
288
289      DynNodeMap(const SmartGraph &_G) :
290        DynMapBase<Node>(_G), container(_G.maxNodeId())
291      {
292        //FIXME: What if there are empty Id's?
293        //FIXME: Can I use 'this' in a constructor?
294        G->dyn_node_maps.push_back(this);
295      }
296      ~DynNodeMap()
297      {
298        if(G) {
299          std::vector<DynMapBase<Node>* >::iterator i;
300          for(i=G->dyn_node_maps.begin();
301              i!=G->dyn_node_maps.end() && *i!=this; ++i) ;
302          //if(*i==this) G->dyn_node_maps.erase(i); //FIXME: Way too slow...
303          //A better way to do that: (Is this really important?)
304          if(*i==this) {
305            *i=G->dyn_node_maps.back();
306            G->dyn_node_maps.pop_back();
307          }
308        }
309      }
310
311      void add(const Node k)
312      {
313        if(k.n>=container.size()) container.resize(k.n+1);
314      }
315
316//       void erase(const Node k)
317//       {
318//      //FIXME: Please implement me.
319//       }
320//       void erase(const Edge k)
321//       {
322//      //FIXME: Please implement me.
323//       }
324     
325      void set(Node n, T a) { container[n.n]=a; }
326      T get(Node n) const { return container[n.n]; }
327      T& operator[](Node n) { return container[n.n]; }
328      const T& operator[](Node n) const { return container[n.n]; }
329
330      void update() {}    //Useless for DynMaps
331      void update(T a) {}  //Useless for DynMaps
332    };
333   
334    template <typename T> class DynEdgeMap : public DynMapBase<Edge>
335    {
336      std::vector<T> container;
337
338    public:
339      typedef T ValueType;
340      typedef Edge KeyType;
341
342      DynEdgeMap(const SmartGraph &_G) :
343        DynMapBase<Edge>(_G), container(_G.maxEdgeId())
344      {
345        //FIXME: What if there are empty Id's?
346        //FIXME: Can I use 'this' in a constructor?
347        G->dyn_edge_maps.push_back(this);
348      }
349      ~DynEdgeMap()
350      {
351        if(G) {
352          std::vector<DynMapBase<Edge>* >::iterator i;
353          for(i=G->dyn_edge_maps.begin();
354              i!=G->dyn_edge_maps.end() && *i!=this; ++i) ;
355          //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow...
356          //A better way to do that: (Is this really important?)
357          if(*i==this) {
358            *i=G->dyn_edge_maps.back();
359            G->dyn_edge_maps.pop_back();
360          }
361        }
362      }
363     
364      void add(const Edge k)
365      {
366        if(k.n>=int(container.size())) container.resize(k.n+1);
367      }
368      void erase(const Edge k)
369      {
370        //FIXME: Please implement me.
371      }
372     
373      void set(Edge n, T a) { container[n.n]=a; }
374      T get(Edge n) const { return container[n.n]; }
375      T& operator[](Edge n) { return container[n.n]; }
376      const T& operator[](Edge n) const { return container[n.n]; }
377
378      void update() {}    //Useless for DynMaps
379      void update(T a) {}  //Useless for DynMaps
380    };
381       
382  };
383} //namespace hugo
384
385
386
387
388#endif //SMART_GRAPH_H
Note: See TracBrowser for help on using the repository browser.