src/hugo/list_graph.h
author alpar
Fri, 23 Jul 2004 16:58:02 +0000
changeset 736 ba76a7f56b23
parent 713 57c0b110b31e
child 774 4297098d9677
permissions -rw-r--r--
Marci (and the other developpers),
please write exhaustive test code to avoid this kind of bugs...
alpar@395
     1
// -*- mode:C++ -*-
alpar@395
     2
alpar@405
     3
#ifndef HUGO_LIST_GRAPH_H
alpar@405
     4
#define HUGO_LIST_GRAPH_H
alpar@395
     5
klao@491
     6
///\ingroup graphs
alpar@395
     7
///\file
alpar@405
     8
///\brief ListGraph, SymListGraph, NodeSet and EdgeSet classes.
alpar@395
     9
alpar@395
    10
#include <vector>
alpar@395
    11
#include <limits.h>
alpar@395
    12
ladanyi@542
    13
#include <hugo/invalid.h>
alpar@395
    14
alpar@395
    15
namespace hugo {
alpar@395
    16
alpar@406
    17
/// \addtogroup graphs
alpar@406
    18
/// @{
alpar@406
    19
alpar@397
    20
  class SymListGraph;
alpar@395
    21
alpar@401
    22
  ///A list graph class.
alpar@395
    23
alpar@397
    24
  ///This is a simple and fast erasable graph implementation.
alpar@397
    25
  ///
alpar@395
    26
  ///It conforms to the graph interface documented under
alpar@395
    27
  ///the description of \ref GraphSkeleton.
alpar@395
    28
  ///\sa \ref GraphSkeleton.
alpar@397
    29
  class ListGraph {
alpar@395
    30
alpar@397
    31
    //Nodes are double linked.
alpar@397
    32
    //The free nodes are only single linked using the "next" field.
alpar@395
    33
    struct NodeT 
alpar@395
    34
    {
alpar@397
    35
      int first_in,first_out;
alpar@397
    36
      int prev, next;
alpar@397
    37
      //      NodeT() {}
alpar@395
    38
    };
alpar@397
    39
    //Edges are double linked.
alpar@397
    40
    //The free edges are only single linked using the "next_in" field.
alpar@395
    41
    struct EdgeT 
alpar@395
    42
    {
alpar@397
    43
      int head, tail;
alpar@397
    44
      int prev_in, prev_out;
alpar@397
    45
      int next_in, next_out;
alpar@395
    46
      //FIXME: is this necessary?
alpar@397
    47
      //      EdgeT() : next_in(-1), next_out(-1) prev_in(-1), prev_out(-1) {}  
alpar@395
    48
    };
alpar@395
    49
alpar@395
    50
    std::vector<NodeT> nodes;
alpar@397
    51
    //The first node
alpar@397
    52
    int first_node;
alpar@397
    53
    //The first free node
alpar@397
    54
    int first_free_node;
alpar@395
    55
    std::vector<EdgeT> edges;
alpar@397
    56
    //The first free edge
alpar@397
    57
    int first_free_edge;
alpar@395
    58
    
alpar@397
    59
  protected:
alpar@395
    60
    
alpar@395
    61
    template <typename Key> class DynMapBase
alpar@395
    62
    {
alpar@395
    63
    protected:
alpar@397
    64
      const ListGraph* G; 
alpar@395
    65
    public:
alpar@515
    66
      virtual void add(const Key k) = 0;
alpar@515
    67
      virtual void erase(const Key k) = 0;
alpar@397
    68
      DynMapBase(const ListGraph &_G) : G(&_G) {}
alpar@395
    69
      virtual ~DynMapBase() {}
alpar@397
    70
      friend class ListGraph;
alpar@395
    71
    };
alpar@395
    72
    
alpar@395
    73
  public:
alpar@395
    74
    template <typename T> class EdgeMap;
alpar@400
    75
    template <typename T> class NodeMap;
alpar@397
    76
    
alpar@395
    77
    class Node;
alpar@395
    78
    class Edge;
alpar@395
    79
alpar@395
    80
    //  protected:
alpar@395
    81
    // HELPME:
alpar@395
    82
  protected:
alpar@395
    83
    ///\bug It must be public because of SymEdgeMap.
alpar@395
    84
    ///
alpar@395
    85
    mutable std::vector<DynMapBase<Node> * > dyn_node_maps;
alpar@395
    86
    ///\bug It must be public because of SymEdgeMap.
alpar@395
    87
    ///
alpar@395
    88
    mutable std::vector<DynMapBase<Edge> * > dyn_edge_maps;
alpar@395
    89
    
alpar@395
    90
  public:
alpar@395
    91
alpar@395
    92
    class NodeIt;
alpar@395
    93
    class EdgeIt;
alpar@395
    94
    class OutEdgeIt;
alpar@395
    95
    class InEdgeIt;
alpar@395
    96
    
alpar@395
    97
  public:
alpar@395
    98
alpar@397
    99
    ListGraph() : nodes(), first_node(-1),
alpar@397
   100
		  first_free_node(-1), edges(), first_free_edge(-1) {}
alpar@397
   101
    ListGraph(const ListGraph &_g) : nodes(_g.nodes), first_node(_g.first_node),
alpar@397
   102
				     first_free_node(_g.first_free_node),
alpar@397
   103
				     edges(_g.edges),
alpar@397
   104
				     first_free_edge(_g.first_free_edge) {}
alpar@395
   105
    
alpar@397
   106
    ~ListGraph()
alpar@395
   107
    {
alpar@395
   108
      for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
alpar@395
   109
	  i!=dyn_node_maps.end(); ++i) (**i).G=NULL;
alpar@395
   110
      for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
alpar@395
   111
	  i!=dyn_edge_maps.end(); ++i) (**i).G=NULL;
alpar@395
   112
    }
alpar@395
   113
alpar@395
   114
    int nodeNum() const { return nodes.size(); }  //FIXME: What is this?
alpar@395
   115
    int edgeNum() const { return edges.size(); }  //FIXME: What is this?
alpar@395
   116
alpar@695
   117
    ///Set the expected number of edges
alpar@695
   118
alpar@695
   119
    ///With this function, it is possible to set the expected number of edges.
alpar@695
   120
    ///The use of this fasten the building of the graph and makes
alpar@695
   121
    ///it possible to avoid the superfluous memory allocation.
alpar@695
   122
    void reserveEdge(int n) { edges.reserve(n); };
alpar@695
   123
    
alpar@395
   124
    ///\bug This function does something different than
alpar@395
   125
    ///its name would suggests...
alpar@395
   126
    int maxNodeId() const { return nodes.size(); }  //FIXME: What is this?
alpar@395
   127
    ///\bug This function does something different than
alpar@395
   128
    ///its name would suggests...
alpar@395
   129
    int maxEdgeId() const { return edges.size(); }  //FIXME: What is this?
alpar@395
   130
alpar@395
   131
    Node tail(Edge e) const { return edges[e.n].tail; }
alpar@395
   132
    Node head(Edge e) const { return edges[e.n].head; }
alpar@395
   133
alpar@395
   134
    Node aNode(OutEdgeIt e) const { return edges[e.n].tail; }
alpar@395
   135
    Node aNode(InEdgeIt e) const { return edges[e.n].head; }
alpar@395
   136
alpar@395
   137
    Node bNode(OutEdgeIt e) const { return edges[e.n].head; }
alpar@395
   138
    Node bNode(InEdgeIt e) const { return edges[e.n].tail; }
alpar@395
   139
alpar@713
   140
    NodeIt& first(NodeIt& v) const { 
alpar@395
   141
      v=NodeIt(*this); return v; }
alpar@713
   142
    EdgeIt& first(EdgeIt& e) const { 
alpar@395
   143
      e=EdgeIt(*this); return e; }
alpar@713
   144
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
alpar@395
   145
      e=OutEdgeIt(*this,v); return e; }
alpar@713
   146
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
alpar@395
   147
      e=InEdgeIt(*this,v); return e; }
alpar@395
   148
alpar@395
   149
//     template< typename It >
alpar@395
   150
//     It first() const { It e; first(e); return e; }
alpar@395
   151
alpar@395
   152
//     template< typename It >
alpar@395
   153
//     It first(Node v) const { It e; first(e,v); return e; }
alpar@395
   154
alpar@713
   155
    static bool valid(Edge e) { return e.n!=-1; }
alpar@713
   156
    static bool valid(Node n) { return n.n!=-1; }
alpar@395
   157
    
alpar@710
   158
    static void setInvalid(Edge &e) { e.n=-1; }
alpar@710
   159
    static void setInvalid(Node &n) { n.n=-1; }
alpar@395
   160
    
alpar@713
   161
    template <typename It> static It getNext(It it)
alpar@395
   162
    { It tmp(it); return next(tmp); }
alpar@395
   163
alpar@395
   164
    NodeIt& next(NodeIt& it) const { 
alpar@397
   165
      it.n=nodes[it.n].next; 
alpar@395
   166
      return it; 
alpar@395
   167
    }
alpar@395
   168
    OutEdgeIt& next(OutEdgeIt& it) const
alpar@395
   169
    { it.n=edges[it.n].next_out; return it; }
alpar@395
   170
    InEdgeIt& next(InEdgeIt& it) const
alpar@395
   171
    { it.n=edges[it.n].next_in; return it; }
alpar@397
   172
    EdgeIt& next(EdgeIt& it) const {
alpar@397
   173
      if(edges[it.n].next_in!=-1) { 
alpar@397
   174
	it.n=edges[it.n].next_in;
alpar@397
   175
      }
alpar@397
   176
      else {
alpar@397
   177
	int n;
alpar@397
   178
	for(n=nodes[edges[it.n].head].next;
alpar@397
   179
	    n!=-1 && nodes[n].first_in == -1;
alpar@397
   180
	    n = nodes[n].next) ;
alpar@397
   181
	it.n = (n==-1)?-1:nodes[n].first_in;
alpar@397
   182
      }
alpar@397
   183
      return it;
alpar@397
   184
    }
alpar@395
   185
alpar@713
   186
    static int id(Node v) { return v.n; }
alpar@713
   187
    static int id(Edge e) { return e.n; }
alpar@395
   188
alpar@397
   189
    /// Adds a new node to the graph.
alpar@397
   190
alpar@397
   191
    /// \todo It adds the nodes in a reversed order.
alpar@397
   192
    /// (i.e. the lastly added node becomes the first.)
alpar@395
   193
    Node addNode() {
alpar@397
   194
      int n;
alpar@397
   195
      
alpar@397
   196
      if(first_free_node==-1)
alpar@397
   197
	{
alpar@397
   198
	  n = nodes.size();
alpar@397
   199
	  nodes.push_back(NodeT());
alpar@397
   200
	}
alpar@397
   201
      else {
alpar@397
   202
	n = first_free_node;
alpar@397
   203
	first_free_node = nodes[n].next;
alpar@397
   204
      }
alpar@397
   205
      
alpar@397
   206
      nodes[n].next = first_node;
alpar@397
   207
      if(first_node != -1) nodes[first_node].prev = n;
alpar@397
   208
      first_node = n;
alpar@397
   209
      nodes[n].prev = -1;
alpar@397
   210
      
alpar@397
   211
      nodes[n].first_in = nodes[n].first_out = -1;
alpar@397
   212
      
alpar@397
   213
      Node nn; nn.n=n;
alpar@395
   214
alpar@397
   215
      //Update dynamic maps
alpar@395
   216
      for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
alpar@397
   217
	  i!=dyn_node_maps.end(); ++i) (**i).add(nn);
