src/hugo/list_graph.h
author alpar
Tue, 07 Sep 2004 10:56:37 +0000
changeset 814 d2d747fe1db3
parent 798 6d1abeb62dd3
child 822 88226d9fe821
permissions -rw-r--r--
Improve docs.
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>
deba@782
    11
#include <climits>
alpar@395
    12
ladanyi@542
    13
#include <hugo/invalid.h>
alpar@395
    14
deba@782
    15
#include <hugo/map_registry.h>
deba@798
    16
#include <hugo/default_map_factory.h>
deba@782
    17
deba@782
    18
#include <hugo/sym_map_factory.h>
deba@782
    19
deba@782
    20
#include <hugo/map_defines.h>
deba@782
    21
deba@782
    22
alpar@395
    23
namespace hugo {
alpar@395
    24
alpar@406
    25
/// \addtogroup graphs
alpar@406
    26
/// @{
alpar@406
    27
deba@782
    28
//  class SymListGraph;
alpar@395
    29
alpar@401
    30
  ///A list graph class.
alpar@395
    31
alpar@397
    32
  ///This is a simple and fast erasable graph implementation.
alpar@397
    33
  ///
alpar@395
    34
  ///It conforms to the graph interface documented under
alpar@395
    35
  ///the description of \ref GraphSkeleton.
alpar@395
    36
  ///\sa \ref GraphSkeleton.
alpar@397
    37
  class ListGraph {
alpar@395
    38
alpar@397
    39
    //Nodes are double linked.
alpar@397
    40
    //The free nodes are only single linked using the "next" field.
alpar@395
    41
    struct NodeT 
alpar@395
    42
    {
alpar@397
    43
      int first_in,first_out;
alpar@397
    44
      int prev, next;
alpar@397
    45
      //      NodeT() {}
alpar@395
    46
    };
alpar@397
    47
    //Edges are double linked.
alpar@397
    48
    //The free edges are only single linked using the "next_in" field.
alpar@395
    49
    struct EdgeT 
alpar@395
    50
    {
alpar@397
    51
      int head, tail;
alpar@397
    52
      int prev_in, prev_out;
alpar@397
    53
      int next_in, next_out;
alpar@395
    54
      //FIXME: is this necessary?
alpar@397
    55
      //      EdgeT() : next_in(-1), next_out(-1) prev_in(-1), prev_out(-1) {}  
alpar@395
    56
    };
alpar@395
    57
alpar@395
    58
    std::vector<NodeT> nodes;
alpar@397
    59
    //The first node
alpar@397
    60
    int first_node;
alpar@397
    61
    //The first free node
alpar@397
    62
    int first_free_node;
alpar@395
    63
    std::vector<EdgeT> edges;
alpar@397
    64
    //The first free edge
alpar@397
    65
    int first_free_edge;
alpar@395
    66
    
deba@782
    67
  public:
alpar@395
    68
    
deba@782
    69
    typedef ListGraph Graph;
alpar@397
    70
    
alpar@395
    71
    class Node;
alpar@395
    72
    class Edge;
alpar@395
    73
alpar@395
    74
    
alpar@395
    75
  public:
alpar@395
    76
alpar@395
    77
    class NodeIt;
alpar@395
    78
    class EdgeIt;
alpar@395
    79
    class OutEdgeIt;
alpar@395
    80
    class InEdgeIt;
deba@782
    81
deba@782
    82
    CREATE_MAP_REGISTRIES;
deba@798
    83
    CREATE_MAPS(DefaultMapFactory);
deba@782
    84
alpar@395
    85
  public:
alpar@395
    86
deba@782
    87
    ListGraph() 
deba@782
    88
      : nodes(), first_node(-1),
deba@782
    89
	first_free_node(-1), edges(), first_free_edge(-1) {}
deba@782
    90
deba@782
    91
    ListGraph(const ListGraph &_g) 
deba@782
    92
      : nodes(_g.nodes), first_node(_g.first_node),
deba@782
    93
	first_free_node(_g.first_free_node), edges(_g.edges),
deba@782
    94
	first_free_edge(_g.first_free_edge) {}
alpar@395
    95
    
alpar@813
    96
    ///Number of nodes.
alpar@813
    97
    int nodeNum() const { return nodes.size(); }
alpar@813
    98
    ///Number of edges.
alpar@813
    99
    int edgeNum() const { return edges.size(); }
alpar@395
   100
alpar@813
   101
    ///Set the expected maximum number of edges.
alpar@695
   102
alpar@695
   103
    ///With this function, it is possible to set the expected number of edges.
alpar@695
   104
    ///The use of this fasten the building of the graph and makes
alpar@695
   105
    ///it possible to avoid the superfluous memory allocation.
alpar@695
   106
    void reserveEdge(int n) { edges.reserve(n); };
alpar@695
   107
    
alpar@813
   108
    /// Maximum node ID.
alpar@813
   109
    
alpar@813
   110
    /// Maximum node ID.
alpar@813
   111
    ///\sa id(Node)
alpar@813
   112
    int maxNodeId() const { return nodes.size()-1; } 
alpar@813
   113
    /// Maximum edge ID.
alpar@813
   114
    
alpar@813
   115
    /// Maximum edge ID.
alpar@813
   116
    ///\sa id(Edge)
alpar@813
   117
    int maxEdgeId() const { return edges.size()-1; }
alpar@395
   118
alpar@395
   119
    Node tail(Edge e) const { return edges[e.n].tail; }
alpar@395
   120
    Node head(Edge e) const { return edges[e.n].head; }
alpar@395
   121
alpar@713
   122
    NodeIt& first(NodeIt& v) const { 
alpar@395
   123
      v=NodeIt(*this); return v; }
alpar@713
   124
    EdgeIt& first(EdgeIt& e) const { 
alpar@395
   125
      e=EdgeIt(*this); return e; }
alpar@713
   126
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
alpar@395
   127
      e=OutEdgeIt(*this,v); return e; }
alpar@713
   128
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
alpar@395
   129
      e=InEdgeIt(*this,v); return e; }
alpar@395
   130
alpar@813
   131
    /// Node ID.
alpar@813
   132
    
alpar@813
   133
    /// The ID of a valid Node is a nonnegative integer not greater than
alpar@813
   134
    /// \ref maxNodeId(). The range of the ID's is not surely continuous
alpar@813
   135
    /// and the greatest node ID can be actually less then \ref maxNodeId().
alpar@813
   136
    ///
alpar@813
   137
    /// The ID of the \ref INVALID node is -1.
alpar@813
   138
    ///\return The ID of the node \c v. 
alpar@713
   139
    static int id(Node v) { return v.n; }
alpar@813
   140
    /// Edge ID.
alpar@813
   141
    
alpar@813
   142
    /// The ID of a valid Edge is a nonnegative integer not greater than
alpar@813
   143
    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
alpar@813
   144
    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
alpar@813
   145
    ///
alpar@813
   146
    /// The ID of the \ref INVALID edge is -1.
alpar@813
   147
    ///\return The ID of the edge \c e. 
alpar@713
   148
    static int id(Edge e) { return e.n; }
alpar@395
   149
alpar@397
   150
    /// Adds a new node to the graph.
alpar@397
   151
alpar@813
   152
    /// \warning It adds the new node to the front of the list.
alpar@397
   153
    /// (i.e. the lastly added node becomes the first.)
