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