alpar@395
   218
alpar@397
   219
      return nn;
alpar@395
   220
    }
alpar@395
   221
    
alpar@395
   222
    Edge addEdge(Node u, Node v) {
alpar@397
   223
      int n;
alpar@397
   224
      
alpar@397
   225
      if(first_free_edge==-1)
alpar@397
   226
	{
alpar@397
   227
	  n = edges.size();
alpar@397
   228
	  edges.push_back(EdgeT());
alpar@397
   229
	}
alpar@397
   230
      else {
alpar@397
   231
	n = first_free_edge;
alpar@397
   232
	first_free_edge = edges[n].next_in;
alpar@397
   233
      }
alpar@397
   234
      
alpar@397
   235
      edges[n].tail = u.n; edges[n].head = v.n;
alpar@395
   236
alpar@397
   237
      edges[n].next_out = nodes[u.n].first_out;
alpar@397
   238
      if(nodes[u.n].first_out != -1) edges[nodes[u.n].first_out].prev_out = n;
alpar@397
   239
      edges[n].next_in = nodes[v.n].first_in;
alpar@397
   240
      if(nodes[v.n].first_in != -1) edges[nodes[v.n].first_in].prev_in = n;
alpar@397
   241
      edges[n].prev_in = edges[n].prev_out = -1;
alpar@397
   242
	
alpar@397
   243
      nodes[u.n].first_out = nodes[v.n].first_in = n;
alpar@397
   244
alpar@397
   245
      Edge e; e.n=n;
alpar@397
   246
alpar@397
   247
      //Update dynamic maps
alpar@395
   248
      for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
alpar@395
   249
	  i!=dyn_edge_maps.end(); ++i) (**i).add(e);
alpar@395
   250
alpar@395
   251
      return e;
alpar@395
   252
    }
alpar@395
   253
alpar@397
   254
  private:
alpar@397
   255
    void eraseEdge(int n) {
alpar@397
   256
      
alpar@397
   257
      if(edges[n].next_in!=-1)
alpar@397
   258
	edges[edges[n].next_in].prev_in = edges[n].prev_in;
alpar@397
   259
      if(edges[n].prev_in!=-1)
alpar@397
   260
	edges[edges[n].prev_in].next_in = edges[n].next_in;
alpar@397
   261
      else nodes[edges[n].head].first_in = edges[n].next_in;
alpar@397
   262
      
alpar@397
   263
      if(edges[n].next_out!=-1)
alpar@397
   264
	edges[edges[n].next_out].prev_out = edges[n].prev_out;
alpar@397
   265
      if(edges[n].prev_out!=-1)
alpar@397
   266
	edges[edges[n].prev_out].next_out = edges[n].next_out;
alpar@397
   267
      else nodes[edges[n].tail].first_out = edges[n].next_out;
alpar@397
   268
      
alpar@397
   269
      edges[n].next_in = first_free_edge;
alpar@695
   270
      first_free_edge = n;      
alpar@397
   271
alpar@397
   272
      //Update dynamic maps
alpar@397
   273
      Edge e; e.n=n;
alpar@397
   274
      for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
alpar@397
   275
	  i!=dyn_edge_maps.end(); ++i) (**i).erase(e);
alpar@397
   276
    }
alpar@397
   277
      
alpar@397
   278
  public:
alpar@397
   279
alpar@397
   280
    void erase(Node nn) {
alpar@397
   281
      int n=nn.n;
alpar@397
   282
      
alpar@397
   283
      int m;
alpar@397
   284
      while((m=nodes[n].first_in)!=-1) eraseEdge(m);
alpar@397
   285
      while((m=nodes[n].first_out)!=-1) eraseEdge(m);
alpar@397
   286
alpar@397
   287
      if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
alpar@397
   288
      if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
alpar@397
   289
      else first_node = nodes[n].next;
alpar@397
   290
      
alpar@397
   291
      nodes[n].next = first_free_node;
alpar@397
   292
      first_free_node = n;
alpar@397
   293
alpar@397
   294
      //Update dynamic maps
alpar@397
   295
      for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
alpar@397
   296
	  i!=dyn_node_maps.end(); ++i) (**i).erase(nn);
alpar@397
   297
    }
alpar@397
   298
    
alpar@397
   299
    void erase(Edge e) { eraseEdge(e.n); }
alpar@397
   300
alpar@397
   301
    ///\bug Dynamic maps must be updated!
alpar@397
   302
    ///
alpar@397
   303
    void clear() {
alpar@397
   304
      nodes.clear();edges.clear();
alpar@397
   305
      first_node=first_free_node=first_free_edge=-1;
alpar@397
   306
    }
alpar@395
   307
alpar@395
   308
    class Node {
alpar@397
   309
      friend class ListGraph;
alpar@395
   310
      template <typename T> friend class NodeMap;
alpar@400
   311
       
alpar@395
   312
      friend class Edge;
alpar@395
   313
      friend class OutEdgeIt;
alpar@395
   314
      friend class InEdgeIt;
alpar@395
   315
      friend class SymEdge;
alpar@395
   316
alpar@395
   317
    protected:
alpar@395
   318
      int n;
alpar@722
   319
      friend int ListGraph::id(Node v); 
alpar@395
   320
      Node(int nn) {n=nn;}
alpar@395
   321
    public:
alpar@395
   322
      Node() {}
alpar@503
   323
      Node (Invalid) { n=-1; }
alpar@395
   324
      bool operator==(const Node i) const {return n==i.n;}
alpar@395
   325
      bool operator!=(const Node i) const {return n!=i.n;}
alpar@395
   326
      bool operator<(const Node i) const {return n<i.n;}
alpar@395
   327
    };
alpar@395
   328
    
alpar@395
   329
    class NodeIt : public Node {
alpar@397
   330
      friend class ListGraph;
alpar@395
   331
    public:
alpar@400
   332
      NodeIt() : Node() { }
alpar@400
   333
      NodeIt(Invalid i) : Node(i) { }
alpar@397
   334
      NodeIt(const ListGraph& G) : Node(G.first_node) { }
alpar@579
   335
      ///\todo Undocumented conversion Node -\> NodeIt.
alpar@579
   336
      NodeIt(const ListGraph& G, const Node &n) : Node(n) { }
alpar@395
   337
    };
alpar@395
   338
alpar@395
   339
    class Edge {
alpar@397
   340
      friend class ListGraph;
alpar@395
   341
      template <typename T> friend class EdgeMap;
alpar@395
   342
alpar@397
   343
      //template <typename T> friend class SymListGraph::SymEdgeMap;      
alpar@397
   344
      //friend Edge SymListGraph::opposite(Edge) const;
alpar@395
   345
      
alpar@395
   346
      friend class Node;
alpar@395
   347
      friend class NodeIt;
alpar@395
   348
    protected:
alpar@395
   349
      int n;
alpar@722
   350
      friend int ListGraph::id(Edge e);
alpar@395
   351
alpar@706
   352
    public:
alpar@706
   353
      /// An Edge with id \c n.
alpar@706
   354
alpar@706
   355
      /// \bug It should be
alpar@706
   356
      /// obtained by a member function of the Graph.
alpar@395
   357
      Edge(int nn) {n=nn;}
alpar@706
   358
alpar@395
   359
      Edge() { }
alpar@395
   360
      Edge (Invalid) { n=-1; }
alpar@395
   361
      bool operator==(const Edge i) const {return n==i.n;}
alpar@395
   362
      bool operator!=(const Edge i) const {return n!=i.n;}
alpar@395
   363
      bool operator<(const Edge i) const {return n<i.n;}
alpar@395
   364
      ///\bug This is a workaround until somebody tells me how to
alpar@397
   365
      ///make class \c SymListGraph::SymEdgeMap friend of Edge
alpar@395
   366
      int &idref() {return n;}
alpar@395
   367
      const int &idref() const {return n;}
alpar@395
   368
    };
alpar@395
   369
    
alpar@395
   370
    class EdgeIt : public Edge {
alpar@397
   371
      friend class ListGraph;
alpar@395
   372
    public:
alpar@397
   373
      EdgeIt(const ListGraph& G) : Edge() {
alpar@397
   374
      	int m;
alpar@397
   375
	for(m=G.first_node;
alpar@397
   376
	    m!=-1 && G.nodes[m].first_in == -1; m = G.nodes[m].next);
alpar@397
   377
	n = (m==-1)?-1:G.nodes[m].first_in;
alpar@397
   378
      }
alpar@395
   379
      EdgeIt (Invalid i) : Edge(i) { }
alpar@395
   380
      EdgeIt() : Edge() { }
alpar@395
   381
      ///\bug This is a workaround until somebody tells me how to
alpar@397
   382
      ///make class \c SymListGraph::SymEdgeMap friend of Edge
alpar@395
   383
      int &idref() {return n;}
alpar@395
   384
    };
alpar@395
   385
    
alpar@395
   386
    class OutEdgeIt : public Edge {
alpar@397
   387
      friend class ListGraph;
alpar@395
   388
    public: 
alpar@395
   389
      OutEdgeIt() : Edge() { }
alpar@395
   390
      OutEdgeIt (Invalid i) : Edge(i) { }
alpar@395
   391
alpar@397
   392
      OutEdgeIt(const ListGraph& G,const Node v)
alpar@395
   393
	: Edge(G.nodes[v.n].first_out) {}
alpar@395
   394
    };
alpar@395
   395
    
alpar@395
   396
    class InEdgeIt : public Edge {
alpar@397
   397
      friend class ListGraph;
alpar@395
   398
    public: 
alpar@395
   399
      InEdgeIt() : Edge() { }
alpar@395
   400
      InEdgeIt (Invalid i) : Edge(i) { }
alpar@681
   401
      InEdgeIt(const ListGraph& G,Node v) :Edge(G.nodes[v.n].first_in) {}
alpar@395
   402
    };
alpar@395
   403
alpar@395
   404
    template <typename T> class NodeMap : public DynMapBase<Node>