alpar@395
   154
    Node addNode() {
alpar@397
   155
      int n;
alpar@397
   156
      
alpar@397
   157
      if(first_free_node==-1)
alpar@397
   158
	{
alpar@397
   159
	  n = nodes.size();
alpar@397
   160
	  nodes.push_back(NodeT());
alpar@397
   161
	}
alpar@397
   162
      else {
alpar@397
   163
	n = first_free_node;
alpar@397
   164
	first_free_node = nodes[n].next;
alpar@397
   165
      }
alpar@397
   166
      
alpar@397
   167
      nodes[n].next = first_node;
alpar@397
   168
      if(first_node != -1) nodes[first_node].prev = n;
alpar@397
   169
      first_node = n;
alpar@397
   170
      nodes[n].prev = -1;
alpar@397
   171
      
alpar@397
   172
      nodes[n].first_in = nodes[n].first_out = -1;
alpar@397
   173
      
alpar@397
   174
      Node nn; nn.n=n;
alpar@395
   175
alpar@397
   176
      //Update dynamic maps
deba@782
   177
      node_maps.add(nn);
alpar@395
   178
alpar@397
   179
      return nn;
alpar@395
   180
    }
alpar@395
   181
    
alpar@395
   182
    Edge addEdge(Node u, Node v) {
alpar@397
   183
      int n;
alpar@397
   184
      
alpar@397
   185
      if(first_free_edge==-1)
alpar@397
   186
	{
alpar@397
   187
	  n = edges.size();
alpar@397
   188
	  edges.push_back(EdgeT());
alpar@397
   189
	}
alpar@397
   190
      else {
alpar@397
   191
	n = first_free_edge;
alpar@397
   192
	first_free_edge = edges[n].next_in;
alpar@397
   193
      }
alpar@397
   194
      
alpar@397
   195
      edges[n].tail = u.n; edges[n].head = v.n;
alpar@395
   196
alpar@397
   197
      edges[n].next_out = nodes[u.n].first_out;
alpar@397
   198
      if(nodes[u.n].first_out != -1) edges[nodes[u.n].first_out].prev_out = n;
alpar@397
   199
      edges[n].next_in = nodes[v.n].first_in;
alpar@397
   200
      if(nodes[v.n].first_in != -1) edges[nodes[v.n].first_in].prev_in = n;
alpar@397
   201
      edges[n].prev_in = edges[n].prev_out = -1;
alpar@397
   202
	
alpar@397
   203
      nodes[u.n].first_out = nodes[v.n].first_in = n;
alpar@397
   204
alpar@397
   205
      Edge e; e.n=n;
alpar@397
   206
alpar@397
   207
      //Update dynamic maps
deba@782
   208
      edge_maps.add(e);
alpar@395
   209
alpar@395
   210
      return e;
alpar@395
   211
    }
alpar@774
   212
    
alpar@774
   213
    /// Finds an edge between two nodes.
alpar@395
   214
alpar@774
   215
    /// Finds an edge from node \c u to node \c v.
alpar@774
   216
    ///
alpar@774
   217
    /// If \c prev is \ref INVALID (this is the default value), then
alpar@774
   218
    /// It finds the first edge from \c u to \c v. Otherwise it looks for
alpar@774
   219
    /// the next edge from \c u to \c v after \c prev.
alpar@774
   220
    /// \return The found edge or INVALID if there is no such an edge.
alpar@774
   221
    Edge findEdge(Node u,Node v, Edge prev = INVALID) 
alpar@774
   222
    {
alpar@774
   223
      int e = (prev.n==-1)? nodes[u.n].first_out : edges[prev.n].next_out;
alpar@774
   224
      while(e!=-1 && edges[e].tail!=v.n) e = edges[e].next_out;
alpar@774
   225
      prev.n=e;
alpar@774
   226
      return prev;
alpar@774
   227
    }
alpar@774
   228
    
alpar@397
   229
  private:
alpar@397
   230
    void eraseEdge(int n) {
alpar@397
   231
      
alpar@397
   232
      if(edges[n].next_in!=-1)
alpar@397
   233
	edges[edges[n].next_in].prev_in = edges[n].prev_in;
alpar@397
   234
      if(edges[n].prev_in!=-1)
alpar@397
   235
	edges[edges[n].prev_in].next_in = edges[n].next_in;
alpar@397
   236
      else nodes[edges[n].head].first_in = edges[n].next_in;
alpar@397
   237
      
alpar@397
   238
      if(edges[n].next_out!=-1)
alpar@397
   239
	edges[edges[n].next_out].prev_out = edges[n].prev_out;
alpar@397
   240
      if(edges[n].prev_out!=-1)
alpar@397
   241
	edges[edges[n].prev_out].next_out = edges[n].next_out;
alpar@397
   242
      else nodes[edges[n].tail].first_out = edges[n].next_out;
alpar@397
   243
      
alpar@397
   244
      edges[n].next_in = first_free_edge;
alpar@695
   245
      first_free_edge = n;      
alpar@397
   246
alpar@397
   247
      //Update dynamic maps
alpar@397
   248
      Edge e; e.n=n;
deba@782
   249
      edge_maps.erase(e);
deba@782
   250
alpar@397
   251
    }
alpar@397
   252
      
alpar@397
   253
  public:
alpar@397
   254
alpar@397
   255
    void erase(Node nn) {
alpar@397
   256
      int n=nn.n;
alpar@397
   257
      
alpar@397
   258
      int m;
alpar@397
   259
      while((m=nodes[n].first_in)!=-1) eraseEdge(m);
alpar@397
   260
      while((m=nodes[n].first_out)!=-1) eraseEdge(m);
alpar@397
   261
alpar@397
   262
      if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
alpar@397
   263
      if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
alpar@397
   264
      else first_node = nodes[n].next;
alpar@397
   265
      
alpar@397
   266
      nodes[n].next = first_free_node;
alpar@397
   267
      first_free_node = n;
alpar@397
   268
alpar@397
   269
      //Update dynamic maps
deba@782
   270
      node_maps.erase(nn);
deba@782
   271
alpar@397
   272
    }
alpar@397
   273
    
alpar@397
   274
    void erase(Edge e) { eraseEdge(e.n); }
alpar@397
   275
alpar@397
   276
    void clear() {
deba@782
   277
      edge_maps.clear();
deba@782
   278
      edges.clear();
deba@782
   279
      node_maps.clear();
deba@782
   280
      nodes.clear();
alpar@397
   281
      first_node=first_free_node=first_free_edge=-1;
alpar@397
   282
    }
alpar@395
   283
alpar@395
   284
    class Node {
alpar@397
   285
      friend class ListGraph;
alpar@395
   286
      template <typename T> friend class NodeMap;
alpar@400
   287
       
alpar@395
   288
      friend class Edge;
alpar@395
   289
      friend class OutEdgeIt;
alpar@395
   290
      friend class InEdgeIt;
alpar@395
   291
      friend class SymEdge;
alpar@395
   292
alpar@395
   293
    protected:
alpar@395
   294
      int n;
alpar@722
   295
      friend int ListGraph::id(Node v); 
alpar@395
   296
      Node(int nn) {n=nn;}
alpar@395
   297
    public:
alpar@395
   298
      Node() {}
alpar@503
   299
      Node (Invalid) { n=-1; }
alpar@395
   300
      bool operator==(const Node i) const {return n==i.n;}
alpar@395
   301
      bool operator!=(const Node i) const {return n!=i.n;}
alpar@395
   302
      bool operator<(const Node i) const {return n<i.n;}
alpar@774
   303
      //      ///Validity check
alpar@774
   304
      //      operator bool() { return n!=-1; }
alpar@395
   305
    };
