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