alpar@395
   405
    {
alpar@395
   406
      std::vector<T> container;
alpar@395
   407
alpar@395
   408
    public:
alpar@395
   409
      typedef T ValueType;
alpar@395
   410
      typedef Node KeyType;
alpar@395
   411
alpar@397
   412
      NodeMap(const ListGraph &_G) :
alpar@395
   413
	DynMapBase<Node>(_G), container(_G.maxNodeId())
alpar@395
   414
      {
alpar@395
   415
	G->dyn_node_maps.push_back(this);
alpar@395
   416
      }
alpar@397
   417
      NodeMap(const ListGraph &_G,const T &t) :
alpar@395
   418
	DynMapBase<Node>(_G), container(_G.maxNodeId(),t)
alpar@395
   419
      {
alpar@395
   420
	G->dyn_node_maps.push_back(this);
alpar@395
   421
      }
alpar@395
   422
      
alpar@395
   423
      NodeMap(const NodeMap<T> &m) :
alpar@395
   424
 	DynMapBase<Node>(*m.G), container(m.container)
alpar@395
   425
      {
alpar@395
   426
 	G->dyn_node_maps.push_back(this);
alpar@395
   427
      }
alpar@395
   428
alpar@395
   429
      template<typename TT> friend class NodeMap;
alpar@395
   430
 
alpar@395
   431
      ///\todo It can copy between different types.
alpar@395
   432
      ///
alpar@395
   433
      template<typename TT> NodeMap(const NodeMap<TT> &m) :
alpar@590
   434
	DynMapBase<Node>(*m.G), container(m.container.size())
alpar@590
   435
alpar@395
   436
      {
alpar@395
   437
	G->dyn_node_maps.push_back(this);
alpar@395
   438
	typename std::vector<TT>::const_iterator i;
alpar@395
   439
	for(typename std::vector<TT>::const_iterator i=m.container.begin();
alpar@395
   440
	    i!=m.container.end();
alpar@395
   441
	    i++)
alpar@395
   442
	  container.push_back(*i);
alpar@395
   443
      }
alpar@395
   444
      ~NodeMap()
alpar@395
   445
      {
alpar@395
   446
	if(G) {
alpar@395
   447
	  std::vector<DynMapBase<Node>* >::iterator i;
alpar@395
   448
	  for(i=G->dyn_node_maps.begin();
alpar@395
   449
	      i!=G->dyn_node_maps.end() && *i!=this; ++i) ;
alpar@395
   450
	  //if(*i==this) G->dyn_node_maps.erase(i); //FIXME: Way too slow...
alpar@395
   451
	  //A better way to do that: (Is this really important?)
alpar@395
   452
	  if(*i==this) {
alpar@395
   453
	    *i=G->dyn_node_maps.back();
alpar@395
   454
	    G->dyn_node_maps.pop_back();
alpar@395
   455
	  }
alpar@395
   456
	}
alpar@395
   457
      }
alpar@395
   458
alpar@395
   459
      void add(const Node k) 
alpar@395
   460
      {
alpar@395
   461
	if(k.n>=int(container.size())) container.resize(k.n+1);
alpar@395
   462
      }
alpar@395
   463
alpar@395
   464
      void erase(const Node) { }
alpar@395
   465
      
alpar@395
   466
      void set(Node n, T a) { container[n.n]=a; }
alpar@395
   467
      //'T& operator[](Node n)' would be wrong here
alpar@395
   468
      typename std::vector<T>::reference
alpar@395
   469
      operator[](Node n) { return container[n.n]; }
alpar@395
   470
      //'const T& operator[](Node n)' would be wrong here
alpar@395
   471
      typename std::vector<T>::const_reference 
alpar@395
   472
      operator[](Node n) const { return container[n.n]; }
alpar@395
   473
alpar@395
   474
      ///\warning There is no safety check at all!
alpar@395
   475
      ///Using operator = between maps attached to different graph may
alpar@395
   476
      ///cause serious problem.
alpar@395
   477
      ///\todo Is this really so?
alpar@395
   478
      ///\todo It can copy between different types.
alpar@395
   479
      const NodeMap<T>& operator=(const NodeMap<T> &m)
alpar@395
   480
      {
alpar@395
   481
	container = m.container;
alpar@395
   482
	return *this;
alpar@395
   483
      }
alpar@395
   484
      template<typename TT>
alpar@395
   485
      const NodeMap<T>& operator=(const NodeMap<TT> &m)
alpar@395
   486
      {
alpar@531
   487
	std::copy(m.container.begin(), m.container.end(), container.begin());
alpar@395
   488
	return *this;
alpar@395
   489
      }
alpar@395
   490
      
alpar@395
   491
      void update() {}    //Useless for Dynamic Maps
alpar@395
   492
      void update(T a) {}  //Useless for Dynamic Maps
alpar@395
   493
    };
alpar@395
   494
    
alpar@395
   495
    template <typename T> class EdgeMap : public DynMapBase<Edge>
alpar@395
   496
    {
alpar@579
   497
    protected:
alpar@395
   498
      std::vector<T> container;
alpar@395
   499
alpar@395
   500
    public:
alpar@395
   501
      typedef T ValueType;
alpar@395
   502
      typedef Edge KeyType;
alpar@395
   503
alpar@397
   504
      EdgeMap(const ListGraph &_G) :
alpar@395
   505
	DynMapBase<Edge>(_G), container(_G.maxEdgeId())
alpar@395
   506
      {
alpar@395
   507
	//FIXME: What if there are empty Id's?
alpar@395
   508
	//FIXME: Can I use 'this' in a constructor?
alpar@395
   509
	G->dyn_edge_maps.push_back(this);
alpar@395
   510
      }
alpar@397
   511
      EdgeMap(const ListGraph &_G,const T &t) :
alpar@395
   512
	DynMapBase<Edge>(_G), container(_G.maxEdgeId(),t)
alpar@395
   513
      {
alpar@395
   514
	G->dyn_edge_maps.push_back(this);
alpar@395
   515
      } 
alpar@395
   516
      EdgeMap(const EdgeMap<T> &m) :
alpar@395
   517
 	DynMapBase<Edge>(*m.G), container(m.container)
alpar@395
   518
      {
alpar@503
   519
 	G->dyn_edge_maps.push_back(this);
alpar@395
   520
      }
alpar@395
   521
alpar@395
   522
      template<typename TT> friend class EdgeMap;
alpar@395
   523
alpar@395
   524
      ///\todo It can copy between different types.
alpar@395
   525
      ///
alpar@395
   526
      template<typename TT> EdgeMap(const EdgeMap<TT> &m) :
alpar@590
   527
	DynMapBase<Edge>(*m.G), container(m.container.size())
alpar@395
   528
      {
alpar@503
   529
	G->dyn_edge_maps.push_back(this);
alpar@395
   530
	typename std::vector<TT>::const_iterator i;
alpar@395
   531
	for(typename std::vector<TT>::const_iterator i=m.container.begin();
alpar@395
   532
	    i!=m.container.end();
alpar@395
   533
	    i++)
alpar@395
   534
	  container.push_back(*i);
alpar@395
   535
      }
alpar@395
   536
      ~EdgeMap()
alpar@395
   537
      {
alpar@395
   538
	if(G) {
alpar@395
   539
	  std::vector<DynMapBase<Edge>* >::iterator i;
alpar@395
   540
	  for(i=G->dyn_edge_maps.begin();
alpar@395
   541
	      i!=G->dyn_edge_maps.end() && *i!=this; ++i) ;
alpar@395
   542
	  //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow...
alpar@395
   543
	  //A better way to do that: (Is this really important?)
alpar@395
   544
	  if(*i==this) {
alpar@395
   545
	    *i=G->dyn_edge_maps.back();
alpar@395
   546
	    G->dyn_edge_maps.pop_back();
alpar@395
   547
	  }
alpar@395
   548
	}
alpar@395
   549
      }
alpar@395
   550
      
alpar@395
   551
      void add(const Edge k) 
alpar@395
   552
      {
alpar@395
   553
	if(k.n>=int(container.size())) container.resize(k.n+1);
alpar@395
   554
      }
alpar@395
   555
      void erase(const Edge) { }
alpar@395
   556
      
alpar@395
   557
      void set(Edge n, T a) { container[n.n]=a; }
alpar@395
   558
      //T get(Edge n) const { return container[n.n]; }
alpar@395
   559
      typename std::vector<T>::reference
alpar@395
   560
      operator[](Edge n) { return container[n.n]; }
alpar@395
   561
      typename std::vector<T>::const_reference
alpar@395
   562
      operator[](Edge n) const { return container[n.n]; }
alpar@395
   563
alpar@395
   564
      ///\warning There is no safety check at all!
alpar@395
   565
      ///Using operator = between maps attached to different graph may
alpar@395
   566
      ///cause serious problem.
alpar@395
   567
      ///\todo Is this really so?
alpar@395
   568
      ///\todo It can copy between different types.
alpar@395
   569
      const EdgeMap<T>& operator=(const EdgeMap<T> &m)
alpar@395
   570
      {
alpar@395
   571
	container = m.container;
alpar@395
   572
	return *this;
alpar@395
   573
      }
alpar@395
   574
      template<typename TT>
alpar@395
   575
      const EdgeMap<T>& operator=(const EdgeMap<TT> &m)
alpar@395
   576
      {
alpar@531
   577
	std::copy(m.container.begin(), m.container.end(), container.begin());
alpar@395
   578
	return *this;
alpar@395
   579
      }
alpar@395
   580
      
alpar@395
   581
      void update() {}    //Useless for DynMaps
alpar@395
   582
      void update(T a) {}  //Useless for DynMaps
alpar@395
   583
    };
alpar@395
   584
alpar@395
   585
  };
alpar@395
   586
alpar@395
   587
  ///Graph for bidirectional edges.
alpar@395
   588
alpar@395
   589
  ///The purpose of this graph structure is to handle graphs
alpar@395
   590
  ///having bidirectional edges. Here the function \c addEdge(u,v) adds a pair
alpar@395
   591
  ///of oppositely directed edges.
alpar@395
   592
  ///There is a new edge map type called
alpar@397
   593
  ///\ref SymListGraph::SymEdgeMap "SymEdgeMap"
alpar@395
   594
  ///that complements this
alpar@395
   595
  ///feature by
alpar@395
   596
  ///storing shared values for the edge pairs. The usual
alpar@395
   597
  ///\ref GraphSkeleton::EdgeMap "EdgeMap"
alpar@395
   598
  ///can be used
alpar@395
   599
  ///as well.
alpar@395
   600
  ///
alpar@395
   601
  ///The oppositely directed edge can also be obtained easily
alpar@395
   602
  ///using \ref opposite.
alpar@397
   603
  ///
alpar@397
   604
  ///Here erase(Edge) deletes a pair of edges.
alpar@397
   605
  ///
alpar@397
   606
  ///\todo this date structure need some reconsiderations. Maybe it
alpar@397
   607
  ///should be implemented independently from ListGraph.
alpar@395
   608
alpar@397
   609
  class SymListGraph : public ListGraph