alpar@395
   306
    
alpar@395
   307
    class NodeIt : public Node {
alpar@774
   308
      const ListGraph *G;
alpar@397
   309
      friend class ListGraph;
alpar@395
   310
    public:
alpar@400
   311
      NodeIt() : Node() { }
alpar@400
   312
      NodeIt(Invalid i) : Node(i) { }
alpar@774
   313
      NodeIt(const ListGraph& _G) : Node(_G.first_node), G(&_G) { }
alpar@579
   314
      ///\todo Undocumented conversion Node -\> NodeIt.
alpar@774
   315
      NodeIt(const ListGraph& _G,Node n) : Node(n), G(&_G) { }
alpar@774
   316
      NodeIt &operator++() {
alpar@774
   317
	n=G->nodes[n].next; 
alpar@774
   318
	return *this; 
alpar@774
   319
      }
alpar@774
   320
      //      ///Validity check
alpar@774
   321
      //      operator bool() { return Node::operator bool(); }      
alpar@395
   322
    };
alpar@395
   323
alpar@395
   324
    class Edge {
alpar@397
   325
      friend class ListGraph;
alpar@395
   326
      template <typename T> friend class EdgeMap;
alpar@395
   327
alpar@397
   328
      //template <typename T> friend class SymListGraph::SymEdgeMap;      
alpar@397
   329
      //friend Edge SymListGraph::opposite(Edge) const;
alpar@395
   330
      
alpar@395
   331
      friend class Node;
alpar@395
   332
      friend class NodeIt;
alpar@395
   333
    protected:
alpar@395
   334
      int n;
alpar@722
   335
      friend int ListGraph::id(Edge e);
alpar@395
   336
alpar@706
   337
    public:
alpar@706
   338
      /// An Edge with id \c n.
alpar@706
   339
alpar@706
   340
      /// \bug It should be
alpar@706
   341
      /// obtained by a member function of the Graph.
alpar@395
   342
      Edge(int nn) {n=nn;}
alpar@706
   343
alpar@395
   344
      Edge() { }
alpar@395
   345
      Edge (Invalid) { n=-1; }
alpar@395
   346
      bool operator==(const Edge i) const {return n==i.n;}
alpar@395
   347
      bool operator!=(const Edge i) const {return n!=i.n;}
alpar@395
   348
      bool operator<(const Edge i) const {return n<i.n;}
alpar@395
   349
      ///\bug This is a workaround until somebody tells me how to
alpar@397
   350
      ///make class \c SymListGraph::SymEdgeMap friend of Edge
alpar@395
   351
      int &idref() {return n;}
alpar@774
   352
      const int &idref() const {return n;} 
alpar@774
   353
      //      ///Validity check
alpar@774
   354
      //      operator bool() { return n!=-1; }
alpar@774
   355
   };
alpar@395
   356
    
alpar@395
   357
    class EdgeIt : public Edge {
alpar@774
   358
      const ListGraph *G;
alpar@397
   359
      friend class ListGraph;
alpar@395
   360
    public:
alpar@774
   361
      EdgeIt(const ListGraph& _G) : Edge(), G(&_G) {
alpar@397
   362
      	int m;
alpar@774
   363
	for(m=_G.first_node;
alpar@774
   364
	    m!=-1 && _G.nodes[m].first_in == -1; m = _G.nodes[m].next);
alpar@774
   365
	n = (m==-1)?-1:_G.nodes[m].first_in;
alpar@397
   366
      }
alpar@395
   367
      EdgeIt (Invalid i) : Edge(i) { }
alpar@774
   368
      EdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
alpar@395
   369
      EdgeIt() : Edge() { }
alpar@395
   370
      ///\bug This is a workaround until somebody tells me how to
alpar@397
   371
      ///make class \c SymListGraph::SymEdgeMap friend of Edge
alpar@395
   372
      int &idref() {return n;}
alpar@774
   373
      EdgeIt &operator++() {
alpar@774
   374
	if(G->edges[n].next_in!=-1) n=G->edges[n].next_in;
alpar@774
   375
	else {
alpar@774
   376
	  int nn;
alpar@774
   377
	  for(nn=G->nodes[G->edges[n].head].next;
alpar@774
   378
	      nn!=-1 && G->nodes[nn].first_in == -1;
alpar@774
   379
	      nn = G->nodes[nn].next) ;
alpar@774
   380
	  n = (nn==-1)?-1:G->nodes[nn].first_in;
alpar@774
   381
	}
alpar@774
   382
	return *this;
alpar@774
   383
      }
alpar@774
   384
      //      ///Validity check
alpar@774
   385
      //      operator bool() { return Edge::operator bool(); }      
alpar@395
   386
    };
alpar@395
   387
    
alpar@395
   388
    class OutEdgeIt : public Edge {
alpar@774
   389
      const ListGraph *G;
alpar@397
   390
      friend class ListGraph;
alpar@395
   391
    public: 
alpar@395
   392
      OutEdgeIt() : Edge() { }
alpar@774
   393
      OutEdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
alpar@395
   394
      OutEdgeIt (Invalid i) : Edge(i) { }
alpar@395
   395
alpar@774
   396
      OutEdgeIt(const ListGraph& _G,const Node v)
alpar@774
   397
	: Edge(_G.nodes[v.n].first_out), G(&_G) {}
alpar@774
   398
      OutEdgeIt &operator++() { n=G->edges[n].next_out; return *this; }
alpar@774
   399
      //      ///Validity check
alpar@774
   400
      //      operator bool() { return Edge::operator bool(); }      
alpar@395
   401
    };
alpar@395
   402
    
alpar@395
   403
    class InEdgeIt : public Edge {
alpar@774
   404
      const ListGraph *G;
alpar@397
   405
      friend class ListGraph;
alpar@395
   406
    public: 
alpar@395
   407
      InEdgeIt() : Edge() { }
alpar@774
   408
      InEdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
alpar@395
   409
      InEdgeIt (Invalid i) : Edge(i) { }
alpar@774
   410
      InEdgeIt(const ListGraph& _G,Node v)
alpar@774
   411
	: Edge(_G.nodes[v.n].first_in), G(&_G) { }
alpar@774
   412
      InEdgeIt &operator++() { n=G->edges[n].next_in; return *this; }
alpar@774
   413
      //      ///Validity check
alpar@774
   414
      //      operator bool() { return Edge::operator bool(); }      
alpar@395
   415
    };
alpar@395
   416
  };
alpar@395
   417
alpar@395
   418
  ///Graph for bidirectional edges.
alpar@395
   419
alpar@395
   420
  ///The purpose of this graph structure is to handle graphs
alpar@395
   421
  ///having bidirectional edges. Here the function \c addEdge(u,v) adds a pair
alpar@395
   422
  ///of oppositely directed edges.
alpar@395
   423
  ///There is a new edge map type called
alpar@397
   424
  ///\ref SymListGraph::SymEdgeMap "SymEdgeMap"
alpar@395
   425
  ///that complements this
alpar@395
   426
  ///feature by
alpar@395
   427
  ///storing shared values for the edge pairs. The usual
alpar@395
   428
  ///\ref GraphSkeleton::EdgeMap "EdgeMap"
alpar@395
   429
  ///can be used
alpar@395
   430
  ///as well.
alpar@395
   431
  ///
alpar@395
   432
  ///The oppositely directed edge can also be obtained easily
