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