alpar@395
   610
  {
alpar@395
   611
  public:
alpar@395
   612
    template<typename T> class SymEdgeMap;
alpar@395
   613
    template<typename T> friend class SymEdgeMap;
alpar@395
   614
alpar@397
   615
    SymListGraph() : ListGraph() { }
alpar@397
   616
    SymListGraph(const ListGraph &_g) : ListGraph(_g) { }
alpar@397
   617
    ///Adds a pair of oppositely directed edges to the graph.
alpar@395
   618
    Edge addEdge(Node u, Node v)
alpar@395
   619
    {
alpar@397
   620
      Edge e = ListGraph::addEdge(u,v);
alpar@397
   621
      ListGraph::addEdge(v,u);
alpar@395
   622
      return e;
alpar@395
   623
    }
alpar@395
   624
alpar@397
   625
    void erase(Node n) { ListGraph::erase(n); }
alpar@395
   626
    ///The oppositely directed edge.
alpar@395
   627
alpar@395
   628
    ///Returns the oppositely directed
alpar@395
   629
    ///pair of the edge \c e.
alpar@713
   630
    static Edge opposite(Edge e)
alpar@395
   631
    {
alpar@395
   632
      Edge f;
alpar@395
   633
      f.idref() = e.idref() - 2*(e.idref()%2) + 1;
alpar@395
   634
      return f;
alpar@395
   635
    }
alpar@395
   636
    
alpar@397
   637
    ///Removes a pair of oppositely directed edges to the graph.
alpar@397
   638
    void erase(Edge e) {
alpar@397
   639
      ListGraph::erase(opposite(e));
alpar@397
   640
      ListGraph::erase(e);
alpar@397
   641
    }
alpar@397
   642
    
alpar@395
   643
    ///Common data storage for the edge pairs.
alpar@395
   644
alpar@395
   645
    ///This map makes it possible to store data shared by the oppositely
alpar@395
   646
    ///directed pairs of edges.
alpar@395
   647
    template <typename T> class SymEdgeMap : public DynMapBase<Edge>
alpar@395
   648
    {
alpar@395
   649
      std::vector<T> container;
alpar@395
   650
      
alpar@395
   651
    public:
alpar@395
   652
      typedef T ValueType;
alpar@395
   653
      typedef Edge KeyType;
alpar@395
   654
alpar@397
   655
      SymEdgeMap(const SymListGraph &_G) :
alpar@395
   656
	DynMapBase<Edge>(_G), container(_G.maxEdgeId()/2)
alpar@395
   657
      {
alpar@397
   658
	static_cast<const SymListGraph*>(G)->dyn_edge_maps.push_back(this);
alpar@395
   659
      }
alpar@397
   660
      SymEdgeMap(const SymListGraph &_G,const T &t) :
alpar@395
   661
	DynMapBase<Edge>(_G), container(_G.maxEdgeId()/2,t)
alpar@395
   662
      {
alpar@395
   663
	G->dyn_edge_maps.push_back(this);
alpar@395
   664
      }
alpar@395
   665
alpar@395
   666
      SymEdgeMap(const SymEdgeMap<T> &m) :
alpar@395
   667
 	DynMapBase<SymEdge>(*m.G), container(m.container)
alpar@395
   668
      {
alpar@395
   669
 	G->dyn_node_maps.push_back(this);
alpar@395
   670
      }
alpar@395
   671
alpar@395
   672
      //      template<typename TT> friend class SymEdgeMap;
alpar@395
   673
alpar@395
   674
      ///\todo It can copy between different types.
alpar@395
   675
      ///
alpar@395
   676
alpar@395
   677
      template<typename TT> SymEdgeMap(const SymEdgeMap<TT> &m) :
alpar@590
   678
	DynMapBase<SymEdge>(*m.G), container(m.container.size())
alpar@395
   679
      {
alpar@395
   680
	G->dyn_node_maps.push_back(this);
alpar@395
   681
	typename std::vector<TT>::const_iterator i;
alpar@395
   682
	for(typename std::vector<TT>::const_iterator i=m.container.begin();
alpar@395
   683
	    i!=m.container.end();
alpar@395
   684
	    i++)
alpar@395
   685
	  container.push_back(*i);
alpar@395
   686
      }
alpar@395
   687
 
alpar@395
   688
      ~SymEdgeMap()
alpar@395
   689
      {
alpar@395
   690
	if(G) {
alpar@395
   691
	  std::vector<DynMapBase<Edge>* >::iterator i;
alpar@397
   692
	  for(i=static_cast<const SymListGraph*>(G)->dyn_edge_maps.begin();
alpar@397
   693
	      i!=static_cast<const SymListGraph*>(G)->dyn_edge_maps.end()
alpar@395
   694
		&& *i!=this; ++i) ;
alpar@395
   695
	  //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow...
alpar@395
   696
	  //A better way to do that: (Is this really important?)
alpar@395
   697
	  if(*i==this) {
alpar@397
   698
	    *i=static_cast<const SymListGraph*>(G)->dyn_edge_maps.back();
alpar@397
   699
	    static_cast<const SymListGraph*>(G)->dyn_edge_maps.pop_back();
alpar@395
   700
	  }
alpar@395
   701
	}
alpar@395
   702
      }
alpar@395
   703
      
alpar@395
   704
      void add(const Edge k) 
alpar@395
   705
      {
alpar@395
   706
	if(!k.idref()%2&&k.idref()/2>=int(container.size()))
alpar@395
   707
	  container.resize(k.idref()/2+1);
alpar@395
   708
      }
alpar@395
   709
      void erase(const Edge k) { }
alpar@395
   710
      
alpar@395
   711
      void set(Edge n, T a) { container[n.idref()/2]=a; }
alpar@395
   712
      //T get(Edge n) const { return container[n.idref()/2]; }
alpar@395
   713
      typename std::vector<T>::reference
alpar@395
   714
      operator[](Edge n) { return container[n.idref()/2]; }
alpar@395
   715
      typename std::vector<T>::const_reference
alpar@395
   716
      operator[](Edge n) const { return container[n.idref()/2]; }
alpar@395
   717
alpar@395
   718
      ///\warning There is no safety check at all!
alpar@395
   719
      ///Using operator = between maps attached to different graph may
alpar@395
   720
      ///cause serious problem.
alpar@395
   721
      ///\todo Is this really so?
alpar@395
   722
      ///\todo It can copy between different types.
alpar@395
   723
      const SymEdgeMap<T>& operator=(const SymEdgeMap<T> &m)
alpar@395
   724
      {
alpar@395
   725
	container = m.container;
alpar@395
   726
	return *this;
alpar@395
   727
      }
alpar@395
   728
      template<typename TT>
alpar@395
   729
      const SymEdgeMap<T>& operator=(const SymEdgeMap<TT> &m)
alpar@395
   730
      {
alpar@531
   731
	std::copy(m.container.begin(), m.container.end(), container.begin());
alpar@395
   732
	return *this;
alpar@395
   733
      }
alpar@395
   734
      
alpar@395
   735
      void update() {}    //Useless for DynMaps
alpar@395
   736
      void update(T a) {}  //Useless for DynMaps
alpar@395
   737
alpar@395
   738
    };
alpar@395
   739
alpar@395
   740
  };
alpar@395
   741
  
alpar@400
   742
alpar@401
   743
  ///A graph class containing only nodes.
alpar@400
   744
alpar@401
   745
  ///This class implements a graph structure without edges.
alpar@401
   746
  ///The most useful application of this class is to be the node set of an
alpar@401
   747
  ///\ref EdgeSet class.
alpar@400
   748
  ///
alpar@400
   749
  ///It conforms to the graph interface documented under
alpar@401
   750
  ///the description of \ref GraphSkeleton with the exception that you cannot
alpar@401
   751
  ///add (or delete) edges. The usual edge iterators are exists, but they are
alpar@401
   752
  ///always \ref INVALID.
alpar@401
   753
  ///\sa \ref GraphSkeleton
alpar@508
   754
  ///\sa \ref EdgeSet
alpar@400
   755
  class NodeSet {
alpar@400
   756
alpar@400
   757
    //Nodes are double linked.
alpar@400
   758
    //The free nodes are only single linked using the "next" field.
alpar@400
   759
    struct NodeT 
alpar@400
   760
    {
alpar@400
   761
      int first_in,first_out;
alpar@400
   762
      int prev, next;
alpar@400
   763
      //      NodeT() {}
alpar@400
   764
    };
alpar@400
   765
alpar@400
   766
    std::vector<NodeT> nodes;
alpar@400
   767
    //The first node
alpar@400
   768
    int first_node;
alpar@400
   769
    //The first free node
alpar@400
   770
    int first_free_node;
alpar@400
   771
    
alpar@400
   772
  protected:
alpar@400
   773
    
alpar@400
   774
    template <typename Key> class DynMapBase
alpar@400
   775
    {
alpar@400
   776
    protected:
alpar@400
   777
      const NodeSet* G; 
alpar@400
   778
    public:
alpar@515
   779
      virtual void add(const Key k) = 0;
alpar@515
   780
      virtual void erase(const Key k) = 0;
alpar@400
   781
      DynMapBase(const NodeSet &_G) : G(&_G) {}
alpar@400
   782
      virtual ~DynMapBase() {}
alpar@400
   783
      friend class NodeSet;
alpar@400
   784
    };
alpar@400
   785
    
alpar@400
   786
  public:
alpar@400
   787
    template <typename T> class EdgeMap;
alpar@400
   788
    template <typename T> class NodeMap;
alpar@400
   789
    
alpar@400
   790
    class Node;
alpar@400
   791
    class Edge;
alpar@400
   792
alpar@400
   793
    //  protected:
alpar@400
   794
    // HELPME:
alpar@400
   795
  protected:
alpar@400
   796
    ///\bug It must be public because of SymEdgeMap.
alpar@400
   797
    ///
alpar@400
   798
    mutable std::vector<DynMapBase<Node> * > dyn_node_maps;
alpar@400
   799
    //mutable std::vector<DynMapBase<Edge> * > dyn_edge_maps;
alpar@400
   800
    
alpar@400
   801
  public:
alpar@400
   802
alpar@400
   803
    class NodeIt;
alpar@400
   804
    class EdgeIt;
alpar@400
   805
    class OutEdgeIt;
alpar@400
   806
    class InEdgeIt;
alpar@400
   807
    
alpar@400
   808
    template <typename T> class NodeMap;
alpar@400
   809
    template <typename T> class EdgeMap;
alpar@400
   810
    
alpar@400
   811
  public:
alpar@400
   812
alpar@408
   813
    ///Default constructor
alpar@400
   814
    NodeSet() : nodes(), first_node(-1),
alpar@400
   815
		  first_free_node(-1) {}
alpar@408
   816
    ///Copy constructor
alpar@400
   817
    NodeSet(const NodeSet &_g) : nodes(_g.nodes), first_node(_g.first_node),
alpar@400
   818
				     first_free_node(_g.first_free_node) {}
alpar@400
   819
    
alpar@400
   820
    ~NodeSet()
alpar@400
   821
    {
alpar@400
   822
      for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
alpar@400
   823
	  i!=dyn_node_maps.end(); ++i) (**i).G=NULL;
alpar@400
   824
      //for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
alpar@400
   825
      //	  i!=dyn_edge_maps.end(); ++i) (**i).G=NULL;
alpar@400
   826
    }
alpar@400
   827
alpar@400
   828
    int nodeNum() const { return nodes.size(); }  //FIXME: What is this?
alpar@400
   829
    int edgeNum() const { return 0; }  //FIXME: What is this?
alpar@400
   830
alpar@400
   831
    ///\bug This function does something different than
alpar@400
   832
    ///its name would suggests...
alpar@400
   833
    int maxNodeId() const { return nodes.size(); }  //FIXME: What is this?
alpar@400
   834
    ///\bug This function does something different than
alpar@400
   835
    ///its name would suggests...
alpar@400
   836
    int maxEdgeId() const { return 0; }  //FIXME: What is this?
alpar@400
   837
alpar@400
   838
    Node tail(Edge e) const { return INVALID; }
alpar@400
   839
    Node head(Edge e) const { return INVALID; }
alpar@400
   840
alpar@400
   841
    Node aNode(OutEdgeIt e) const { return INVALID; }
alpar@400
   842
    Node aNode(InEdgeIt e) const { return INVALID; }
alpar@400
   843
alpar@400
   844
    Node bNode(OutEdgeIt e) const { return INVALID; }