alpar@395
   433
  ///using \ref opposite.
alpar@397
   434
  ///
alpar@397
   435
  ///Here erase(Edge) deletes a pair of edges.
alpar@397
   436
  ///
alpar@397
   437
  ///\todo this date structure need some reconsiderations. Maybe it
alpar@397
   438
  ///should be implemented independently from ListGraph.
deba@782
   439
  
alpar@397
   440
  class SymListGraph : public ListGraph
alpar@395
   441
  {
alpar@395
   442
  public:
deba@782
   443
deba@782
   444
    typedef SymListGraph Graph;
deba@782
   445
deba@782
   446
    KEEP_NODE_MAP(ListGraph);
deba@782
   447
    KEEP_EDGE_MAP(ListGraph);
deba@782
   448
deba@782
   449
    CREATE_SYM_EDGE_MAP_REGISTRY;
deba@798
   450
    CREATE_SYM_EDGE_MAP_FACTORY(DefaultMapFactory);
deba@782
   451
    IMPORT_SYM_EDGE_MAP(SymEdgeMapFactory);
alpar@395
   452
alpar@397
   453
    SymListGraph() : ListGraph() { }
alpar@397
   454
    SymListGraph(const ListGraph &_g) : ListGraph(_g) { }
alpar@397
   455
    ///Adds a pair of oppositely directed edges to the graph.
alpar@395
   456
    Edge addEdge(Node u, Node v)
alpar@395
   457
    {
alpar@397
   458
      Edge e = ListGraph::addEdge(u,v);
deba@782
   459
      Edge f = ListGraph::addEdge(v,u);
deba@782
   460
      sym_edge_maps.add(e);
deba@782
   461
      sym_edge_maps.add(f);
deba@782
   462
      
alpar@395
   463
      return e;
alpar@395
   464
    }
alpar@395
   465
deba@782
   466
    void erase(Node n) { ListGraph::erase(n);}
alpar@395
   467
    ///The oppositely directed edge.
alpar@395
   468
alpar@395
   469
    ///Returns the oppositely directed
alpar@395
   470
    ///pair of the edge \c e.
alpar@713
   471
    static Edge opposite(Edge e)
alpar@395
   472
    {
alpar@395
   473
      Edge f;
alpar@395
   474
      f.idref() = e.idref() - 2*(e.idref()%2) + 1;
alpar@395
   475
      return f;
alpar@395
   476
    }
alpar@395
   477
    
alpar@397
   478
    ///Removes a pair of oppositely directed edges to the graph.
alpar@397
   479
    void erase(Edge e) {
deba@782
   480
      Edge f = opposite(e);
deba@782
   481
      sym_edge_maps.erase(e);
deba@782
   482
      sym_edge_maps.erase(f);
deba@782
   483
      ListGraph::erase(f);
alpar@397
   484
      ListGraph::erase(e);
deba@782
   485
    }    
deba@782
   486
  };
alpar@395
   487
alpar@400
   488
alpar@401
   489
  ///A graph class containing only nodes.
alpar@400
   490
alpar@401
   491
  ///This class implements a graph structure without edges.
alpar@401
   492
  ///The most useful application of this class is to be the node set of an
alpar@401
   493
  ///\ref EdgeSet class.
alpar@400
   494
  ///
alpar@400
   495
  ///It conforms to the graph interface documented under
alpar@401
   496
  ///the description of \ref GraphSkeleton with the exception that you cannot
alpar@401
   497
  ///add (or delete) edges. The usual edge iterators are exists, but they are
alpar@401
   498
  ///always \ref INVALID.
alpar@401
   499
  ///\sa \ref GraphSkeleton
alpar@508
   500
  ///\sa \ref EdgeSet
alpar@400
   501
  class NodeSet {
alpar@400
   502
alpar@400
   503
    //Nodes are double linked.
alpar@400
   504
    //The free nodes are only single linked using the "next" field.
alpar@400
   505
    struct NodeT 
alpar@400
   506
    {
alpar@400
   507
      int first_in,first_out;
alpar@400
   508
      int prev, next;
alpar@400
   509
      //      NodeT() {}
alpar@400
   510
    };
alpar@400
   511
alpar@400
   512
    std::vector<NodeT> nodes;
alpar@400
   513
    //The first node
alpar@400
   514
    int first_node;
alpar@400
   515
    //The first free node
alpar@400
   516
    int first_free_node;
alpar@400
   517
    
alpar@400
   518
  public:
deba@782
   519
deba@782
   520
    typedef NodeSet Graph;
alpar@400
   521
    
alpar@400
   522
    class Node;
alpar@400
   523
    class Edge;
alpar@400
   524
alpar@400
   525
  public:
alpar@400
   526
alpar@400
   527
    class NodeIt;
alpar@400
   528
    class EdgeIt;
alpar@400
   529
    class OutEdgeIt;
alpar@400
   530
    class InEdgeIt;
alpar@400
   531
    
deba@782
   532
    CREATE_MAP_REGISTRIES;
deba@798
   533
    CREATE_MAPS(DefaultMapFactory);
alpar@400
   534
    
alpar@400
   535
  public:
alpar@400
   536
alpar@408
   537
    ///Default constructor
deba@782
   538
    NodeSet() 
deba@782
   539
      : nodes(), first_node(-1), first_free_node(-1) {}
alpar@408
   540
    ///Copy constructor
deba@782
   541
    NodeSet(const NodeSet &_g) 
deba@782
   542
      : nodes(_g.nodes), first_node(_g.first_node),
deba@782
   543
	first_free_node(_g.first_free_node) {}
alpar@400
   544
    
alpar@813
   545
    ///Number of nodes.
alpar@813
   546
    int nodeNum() const { return nodes.size(); }
alpar@813
   547
    ///Number of edges.
alpar@813
   548
    int edgeNum() const { return 0; }
alpar@400
   549
alpar@813
   550
    /// Maximum node ID.
alpar@813
   551
    
alpar@813
   552
    /// Maximum node ID.
alpar@813
   553
    ///\sa id(Node)
alpar@813
   554
    int maxNodeId() const { return nodes.size()-1; }
alpar@813
   555
    /// Maximum edge ID.
alpar@813
   556
    
alpar@813
   557
    /// Maximum edge ID.
alpar@813
   558
    ///\sa id(Edge)
alpar@813
   559
    int maxEdgeId() const { return 0; }
alpar@400
   560
alpar@400
   561
    Node tail(Edge e) const { return INVALID; }
alpar@400
   562
    Node head(Edge e) const { return INVALID; }
alpar@400
   563
alpar@400
   564
    NodeIt& first(NodeIt& v) const { 
alpar@400
   565
      v=NodeIt(*this); return v; }
alpar@400
   566
    EdgeIt& first(EdgeIt& e) const { 
alpar@400
   567
      e=EdgeIt(*this); return e; }
alpar@400
   568
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
alpar@400
   569
      e=OutEdgeIt(*this,v); return e; }
alpar@400
   570
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
alpar@400
   571
      e=InEdgeIt(*this,v); return e; }
alpar@400
   572
alpar@813
   573
    /// Node ID.
alpar@813
   574
    
alpar@813
   575
    /// The ID of a valid Node is a nonnegative integer not greater than
alpar@813
   576
    /// \ref maxNodeId(). The range of the ID's is not surely continuous
alpar@813
   577
    /// and the greatest node ID can be actually less then \ref maxNodeId().
alpar@813
   578
    ///
