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