alpar@400
   845
    Node bNode(InEdgeIt e) const { return INVALID; }
alpar@400
   846
alpar@400
   847
    NodeIt& first(NodeIt& v) const { 
alpar@400
   848
      v=NodeIt(*this); return v; }
alpar@400
   849
    EdgeIt& first(EdgeIt& e) const { 
alpar@400
   850
      e=EdgeIt(*this); return e; }
alpar@400
   851
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
alpar@400
   852
      e=OutEdgeIt(*this,v); return e; }
alpar@400
   853
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
alpar@400
   854
      e=InEdgeIt(*this,v); return e; }
alpar@400
   855
alpar@400
   856
//     template< typename It >
alpar@400
   857
//     It first() const { It e; first(e); return e; }
alpar@400
   858
alpar@400
   859
//     template< typename It >
alpar@400
   860
//     It first(Node v) const { It e; first(e,v); return e; }
alpar@400
   861
alpar@400
   862
    bool valid(Edge e) const { return false; }
alpar@400
   863
    bool valid(Node n) const { return n.n!=-1; }
alpar@400
   864
    
alpar@400
   865
    void setInvalid(Edge &e) { }
alpar@400
   866
    void setInvalid(Node &n) { n.n=-1; }
alpar@400
   867
    
alpar@400
   868
    template <typename It> It getNext(It it) const
alpar@400
   869
    { It tmp(it); return next(tmp); }
alpar@400
   870
alpar@400
   871
    NodeIt& next(NodeIt& it) const { 
alpar@400
   872
      it.n=nodes[it.n].next; 
alpar@400
   873
      return it; 
alpar@400
   874
    }
alpar@400
   875
    OutEdgeIt& next(OutEdgeIt& it) const { return it; }
alpar@400
   876
    InEdgeIt& next(InEdgeIt& it) const { return it; }
alpar@400
   877
    EdgeIt& next(EdgeIt& it) const { return it; }
alpar@400
   878
alpar@400
   879
    int id(Node v) const { return v.n; }
alpar@400
   880
    int id(Edge e) const { return -1; }
alpar@400
   881
alpar@400
   882
    /// Adds a new node to the graph.
alpar@400
   883
alpar@400
   884
    /// \todo It adds the nodes in a reversed order.
alpar@400
   885
    /// (i.e. the lastly added node becomes the first.)
alpar@400
   886
    Node addNode() {
alpar@400
   887
      int n;
alpar@400
   888
      
alpar@400
   889
      if(first_free_node==-1)
alpar@400
   890
	{
alpar@400
   891
	  n = nodes.size();
alpar@400
   892
	  nodes.push_back(NodeT());
alpar@400
   893
	}
alpar@400
   894
      else {
alpar@400
   895
	n = first_free_node;
alpar@400
   896
	first_free_node = nodes[n].next;
alpar@400
   897
      }
alpar@400
   898
      
alpar@400
   899
      nodes[n].next = first_node;
alpar@400
   900
      if(first_node != -1) nodes[first_node].prev = n;
alpar@400
   901
      first_node = n;
alpar@400
   902
      nodes[n].prev = -1;
alpar@400
   903
      
alpar@400
   904
      nodes[n].first_in = nodes[n].first_out = -1;
alpar@400
   905
      
alpar@400
   906
      Node nn; nn.n=n;
alpar@400
   907
alpar@400
   908
      //Update dynamic maps
alpar@400
   909
      for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
alpar@400
   910
	  i!=dyn_node_maps.end(); ++i) (**i).add(nn);
alpar@400
   911
alpar@400
   912
      return nn;
alpar@400
   913
    }
alpar@400
   914
    
alpar@400
   915
    void erase(Node nn) {
alpar@400
   916
      int n=nn.n;
alpar@400
   917
      
alpar@400
   918
      if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
alpar@400
   919
      if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
alpar@400
   920
      else first_node = nodes[n].next;
alpar@400
   921
      
alpar@400
   922
      nodes[n].next = first_free_node;
alpar@400
   923
      first_free_node = n;
alpar@400
   924
alpar@400
   925
      //Update dynamic maps
alpar@400
   926
      for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
alpar@400
   927
	  i!=dyn_node_maps.end(); ++i) (**i).erase(nn);
alpar@400
   928
    }
alpar@400
   929
    
alpar@400
   930
    ///\bug Dynamic maps must be updated!
alpar@400
   931
    ///
alpar@400
   932
    void clear() {
alpar@400
   933
      nodes.clear();
alpar@400
   934
      first_node = first_free_node = -1;
alpar@400
   935
    }
alpar@400
   936
alpar@400
   937
    class Node {
alpar@400
   938
      friend class NodeSet;
alpar@400
   939
      template <typename T> friend class NodeMap;
alpar@400
   940
      
alpar@400
   941
      friend class Edge;
alpar@400
   942
      friend class OutEdgeIt;
alpar@400
   943
      friend class InEdgeIt;
alpar@400
   944
alpar@400
   945
    protected:
alpar@400
   946
      int n;
alpar@400
   947
      friend int NodeSet::id(Node v) const; 
alpar@400
   948
      Node(int nn) {n=nn;}
alpar@400
   949
    public:
alpar@400
   950
      Node() {}
alpar@400
   951
      Node (Invalid i) { n=-1; }
alpar@400
   952
      bool operator==(const Node i) const {return n==i.n;}
alpar@400
   953
      bool operator!=(const Node i) const {return n!=i.n;}
alpar@400
   954
      bool operator<(const Node i) const {return n<i.n;}
alpar@400
   955
    };
alpar@400
   956
    
alpar@400
   957
    class NodeIt : public Node {
alpar@400
   958
      friend class NodeSet;
alpar@400
   959
    public:
alpar@579
   960
      NodeIt() : Node() { }
alpar@579
   961
      NodeIt(Invalid i) : Node(i) { }
alpar@400
   962
      NodeIt(const NodeSet& G) : Node(G.first_node) { }
alpar@579
   963
      ///\todo Undocumented conversion Node -\> NodeIt.
alpar@579
   964
      NodeIt(const NodeSet& G, const Node &n) : Node(n) { }
alpar@579
   965
alpar@400
   966
    };
alpar@400
   967
alpar@400
   968
    class Edge {
alpar@400
   969
      //friend class NodeSet;
alpar@400
   970
      //template <typename T> friend class EdgeMap;
alpar@400
   971
alpar@400
   972
      //template <typename T> friend class SymNodeSet::SymEdgeMap;      
alpar@400
   973
      //friend Edge SymNodeSet::opposite(Edge) const;
alpar@400
   974
      
alpar@400
   975
      //      friend class Node;
alpar@400
   976
      //      friend class NodeIt;
alpar@400
   977
    protected:
alpar@400
   978
      //friend int NodeSet::id(Edge e) const;
alpar@400
   979
      //      Edge(int nn) {}
alpar@400
   980
    public:
alpar@400
   981
      Edge() { }
alpar@400
   982
      Edge (Invalid) { }
alpar@400
   983
      bool operator==(const Edge i) const {return true;}
alpar@400
   984
      bool operator!=(const Edge i) const {return false;}
alpar@400
   985
      bool operator<(const Edge i) const {return false;}
alpar@400
   986
      ///\bug This is a workaround until somebody tells me how to
alpar@400
   987
      ///make class \c SymNodeSet::SymEdgeMap friend of Edge
alpar@400
   988
      //      int idref() {return -1;}
alpar@400
   989
      //      int idref() const {return -1;}
alpar@400
   990
    };
alpar@400
   991
    
alpar@400
   992
    class EdgeIt : public Edge {
alpar@400
   993
      //friend class NodeSet;
alpar@400
   994
    public:
alpar@400
   995
      EdgeIt(const NodeSet& G) : Edge() { }
alpar@400
   996
      EdgeIt (Invalid i) : Edge(i) { }
alpar@400
   997
      EdgeIt() : Edge() { }
alpar@400
   998
      ///\bug This is a workaround until somebody tells me how to
alpar@400
   999
      ///make class \c SymNodeSet::SymEdgeMap friend of Edge
alpar@400
  1000
      //      int idref() {return -1;}
alpar@400
  1001
    };
alpar@400
  1002
    
alpar@400
  1003
    class OutEdgeIt : public Edge {
alpar@400
  1004
      friend class NodeSet;
alpar@400
  1005
    public: 
alpar@400
  1006
      OutEdgeIt() : Edge() { }
alpar@400
  1007
      OutEdgeIt (Invalid i) : Edge(i) { }
alpar@400
  1008
      OutEdgeIt(const NodeSet& G,const Node v)	: Edge() {}
alpar@400
  1009
    };
alpar@400
  1010
    
alpar@400
  1011
    class InEdgeIt : public Edge {
alpar@400
  1012
      friend class NodeSet;
alpar@400
  1013
    public: 
alpar@400
  1014
      InEdgeIt() : Edge() { }
alpar@400
  1015
      InEdgeIt (Invalid i) : Edge(i) { }
alpar@400
  1016
      InEdgeIt(const NodeSet& G,Node v) :Edge() {}
alpar@400
  1017
    };
alpar@400
  1018
alpar@400
  1019
    template <typename T> class NodeMap : public DynMapBase<Node>