alpar@813
   579
    /// The ID of the \ref INVALID node is -1.
alpar@813
   580
    ///\return The ID of the node \c v. 
alpar@400
   581
    int id(Node v) const { return v.n; }
alpar@813
   582
    /// Edge ID.
alpar@813
   583
    
alpar@813
   584
    /// The ID of a valid Edge is a nonnegative integer not greater than
alpar@813
   585
    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
alpar@813
   586
    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
alpar@813
   587
    ///
alpar@813
   588
    /// The ID of the \ref INVALID edge is -1.
alpar@813
   589
    ///\return The ID of the edge \c e. 
alpar@400
   590
    int id(Edge e) const { return -1; }
alpar@400
   591
alpar@400
   592
    /// Adds a new node to the graph.
alpar@400
   593
alpar@813
   594
    /// \warning It adds the new node to the front of the list.
alpar@400
   595
    /// (i.e. the lastly added node becomes the first.)
alpar@400
   596
    Node addNode() {
alpar@400
   597
      int n;
alpar@400
   598
      
alpar@400
   599
      if(first_free_node==-1)
alpar@400
   600
	{
alpar@400
   601
	  n = nodes.size();
alpar@400
   602
	  nodes.push_back(NodeT());
alpar@400
   603
	}
alpar@400
   604
      else {
alpar@400
   605
	n = first_free_node;
alpar@400
   606
	first_free_node = nodes[n].next;
alpar@400
   607
      }
alpar@400
   608
      
alpar@400
   609
      nodes[n].next = first_node;
alpar@400
   610
      if(first_node != -1) nodes[first_node].prev = n;
alpar@400
   611
      first_node = n;
alpar@400
   612
      nodes[n].prev = -1;
alpar@400
   613
      
alpar@400
   614
      nodes[n].first_in = nodes[n].first_out = -1;
alpar@400
   615
      
alpar@400
   616
      Node nn; nn.n=n;
alpar@400
   617
alpar@400
   618
      //Update dynamic maps
deba@782
   619
      node_maps.add(nn);
alpar@400
   620
alpar@400
   621
      return nn;
alpar@400
   622
    }
alpar@400
   623
    
alpar@400
   624
    void erase(Node nn) {
alpar@400
   625
      int n=nn.n;
alpar@400
   626
      
alpar@400
   627
      if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
alpar@400
   628
      if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
alpar@400
   629
      else first_node = nodes[n].next;
alpar@400
   630
      
alpar@400
   631
      nodes[n].next = first_free_node;
alpar@400
   632
      first_free_node = n;
alpar@400
   633
alpar@400
   634
      //Update dynamic maps
deba@782
   635
      node_maps.erase(nn);
alpar@400
   636
    }
alpar@400
   637
    
alpar@774
   638
        
alpar@774
   639
    Edge findEdge(Node u,Node v, Edge prev = INVALID) 
alpar@774
   640
    {
alpar@774
   641
      return INVALID;
alpar@774
   642
    }
alpar@774
   643
    
alpar@400
   644
    void clear() {
deba@782
   645
      node_maps.clear();
alpar@400
   646
      nodes.clear();
alpar@400
   647
      first_node = first_free_node = -1;
alpar@400
   648
    }
alpar@400
   649
alpar@400
   650
    class Node {
alpar@400
   651
      friend class NodeSet;
alpar@400
   652
      template <typename T> friend class NodeMap;
alpar@400
   653
      
alpar@400
   654
      friend class Edge;
alpar@400
   655
      friend class OutEdgeIt;
alpar@400
   656
      friend class InEdgeIt;
alpar@400
   657
alpar@400
   658
    protected:
alpar@400
   659
      int n;
alpar@400
   660
      friend int NodeSet::id(Node v) const; 
alpar@400
   661
      Node(int nn) {n=nn;}
alpar@400
   662
    public:
alpar@400
   663
      Node() {}
alpar@400
   664
      Node (Invalid i) { n=-1; }
alpar@400
   665
      bool operator==(const Node i) const {return n==i.n;}
alpar@400
   666
      bool operator!=(const Node i) const {return n!=i.n;}
alpar@400
   667
      bool operator<(const Node i) const {return n<i.n;}
alpar@400
   668
    };
alpar@400
   669
    
alpar@400
   670
    class NodeIt : public Node {
alpar@774
   671
      const NodeSet *G;
alpar@400
   672
      friend class NodeSet;
alpar@400
   673
    public:
alpar@579
   674
      NodeIt() : Node() { }
alpar@774
   675
      NodeIt(const NodeSet& _G,Node n) : Node(n), G(&_G) { }
alpar@579
   676
      NodeIt(Invalid i) : Node(i) { }
alpar@774
   677
      NodeIt(const NodeSet& _G) : Node(_G.first_node), G(&_G) { }
alpar@774
   678
      NodeIt &operator++() {
alpar@774
   679
	n=G->nodes[n].next; 
alpar@774
   680
	return *this; 
alpar@774
   681
      }
alpar@400
   682
    };
alpar@400
   683
alpar@400
   684
    class Edge {
alpar@400
   685
      //friend class NodeSet;
alpar@400
   686
      //template <typename T> friend class EdgeMap;
alpar@400
   687
alpar@400
   688
      //template <typename T> friend class SymNodeSet::SymEdgeMap;      
alpar@400
   689
      //friend Edge SymNodeSet::opposite(Edge) const;
alpar@400
   690
      
alpar@400
   691
      //      friend class Node;
alpar@400
   692
      //      friend class NodeIt;
alpar@400
   693
    protected:
alpar@400
   694
      //friend int NodeSet::id(Edge e) const;
alpar@400
   695
      //      Edge(int nn) {}
alpar@400
   696
    public:
alpar@400
   697
      Edge() { }
alpar@400
   698
      Edge (Invalid) { }
alpar@400
   699
      bool operator==(const Edge i) const {return true;}
alpar@400
   700
      bool operator!=(const Edge i) const {return false;}
alpar@400
   701
      bool operator<(const Edge i) const {return false;}
alpar@400
   702
      ///\bug This is a workaround until somebody tells me how to
alpar@400
   703
      ///make class \c SymNodeSet::SymEdgeMap friend of Edge
alpar@400
   704
      //      int idref() {return -1;}
alpar@400
   705
      //      int idref() const {return -1;}
alpar@400
   706
    };
alpar@400
   707
    
alpar@400
   708
    class EdgeIt : public Edge {
alpar@400
   709
      //friend class NodeSet;
alpar@400
   710
    public:
alpar@400
   711
      EdgeIt(const NodeSet& G) : Edge() { }
alpar@774
   712
      EdgeIt(const NodeSet&, Edge) : Edge() { }
alpar@400
   713
      EdgeIt (Invalid i) : Edge(i) { }
alpar@400
   714
      EdgeIt() : Edge() { }
alpar@400
   715
      ///\bug This is a workaround until somebody tells me how to
alpar@400
   716
      ///make class \c SymNodeSet::SymEdgeMap friend of Edge
alpar@400
   717
      //      int idref() {return -1;}
alpar@774
   718
      EdgeIt operator++() { return INVALID; }
alpar@400
   719
    };
alpar@400
   720
    
alpar@400
   721
    class OutEdgeIt : public Edge {
alpar@400
   722
      friend class NodeSet;
alpar@400
   723
    public: 
alpar@400
   724
      OutEdgeIt() : Edge() { }
alpar@774
   725
      OutEdgeIt(const NodeSet&, Edge) : Edge() { }
alpar@400
   726
      OutEdgeIt (Invalid i) : Edge(i) { }
alpar@400
   727
      OutEdgeIt(const NodeSet& G,const Node v)	: Edge() {}
alpar@774
   728
      OutEdgeIt operator++() { return INVALID; }
alpar@400
   729
    };
