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