alpar@400
  1020
    {
alpar@400
  1021
      std::vector<T> container;
alpar@400
  1022
alpar@400
  1023
    public:
alpar@400
  1024
      typedef T ValueType;
alpar@400
  1025
      typedef Node KeyType;
alpar@400
  1026
alpar@400
  1027
      NodeMap(const NodeSet &_G) :
alpar@400
  1028
	DynMapBase<Node>(_G), container(_G.maxNodeId())
alpar@400
  1029
      {
alpar@400
  1030
	G->dyn_node_maps.push_back(this);
alpar@400
  1031
      }
alpar@400
  1032
      NodeMap(const NodeSet &_G,const T &t) :
alpar@400
  1033
	DynMapBase<Node>(_G), container(_G.maxNodeId(),t)
alpar@400
  1034
      {
alpar@400
  1035
	G->dyn_node_maps.push_back(this);
alpar@400
  1036
      }
alpar@400
  1037
      
alpar@400
  1038
      NodeMap(const NodeMap<T> &m) :
alpar@400
  1039
 	DynMapBase<Node>(*m.G), container(m.container)
alpar@400
  1040
      {
alpar@400
  1041
 	G->dyn_node_maps.push_back(this);
alpar@400
  1042
      }
alpar@400
  1043
alpar@400
  1044
      template<typename TT> friend class NodeMap;
alpar@400
  1045
 
alpar@400
  1046
      ///\todo It can copy between different types.
alpar@400
  1047
      ///
alpar@400
  1048
      template<typename TT> NodeMap(const NodeMap<TT> &m) :
alpar@590
  1049
	DynMapBase<Node>(*m.G), container(m.container.size())
alpar@400
  1050
      {
alpar@400
  1051
	G->dyn_node_maps.push_back(this);
alpar@400
  1052
	typename std::vector<TT>::const_iterator i;
alpar@400
  1053
	for(typename std::vector<TT>::const_iterator i=m.container.begin();
alpar@400
  1054
	    i!=m.container.end();
alpar@400
  1055
	    i++)
alpar@400
  1056
	  container.push_back(*i);
alpar@400
  1057
      }
alpar@400
  1058
      ~NodeMap()
alpar@400
  1059
      {
alpar@400
  1060
	if(G) {
alpar@400
  1061
	  std::vector<DynMapBase<Node>* >::iterator i;
alpar@400
  1062
	  for(i=G->dyn_node_maps.begin();
alpar@400
  1063
	      i!=G->dyn_node_maps.end() && *i!=this; ++i) ;
alpar@400
  1064
	  //if(*i==this) G->dyn_node_maps.erase(i); //FIXME: Way too slow...
alpar@400
  1065
	  //A better way to do that: (Is this really important?)
alpar@400
  1066
	  if(*i==this) {
alpar@400
  1067
	    *i=G->dyn_node_maps.back();
alpar@400
  1068
	    G->dyn_node_maps.pop_back();
alpar@400
  1069
	  }
alpar@400
  1070
	}
alpar@400
  1071
      }
alpar@400
  1072
alpar@400
  1073
      void add(const Node k) 
alpar@400
  1074
      {
alpar@400
  1075
	if(k.n>=int(container.size())) container.resize(k.n+1);
alpar@400
  1076
      }
alpar@400
  1077
alpar@400
  1078
      void erase(const Node) { }
alpar@400
  1079
      
alpar@400
  1080
      void set(Node n, T a) { container[n.n]=a; }
alpar@400
  1081
      //'T& operator[](Node n)' would be wrong here
alpar@400
  1082
      typename std::vector<T>::reference
alpar@400
  1083
      operator[](Node n) { return container[n.n]; }
alpar@400
  1084
      //'const T& operator[](Node n)' would be wrong here
alpar@400
  1085
      typename std::vector<T>::const_reference 
alpar@400
  1086
      operator[](Node n) const { return container[n.n]; }
alpar@400
  1087
alpar@400
  1088
      ///\warning There is no safety check at all!
alpar@400
  1089
      ///Using operator = between maps attached to different graph may
alpar@400
  1090
      ///cause serious problem.
alpar@400
  1091
      ///\todo Is this really so?
alpar@400
  1092
      ///\todo It can copy between different types.
alpar@400
  1093
      const NodeMap<T>& operator=(const NodeMap<T> &m)
alpar@400
  1094
      {
alpar@400
  1095
	container = m.container;
alpar@400
  1096
	return *this;
alpar@400
  1097
      }
alpar@400
  1098
      template<typename TT>
alpar@400
  1099
      const NodeMap<T>& operator=(const NodeMap<TT> &m)
alpar@400
  1100
      {
alpar@531
  1101
	std::copy(m.container.begin(), m.container.end(), container.begin());
alpar@400
  1102
	return *this;
alpar@400
  1103
      }
alpar@400
  1104
      
alpar@400
  1105
      void update() {}    //Useless for Dynamic Maps
alpar@400
  1106
      void update(T a) {}  //Useless for Dynamic Maps
alpar@400
  1107
    };
alpar@400
  1108
    
alpar@400
  1109
    template <typename T> class EdgeMap
alpar@400
  1110
    {
alpar@400
  1111
    public:
alpar@400
  1112
      typedef T ValueType;
alpar@400
  1113
      typedef Edge KeyType;
alpar@400
  1114
alpar@400
  1115
      EdgeMap(const NodeSet &) { }
alpar@400
  1116
      EdgeMap(const NodeSet &,const T &) { }
alpar@400
  1117
      EdgeMap(const EdgeMap<T> &) { }
alpar@400
  1118
      //      template<typename TT> friend class EdgeMap;
alpar@400
  1119
alpar@400
  1120
      ///\todo It can copy between different types.
alpar@400
  1121
      ///
alpar@400
  1122
      template<typename TT> EdgeMap(const EdgeMap<TT> &) { }
alpar@400
  1123
      ~EdgeMap() { }
alpar@400
  1124
alpar@400
  1125
      void add(const Edge  ) { }
alpar@400
  1126
      void erase(const Edge) { }
alpar@400
  1127
      
alpar@400
  1128
      void set(Edge, T) { }
alpar@400
  1129
      //T get(Edge n) const { return container[n.n]; }
alpar@400
  1130
      ValueType &operator[](Edge) { return *((T*)(NULL)); }
alpar@400
  1131
      const ValueType &operator[](Edge) const { return *((T*)(NULL)); }
alpar@400
  1132
alpar@400
  1133
      const EdgeMap<T>& operator=(const EdgeMap<T> &) { return *this; }
alpar@400
  1134
    
alpar@400
  1135
      template<typename TT>
alpar@400
  1136
      const EdgeMap<T>& operator=(const EdgeMap<TT> &m) { return *this; }
alpar@400
  1137
      
alpar@400
  1138
      void update() {}
alpar@400
  1139
      void update(T a) {}
alpar@400
  1140
    };
alpar@400
  1141
  };
alpar@400
  1142
alpar@400
  1143
alpar@400
  1144
alpar@401
  1145
  ///Graph structure using a node set of another graph.
alpar@401
  1146
alpar@401
  1147
  ///This structure can be used to establish another graph over a node set
alpar@401
  1148
  /// of an existing one. The node iterator will go through the nodes of the
alpar@401
  1149
  /// original graph, and the NodeMap's of both graphs will convert to
alpar@401
  1150
  /// each other.
alpar@401
  1151
  ///
alpar@404
  1152
  ///\warning Adding or deleting nodes from the graph is not safe if an
alpar@404
  1153
  ///\ref EdgeSet is currently attached to it!
alpar@404
  1154
  ///
alpar@404
  1155
  ///\todo Make it possible to add/delete edges from the base graph
alpar@404
  1156
  ///(and from \ref EdgeSet, as well)
alpar@404
  1157
  ///
alpar@401
  1158
  ///\param GG The type of the graph which shares its node set with this class.
alpar@401
  1159
  ///Its interface must conform with \ref GraphSkeleton.
alpar@400
  1160
  ///
alpar@400
  1161
  ///It conforms to the graph interface documented under
alpar@400
  1162
  ///the description of \ref GraphSkeleton.
alpar@400
  1163
  ///\sa \ref GraphSkeleton.
alpar@401
  1164
  ///\sa \ref NodeSet.
alpar@400
  1165
  template<typename GG>
alpar@400
  1166
  class EdgeSet {
alpar@400
  1167
alpar@400
  1168
    typedef GG NodeGraphType;
alpar@400
  1169
alpar@400
  1170
    NodeGraphType &G;
alpar@400
  1171
alpar@515
  1172
  public:
alpar@400
  1173
    class Node;
alpar@705
  1174
    class Edge;
alpar@705
  1175
    class OutEdgeIt;
alpar@705
  1176
    class InEdgeIt;
alpar@705
  1177
    class SymEdge;
alpar@531
  1178
    int id(Node v) const; 
alpar@531
  1179
alpar@531
  1180
    class Node : public NodeGraphType::Node {
alpar@531
  1181
      friend class EdgeSet;
alpar@531
  1182
      //      template <typename T> friend class NodeMap;
alpar@531
  1183
      
alpar@531
  1184
      friend class Edge;
alpar@531
  1185
      friend class OutEdgeIt;
alpar@531
  1186
      friend class InEdgeIt;
alpar@531
  1187
      friend class SymEdge;
alpar@531
  1188
alpar@531
  1189
    public:
alpar@531
  1190
      friend int EdgeSet::id(Node v) const; 
alpar@531
  1191
      //      Node(int nn) {n=nn;}
alpar@531
  1192
    public:
alpar@531
  1193
      Node() : NodeGraphType::Node() {}
alpar@531
  1194
      Node (Invalid i) : NodeGraphType::Node(i) {}
alpar@531
  1195
      Node(const typename NodeGraphType::Node &n) : NodeGraphType::Node(n) {}
alpar@531
  1196
    };
alpar@531
  1197
    
alpar@531
  1198
    class NodeIt : public NodeGraphType::NodeIt {
alpar@531
  1199
      friend class EdgeSet;
alpar@531
  1200
    public:
alpar@531
  1201
      NodeIt() : NodeGraphType::NodeIt() { }
alpar@531
  1202
      NodeIt (Invalid i) : NodeGraphType::NodeIt(i) {}
alpar@531
  1203
      NodeIt(const EdgeSet& _G) : NodeGraphType::NodeIt(_G.G) { }
alpar@531
  1204
      NodeIt(const typename NodeGraphType::NodeIt &n)
alpar@531
  1205
	: NodeGraphType::NodeIt(n) {}
alpar@579
  1206
      ///\todo Undocumented conversion Node -\> NodeIt.
alpar@579
  1207
      NodeIt(const EdgeSet& _G, const Node &n)
alpar@579
  1208
	: NodeGraphType::NodeIt(_G.G,n) { }
alpar@579
  1209
alpar@531
  1210
      operator Node() { return Node(*this);}
alpar@531
  1211
    };
alpar@515
  1212
alpar@515
  1213
  private:
alpar@400
  1214
    //Edges are double linked.
alpar@400
  1215
    //The free edges are only single linked using the "next_in" field.
alpar@400
  1216
    struct NodeT 
alpar@400
  1217
    {
alpar@400
  1218
      int first_in,first_out;
alpar@400
  1219
      NodeT() : first_in(-1), first_out(-1) { }
alpar@400
  1220
    };
alpar@400
  1221
alpar@400
  1222
    struct EdgeT 
alpar@400
  1223
    {
alpar@400
  1224
      Node head, tail;
alpar@400
  1225
      int prev_in, prev_out;
alpar@400
  1226
      int next_in, next_out;
alpar@400
  1227
    };
alpar@400
  1228
alpar@400
  1229
    
alpar@515
  1230
    typename NodeGraphType::template NodeMap<NodeT> nodes;
alpar@400
  1231
    
alpar@400
  1232
    std::vector<EdgeT> edges;
alpar@400
  1233
    //The first free edge
alpar@400
  1234
    int first_free_edge;
alpar@400
  1235
    
alpar@400
  1236
  protected:
alpar@400
  1237
    
alpar@400
  1238
    template <typename Key> class DynMapBase
alpar@400
  1239
    {
alpar@400
  1240
    protected:
alpar@400
  1241
      const EdgeSet* G; 
alpar@400
  1242
    public:
alpar@515
  1243
      virtual void add(const Key k) = 0;
alpar@515
  1244
      virtual void erase(const Key k) = 0;
alpar@400
  1245
      DynMapBase(const EdgeSet &_G) : G(&_G) {}
alpar@400
  1246
      virtual ~DynMapBase() {}
alpar@400
  1247
      friend class EdgeSet;
alpar@400
  1248
    };
alpar@400
  1249
    
alpar@400
  1250
  public:
alpar@400
  1251
    //template <typename T> class NodeMap;
alpar@400
  1252
    template <typename T> class EdgeMap;
alpar@400
  1253
    
alpar@400
  1254
    class Node;
alpar@400
  1255
    class Edge;
alpar@400
  1256
alpar@400
  1257
    //  protected:
alpar@400
  1258
    // HELPME:
alpar@400
  1259
  protected:
alpar@400
  1260
    // mutable std::vector<DynMapBase<Node> * > dyn_node_maps;
alpar@400
  1261
    ///\bug It must be public because of SymEdgeMap.
alpar@400
  1262
    ///
alpar@400
  1263
    mutable std::vector<DynMapBase<Edge> * > dyn_edge_maps;
alpar@400
  1264
    
alpar@400
  1265
  public:
alpar@400
  1266
alpar@400
  1267
    class NodeIt;
alpar@400
  1268
    class EdgeIt;
alpar@400
  1269
    class OutEdgeIt;
alpar@400
  1270
    class InEdgeIt;
alpar@400
  1271
    
alpar@400
  1272
    template <typename T> class NodeMap;
alpar@400
  1273
    template <typename T> class EdgeMap;
alpar@400
  1274
    
alpar@400
  1275
  public:
alpar@400
  1276
alpar@408
  1277
    ///Constructor
alpar@408
  1278
    
alpar@408
  1279
    ///Construates a new graph based on the nodeset of an existing one.
alpar@408
  1280
    ///\param _G the base graph.
alpar@408
  1281
    ///\todo It looks like a copy constructor, but it isn't.
alpar@401
  1282
    EdgeSet(NodeGraphType &_G) : G(_G),
alpar@401
  1283
				 nodes(_G), edges(),
alpar@401
  1284
				 first_free_edge(-1) { }
alpar@408
  1285
    ///Copy constructor
alpar@408
  1286
alpar@408
  1287
    ///Makes a copy of an EdgeSet.
alpar@408
  1288
    ///It will be based on the same graph.
alpar@400
  1289
    EdgeSet(const EdgeSet &_g) : G(_g.G), nodes(_g.G), edges(_g.edges),
alpar@401
  1290
				 first_free_edge(_g.first_free_edge) { }
alpar@400
  1291
    
alpar@400
  1292
    ~EdgeSet()
alpar@400
  1293
    {
alpar@400
  1294
      // for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
alpar@400
  1295
      //  i!=dyn_node_maps.end(); ++i) (**i).G=NULL;
alpar@400
  1296
      for(typename std::vector<DynMapBase<Edge> * >::iterator
alpar@400
  1297
	    i=dyn_edge_maps.begin();
alpar@400
  1298
	  i!=dyn_edge_maps.end(); ++i) (**i).G=NULL;
alpar@400
  1299
    }
alpar@400
  1300
alpar@400
  1301
    int nodeNum() const { return G.nodeNum(); }  //FIXME: What is this?
alpar@400
  1302
    int edgeNum() const { return edges.size(); }  //FIXME: What is this?
alpar@400
  1303
alpar@400
  1304
    ///\bug This function does something different than
alpar@400
  1305
    ///its name would suggests...
alpar@400
  1306
    int maxNodeId() const { return G.maxNodeId(); }  //FIXME: What is this?
alpar@400
  1307
    ///\bug This function does something different than
alpar@400
  1308
    ///its name would suggests...
alpar@400
  1309
    int maxEdgeId() const { return edges.size(); }  //FIXME: What is this?
alpar@400
  1310
alpar@400
  1311
    Node tail(Edge e) const { return edges[e.n].tail; }
alpar@400
  1312
    Node head(Edge e) const { return edges[e.n].head; }
alpar@400
  1313
alpar@400
  1314
    Node aNode(OutEdgeIt e) const { return edges[e.n].tail; }
alpar@400
  1315
    Node aNode(InEdgeIt e) const { return edges[e.n].head; }
alpar@400
  1316
alpar@400
  1317
    Node bNode(OutEdgeIt e) const { return edges[e.n].head; }
alpar@400
  1318
    Node bNode(InEdgeIt e) const { return edges[e.n].tail; }
alpar@400
  1319
alpar@400
  1320
    NodeIt& first(NodeIt& v) const { 
alpar@400
  1321
      v=NodeIt(*this); return v; }
alpar@400
  1322
    EdgeIt& first(EdgeIt& e) const { 
alpar@400
  1323
      e=EdgeIt(*this); return e; }
alpar@400
  1324
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
alpar@400
  1325
      e=OutEdgeIt(*this,v); return e; }