alpar@400
   730
    
alpar@400
   731
    class InEdgeIt : public Edge {
alpar@400
   732
      friend class NodeSet;
alpar@400
   733
    public: 
alpar@400
   734
      InEdgeIt() : Edge() { }
alpar@774
   735
      InEdgeIt(const NodeSet&, Edge) : Edge() { }
alpar@400
   736
      InEdgeIt (Invalid i) : Edge(i) { }
alpar@400
   737
      InEdgeIt(const NodeSet& G,Node v) :Edge() {}
alpar@774
   738
      InEdgeIt operator++() { return INVALID; }
alpar@400
   739
    };
alpar@400
   740
alpar@400
   741
  };
alpar@400
   742
alpar@400
   743
alpar@400
   744
alpar@401
   745
  ///Graph structure using a node set of another graph.
alpar@401
   746
alpar@401
   747
  ///This structure can be used to establish another graph over a node set
alpar@401
   748
  /// of an existing one. The node iterator will go through the nodes of the
alpar@401
   749
  /// original graph, and the NodeMap's of both graphs will convert to
alpar@401
   750
  /// each other.
alpar@401
   751
  ///
alpar@404
   752
  ///\warning Adding or deleting nodes from the graph is not safe if an
alpar@404
   753
  ///\ref EdgeSet is currently attached to it!
alpar@404
   754
  ///
alpar@404
   755
  ///\todo Make it possible to add/delete edges from the base graph
alpar@404
   756
  ///(and from \ref EdgeSet, as well)
alpar@404
   757
  ///
alpar@401
   758
  ///\param GG The type of the graph which shares its node set with this class.
alpar@401
   759
  ///Its interface must conform with \ref GraphSkeleton.
alpar@400
   760
  ///
alpar@400
   761
  ///It conforms to the graph interface documented under
alpar@400
   762
  ///the description of \ref GraphSkeleton.
alpar@400
   763
  ///\sa \ref GraphSkeleton.
alpar@401
   764
  ///\sa \ref NodeSet.
alpar@400
   765
  template<typename GG>
alpar@400
   766
  class EdgeSet {
alpar@400
   767
alpar@400
   768
    typedef GG NodeGraphType;
alpar@400
   769
alpar@400
   770
    NodeGraphType &G;
alpar@400
   771
alpar@515
   772
  public:
deba@782
   773
alpar@400
   774
    class Node;
alpar@705
   775
    class Edge;
alpar@705
   776
    class OutEdgeIt;
alpar@705
   777
    class InEdgeIt;
alpar@705
   778
    class SymEdge;
deba@782
   779
deba@782
   780
    typedef EdgeSet Graph;
deba@782
   781
alpar@531
   782
    int id(Node v) const; 
alpar@531
   783
alpar@531
   784
    class Node : public NodeGraphType::Node {
alpar@531
   785
      friend class EdgeSet;
alpar@531
   786
      //      template <typename T> friend class NodeMap;
alpar@531
   787
      
alpar@531
   788
      friend class Edge;
alpar@531
   789
      friend class OutEdgeIt;
alpar@531
   790
      friend class InEdgeIt;
alpar@531
   791
      friend class SymEdge;
alpar@531
   792
alpar@531
   793
    public:
alpar@531
   794
      friend int EdgeSet::id(Node v) const; 
alpar@531
   795
      //      Node(int nn) {n=nn;}
alpar@531
   796
    public:
alpar@531
   797
      Node() : NodeGraphType::Node() {}
alpar@531
   798
      Node (Invalid i) : NodeGraphType::Node(i) {}
alpar@531
   799
      Node(const typename NodeGraphType::Node &n) : NodeGraphType::Node(n) {}
alpar@531
   800
    };
alpar@531
   801
    
alpar@531
   802
    class NodeIt : public NodeGraphType::NodeIt {
alpar@531
   803
      friend class EdgeSet;
alpar@531
   804
    public:
alpar@531
   805
      NodeIt() : NodeGraphType::NodeIt() { }
alpar@774
   806
      NodeIt(const EdgeSet& _G,Node n) : NodeGraphType::NodeIt(_G.G,n) { }
alpar@531
   807
      NodeIt (Invalid i) : NodeGraphType::NodeIt(i) {}
alpar@531
   808
      NodeIt(const EdgeSet& _G) : NodeGraphType::NodeIt(_G.G) { }
alpar@531
   809
      NodeIt(const typename NodeGraphType::NodeIt &n)
alpar@531
   810
	: NodeGraphType::NodeIt(n) {}
alpar@579
   811
alpar@531
   812
      operator Node() { return Node(*this);}
alpar@774
   813
      NodeIt &operator++()
alpar@774
   814
      { this->NodeGraphType::NodeIt::operator++(); return *this;} 
alpar@531
   815
    };
alpar@515
   816
alpar@515
   817
  private:
alpar@400
   818
    //Edges are double linked.
alpar@400
   819
    //The free edges are only single linked using the "next_in" field.
alpar@400
   820
    struct NodeT 
alpar@400
   821
    {
alpar@400
   822
      int first_in,first_out;
alpar@400
   823
      NodeT() : first_in(-1), first_out(-1) { }
alpar@400
   824
    };
alpar@400
   825
alpar@400
   826
    struct EdgeT 
alpar@400
   827
    {
alpar@400
   828
      Node head, tail;
alpar@400
   829
      int prev_in, prev_out;
alpar@400
   830
      int next_in, next_out;
alpar@400
   831
    };
alpar@400
   832
alpar@400
   833
    
alpar@515
   834
    typename NodeGraphType::template NodeMap<NodeT> nodes;
alpar@400
   835
    
alpar@400
   836
    std::vector<EdgeT> edges;
alpar@400
   837
    //The first free edge
alpar@400
   838
    int first_free_edge;
alpar@400
   839
    
alpar@400
   840
  public:
alpar@400
   841
    
alpar@400
   842
    class Node;
alpar@400
   843
    class Edge;
alpar@400
   844
alpar@400
   845
    class NodeIt;
alpar@400
   846
    class EdgeIt;
alpar@400
   847
    class OutEdgeIt;
alpar@400
   848
    class InEdgeIt;
deba@782
   849
deba@782
   850
deba@782
   851
    CREATE_EDGE_MAP_REGISTRY;
deba@798
   852
    CREATE_EDGE_MAP_FACTORY(DefaultMapFactory);
deba@782
   853
    IMPORT_EDGE_MAP(EdgeMapFactory);
alpar@400
   854
    
alpar@400
   855
    
alpar@400
   856
  public:
alpar@400
   857
alpar@408
   858
    ///Constructor
alpar@408
   859
    
alpar@408
   860
    ///Construates a new graph based on the nodeset of an existing one.
alpar@408
   861
    ///\param _G the base graph.
alpar@408
   862
    ///\todo It looks like a copy constructor, but it isn't.
deba@782
   863
    EdgeSet(NodeGraphType &_G) 
deba@782
   864
      : G(_G), nodes(_G), edges(),
deba@782
   865
	first_free_edge(-1) {}
alpar@408
   866
    ///Copy constructor
alpar@408
   867
alpar@408
   868
    ///Makes a copy of an EdgeSet.
alpar@408
   869
    ///It will be based on the same graph.
deba@782
   870
    EdgeSet(const EdgeSet &_g) 
deba@782
   871
      : G(_g.G), nodes(_g.G), edges(_g.edges),
deba@782
   872
	first_free_edge(_g.first_free_edge) {}
alpar@400
   873
    
alpar@813
   874
    ///Number of nodes.
alpar@813
   875
    int nodeNum() const { return G.nodeNum(); }
alpar@813
   876
    ///Number of edges.
alpar@813
   877
    int edgeNum() const { return edges.size(); }
alpar@400
   878
alpar@813
   879
    /// Maximum node ID.
alpar@813
   880
    
alpar@813
   881
    /// Maximum node ID.
alpar@813
   882
    ///\sa id(Node)
alpar@813
   883
    int maxNodeId() const { return G.maxNodeId(); }
alpar@813
   884
    /// Maximum edge ID.
alpar@813
   885
    
alpar@813
   886
    /// Maximum edge ID.
alpar@813
   887
    ///\sa id(Edge)
alpar@813
   888
    int maxEdgeId() const { return edges.size()-1; }
alpar@400
   889
alpar@400
   890
    Node tail(Edge e) const { return edges[e.n].tail; }
alpar@400
   891
    Node head(Edge e) const { return edges[e.n].head; }
alpar@400
   892
alpar@400
   893
    NodeIt& first(NodeIt& v) const { 
alpar@400
   894
      v=NodeIt(*this); return v; }
alpar@400
   895
    EdgeIt& first(EdgeIt& e) const { 
alpar@400
   896
      e=EdgeIt(*this); return e; }
alpar@400
   897
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
alpar@400
   898
      e=OutEdgeIt(*this,v); return e; }