alpar@400
  1326
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
alpar@400
  1327
      e=InEdgeIt(*this,v); return e; }
alpar@400
  1328
alpar@400
  1329
//     template< typename It >
alpar@400
  1330
//     It first() const { It e; first(e); return e; }
alpar@400
  1331
alpar@400
  1332
//     template< typename It >
alpar@400
  1333
//     It first(Node v) const { It e; first(e,v); return e; }
alpar@400
  1334
alpar@400
  1335
    bool valid(Edge e) const { return e.n!=-1; }
alpar@400
  1336
    bool valid(Node n) const { return G.valid(n); }
alpar@400
  1337
    
alpar@400
  1338
    void setInvalid(Edge &e) { e.n=-1; }
alpar@400
  1339
    void setInvalid(Node &n) { G.setInvalid(n); }
alpar@400
  1340
    
alpar@400
  1341
    template <typename It> It getNext(It it) const
alpar@400
  1342
    { It tmp(it); return next(tmp); }
alpar@400
  1343
alpar@400
  1344
    NodeIt& next(NodeIt& it) const { G.next(it); return it; }
alpar@400
  1345
    OutEdgeIt& next(OutEdgeIt& it) const
alpar@400
  1346
    { it.n=edges[it.n].next_out; return it; }
alpar@400
  1347
    InEdgeIt& next(InEdgeIt& it) const
alpar@400
  1348
    { it.n=edges[it.n].next_in; return it; }
alpar@400
  1349
    EdgeIt& next(EdgeIt& it) const {
alpar@400
  1350
      if(edges[it.n].next_in!=-1) { 
alpar@400
  1351
	it.n=edges[it.n].next_in;
alpar@400
  1352
      }
alpar@400
  1353
      else {
alpar@579
  1354
	NodeIt n(*this,edges[it.n].head);
alpar@579
  1355
	for(n=next(n);
alpar@503
  1356
	    valid(n) && nodes[n].first_in == -1;
alpar@503
  1357
	    next(n)) ;
alpar@503
  1358
	it.n = (valid(n))?-1:nodes[n].first_in;
alpar@400
  1359
      }
alpar@400
  1360
      return it;
alpar@400
  1361
    }
alpar@400
  1362
alpar@400
  1363
    int id(Edge e) const { return e.n; }
alpar@400
  1364
alpar@400
  1365
    /// Adds a new node to the graph.
alpar@579
  1366
    Node addNode() { return G.addNode(); }
alpar@400
  1367
    
alpar@400
  1368
    Edge addEdge(Node u, Node v) {
alpar@400
  1369
      int n;
alpar@400
  1370
      
alpar@400
  1371
      if(first_free_edge==-1)
alpar@400
  1372
	{
alpar@400
  1373
	  n = edges.size();
alpar@400
  1374
	  edges.push_back(EdgeT());
alpar@400
  1375
	}
alpar@400
  1376
      else {
alpar@400
  1377
	n = first_free_edge;
alpar@400
  1378
	first_free_edge = edges[n].next_in;
alpar@400
  1379
      }
alpar@400
  1380
      
alpar@401
  1381
      edges[n].tail = u; edges[n].head = v;
alpar@400
  1382
alpar@401
  1383
      edges[n].next_out = nodes[u].first_out;
alpar@401
  1384
      if(nodes[u].first_out != -1) edges[nodes[u].first_out].prev_out = n;
alpar@401
  1385
      edges[n].next_in = nodes[v].first_in;
alpar@401
  1386
      if(nodes[v].first_in != -1) edges[nodes[v].first_in].prev_in = n;
alpar@400
  1387
      edges[n].prev_in = edges[n].prev_out = -1;
alpar@400
  1388
	
alpar@401
  1389
      nodes[u].first_out = nodes[v].first_in = n;
alpar@400
  1390
alpar@400
  1391
      Edge e; e.n=n;
alpar@400
  1392
alpar@400
  1393
      //Update dynamic maps
alpar@400
  1394
      for(typename std::vector<DynMapBase<Edge> * >::iterator
alpar@400
  1395
	    i=dyn_edge_maps.begin();
alpar@400
  1396
	  i!=dyn_edge_maps.end(); ++i) (**i).add(e);
alpar@400
  1397
alpar@400
  1398
      return e;
alpar@400
  1399
    }
alpar@400
  1400
alpar@400
  1401
  private:
alpar@400
  1402
    void eraseEdge(int n) {
alpar@400
  1403
      
alpar@400
  1404
      if(edges[n].next_in!=-1)
alpar@400
  1405
	edges[edges[n].next_in].prev_in = edges[n].prev_in;
alpar@400
  1406
      if(edges[n].prev_in!=-1)
alpar@400
  1407
	edges[edges[n].prev_in].next_in = edges[n].next_in;
alpar@400
  1408
      else nodes[edges[n].head].first_in = edges[n].next_in;
alpar@400
  1409
      
alpar@400
  1410
      if(edges[n].next_out!=-1)
alpar@400
  1411
	edges[edges[n].next_out].prev_out = edges[n].prev_out;
alpar@400
  1412
      if(edges[n].prev_out!=-1)
alpar@400
  1413
	edges[edges[n].prev_out].next_out = edges[n].next_out;
alpar@400
  1414
      else nodes[edges[n].tail].first_out = edges[n].next_out;
alpar@400
  1415
      
alpar@400
  1416
      edges[n].next_in = first_free_edge;
alpar@400
  1417
      first_free_edge = -1;      
alpar@400
  1418
alpar@400
  1419
      //Update dynamic maps
alpar@400
  1420
      Edge e; e.n=n;
alpar@400
  1421
      for(typename std::vector<DynMapBase<Edge> * >::iterator
alpar@400
  1422
	    i=dyn_edge_maps.begin();
alpar@400
  1423
	  i!=dyn_edge_maps.end(); ++i) (**i).erase(e);
alpar@400
  1424
    }
alpar@400
  1425
      
alpar@400
  1426
  public:
alpar@400
  1427
alpar@400
  1428
//     void erase(Node nn) {
alpar@400
  1429
//       int n=nn.n;
alpar@400
  1430
//       int m;
alpar@400
  1431
//       while((m=nodes[n].first_in)!=-1) eraseEdge(m);
alpar@400
  1432
//       while((m=nodes[n].first_out)!=-1) eraseEdge(m);
alpar@400
  1433
//     }
alpar@400
  1434
    
alpar@400
  1435
    void erase(Edge e) { eraseEdge(e.n); }
alpar@400
  1436
alpar@579
  1437
    ///Clear all edges. (Doesn't clear the nodes!)
alpar@579
  1438
    void clear() {
alpar@579
  1439
      edges.clear();
alpar@579
  1440
      first_free_edge=-1;
alpar@579
  1441
    }
alpar@579
  1442
alpar@579
  1443
alpar@400
  1444
//     //\bug Dynamic maps must be updated!
alpar@400
  1445
//     //
alpar@400
  1446
//     void clear() {
alpar@400
  1447
//       nodes.clear();edges.clear();
alpar@400
  1448
//       first_node=first_free_node=first_free_edge=-1;
alpar@400
  1449
//     }
alpar@400
  1450
alpar@579
  1451
  public:
alpar@579
  1452
    template <typename T> class EdgeMap;
alpar@579
  1453
    
alpar@579
  1454
    ///