alpar@400
   899
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
alpar@400
   900
      e=InEdgeIt(*this,v); return e; }
alpar@400
   901
alpar@813
   902
    /// Node ID.
alpar@813
   903
    
alpar@813
   904
    /// The ID of a valid Node is a nonnegative integer not greater than
alpar@813
   905
    /// \ref maxNodeId(). The range of the ID's is not surely continuous
alpar@813
   906
    /// and the greatest node ID can be actually less then \ref maxNodeId().
alpar@813
   907
    ///
alpar@813
   908
    /// The ID of the \ref INVALID node is -1.
alpar@813
   909
    ///\return The ID of the node \c v. 
alpar@813
   910
    int id(Node v) { return G.id(v); }
alpar@813
   911
    /// Edge ID.
alpar@813
   912
    
alpar@813
   913
    /// The ID of a valid Edge is a nonnegative integer not greater than
alpar@813
   914
    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
alpar@813
   915
    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
alpar@813
   916
    ///
alpar@813
   917
    /// The ID of the \ref INVALID edge is -1.
alpar@813
   918
    ///\return The ID of the edge \c e. 
alpar@400
   919
    int id(Edge e) const { return e.n; }
alpar@400
   920
alpar@400
   921
    /// Adds a new node to the graph.
alpar@579
   922
    Node addNode() { return G.addNode(); }
alpar@400
   923
    
alpar@400
   924
    Edge addEdge(Node u, Node v) {
alpar@400
   925
      int n;
alpar@400
   926
      
alpar@400
   927
      if(first_free_edge==-1)
alpar@400
   928
	{
alpar@400
   929
	  n = edges.size();
alpar@400
   930
	  edges.push_back(EdgeT());
alpar@400
   931
	}
alpar@400
   932
      else {
alpar@400
   933
	n = first_free_edge;
alpar@400
   934
	first_free_edge = edges[n].next_in;
alpar@400
   935
      }
alpar@400
   936
      
alpar@401
   937
      edges[n].tail = u; edges[n].head = v;
alpar@400
   938
alpar@401
   939
      edges[n].next_out = nodes[u].first_out;
alpar@401
   940
      if(nodes[u].first_out != -1) edges[nodes[u].first_out].prev_out = n;
alpar@401
   941
      edges[n].next_in = nodes[v].first_in;
alpar@401
   942
      if(nodes[v].first_in != -1) edges[nodes[v].first_in].prev_in = n;
alpar@400
   943
      edges[n].prev_in = edges[n].prev_out = -1;
alpar@400
   944
	
alpar@401
   945
      nodes[u].first_out = nodes[v].first_in = n;
alpar@400
   946
alpar@400
   947
      Edge e; e.n=n;
alpar@400
   948
alpar@400
   949
      //Update dynamic maps
deba@782
   950
      edge_maps.add(e);
alpar@400
   951
alpar@400
   952
      return e;
alpar@400
   953
    }
alpar@400
   954
alpar@774
   955
    /// Finds an edge between two nodes.
alpar@774
   956
alpar@774
   957
    /// Finds an edge from node \c u to node \c v.
alpar@774
   958
    ///
alpar@774
   959
    /// If \c prev is \ref INVALID (this is the default value), then
alpar@774
   960
    /// It finds the first edge from \c u to \c v. Otherwise it looks for
alpar@774
   961
    /// the next edge from \c u to \c v after \c prev.
alpar@774
   962
    /// \return The found edge or INVALID if there is no such an edge.
alpar@774
   963
    Edge findEdge(Node u,Node v, Edge prev = INVALID) 
alpar@774
   964
    {
alpar@774
   965
      int e = (prev.n==-1)? nodes[u].first_out : edges[prev.n].next_out;
alpar@774
   966
      while(e!=-1 && edges[e].tail!=v) e = edges[e].next_out;
alpar@774
   967
      prev.n=e;
alpar@774
   968
      return prev;
alpar@774
   969
    }
alpar@774
   970
    
alpar@400
   971
  private:
alpar@400
   972
    void eraseEdge(int n) {
alpar@400
   973
      
alpar@400
   974
      if(edges[n].next_in!=-1)
alpar@400
   975
	edges[edges[n].next_in].prev_in = edges[n].prev_in;
alpar@400
   976
      if(edges[n].prev_in!=-1)
alpar@400
   977
	edges[edges[n].prev_in].next_in = edges[n].next_in;
alpar@400
   978
      else nodes[edges[n].head].first_in = edges[n].next_in;
alpar@400
   979
      
alpar@400
   980
      if(edges[n].next_out!=-1)
alpar@400
   981
	edges[edges[n].next_out].prev_out = edges[n].prev_out;
alpar@400
   982
      if(edges[n].prev_out!=-1)
alpar@400
   983
	edges[edges[n].prev_out].next_out = edges[n].next_out;
alpar@400
   984
      else nodes[edges[n].tail].first_out = edges[n].next_out;
alpar@400
   985
      
alpar@400
   986
      edges[n].next_in = first_free_edge;
alpar@400
   987
      first_free_edge = -1;      
alpar@400
   988
alpar@400
   989
      //Update dynamic maps
deba@782
   990
      Edge e; e.n = n;
deba@782
   991
      edge_maps.erase(e);
alpar@400
   992
    }
alpar@400
   993
      
alpar@400
   994
  public:
alpar@400
   995
alpar@400
   996
//     void erase(Node nn) {
alpar@400
   997
//       int n=nn.n;
alpar@400
   998
//       int m;
alpar@400
   999
//       while((m=nodes[n].first_in)!=-1) eraseEdge(m);
alpar@400
  1000
//       while((m=nodes[n].first_out)!=-1) eraseEdge(m);
alpar@400
  1001
//     }
alpar@400
  1002
    
alpar@400
  1003
    void erase(Edge e) { eraseEdge(e.n); }
alpar@400
  1004
alpar@579
  1005
    ///Clear all edges. (Doesn't clear the nodes!)
alpar@579
  1006
    void clear() {
deba@782
  1007
      edge_maps.clear();
alpar@579
  1008
      edges.clear();
alpar@579
  1009
      first_free_edge=-1;
alpar@579
  1010
    }
alpar@579
  1011
alpar@579
  1012
alpar@400
  1013
    class Edge {
alpar@579
  1014
    public:
alpar@400
  1015
      friend class EdgeSet;
alpar@400
  1016
      template <typename T> friend class EdgeMap;
alpar@400
  1017
alpar@400
  1018
      friend class Node;
alpar@400
  1019
      friend class NodeIt;
alpar@579
  1020
    public:
alpar@774
  1021
      ///\bug It should be at least protected
alpar@579
  1022
      ///
alpar@579
  1023
      int n;
alpar@400
  1024
    protected:
alpar@400
  1025
      friend int EdgeSet::id(Edge e) const;
alpar@400
  1026
alpar@400
  1027
      Edge(int nn) {n=nn;}
alpar@400
  1028
    public:
alpar@400
  1029
      Edge() { }
alpar@400
  1030
      Edge (Invalid) { n=-1; }
alpar@400
  1031
      bool operator==(const Edge i) const {return n==i.n;}
alpar@400
  1032
      bool operator!=(const Edge i) const {return n!=i.n;}
alpar@400
  1033
      bool operator<(const Edge i) const {return n<i.n;}
alpar@400
  1034
      ///\bug This is a workaround until somebody tells me how to
alpar@400
  1035
      ///make class \c SymEdgeSet::SymEdgeMap friend of Edge
alpar@400
  1036
      int &idref() {return n;}
alpar@400
  1037
      const int &idref() const {return n;}
alpar@400
  1038
    };
alpar@400
  1039
    
alpar@400
  1040
    class EdgeIt : public Edge {
alpar@400
  1041
      friend class EdgeSet;
alpar@579
  1042
      template <typename T> friend class EdgeMap;
alpar@579
  1043
    
alpar@774
  1044
      const EdgeSet *G;
alpar@400
  1045
    public:
alpar@774
  1046
      EdgeIt(const EdgeSet& _G) : Edge(), G(&_G) {
alpar@503
  1047
	//      	typename NodeGraphType::Node m;
alpar@503
  1048
        NodeIt m;
alpar@774
  1049
	for(G->first(m);
alpar@774
  1050
	    m!=INVALID && G->nodes[m].first_in == -1;  ++m);
alpar@774
  1051
	///\bug AJJAJ! This is a non sense!!!!!!!
alpar@774
  1052
	this->n = m!=INVALID?-1:G->nodes[m].first_in;
alpar@400
  1053
      }
alpar@774
  1054
      EdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
alpar@400
  1055
      EdgeIt (Invalid i) : Edge(i) { }
alpar@400
  1056
      EdgeIt() : Edge() { }
alpar@774
  1057
      ///.
alpar@774
  1058
      
alpar@774
  1059
      ///\bug UNIMPLEMENTED!!!!!
alpar@774
  1060
      //
alpar@774
  1061
      EdgeIt &operator++() {
alpar@774
  1062
	return *this;
alpar@774
  1063
      }
alpar@774
  1064
       ///\bug This is a workaround until somebody tells me how to
alpar@400
  1065
      ///make class \c SymEdgeSet::SymEdgeMap friend of Edge
alpar@515
  1066
      int &idref() {return this->n;}
alpar@400
  1067
    };
alpar@400
  1068
    
alpar@400
  1069
    class OutEdgeIt : public Edge {
alpar@774
  1070
      const EdgeSet *G;
alpar@400
  1071
      friend class EdgeSet;
alpar@400
  1072
    public: 
alpar@400
  1073
      OutEdgeIt() : Edge() { }
alpar@400
  1074
      OutEdgeIt (Invalid i) : Edge(i) { }
alpar@774
  1075
      OutEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
alpar@400
  1076
alpar@774
  1077
      OutEdgeIt(const EdgeSet& _G,const Node v) :
alpar@774
  1078
	Edge(_G.nodes[v].first_out), G(&_G) { }
deba@782
  1079
      OutEdgeIt &operator++() { n = G->edges[n].next_out; return *this; }
alpar@400
  1080
    };
alpar@400
  1081
    
alpar@400
  1082
    class InEdgeIt : public Edge {
alpar@774
  1083
      const EdgeSet *G;
alpar@400
  1084
      friend class EdgeSet;
alpar@400
  1085
    public: 
alpar@400
  1086
      InEdgeIt() : Edge() { }
alpar@400
  1087
      InEdgeIt (Invalid i) : Edge(i) { }
alpar@774
  1088
      InEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
alpar@774
  1089
      InEdgeIt(const EdgeSet& _G,Node v)
alpar@774
  1090
	: Edge(_G.nodes[v].first_in), G(&_G) { }
alpar@774
  1091
      InEdgeIt &operator++() { n=G->edges[n].next_in; return *this; }
alpar@400
  1092
    };
alpar@400
  1093
deba@782
  1094
    
deba@782
  1095
    template <typename V> class NodeMap 
deba@782
  1096
      : public NodeGraphType::template NodeMap<V>
alpar@400
  1097
    {
alpar@579
  1098
      //This is a must, the constructors need it.
deba@782
  1099
      typedef typename NodeGraphType::template NodeMap<V> MapImpl;
deba@782
  1100
      typedef V Value;
alpar@400
  1101
    public:
deba@782
  1102
      NodeMap() : MapImpl() {}
deba@782
  1103
      
deba@782
  1104
      NodeMap(const EdgeSet& graph) 
deba@782
  1105
	: MapImpl(graph.G) { }
alpar@400
  1106
deba@782
  1107
      NodeMap(const EdgeSet& graph, const Value& value) 
deba@782
  1108
	: MapImpl(graph.G, value) { }
alpar@400
  1109
deba@782
  1110
      NodeMap(const NodeMap& copy) 
deba@782
  1111
	: MapImpl(static_cast<const MapImpl&>(copy)) {}
alpar@400
  1112
deba@782
  1113
      template<typename CMap>
deba@782
  1114
      NodeMap(const CMap& copy)
deba@782
  1115
	: MapImpl(copy) { }
deba@782
  1116
deba@782
  1117
      NodeMap& operator=(const NodeMap& copy) {
deba@782
  1118
	MapImpl::operator=(static_cast<const MapImpl&>(copy));
deba@782
  1119
	return *this;
alpar@400
  1120
      }
alpar@400
  1121
deba@782
  1122
      template <typename CMap>
deba@782
  1123
      NodeMap& operator=(const CMap& copy) {
deba@782
  1124
	MapImpl::operator=(copy);
alpar@400
  1125
	return *this;
alpar@400
  1126
      }
alpar@579
  1127
alpar@400
  1128
    };
alpar@400
  1129
  };
alpar@406
  1130
alpar@579
  1131
  template<typename GG>
alpar@579
  1132
  inline int EdgeSet<GG>::id(Node v) const { return G.id(v); }
alpar@531
  1133
alpar@406
  1134
/// @}  
alpar@406
  1135
alpar@395
  1136
} //namespace hugo
alpar@395
  1137
alpar@405
  1138
#endif //HUGO_LIST_GRAPH_H