alpar@400
  1455
    class Edge {
alpar@579
  1456
    public:
alpar@400
  1457
      friend class EdgeSet;
alpar@400
  1458
      template <typename T> friend class EdgeMap;
alpar@400
  1459
alpar@400
  1460
      friend class Node;
alpar@400
  1461
      friend class NodeIt;
alpar@579
  1462
    public:
alpar@579
  1463
      ///\bug It shoud be at least protected
alpar@579
  1464
      ///
alpar@579
  1465
      int n;
alpar@400
  1466
    protected:
alpar@400
  1467
      friend int EdgeSet::id(Edge e) const;
alpar@400
  1468
alpar@400
  1469
      Edge(int nn) {n=nn;}
alpar@400
  1470
    public:
alpar@400
  1471
      Edge() { }
alpar@400
  1472
      Edge (Invalid) { n=-1; }
alpar@400
  1473
      bool operator==(const Edge i) const {return n==i.n;}
alpar@400
  1474
      bool operator!=(const Edge i) const {return n!=i.n;}
alpar@400
  1475
      bool operator<(const Edge i) const {return n<i.n;}
alpar@400
  1476
      ///\bug This is a workaround until somebody tells me how to
alpar@400
  1477
      ///make class \c SymEdgeSet::SymEdgeMap friend of Edge
alpar@400
  1478
      int &idref() {return n;}
alpar@400
  1479
      const int &idref() const {return n;}
alpar@400
  1480
    };
alpar@400
  1481
    
alpar@400
  1482
    class EdgeIt : public Edge {
alpar@400
  1483
      friend class EdgeSet;
alpar@579
  1484
      template <typename T> friend class EdgeMap;
alpar@579
  1485
    
alpar@579
  1486
      
alpar@400
  1487
    public:
alpar@400
  1488
      EdgeIt(const EdgeSet& G) : Edge() {
alpar@503
  1489
	//      	typename NodeGraphType::Node m;
alpar@503
  1490
        NodeIt m;
alpar@400
  1491
	for(G.first(m);
alpar@503
  1492
	    G.valid(m) && G.nodes[m].first_in == -1;  G.next(m));
alpar@515
  1493
	//AJJAJ! This is a non sense!!!!!!!
alpar@515
  1494
	this->n = G.valid(m)?-1:G.nodes[m].first_in;
alpar@400
  1495
      }
alpar@400
  1496
      EdgeIt (Invalid i) : Edge(i) { }
alpar@400
  1497
      EdgeIt() : Edge() { }
alpar@400
  1498
      ///\bug This is a workaround until somebody tells me how to
alpar@400
  1499
      ///make class \c SymEdgeSet::SymEdgeMap friend of Edge
alpar@515
  1500
      int &idref() {return this->n;}
alpar@400
  1501
    };
alpar@400
  1502
    
alpar@400
  1503
    class OutEdgeIt : public Edge {
alpar@400
  1504
      friend class EdgeSet;
alpar@400
  1505
    public: 
alpar@400
  1506
      OutEdgeIt() : Edge() { }
alpar@400
  1507
      OutEdgeIt (Invalid i) : Edge(i) { }
alpar@400
  1508
alpar@579
  1509
      OutEdgeIt(const EdgeSet& G,const Node v) : Edge(G.nodes[v].first_out) { }
alpar@400
  1510
    };
alpar@400
  1511
    
alpar@400
  1512
    class InEdgeIt : public Edge {
alpar@400
  1513
      friend class EdgeSet;
alpar@400
  1514
    public: 
alpar@400
  1515
      InEdgeIt() : Edge() { }
alpar@400
  1516
      InEdgeIt (Invalid i) : Edge(i) { }
alpar@579
  1517
      InEdgeIt(const EdgeSet& G,Node v) :Edge(G.nodes[v].first_in) { }
alpar@400
  1518
    };
alpar@400
  1519
alpar@515
  1520
    template <typename T> class NodeMap : 
alpar@515
  1521
      public NodeGraphType::template NodeMap<T>
alpar@400
  1522
    {
alpar@579
  1523
      //This is a must, the constructors need it.
alpar@579
  1524
      typedef typename NodeGraphType::template NodeMap<T> ParentNodeMap;
alpar@400
  1525
    public:
alpar@579
  1526
      NodeMap(const EdgeSet &_G) : ParentNodeMap(_G.G) { }
alpar@579
  1527
      NodeMap(const EdgeSet &_G,const T &t) : ParentNodeMap(_G.G,t) { }
alpar@400
  1528
      //It is unnecessary
alpar@515
  1529
      NodeMap(const typename NodeGraphType::template NodeMap<T> &m) :
alpar@579
  1530
	ParentNodeMap(m) { }
alpar@400
  1531
alpar@400
  1532
      ///\todo It can copy between different types.
alpar@400
  1533
      ///
alpar@401
  1534
      template<typename TT>
alpar@515
  1535
      NodeMap(const typename NodeGraphType::template NodeMap<TT> &m)
alpar@579
  1536
	: ParentNodeMap(m) { }
alpar@400
  1537
    };
alpar@400
  1538
    
alpar@579
  1539
    ///
alpar@400
  1540
    template <typename T> class EdgeMap : public DynMapBase<Edge>
alpar@400
  1541
    {
alpar@579
  1542
    protected:
alpar@579
  1543
    public:
alpar@579
  1544
      ///\bug It should be at least protected
alpar@579
  1545
      ///
alpar@400
  1546
      std::vector<T> container;
alpar@400
  1547
alpar@400
  1548
    public:
alpar@400
  1549
      typedef T ValueType;
alpar@400
  1550
      typedef Edge KeyType;
alpar@400
  1551
alpar@400
  1552
      EdgeMap(const EdgeSet &_G) :
alpar@400
  1553
	DynMapBase<Edge>(_G), container(_G.maxEdgeId())
alpar@400
  1554
      {
alpar@400
  1555
	//FIXME: What if there are empty Id's?
alpar@400
  1556
	//FIXME: Can I use 'this' in a constructor?
alpar@400
  1557
	G->dyn_edge_maps.push_back(this);
alpar@400
  1558
      }
alpar@400
  1559
      EdgeMap(const EdgeSet &_G,const T &t) :
alpar@400
  1560
	DynMapBase<Edge>(_G), container(_G.maxEdgeId(),t)
alpar@400
  1561
      {
alpar@400
  1562
	G->dyn_edge_maps.push_back(this);
alpar@400
  1563
      } 
alpar@400
  1564
      EdgeMap(const EdgeMap<T> &m) :
alpar@400
  1565
 	DynMapBase<Edge>(*m.G), container(m.container)
alpar@400
  1566
      {
alpar@503
  1567
 	G->dyn_edge_maps.push_back(this);
alpar@400
  1568
      }
alpar@400
  1569
alpar@400
  1570
      ///\todo It can copy between different types.
alpar@400
  1571
      ///
alpar@400
  1572
      template<typename TT> EdgeMap(const EdgeMap<TT> &m) :
alpar@590
  1573
	DynMapBase<Edge>(*m.G), container(m.container.size())
alpar@400
  1574
      {
alpar@503
  1575
	G->dyn_edge_maps.push_back(this);
alpar@400
  1576
	typename std::vector<TT>::const_iterator i;
alpar@400
  1577
	for(typename std::vector<TT>::const_iterator i=m.container.begin();
alpar@400
  1578
	    i!=m.container.end();
alpar@400
  1579
	    i++)
alpar@400
  1580
	  container.push_back(*i);
alpar@400
  1581
      }
alpar@400
  1582
      ~EdgeMap()
alpar@400
  1583
      {
alpar@400
  1584
	if(G) {
alpar@400
  1585
	  typename std::vector<DynMapBase<Edge>* >::iterator i;
alpar@400
  1586
	  for(i=G->dyn_edge_maps.begin();
alpar@400
  1587
	      i!=G->dyn_edge_maps.end() && *i!=this; ++i) ;
alpar@400
  1588
	  //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow...
alpar@400
  1589
	  //A better way to do that: (Is this really important?)
alpar@400
  1590
	  if(*i==this) {
alpar@400
  1591
	    *i=G->dyn_edge_maps.back();
alpar@400
  1592
	    G->dyn_edge_maps.pop_back();
alpar@400
  1593
	  }
alpar@400
  1594
	}
alpar@400
  1595
      }
alpar@400
  1596
      
alpar@400
  1597
      void add(const Edge k) 
alpar@400
  1598
      {
alpar@400
  1599
	if(k.n>=int(container.size())) container.resize(k.n+1);
alpar@400
  1600
      }
alpar@400
  1601
      void erase(const Edge) { }
alpar@400
  1602
      
alpar@579
  1603
      ///\bug This doesn't work. Why?
alpar@579
  1604
      ///      void set(Edge n, T a) { container[n.n]=a; }
alpar@579
  1605
      void set(Edge n, T a) { container[G->id(n)]=a; }
alpar@400
  1606
      //T get(Edge n) const { return container[n.n]; }
alpar@400
  1607
      typename std::vector<T>::reference
alpar@579
  1608
      ///\bug This doesn't work. Why?
alpar@579
  1609
      ///      operator[](Edge n) { return container[n.n]; }
alpar@579
  1610
      operator[](Edge n) { return container[G->id(n)]; }
alpar@400
  1611
      typename std::vector<T>::const_reference
alpar@579
  1612
      ///\bug This doesn't work. Why?
alpar@579
  1613
      ///      operator[](Edge n) const { return container[n.n]; }
alpar@579
  1614
      operator[](Edge n) const { return container[G->id(n)]; }
alpar@400
  1615
alpar@400
  1616
      ///\warning There is no safety check at all!
alpar@400
  1617
      ///Using operator = between maps attached to different graph may
alpar@400
  1618
      ///cause serious problem.
alpar@400
  1619
      ///\todo Is this really so?
alpar@400
  1620
      ///\todo It can copy between different types.
alpar@400
  1621
      const EdgeMap<T>& operator=(const EdgeMap<T> &m)
alpar@400
  1622
      {
alpar@400
  1623
	container = m.container;
alpar@400
  1624
	return *this;
alpar@400
  1625
      }
alpar@579
  1626
      
alpar@579
  1627
      template<typename TT> friend class EdgeMap;
alpar@579
  1628
alpar@400
  1629
      template<typename TT>
alpar@400
  1630
      const EdgeMap<T>& operator=(const EdgeMap<TT> &m)
alpar@400
  1631
      {
alpar@531
  1632
	std::copy(m.container.begin(), m.container.end(), container.begin());
alpar@400
  1633
	return *this;
alpar@400
  1634
      }
alpar@400
  1635
      
alpar@400
  1636
      void update() {}    //Useless for DynMaps
alpar@400
  1637
      void update(T a) {}  //Useless for DynMaps
alpar@400
  1638
    };
alpar@400
  1639
alpar@400
  1640
  };
alpar@406
  1641
alpar@579
  1642
  template<typename GG>
alpar@579
  1643
  inline int EdgeSet<GG>::id(Node v) const { return G.id(v); }
alpar@531
  1644
alpar@406
  1645
/// @}  
alpar@406
  1646
alpar@395
  1647
} //namespace hugo
alpar@395
  1648
alpar@405
  1649
#endif //HUGO_LIST_GRAPH_H