src/hugo/list_graph.h
author deba
Sun, 26 Sep 2004 21:43:38 +0000
changeset 909 6a22e0dfd453
parent 906 17f31d280385
child 911 89a4fbb99cad
permissions -rw-r--r--
New symmetric Graph concept.
New symmetric list and smart graph.
Symmetric Graph tests based on the Graph Tests.
alpar@906
     1
/* -*- C++ -*-
alpar@906
     2
 * src/hugo/list_graph.h - Part of HUGOlib, a generic C++ optimization library
alpar@906
     3
 *
alpar@906
     4
 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@906
     5
 * (Egervary Combinatorial Optimization Research Group, EGRES).
alpar@906
     6
 *
alpar@906
     7
 * Permission to use, modify and distribute this software is granted
alpar@906
     8
 * provided that this copyright notice appears in all copies. For
alpar@906
     9
 * precise terms see the accompanying LICENSE file.
alpar@906
    10
 *
alpar@906
    11
 * This software is provided "AS IS" with no warranty of any kind,
alpar@906
    12
 * express or implied, and with no claim as to its suitability for any
alpar@906
    13
 * purpose.
alpar@906
    14
 *
alpar@906
    15
 */
alpar@395
    16
alpar@405
    17
#ifndef HUGO_LIST_GRAPH_H
alpar@405
    18
#define HUGO_LIST_GRAPH_H
alpar@395
    19
klao@491
    20
///\ingroup graphs
alpar@395
    21
///\file
alpar@405
    22
///\brief ListGraph, SymListGraph, NodeSet and EdgeSet classes.
alpar@395
    23
alpar@395
    24
#include <vector>
deba@782
    25
#include <climits>
alpar@395
    26
ladanyi@542
    27
#include <hugo/invalid.h>
alpar@395
    28
deba@782
    29
#include <hugo/map_registry.h>
deba@897
    30
#include <hugo/array_map.h>
deba@782
    31
deba@782
    32
#include <hugo/map_defines.h>
deba@782
    33
deba@782
    34
alpar@395
    35
namespace hugo {
alpar@395
    36
alpar@406
    37
/// \addtogroup graphs
alpar@406
    38
/// @{
alpar@406
    39
alpar@401
    40
  ///A list graph class.
alpar@395
    41
alpar@397
    42
  ///This is a simple and fast erasable graph implementation.
alpar@397
    43
  ///
alpar@880
    44
  ///It conforms to the
alpar@880
    45
  ///\ref skeleton::ErasableGraph "ErasableGraph" concept.
alpar@880
    46
  ///\sa skeleton::ErasableGraph.
alpar@397
    47
  class ListGraph {
alpar@395
    48
alpar@397
    49
    //Nodes are double linked.
alpar@397
    50
    //The free nodes are only single linked using the "next" field.
alpar@395
    51
    struct NodeT 
alpar@395
    52
    {
alpar@397
    53
      int first_in,first_out;
alpar@397
    54
      int prev, next;
alpar@395
    55
    };
alpar@397
    56
    //Edges are double linked.
alpar@397
    57
    //The free edges are only single linked using the "next_in" field.
alpar@395
    58
    struct EdgeT 
alpar@395
    59
    {
alpar@397
    60
      int head, tail;
alpar@397
    61
      int prev_in, prev_out;
alpar@397
    62
      int next_in, next_out;
alpar@395
    63
    };
alpar@395
    64
alpar@395
    65
    std::vector<NodeT> nodes;
alpar@397
    66
    //The first node
alpar@397
    67
    int first_node;
alpar@397
    68
    //The first free node
alpar@397
    69
    int first_free_node;
alpar@395
    70
    std::vector<EdgeT> edges;
alpar@397
    71
    //The first free edge
alpar@397
    72
    int first_free_edge;
alpar@395
    73
    
deba@782
    74
  public:
alpar@395
    75
    
deba@782
    76
    typedef ListGraph Graph;
alpar@397
    77
    
alpar@395
    78
    class Node;
alpar@395
    79
    class Edge;
alpar@395
    80
alpar@395
    81
    
alpar@395
    82
  public:
alpar@395
    83
alpar@395
    84
    class NodeIt;
alpar@395
    85
    class EdgeIt;
alpar@395
    86
    class OutEdgeIt;
alpar@395
    87
    class InEdgeIt;
deba@782
    88
alpar@904
    89
    // Create map registries.
deba@782
    90
    CREATE_MAP_REGISTRIES;
alpar@905
    91
    // Create node and edge maps.
deba@897
    92
    CREATE_MAPS(ArrayMap);
deba@782
    93
alpar@395
    94
  public:
alpar@395
    95
deba@782
    96
    ListGraph() 
deba@782
    97
      : nodes(), first_node(-1),
deba@782
    98
	first_free_node(-1), edges(), first_free_edge(-1) {}
deba@782
    99
deba@782
   100
    ListGraph(const ListGraph &_g) 
deba@782
   101
      : nodes(_g.nodes), first_node(_g.first_node),
deba@782
   102
	first_free_node(_g.first_free_node), edges(_g.edges),
deba@782
   103
	first_free_edge(_g.first_free_edge) {}
alpar@395
   104
    
alpar@813
   105
    ///Number of nodes.
alpar@813
   106
    int nodeNum() const { return nodes.size(); }
alpar@813
   107
    ///Number of edges.
alpar@813
   108
    int edgeNum() const { return edges.size(); }
alpar@395
   109
alpar@813
   110
    ///Set the expected maximum number of edges.
alpar@695
   111
alpar@695
   112
    ///With this function, it is possible to set the expected number of edges.
alpar@695
   113
    ///The use of this fasten the building of the graph and makes
alpar@695
   114
    ///it possible to avoid the superfluous memory allocation.
alpar@695
   115
    void reserveEdge(int n) { edges.reserve(n); };
alpar@695
   116
    
alpar@813
   117
    /// Maximum node ID.
alpar@813
   118
    
alpar@813
   119
    /// Maximum node ID.
alpar@813
   120
    ///\sa id(Node)
alpar@813
   121
    int maxNodeId() const { return nodes.size()-1; } 
alpar@813
   122
    /// Maximum edge ID.
alpar@813
   123
    
alpar@813
   124
    /// Maximum edge ID.
alpar@813
   125
    ///\sa id(Edge)
alpar@813
   126
    int maxEdgeId() const { return edges.size()-1; }
alpar@395
   127
alpar@395
   128
    Node tail(Edge e) const { return edges[e.n].tail; }
alpar@395
   129
    Node head(Edge e) const { return edges[e.n].head; }
alpar@395
   130
alpar@713
   131
    NodeIt& first(NodeIt& v) const { 
alpar@395
   132
      v=NodeIt(*this); return v; }
alpar@713
   133
    EdgeIt& first(EdgeIt& e) const { 
alpar@395
   134
      e=EdgeIt(*this); return e; }
alpar@713
   135
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
alpar@395
   136
      e=OutEdgeIt(*this,v); return e; }
alpar@713
   137
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
alpar@395
   138
      e=InEdgeIt(*this,v); return e; }
alpar@395
   139
alpar@813
   140
    /// Node ID.
alpar@813
   141
    
alpar@813
   142
    /// The ID of a valid Node is a nonnegative integer not greater than
alpar@813
   143
    /// \ref maxNodeId(). The range of the ID's is not surely continuous
alpar@813
   144
    /// and the greatest node ID can be actually less then \ref maxNodeId().
alpar@813
   145
    ///
alpar@813
   146
    /// The ID of the \ref INVALID node is -1.
alpar@813
   147
    ///\return The ID of the node \c v. 
alpar@713
   148
    static int id(Node v) { return v.n; }
alpar@813
   149
    /// Edge ID.
alpar@813
   150
    
alpar@813
   151
    /// The ID of a valid Edge is a nonnegative integer not greater than
alpar@813
   152
    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
alpar@813
   153
    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
alpar@813
   154
    ///
alpar@813
   155
    /// The ID of the \ref INVALID edge is -1.
alpar@813
   156
    ///\return The ID of the edge \c e. 
alpar@713
   157
    static int id(Edge e) { return e.n; }
alpar@395
   158
alpar@397
   159
    /// Adds a new node to the graph.
alpar@397
   160
alpar@813
   161
    /// \warning It adds the new node to the front of the list.
alpar@397
   162
    /// (i.e. the lastly added node becomes the first.)
alpar@395
   163
    Node addNode() {
alpar@397
   164
      int n;
alpar@397
   165
      
alpar@397
   166
      if(first_free_node==-1)
alpar@397
   167
	{
alpar@397
   168
	  n = nodes.size();
alpar@397
   169
	  nodes.push_back(NodeT());
alpar@397
   170
	}
alpar@397
   171
      else {
alpar@397
   172
	n = first_free_node;
alpar@397
   173
	first_free_node = nodes[n].next;
alpar@397
   174
      }
alpar@397
   175
      
alpar@397
   176
      nodes[n].next = first_node;
alpar@397
   177
      if(first_node != -1) nodes[first_node].prev = n;
alpar@397
   178
      first_node = n;
alpar@397
   179
      nodes[n].prev = -1;
alpar@397
   180
      
alpar@397
   181
      nodes[n].first_in = nodes[n].first_out = -1;
alpar@397
   182
      
alpar@397
   183
      Node nn; nn.n=n;
alpar@395
   184
alpar@397
   185
      //Update dynamic maps
deba@782
   186
      node_maps.add(nn);
alpar@395
   187
alpar@397
   188
      return nn;
alpar@395
   189
    }
alpar@395
   190
    
alpar@395
   191
    Edge addEdge(Node u, Node v) {
alpar@397
   192
      int n;
alpar@397
   193
      
alpar@397
   194
      if(first_free_edge==-1)
alpar@397
   195
	{
alpar@397
   196
	  n = edges.size();
alpar@397
   197
	  edges.push_back(EdgeT());
alpar@397
   198
	}
alpar@397
   199
      else {
alpar@397
   200
	n = first_free_edge;
alpar@397
   201
	first_free_edge = edges[n].next_in;
alpar@397
   202
      }
alpar@397
   203
      
alpar@397
   204
      edges[n].tail = u.n; edges[n].head = v.n;
alpar@395
   205
alpar@397
   206
      edges[n].next_out = nodes[u.n].first_out;
alpar@397
   207
      if(nodes[u.n].first_out != -1) edges[nodes[u.n].first_out].prev_out = n;
alpar@397
   208
      edges[n].next_in = nodes[v.n].first_in;
alpar@397
   209
      if(nodes[v.n].first_in != -1) edges[nodes[v.n].first_in].prev_in = n;
alpar@397
   210
      edges[n].prev_in = edges[n].prev_out = -1;
alpar@397
   211
	
alpar@397
   212
      nodes[u.n].first_out = nodes[v.n].first_in = n;
alpar@397
   213
alpar@397
   214
      Edge e; e.n=n;
alpar@397
   215
alpar@397
   216
      //Update dynamic maps
deba@782
   217
      edge_maps.add(e);
alpar@395
   218
alpar@395
   219
      return e;
alpar@395
   220
    }
alpar@774
   221
    
alpar@774
   222
    /// Finds an edge between two nodes.
alpar@395
   223
alpar@774
   224
    /// Finds an edge from node \c u to node \c v.
alpar@774
   225
    ///
alpar@774
   226
    /// If \c prev is \ref INVALID (this is the default value), then
alpar@774
   227
    /// It finds the first edge from \c u to \c v. Otherwise it looks for
alpar@774
   228
    /// the next edge from \c u to \c v after \c prev.
alpar@774
   229
    /// \return The found edge or INVALID if there is no such an edge.
alpar@774
   230
    Edge findEdge(Node u,Node v, Edge prev = INVALID) 
alpar@774
   231
    {
alpar@774
   232
      int e = (prev.n==-1)? nodes[u.n].first_out : edges[prev.n].next_out;
alpar@774
   233
      while(e!=-1 && edges[e].tail!=v.n) e = edges[e].next_out;
alpar@774
   234
      prev.n=e;
alpar@774
   235
      return prev;
alpar@774
   236
    }
alpar@774
   237
    
alpar@397
   238
  private:
alpar@397
   239
    void eraseEdge(int n) {
alpar@397
   240
      
alpar@397
   241
      if(edges[n].next_in!=-1)
alpar@397
   242
	edges[edges[n].next_in].prev_in = edges[n].prev_in;
alpar@397
   243
      if(edges[n].prev_in!=-1)
alpar@397
   244
	edges[edges[n].prev_in].next_in = edges[n].next_in;
alpar@397
   245
      else nodes[edges[n].head].first_in = edges[n].next_in;
alpar@397
   246
      
alpar@397
   247
      if(edges[n].next_out!=-1)
alpar@397
   248
	edges[edges[n].next_out].prev_out = edges[n].prev_out;
alpar@397
   249
      if(edges[n].prev_out!=-1)
alpar@397
   250
	edges[edges[n].prev_out].next_out = edges[n].next_out;
alpar@397
   251
      else nodes[edges[n].tail].first_out = edges[n].next_out;
alpar@397
   252
      
alpar@397
   253
      edges[n].next_in = first_free_edge;
alpar@695
   254
      first_free_edge = n;      
alpar@397
   255
alpar@397
   256
      //Update dynamic maps
alpar@397
   257
      Edge e; e.n=n;
deba@782
   258
      edge_maps.erase(e);
deba@782
   259
alpar@397
   260
    }
alpar@397
   261
      
alpar@397
   262
  public:
alpar@397
   263
alpar@397
   264
    void erase(Node nn) {
alpar@397
   265
      int n=nn.n;
alpar@397
   266
      
alpar@397
   267
      int m;
alpar@397
   268
      while((m=nodes[n].first_in)!=-1) eraseEdge(m);
alpar@397
   269
      while((m=nodes[n].first_out)!=-1) eraseEdge(m);
alpar@397
   270
alpar@397
   271
      if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
alpar@397
   272
      if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
alpar@397
   273
      else first_node = nodes[n].next;
alpar@397
   274
      
alpar@397
   275
      nodes[n].next = first_free_node;
alpar@397
   276
      first_free_node = n;
alpar@397
   277
alpar@397
   278
      //Update dynamic maps
deba@782
   279
      node_maps.erase(nn);
deba@782
   280
alpar@397
   281
    }
alpar@397
   282
    
alpar@397
   283
    void erase(Edge e) { eraseEdge(e.n); }
alpar@397
   284
alpar@397
   285
    void clear() {
deba@782
   286
      edge_maps.clear();
deba@782
   287
      edges.clear();
deba@782
   288
      node_maps.clear();
deba@782
   289
      nodes.clear();
alpar@397
   290
      first_node=first_free_node=first_free_edge=-1;
alpar@397
   291
    }
alpar@395
   292
alpar@395
   293
    class Node {
alpar@397
   294
      friend class ListGraph;
alpar@395
   295
      template <typename T> friend class NodeMap;
alpar@400
   296
       
alpar@395
   297
      friend class Edge;
alpar@395
   298
      friend class OutEdgeIt;
alpar@395
   299
      friend class InEdgeIt;
alpar@395
   300
      friend class SymEdge;
alpar@395
   301
alpar@395
   302
    protected:
alpar@395
   303
      int n;
alpar@722
   304
      friend int ListGraph::id(Node v); 
alpar@395
   305
      Node(int nn) {n=nn;}
alpar@395
   306
    public:
alpar@395
   307
      Node() {}
alpar@503
   308
      Node (Invalid) { n=-1; }
alpar@395
   309
      bool operator==(const Node i) const {return n==i.n;}
alpar@395
   310
      bool operator!=(const Node i) const {return n!=i.n;}
alpar@395
   311
      bool operator<(const Node i) const {return n<i.n;}
alpar@774
   312
      //      ///Validity check
alpar@774
   313
      //      operator bool() { return n!=-1; }
alpar@395
   314
    };
alpar@395
   315
    
alpar@395
   316
    class NodeIt : public Node {
alpar@774
   317
      const ListGraph *G;
alpar@397
   318
      friend class ListGraph;
alpar@395
   319
    public:
alpar@400
   320
      NodeIt() : Node() { }
alpar@400
   321
      NodeIt(Invalid i) : Node(i) { }
alpar@774
   322
      NodeIt(const ListGraph& _G) : Node(_G.first_node), G(&_G) { }
alpar@774
   323
      NodeIt(const ListGraph& _G,Node n) : Node(n), G(&_G) { }
alpar@774
   324
      NodeIt &operator++() {
alpar@774
   325
	n=G->nodes[n].next; 
alpar@774
   326
	return *this; 
alpar@774
   327
      }
alpar@774
   328
      //      ///Validity check
alpar@774
   329
      //      operator bool() { return Node::operator bool(); }      
alpar@395
   330
    };
alpar@395
   331
alpar@395
   332
    class Edge {
alpar@397
   333
      friend class ListGraph;
alpar@395
   334
      template <typename T> friend class EdgeMap;
alpar@395
   335
alpar@905
   336
      friend class SymListGraph;
alpar@395
   337
      
alpar@395
   338
      friend class Node;
alpar@395
   339
      friend class NodeIt;
alpar@395
   340
    protected:
alpar@395
   341
      int n;
alpar@722
   342
      friend int ListGraph::id(Edge e);
alpar@395
   343
alpar@706
   344
    public:
alpar@706
   345
      /// An Edge with id \c n.
alpar@706
   346
alpar@706
   347
      /// \bug It should be
alpar@706
   348
      /// obtained by a member function of the Graph.
alpar@395
   349
      Edge(int nn) {n=nn;}
alpar@706
   350
alpar@395
   351
      Edge() { }
alpar@395
   352
      Edge (Invalid) { n=-1; }
alpar@395
   353
      bool operator==(const Edge i) const {return n==i.n;}
alpar@395
   354
      bool operator!=(const Edge i) const {return n!=i.n;}
alpar@395
   355
      bool operator<(const Edge i) const {return n<i.n;}
alpar@774
   356
      //      ///Validity check
alpar@774
   357
      //      operator bool() { return n!=-1; }
alpar@774
   358
   };
alpar@395
   359
    
alpar@395
   360
    class EdgeIt : public Edge {
alpar@774
   361
      const ListGraph *G;
alpar@397
   362
      friend class ListGraph;
alpar@395
   363
    public:
alpar@774
   364
      EdgeIt(const ListGraph& _G) : Edge(), G(&_G) {
alpar@397
   365
      	int m;
alpar@774
   366
	for(m=_G.first_node;
alpar@774
   367
	    m!=-1 && _G.nodes[m].first_in == -1; m = _G.nodes[m].next);
alpar@774
   368
	n = (m==-1)?-1:_G.nodes[m].first_in;
alpar@397
   369
      }
alpar@395
   370
      EdgeIt (Invalid i) : Edge(i) { }
alpar@774
   371
      EdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
alpar@395
   372
      EdgeIt() : Edge() { }
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@880
   428
  ///\ref Graph::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@909
   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
alpar@904
   446
    // Create symmetric map registry.
deba@782
   447
    CREATE_SYM_EDGE_MAP_REGISTRY;
alpar@904
   448
    // Create symmetric edge map.
deba@897
   449
    CREATE_SYM_EDGE_MAP(ArrayMap);
alpar@395
   450
alpar@397
   451
    SymListGraph() : ListGraph() { }
alpar@397
   452
    SymListGraph(const ListGraph &_g) : ListGraph(_g) { }
alpar@397
   453
    ///Adds a pair of oppositely directed edges to the graph.
alpar@395
   454
    Edge addEdge(Node u, Node v)
alpar@395
   455
    {
alpar@397
   456
      Edge e = ListGraph::addEdge(u,v);
deba@782
   457
      Edge f = ListGraph::addEdge(v,u);
deba@782
   458
      sym_edge_maps.add(e);
deba@782
   459
      sym_edge_maps.add(f);
deba@782
   460
      
alpar@395
   461
      return e;
alpar@395
   462
    }
alpar@395
   463
deba@782
   464
    void erase(Node n) { ListGraph::erase(n);}
alpar@395
   465
    ///The oppositely directed edge.
alpar@395
   466
alpar@395
   467
    ///Returns the oppositely directed
alpar@395
   468
    ///pair of the edge \c e.
alpar@713
   469
    static Edge opposite(Edge e)
alpar@395
   470
    {
alpar@395
   471
      Edge f;
alpar@905
   472
      f.n = e.n - 2*(e.n%2) + 1;
alpar@395
   473
      return f;
alpar@395
   474
    }
alpar@395
   475
    
alpar@397
   476
    ///Removes a pair of oppositely directed edges to the graph.
alpar@397
   477
    void erase(Edge e) {
deba@782
   478
      Edge f = opposite(e);
deba@782
   479
      sym_edge_maps.erase(e);
deba@782
   480
      sym_edge_maps.erase(f);
deba@782
   481
      ListGraph::erase(f);
alpar@397
   482
      ListGraph::erase(e);
deba@782
   483
    }    
deba@909
   484
    };*/
deba@909
   485
deba@909
   486
  class SymListGraph : public ListGraph {
deba@909
   487
    typedef ListGraph Parent;
deba@909
   488
  public:
deba@909
   489
deba@909
   490
    typedef SymListGraph Graph;
deba@909
   491
deba@909
   492
    typedef ListGraph::Node Node;
deba@909
   493
    typedef ListGraph::NodeIt NodeIt;
deba@909
   494
deba@909
   495
    class SymEdge;
deba@909
   496
    class SymEdgeIt;
deba@909
   497
deba@909
   498
    class Edge;
deba@909
   499
    class EdgeIt;
deba@909
   500
    class OutEdgeIt;
deba@909
   501
    class InEdgeIt;
deba@909
   502
deba@909
   503
    template <typename Value>
deba@909
   504
    class NodeMap : public Parent::NodeMap<Value> {      
deba@909
   505
    public:
deba@909
   506
      NodeMap(const SymListGraph& g) 
deba@909
   507
	: SymListGraph::Parent::NodeMap<Value>(g) {}
deba@909
   508
      NodeMap(const SymListGraph& g, Value v) 
deba@909
   509
	: SymListGraph::Parent::NodeMap<Value>(g, v) {}
deba@909
   510
      template<typename TT> 
deba@909
   511
      NodeMap(const NodeMap<TT>& copy) 
deba@909
   512
	: SymListGraph::Parent::NodeMap<Value>(copy) { }            
deba@909
   513
    };
deba@909
   514
deba@909
   515
    template <typename Value>
deba@909
   516
    class SymEdgeMap : public Parent::EdgeMap<Value> {
deba@909
   517
    public:
deba@909
   518
      typedef SymEdge KeyType;
deba@909
   519
deba@909
   520
      SymEdgeMap(const SymListGraph& g) 
deba@909
   521
	: SymListGraph::Parent::EdgeMap<Value>(g) {}
deba@909
   522
      SymEdgeMap(const SymListGraph& g, Value v) 
deba@909
   523
	: SymListGraph::Parent::EdgeMap<Value>(g, v) {}
deba@909
   524
      template<typename TT> 
deba@909
   525
      SymEdgeMap(const SymEdgeMap<TT>& copy) 
deba@909
   526
	: SymListGraph::Parent::EdgeMap<Value>(copy) { }
deba@909
   527
      
deba@909
   528
    };
deba@909
   529
deba@909
   530
    // Create edge map registry.
deba@909
   531
    CREATE_EDGE_MAP_REGISTRY;
deba@909
   532
    // Create edge maps.
deba@909
   533
    CREATE_EDGE_MAP(ArrayMap);
deba@909
   534
deba@909
   535
    class Edge {
deba@909
   536
      friend class SymListGraph;
deba@909
   537
      friend class SymListGraph::EdgeIt;
deba@909
   538
      friend class SymListGraph::OutEdgeIt;
deba@909
   539
      friend class SymListGraph::InEdgeIt;
deba@909
   540
      
deba@909
   541
    protected:
deba@909
   542
      int id;
deba@909
   543
deba@909
   544
      Edge(int pid) { id = pid; }
deba@909
   545
deba@909
   546
    public:
deba@909
   547
      /// An Edge with id \c n.
deba@909
   548
deba@909
   549
      Edge() { }
deba@909
   550
      Edge (Invalid) { id = -1; }
deba@909
   551
deba@909
   552
      operator SymEdge(){ return SymEdge(id >> 1);}
deba@909
   553
      
deba@909
   554
      bool operator==(const Edge i) const {return id == i.id;}
deba@909
   555
      bool operator!=(const Edge i) const {return id != i.id;}
deba@909
   556
      bool operator<(const Edge i) const {return id < i.id;}
deba@909
   557
      //      ///Validity check
deba@909
   558
      //      operator bool() { return n!=-1; }
deba@909
   559
    };
deba@909
   560
deba@909
   561
    class SymEdge : public ListGraph::Edge {
deba@909
   562
      friend class SymListGraph;
deba@909
   563
      friend class SymListGraph::Edge;
deba@909
   564
      typedef ListGraph::Edge Parent;
deba@909
   565
deba@909
   566
    protected:      
deba@909
   567
      SymEdge(int pid) : Parent(pid) {}
deba@909
   568
    public:
deba@909
   569
deba@909
   570
      SymEdge() { }
deba@909
   571
      SymEdge(const ListGraph::Edge& i) : Parent(i) {} 
deba@909
   572
      SymEdge (Invalid) : Parent(INVALID) {}
deba@909
   573
deba@909
   574
    };
deba@909
   575
deba@909
   576
    class OutEdgeIt {
deba@909
   577
      Parent::OutEdgeIt out;
deba@909
   578
      Parent::InEdgeIt in;      
deba@909
   579
    public: 
deba@909
   580
      OutEdgeIt() {}
deba@909
   581
      OutEdgeIt(const SymListGraph& g, Edge e) { 
deba@909
   582
	if (e.id & 1 == 0) {	
deba@909
   583
	  out = Parent::OutEdgeIt(g, SymEdge(e));
deba@909
   584
	  in = Parent::InEdgeIt(g, g.tail(e));
deba@909
   585
	} else {
deba@909
   586
	  out = Parent::OutEdgeIt(INVALID);
deba@909
   587
	  in = Parent::InEdgeIt(g, SymEdge(e));
deba@909
   588
	}
deba@909
   589
      }
deba@909
   590
      OutEdgeIt (Invalid i) : out(INVALID), in(INVALID) { }
deba@909
   591
deba@909
   592
      OutEdgeIt(const SymListGraph& g, const Node v)
deba@909
   593
	: out(g, v), in(g, v) {}
deba@909
   594
      OutEdgeIt &operator++() { 
deba@909
   595
	if (out != INVALID) {
deba@909
   596
	  ++out;
deba@909
   597
	} else {
deba@909
   598
	  ++in;
deba@909
   599
	}
deba@909
   600
	return *this; 
deba@909
   601
      }
deba@909
   602
deba@909
   603
      operator Edge() const {
deba@909
   604
	if (out == INVALID && in == INVALID) return INVALID;
deba@909
   605
	return out != INVALID ? forward(out) : backward(in);
deba@909
   606
      }
deba@909
   607
deba@909
   608
      bool operator==(const Edge i) const {return Edge(*this) == i;}
deba@909
   609
      bool operator!=(const Edge i) const {return Edge(*this) != i;}
deba@909
   610
      bool operator<(const Edge i) const {return Edge(*this) < i;}
deba@909
   611
    };
deba@909
   612
deba@909
   613
    class InEdgeIt {
deba@909
   614
      Parent::OutEdgeIt out;
deba@909
   615
      Parent::InEdgeIt in;      
deba@909
   616
    public: 
deba@909
   617
      InEdgeIt() {}
deba@909
   618
      InEdgeIt(const SymListGraph& g, Edge e) { 
deba@909
   619
	if (e.id & 1 == 0) {	
deba@909
   620
	  out = Parent::OutEdgeIt(g, SymEdge(e));
deba@909
   621
	  in = Parent::InEdgeIt(g, g.tail(e));
deba@909
   622
	} else {
deba@909
   623
	  out = Parent::OutEdgeIt(INVALID);
deba@909
   624
	  in = Parent::InEdgeIt(g, SymEdge(e));
deba@909
   625
	}
deba@909
   626
      }
deba@909
   627
      InEdgeIt (Invalid i) : out(INVALID), in(INVALID) { }
deba@909
   628
deba@909
   629
      InEdgeIt(const SymListGraph& g, const Node v)
deba@909
   630
	: out(g, v), in(g, v) {}
deba@909
   631
deba@909
   632
      InEdgeIt &operator++() { 
deba@909
   633
	if (out != INVALID) {
deba@909
   634
	  ++out;
deba@909
   635
	} else {
deba@909
   636
	  ++in;
deba@909
   637
	}
deba@909
   638
	return *this; 
deba@909
   639
      }
deba@909
   640
deba@909
   641
      operator Edge() const {
deba@909
   642
	if (out == INVALID && in == INVALID) return INVALID;
deba@909
   643
	return out != INVALID ? backward(out) : forward(in);
deba@909
   644
      }
deba@909
   645
deba@909
   646
      bool operator==(const Edge i) const {return Edge(*this) == i;}
deba@909
   647
      bool operator!=(const Edge i) const {return Edge(*this) != i;}
deba@909
   648
      bool operator<(const Edge i) const {return Edge(*this) < i;}
deba@909
   649
    };
deba@909
   650
deba@909
   651
    class SymEdgeIt : public Parent::EdgeIt {
deba@909
   652
deba@909
   653
    public:
deba@909
   654
      SymEdgeIt() {}
deba@909
   655
deba@909
   656
      SymEdgeIt(const SymListGraph& g) 
deba@909
   657
	: SymListGraph::Parent::EdgeIt(g) {}
deba@909
   658
deba@909
   659
      SymEdgeIt(const SymListGraph& g, SymEdge e) 
deba@909
   660
	: SymListGraph::Parent::EdgeIt(g, e) {}
deba@909
   661
deba@909
   662
      SymEdgeIt(Invalid i) 
deba@909
   663
	: SymListGraph::Parent::EdgeIt(INVALID) {}
deba@909
   664
deba@909
   665
      SymEdgeIt& operator++() {
deba@909
   666
	SymListGraph::Parent::EdgeIt::operator++();
deba@909
   667
	return *this;
deba@909
   668
      }
deba@909
   669
deba@909
   670
      operator SymEdge() const {
deba@909
   671
	return SymEdge
deba@909
   672
	  (static_cast<const SymListGraph::Parent::EdgeIt&>(*this));
deba@909
   673
      }
deba@909
   674
      bool operator==(const SymEdge i) const {return SymEdge(*this) == i;}
deba@909
   675
      bool operator!=(const SymEdge i) const {return SymEdge(*this) != i;}
deba@909
   676
      bool operator<(const SymEdge i) const {return SymEdge(*this) < i;}
deba@909
   677
    };
deba@909
   678
deba@909
   679
    class EdgeIt {
deba@909
   680
      SymEdgeIt it;
deba@909
   681
      bool fw;
deba@909
   682
    public:
deba@909
   683
      EdgeIt(const SymListGraph& g) : it(g), fw(true) {}
deba@909
   684
      EdgeIt (Invalid i) : it(i) { }
deba@909
   685
      EdgeIt(const SymListGraph& g, Edge e) 
deba@909
   686
	: it(g, SymEdge(e)), fw(id(e) & 1 == 0) { }
deba@909
   687
      EdgeIt() { }
deba@909
   688
      EdgeIt& operator++() {
deba@909
   689
	fw = !fw;
deba@909
   690
	if (fw) ++it;
deba@909
   691
	return *this;
deba@909
   692
      }
deba@909
   693
      operator Edge() const {
deba@909
   694
	if (it == INVALID) return INVALID;
deba@909
   695
	return fw ? forward(it) : backward(it);
deba@909
   696
      }
deba@909
   697
      bool operator==(const Edge i) const {return Edge(*this) == i;}
deba@909
   698
      bool operator!=(const Edge i) const {return Edge(*this) != i;}
deba@909
   699
      bool operator<(const Edge i) const {return Edge(*this) < i;}
deba@909
   700
deba@909
   701
    };
deba@909
   702
deba@909
   703
    ///Number of nodes.
deba@909
   704
    int nodeNum() const { return Parent::nodeNum(); }
deba@909
   705
    ///Number of edges.
deba@909
   706
    int edgeNum() const { return 2*Parent::edgeNum(); }
deba@909
   707
    ///Number of symmetric edges.
deba@909
   708
    int symEdgeNum() const { return Parent::edgeNum(); }
deba@909
   709
deba@909
   710
    ///Set the expected maximum number of edges.
deba@909
   711
deba@909
   712
    ///With this function, it is possible to set the expected number of edges.
deba@909
   713
    ///The use of this fasten the building of the graph and makes
deba@909
   714
    ///it possible to avoid the superfluous memory allocation.
deba@909
   715
    void reserveSymEdge(int n) { Parent::reserveEdge(n); };
deba@909
   716
    
deba@909
   717
    /// Maximum node ID.
deba@909
   718
    
deba@909
   719
    /// Maximum node ID.
deba@909
   720
    ///\sa id(Node)
deba@909
   721
    int maxNodeId() const { return Parent::maxNodeId(); } 
deba@909
   722
    /// Maximum edge ID.
deba@909
   723
    
deba@909
   724
    /// Maximum edge ID.
deba@909
   725
    ///\sa id(Edge)
deba@909
   726
    int maxEdgeId() const { return 2*Parent::maxEdgeId(); }
deba@909
   727
    /// Maximum symmetric edge ID.
deba@909
   728
    
deba@909
   729
    /// Maximum symmetric edge ID.
deba@909
   730
    ///\sa id(SymEdge)
deba@909
   731
    int maxSymEdgeId() const { return Parent::maxEdgeId(); }
deba@909
   732
deba@909
   733
deba@909
   734
    Node tail(Edge e) const { 
deba@909
   735
      return e.id & 1 == 0 ? 
deba@909
   736
	Parent::tail(SymEdge(e)) : Parent::head(SymEdge(e)); 
deba@909
   737
    }
deba@909
   738
deba@909
   739
    Node head(Edge e) const { 
deba@909
   740
      return e.id & 1 == 0 ? 
deba@909
   741
	Parent::head(SymEdge(e)) : Parent::tail(SymEdge(e)); 
deba@909
   742
    }
deba@909
   743
deba@909
   744
    Node tail(SymEdge e) const { 
deba@909
   745
      return Parent::tail(e); 
deba@909
   746
    }
deba@909
   747
deba@909
   748
    Node head(SymEdge e) const { 
deba@909
   749
      return Parent::head(e); 
deba@909
   750
    }
deba@909
   751
deba@909
   752
    NodeIt& first(NodeIt& v) const { 
deba@909
   753
      v=NodeIt(*this); return v; }
deba@909
   754
    EdgeIt& first(EdgeIt& e) const { 
deba@909
   755
      e=EdgeIt(*this); return e; }
deba@909
   756
    SymEdgeIt& first(SymEdgeIt& e) const {
deba@909
   757
      e=SymEdgeIt(*this); return e; }
deba@909
   758
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
deba@909
   759
      e=OutEdgeIt(*this,v); return e; }
deba@909
   760
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
deba@909
   761
      e=InEdgeIt(*this,v); return e; }
deba@909
   762
deba@909
   763
    /// Node ID.
deba@909
   764
    
deba@909
   765
    /// The ID of a valid Node is a nonnegative integer not greater than
deba@909
   766
    /// \ref maxNodeId(). The range of the ID's is not surely continuous
deba@909
   767
    /// and the greatest node ID can be actually less then \ref maxNodeId().
deba@909
   768
    ///
deba@909
   769
    /// The ID of the \ref INVALID node is -1.
deba@909
   770
    ///\return The ID of the node \c v. 
deba@909
   771
    static int id(Node v) { return Parent::id(v); }
deba@909
   772
    /// Edge ID.
deba@909
   773
    
deba@909
   774
    /// The ID of a valid Edge is a nonnegative integer not greater than
deba@909
   775
    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
deba@909
   776
    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
deba@909
   777
    ///
deba@909
   778
    /// The ID of the \ref INVALID edge is -1.
deba@909
   779
    ///\return The ID of the edge \c e. 
deba@909
   780
    static int id(Edge e) { return e.id; }
deba@909
   781
deba@909
   782
    /// The ID of a valid SymEdge is a nonnegative integer not greater than
deba@909
   783
    /// \ref maxSymEdgeId(). The range of the ID's is not surely continuous
deba@909
   784
    /// and the greatest edge ID can be actually less then \ref maxSymEdgeId().
deba@909
   785
    ///
deba@909
   786
    /// The ID of the \ref INVALID symmetric edge is -1.
deba@909
   787
    ///\return The ID of the edge \c e. 
deba@909
   788
    static int id(SymEdge e) { return Parent::id(e); }
deba@909
   789
deba@909
   790
    /// Adds a new node to the graph.
deba@909
   791
deba@909
   792
    /// \warning It adds the new node to the front of the list.
deba@909
   793
    /// (i.e. the lastly added node becomes the first.)
deba@909
   794
    Node addNode() {
deba@909
   795
      return Parent::addNode();
deba@909
   796
    }
deba@909
   797
    
deba@909
   798
    SymEdge addEdge(Node u, Node v) {
deba@909
   799
      SymEdge se = Parent::addEdge(u, v);
deba@909
   800
      edge_maps.add(forward(se));
deba@909
   801
      edge_maps.add(backward(se));
deba@909
   802
      return se;
deba@909
   803
    }
deba@909
   804
    
deba@909
   805
    /// Finds an edge between two nodes.
deba@909
   806
deba@909
   807
    /// Finds an edge from node \c u to node \c v.
deba@909
   808
    ///
deba@909
   809
    /// If \c prev is \ref INVALID (this is the default value), then
deba@909
   810
    /// It finds the first edge from \c u to \c v. Otherwise it looks for
deba@909
   811
    /// the next edge from \c u to \c v after \c prev.
deba@909
   812
    /// \return The found edge or INVALID if there is no such an edge.
deba@909
   813
    Edge findEdge(Node u, Node v, Edge prev = INVALID) 
deba@909
   814
    {     
deba@909
   815
      if (prev == INVALID || id(prev) & 1 == 0) {
deba@909
   816
	SymEdge se = Parent::findEdge(u, v, SymEdge(prev));
deba@909
   817
	if (se != INVALID) return forward(se);
deba@909
   818
      } else {
deba@909
   819
	SymEdge se = Parent::findEdge(v, u, SymEdge(prev));
deba@909
   820
	if (se != INVALID) return backward(se);	
deba@909
   821
      }
deba@909
   822
      return INVALID;
deba@909
   823
    }
deba@909
   824
deba@909
   825
    /// Finds an symmetric edge between two nodes.
deba@909
   826
deba@909
   827
    /// Finds an symmetric edge from node \c u to node \c v.
deba@909
   828
    ///
deba@909
   829
    /// If \c prev is \ref INVALID (this is the default value), then
deba@909
   830
    /// It finds the first edge from \c u to \c v. Otherwise it looks for
deba@909
   831
    /// the next edge from \c u to \c v after \c prev.
deba@909
   832
    /// \return The found edge or INVALID if there is no such an edge.
deba@909
   833
deba@909
   834
//     SymEdge findEdge(Node u, Node v, SymEdge prev = INVALID) 
deba@909
   835
//     {     
deba@909
   836
//       if (prev == INVALID || id(prev) & 1 == 0) {
deba@909
   837
// 	SymEdge se = Parent::findEdge(u, v, SymEdge(prev));
deba@909
   838
// 	if (se != INVALID) return se;
deba@909
   839
//       } else {
deba@909
   840
// 	SymEdge se = Parent::findEdge(v, u, SymEdge(prev));
deba@909
   841
// 	if (se != INVALID) return se;	
deba@909
   842
//       }
deba@909
   843
//       return INVALID;
deba@909
   844
//     }
deba@909
   845
    
deba@909
   846
  public:
deba@909
   847
deba@909
   848
    void erase(Node n) {      
deba@909
   849
      for (OutEdgeIt it(*this, n); it != INVALID; ++it) {
deba@909
   850
	edge_maps.erase(it);
deba@909
   851
	edge_maps.erase(opposite(it));
deba@909
   852
      }
deba@909
   853
      Parent::erase(n);
deba@909
   854
    }
deba@909
   855
    
deba@909
   856
    void erase(SymEdge e) { 
deba@909
   857
      edge_maps.erase(forward(e));
deba@909
   858
      edge_maps.erase(backward(e));
deba@909
   859
      Parent::erase(e); 
deba@909
   860
    };
deba@909
   861
deba@909
   862
    void clear() {
deba@909
   863
      edge_maps.clear();
deba@909
   864
      Parent::clear();
deba@909
   865
    }
deba@909
   866
deba@909
   867
    static Edge opposite(Edge e) {
deba@909
   868
      return Edge(id(e) ^ 1);
deba@909
   869
    }
deba@909
   870
deba@909
   871
    static Edge forward(SymEdge e) {
deba@909
   872
      return Edge(id(e) << 1);
deba@909
   873
    }
deba@909
   874
deba@909
   875
    static Edge backward(SymEdge e) {
deba@909
   876
      return Edge((id(e) << 1) & 1);
deba@909
   877
    }
deba@909
   878
deba@782
   879
  };
alpar@395
   880
alpar@401
   881
  ///A graph class containing only nodes.
alpar@400
   882
alpar@401
   883
  ///This class implements a graph structure without edges.
alpar@401
   884
  ///The most useful application of this class is to be the node set of an
alpar@401
   885
  ///\ref EdgeSet class.
alpar@400
   886
  ///
alpar@880
   887
  ///It conforms to 
alpar@880
   888
  ///the \ref skeleton::ExtendableGraph "ExtendableGraph" concept
alpar@880
   889
  ///with the exception that you cannot
alpar@401
   890
  ///add (or delete) edges. The usual edge iterators are exists, but they are
alpar@401
   891
  ///always \ref INVALID.
alpar@880
   892
  ///\sa skeleton::ExtendableGraph
alpar@880
   893
  ///\sa EdgeSet
alpar@400
   894
  class NodeSet {
alpar@400
   895
alpar@400
   896
    //Nodes are double linked.
alpar@400
   897
    //The free nodes are only single linked using the "next" field.
alpar@400
   898
    struct NodeT 
alpar@400
   899
    {
alpar@400
   900
      int first_in,first_out;
alpar@400
   901
      int prev, next;
alpar@400
   902
      //      NodeT() {}
alpar@400
   903
    };
alpar@400
   904
alpar@400
   905
    std::vector<NodeT> nodes;
alpar@400
   906
    //The first node
alpar@400
   907
    int first_node;
alpar@400
   908
    //The first free node
alpar@400
   909
    int first_free_node;
alpar@400
   910
    
alpar@400
   911
  public:
deba@782
   912
deba@782
   913
    typedef NodeSet Graph;
alpar@400
   914
    
alpar@400
   915
    class Node;
alpar@400
   916
    class Edge;
alpar@400
   917
alpar@400
   918
  public:
alpar@400
   919
alpar@400
   920
    class NodeIt;
alpar@400
   921
    class EdgeIt;
alpar@400
   922
    class OutEdgeIt;
alpar@400
   923
    class InEdgeIt;
alpar@400
   924
    
alpar@904
   925
    // Create node map registry.
deba@822
   926
    CREATE_NODE_MAP_REGISTRY;
alpar@904
   927
    // Create node maps.
deba@897
   928
    CREATE_NODE_MAP(ArrayMap);
deba@822
   929
deba@822
   930
    /// Creating empty map structure for edges.
deba@822
   931
    template <typename Value>
deba@822
   932
    class EdgeMap {
deba@822
   933
    public:
deba@822
   934
      EdgeMap(const Graph&) {}
deba@822
   935
      EdgeMap(const Graph&, const Value&) {}
deba@822
   936
deba@822
   937
      EdgeMap(const EdgeMap&) {}
deba@822
   938
      template <typename CMap> EdgeMap(const CMap&) {}
deba@822
   939
deba@822
   940
      EdgeMap& operator=(const EdgeMap&) {}
deba@822
   941
      template <typename CMap> EdgeMap& operator=(const CMap&) {}
deba@822
   942
      
deba@822
   943
      class ConstIterator {
deba@822
   944
      public:
deba@822
   945
	bool operator==(const ConstIterator&) {return true;}
deba@822
   946
	bool operator!=(const ConstIterator&) {return false;}
deba@822
   947
      };
deba@822
   948
deba@822
   949
      typedef ConstIterator Iterator;
deba@822
   950
      
deba@822
   951
      Iterator begin() { return Iterator();}
deba@822
   952
      Iterator end() { return Iterator();}
deba@822
   953
deba@822
   954
      ConstIterator begin() const { return ConstIterator();}
deba@822
   955
      ConstIterator end() const { return ConstIterator();}
deba@822
   956
deba@822
   957
    };
alpar@400
   958
    
alpar@400
   959
  public:
alpar@400
   960
alpar@408
   961
    ///Default constructor
deba@782
   962
    NodeSet() 
deba@782
   963
      : nodes(), first_node(-1), first_free_node(-1) {}
alpar@408
   964
    ///Copy constructor
deba@782
   965
    NodeSet(const NodeSet &_g) 
deba@782
   966
      : nodes(_g.nodes), first_node(_g.first_node),
deba@782
   967
	first_free_node(_g.first_free_node) {}
alpar@400
   968
    
alpar@813
   969
    ///Number of nodes.
alpar@813
   970
    int nodeNum() const { return nodes.size(); }
alpar@813
   971
    ///Number of edges.
alpar@813
   972
    int edgeNum() const { return 0; }
alpar@400
   973
alpar@813
   974
    /// Maximum node ID.
alpar@813
   975
    
alpar@813
   976
    /// Maximum node ID.
alpar@813
   977
    ///\sa id(Node)
alpar@813
   978
    int maxNodeId() const { return nodes.size()-1; }
alpar@813
   979
    /// Maximum edge ID.
alpar@813
   980
    
alpar@813
   981
    /// Maximum edge ID.
alpar@813
   982
    ///\sa id(Edge)
alpar@813
   983
    int maxEdgeId() const { return 0; }
alpar@400
   984
alpar@400
   985
    Node tail(Edge e) const { return INVALID; }
alpar@400
   986
    Node head(Edge e) const { return INVALID; }
alpar@400
   987
alpar@400
   988
    NodeIt& first(NodeIt& v) const { 
alpar@400
   989
      v=NodeIt(*this); return v; }
alpar@400
   990
    EdgeIt& first(EdgeIt& e) const { 
alpar@400
   991
      e=EdgeIt(*this); return e; }
alpar@400
   992
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
alpar@400
   993
      e=OutEdgeIt(*this,v); return e; }
alpar@400
   994
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
alpar@400
   995
      e=InEdgeIt(*this,v); return e; }
alpar@400
   996
alpar@813
   997
    /// Node ID.
alpar@813
   998
    
alpar@813
   999
    /// The ID of a valid Node is a nonnegative integer not greater than
alpar@813
  1000
    /// \ref maxNodeId(). The range of the ID's is not surely continuous
alpar@813
  1001
    /// and the greatest node ID can be actually less then \ref maxNodeId().
alpar@813
  1002
    ///
alpar@813
  1003
    /// The ID of the \ref INVALID node is -1.
alpar@813
  1004
    ///\return The ID of the node \c v. 
alpar@905
  1005
    static int id(Node v) { return v.n; }
alpar@813
  1006
    /// Edge ID.
alpar@813
  1007
    
alpar@813
  1008
    /// The ID of a valid Edge is a nonnegative integer not greater than
alpar@813
  1009
    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
alpar@813
  1010
    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
alpar@813
  1011
    ///
alpar@813
  1012
    /// The ID of the \ref INVALID edge is -1.
alpar@813
  1013
    ///\return The ID of the edge \c e. 
alpar@905
  1014
    static int id(Edge e) { return -1; }
alpar@400
  1015
alpar@400
  1016
    /// Adds a new node to the graph.
alpar@400
  1017
alpar@813
  1018
    /// \warning It adds the new node to the front of the list.
alpar@400
  1019
    /// (i.e. the lastly added node becomes the first.)
alpar@400
  1020
    Node addNode() {
alpar@400
  1021
      int n;
alpar@400
  1022
      
alpar@400
  1023
      if(first_free_node==-1)
alpar@400
  1024
	{
alpar@400
  1025
	  n = nodes.size();
alpar@400
  1026
	  nodes.push_back(NodeT());
alpar@400
  1027
	}
alpar@400
  1028
      else {
alpar@400
  1029
	n = first_free_node;
alpar@400
  1030
	first_free_node = nodes[n].next;
alpar@400
  1031
      }
alpar@400
  1032
      
alpar@400
  1033
      nodes[n].next = first_node;
alpar@400
  1034
      if(first_node != -1) nodes[first_node].prev = n;
alpar@400
  1035
      first_node = n;
alpar@400
  1036
      nodes[n].prev = -1;
alpar@400
  1037
      
alpar@400
  1038
      nodes[n].first_in = nodes[n].first_out = -1;
alpar@400
  1039
      
alpar@400
  1040
      Node nn; nn.n=n;
alpar@400
  1041
alpar@400
  1042
      //Update dynamic maps
deba@782
  1043
      node_maps.add(nn);
alpar@400
  1044
alpar@400
  1045
      return nn;
alpar@400
  1046
    }
alpar@400
  1047
    
alpar@400
  1048
    void erase(Node nn) {
alpar@400
  1049
      int n=nn.n;
alpar@400
  1050
      
alpar@400
  1051
      if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
alpar@400
  1052
      if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
alpar@400
  1053
      else first_node = nodes[n].next;
alpar@400
  1054
      
alpar@400
  1055
      nodes[n].next = first_free_node;
alpar@400
  1056
      first_free_node = n;
alpar@400
  1057
alpar@400
  1058
      //Update dynamic maps
deba@782
  1059
      node_maps.erase(nn);
alpar@400
  1060
    }
alpar@400
  1061
    
alpar@774
  1062
        
alpar@774
  1063
    Edge findEdge(Node u,Node v, Edge prev = INVALID) 
alpar@774
  1064
    {
alpar@774
  1065
      return INVALID;
alpar@774
  1066
    }
alpar@774
  1067
    
alpar@400
  1068
    void clear() {
deba@782
  1069
      node_maps.clear();
alpar@400
  1070
      nodes.clear();
alpar@400
  1071
      first_node = first_free_node = -1;
alpar@400
  1072
    }
alpar@400
  1073
alpar@400
  1074
    class Node {
alpar@400
  1075
      friend class NodeSet;
alpar@400
  1076
      template <typename T> friend class NodeMap;
alpar@400
  1077
      
alpar@400
  1078
      friend class Edge;
alpar@400
  1079
      friend class OutEdgeIt;
alpar@400
  1080
      friend class InEdgeIt;
alpar@400
  1081
alpar@400
  1082
    protected:
alpar@400
  1083
      int n;
alpar@905
  1084
      friend int NodeSet::id(Node v); 
alpar@400
  1085
      Node(int nn) {n=nn;}
alpar@400
  1086
    public:
alpar@400
  1087
      Node() {}
alpar@400
  1088
      Node (Invalid i) { n=-1; }
alpar@400
  1089
      bool operator==(const Node i) const {return n==i.n;}
alpar@400
  1090
      bool operator!=(const Node i) const {return n!=i.n;}
alpar@400
  1091
      bool operator<(const Node i) const {return n<i.n;}
alpar@400
  1092
    };
alpar@400
  1093
    
alpar@400
  1094
    class NodeIt : public Node {
alpar@774
  1095
      const NodeSet *G;
alpar@400
  1096
      friend class NodeSet;
alpar@400
  1097
    public:
alpar@579
  1098
      NodeIt() : Node() { }
alpar@774
  1099
      NodeIt(const NodeSet& _G,Node n) : Node(n), G(&_G) { }
alpar@579
  1100
      NodeIt(Invalid i) : Node(i) { }
alpar@774
  1101
      NodeIt(const NodeSet& _G) : Node(_G.first_node), G(&_G) { }
alpar@774
  1102
      NodeIt &operator++() {
alpar@774
  1103
	n=G->nodes[n].next; 
alpar@774
  1104
	return *this; 
alpar@774
  1105
      }
alpar@400
  1106
    };
alpar@400
  1107
alpar@400
  1108
    class Edge {
alpar@400
  1109
    public:
alpar@400
  1110
      Edge() { }
alpar@400
  1111
      Edge (Invalid) { }
alpar@400
  1112
      bool operator==(const Edge i) const {return true;}
alpar@400
  1113
      bool operator!=(const Edge i) const {return false;}
alpar@400
  1114
      bool operator<(const Edge i) const {return false;}
alpar@400
  1115
    };
alpar@400
  1116
    
alpar@400
  1117
    class EdgeIt : public Edge {
alpar@400
  1118
    public:
alpar@400
  1119
      EdgeIt(const NodeSet& G) : Edge() { }
alpar@774
  1120
      EdgeIt(const NodeSet&, Edge) : Edge() { }
alpar@400
  1121
      EdgeIt (Invalid i) : Edge(i) { }
alpar@400
  1122
      EdgeIt() : Edge() { }
alpar@774
  1123
      EdgeIt operator++() { return INVALID; }
alpar@400
  1124
    };
alpar@400
  1125
    
alpar@400
  1126
    class OutEdgeIt : public Edge {
alpar@400
  1127
      friend class NodeSet;
alpar@400
  1128
    public: 
alpar@400
  1129
      OutEdgeIt() : Edge() { }
alpar@774
  1130
      OutEdgeIt(const NodeSet&, Edge) : Edge() { }
alpar@400
  1131
      OutEdgeIt (Invalid i) : Edge(i) { }
alpar@400
  1132
      OutEdgeIt(const NodeSet& G,const Node v)	: Edge() {}
alpar@774
  1133
      OutEdgeIt operator++() { return INVALID; }
alpar@400
  1134
    };
alpar@400
  1135
    
alpar@400
  1136
    class InEdgeIt : public Edge {
alpar@400
  1137
      friend class NodeSet;
alpar@400
  1138
    public: 
alpar@400
  1139
      InEdgeIt() : Edge() { }
alpar@774
  1140
      InEdgeIt(const NodeSet&, Edge) : Edge() { }
alpar@400
  1141
      InEdgeIt (Invalid i) : Edge(i) { }
alpar@400
  1142
      InEdgeIt(const NodeSet& G,Node v) :Edge() {}
alpar@774
  1143
      InEdgeIt operator++() { return INVALID; }
alpar@400
  1144
    };
alpar@400
  1145
alpar@400
  1146
  };
alpar@400
  1147
alpar@400
  1148
alpar@400
  1149
alpar@401
  1150
  ///Graph structure using a node set of another graph.
alpar@401
  1151
alpar@401
  1152
  ///This structure can be used to establish another graph over a node set
alpar@401
  1153
  /// of an existing one. The node iterator will go through the nodes of the
alpar@401
  1154
  /// original graph, and the NodeMap's of both graphs will convert to
alpar@401
  1155
  /// each other.
alpar@401
  1156
  ///
alpar@404
  1157
  ///\warning Adding or deleting nodes from the graph is not safe if an
alpar@404
  1158
  ///\ref EdgeSet is currently attached to it!
alpar@404
  1159
  ///
alpar@404
  1160
  ///\todo Make it possible to add/delete edges from the base graph
alpar@404
  1161
  ///(and from \ref EdgeSet, as well)
alpar@404
  1162
  ///
alpar@401
  1163
  ///\param GG The type of the graph which shares its node set with this class.
alpar@880
  1164
  ///Its interface must conform to the
alpar@880
  1165
  ///\ref skeleton::StaticGraph "StaticGraph" concept.
alpar@400
  1166
  ///
alpar@880
  1167
  ///It conforms to the 
alpar@880
  1168
  ///\ref skeleton::ExtendableGraph "ExtendableGraph" concept.
alpar@880
  1169
  ///\sa skeleton::ExtendableGraph.
alpar@880
  1170
  ///\sa NodeSet.
alpar@400
  1171
  template<typename GG>
alpar@400
  1172
  class EdgeSet {
alpar@400
  1173
alpar@400
  1174
    typedef GG NodeGraphType;
alpar@400
  1175
alpar@400
  1176
    NodeGraphType &G;
alpar@400
  1177
alpar@515
  1178
  public:
deba@782
  1179
alpar@400
  1180
    class Node;
alpar@705
  1181
    class Edge;
alpar@705
  1182
    class OutEdgeIt;
alpar@705
  1183
    class InEdgeIt;
alpar@705
  1184
    class SymEdge;
deba@782
  1185
deba@782
  1186
    typedef EdgeSet Graph;
deba@782
  1187
alpar@531
  1188
    int id(Node v) const; 
alpar@531
  1189
alpar@531
  1190
    class Node : public NodeGraphType::Node {
alpar@531
  1191
      friend class EdgeSet;
alpar@531
  1192
      
alpar@531
  1193
      friend class Edge;
alpar@531
  1194
      friend class OutEdgeIt;
alpar@531
  1195
      friend class InEdgeIt;
alpar@531
  1196
      friend class SymEdge;
alpar@531
  1197
alpar@531
  1198
    public:
alpar@531
  1199
      friend int EdgeSet::id(Node v) const; 
alpar@531
  1200
    public:
alpar@531
  1201
      Node() : NodeGraphType::Node() {}
alpar@531
  1202
      Node (Invalid i) : NodeGraphType::Node(i) {}
alpar@531
  1203
      Node(const typename NodeGraphType::Node &n) : NodeGraphType::Node(n) {}
alpar@531
  1204
    };
alpar@531
  1205
    
alpar@531
  1206
    class NodeIt : public NodeGraphType::NodeIt {
alpar@531
  1207
      friend class EdgeSet;
alpar@531
  1208
    public:
alpar@531
  1209
      NodeIt() : NodeGraphType::NodeIt() { }
alpar@774
  1210
      NodeIt(const EdgeSet& _G,Node n) : NodeGraphType::NodeIt(_G.G,n) { }
alpar@531
  1211
      NodeIt (Invalid i) : NodeGraphType::NodeIt(i) {}
alpar@531
  1212
      NodeIt(const EdgeSet& _G) : NodeGraphType::NodeIt(_G.G) { }
alpar@531
  1213
      NodeIt(const typename NodeGraphType::NodeIt &n)
alpar@531
  1214
	: NodeGraphType::NodeIt(n) {}
alpar@579
  1215
alpar@531
  1216
      operator Node() { return Node(*this);}
alpar@774
  1217
      NodeIt &operator++()
alpar@774
  1218
      { this->NodeGraphType::NodeIt::operator++(); return *this;} 
alpar@531
  1219
    };
alpar@515
  1220
alpar@515
  1221
  private:
alpar@400
  1222
    //Edges are double linked.
alpar@400
  1223
    //The free edges are only single linked using the "next_in" field.
alpar@400
  1224
    struct NodeT 
alpar@400
  1225
    {
alpar@400
  1226
      int first_in,first_out;
alpar@400
  1227
      NodeT() : first_in(-1), first_out(-1) { }
alpar@400
  1228
    };
alpar@400
  1229
alpar@400
  1230
    struct EdgeT 
alpar@400
  1231
    {
alpar@400
  1232
      Node head, tail;
alpar@400
  1233
      int prev_in, prev_out;
alpar@400
  1234
      int next_in, next_out;
alpar@400
  1235
    };
alpar@400
  1236
alpar@400
  1237
    
alpar@515
  1238
    typename NodeGraphType::template NodeMap<NodeT> nodes;
alpar@400
  1239
    
alpar@400
  1240
    std::vector<EdgeT> edges;
alpar@400
  1241
    //The first free edge
alpar@400
  1242
    int first_free_edge;
alpar@400
  1243
    
alpar@400
  1244
  public:
alpar@400
  1245
    
alpar@400
  1246
    class Node;
alpar@400
  1247
    class Edge;
alpar@400
  1248
alpar@400
  1249
    class NodeIt;
alpar@400
  1250
    class EdgeIt;
alpar@400
  1251
    class OutEdgeIt;
alpar@400
  1252
    class InEdgeIt;
deba@782
  1253
deba@782
  1254
alpar@904
  1255
    // Create edge map registry.
deba@782
  1256
    CREATE_EDGE_MAP_REGISTRY;
alpar@904
  1257
    // Create edge maps.
deba@897
  1258
    CREATE_EDGE_MAP(ArrayMap);
deba@822
  1259
alpar@904
  1260
    // Import node maps from the NodeGraphType.
deba@822
  1261
    IMPORT_NODE_MAP(NodeGraphType, graph.G, EdgeSet, graph);
alpar@400
  1262
    
alpar@400
  1263
    
alpar@400
  1264
  public:
alpar@400
  1265
alpar@408
  1266
    ///Constructor
alpar@408
  1267
    
alpar@408
  1268
    ///Construates a new graph based on the nodeset of an existing one.
alpar@408
  1269
    ///\param _G the base graph.
alpar@880
  1270
    explicit EdgeSet(NodeGraphType &_G) 
deba@782
  1271
      : G(_G), nodes(_G), edges(),
deba@782
  1272
	first_free_edge(-1) {}
alpar@408
  1273
    ///Copy constructor
alpar@408
  1274
alpar@408
  1275
    ///Makes a copy of an EdgeSet.
alpar@408
  1276
    ///It will be based on the same graph.
alpar@880
  1277
    explicit EdgeSet(const EdgeSet &_g) 
deba@782
  1278
      : G(_g.G), nodes(_g.G), edges(_g.edges),
deba@782
  1279
	first_free_edge(_g.first_free_edge) {}
alpar@400
  1280
    
alpar@813
  1281
    ///Number of nodes.
alpar@813
  1282
    int nodeNum() const { return G.nodeNum(); }
alpar@813
  1283
    ///Number of edges.
alpar@813
  1284
    int edgeNum() const { return edges.size(); }
alpar@400
  1285
alpar@813
  1286
    /// Maximum node ID.
alpar@813
  1287
    
alpar@813
  1288
    /// Maximum node ID.
alpar@813
  1289
    ///\sa id(Node)
alpar@813
  1290
    int maxNodeId() const { return G.maxNodeId(); }
alpar@813
  1291
    /// Maximum edge ID.
alpar@813
  1292
    
alpar@813
  1293
    /// Maximum edge ID.
alpar@813
  1294
    ///\sa id(Edge)
alpar@813
  1295
    int maxEdgeId() const { return edges.size()-1; }
alpar@400
  1296
alpar@400
  1297
    Node tail(Edge e) const { return edges[e.n].tail; }
alpar@400
  1298
    Node head(Edge e) const { return edges[e.n].head; }
alpar@400
  1299
alpar@400
  1300
    NodeIt& first(NodeIt& v) const { 
alpar@400
  1301
      v=NodeIt(*this); return v; }
alpar@400
  1302
    EdgeIt& first(EdgeIt& e) const { 
alpar@400
  1303
      e=EdgeIt(*this); return e; }
alpar@400
  1304
    OutEdgeIt& first(OutEdgeIt& e, const Node v) const { 
alpar@400
  1305
      e=OutEdgeIt(*this,v); return e; }
alpar@400
  1306
    InEdgeIt& first(InEdgeIt& e, const Node v) const { 
alpar@400
  1307
      e=InEdgeIt(*this,v); return e; }
alpar@400
  1308
alpar@813
  1309
    /// Node ID.
alpar@813
  1310
    
alpar@813
  1311
    /// The ID of a valid Node is a nonnegative integer not greater than
alpar@813
  1312
    /// \ref maxNodeId(). The range of the ID's is not surely continuous
alpar@813
  1313
    /// and the greatest node ID can be actually less then \ref maxNodeId().
alpar@813
  1314
    ///
alpar@813
  1315
    /// The ID of the \ref INVALID node is -1.
alpar@813
  1316
    ///\return The ID of the node \c v. 
alpar@813
  1317
    int id(Node v) { return G.id(v); }
alpar@813
  1318
    /// Edge ID.
alpar@813
  1319
    
alpar@813
  1320
    /// The ID of a valid Edge is a nonnegative integer not greater than
alpar@813
  1321
    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
alpar@813
  1322
    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
alpar@813
  1323
    ///
alpar@813
  1324
    /// The ID of the \ref INVALID edge is -1.
alpar@813
  1325
    ///\return The ID of the edge \c e. 
alpar@905
  1326
    static int id(Edge e) { return e.n; }
alpar@400
  1327
alpar@400
  1328
    /// Adds a new node to the graph.
alpar@579
  1329
    Node addNode() { return G.addNode(); }
alpar@400
  1330
    
alpar@400
  1331
    Edge addEdge(Node u, Node v) {
alpar@400
  1332
      int n;
alpar@400
  1333
      
alpar@400
  1334
      if(first_free_edge==-1)
alpar@400
  1335
	{
alpar@400
  1336
	  n = edges.size();
alpar@400
  1337
	  edges.push_back(EdgeT());
alpar@400
  1338
	}
alpar@400
  1339
      else {
alpar@400
  1340
	n = first_free_edge;
alpar@400
  1341
	first_free_edge = edges[n].next_in;
alpar@400
  1342
      }
alpar@400
  1343
      
alpar@401
  1344
      edges[n].tail = u; edges[n].head = v;
alpar@400
  1345
alpar@401
  1346
      edges[n].next_out = nodes[u].first_out;
alpar@401
  1347
      if(nodes[u].first_out != -1) edges[nodes[u].first_out].prev_out = n;
alpar@401
  1348
      edges[n].next_in = nodes[v].first_in;
alpar@401
  1349
      if(nodes[v].first_in != -1) edges[nodes[v].first_in].prev_in = n;
alpar@400
  1350
      edges[n].prev_in = edges[n].prev_out = -1;
alpar@400
  1351
	
alpar@401
  1352
      nodes[u].first_out = nodes[v].first_in = n;
alpar@400
  1353
alpar@400
  1354
      Edge e; e.n=n;
alpar@400
  1355
alpar@400
  1356
      //Update dynamic maps
deba@782
  1357
      edge_maps.add(e);
alpar@400
  1358
alpar@400
  1359
      return e;
alpar@400
  1360
    }
alpar@400
  1361
alpar@774
  1362
    /// Finds an edge between two nodes.
alpar@774
  1363
alpar@774
  1364
    /// Finds an edge from node \c u to node \c v.
alpar@774
  1365
    ///
alpar@774
  1366
    /// If \c prev is \ref INVALID (this is the default value), then
alpar@774
  1367
    /// It finds the first edge from \c u to \c v. Otherwise it looks for
alpar@774
  1368
    /// the next edge from \c u to \c v after \c prev.
alpar@774
  1369
    /// \return The found edge or INVALID if there is no such an edge.
alpar@774
  1370
    Edge findEdge(Node u,Node v, Edge prev = INVALID) 
alpar@774
  1371
    {
alpar@774
  1372
      int e = (prev.n==-1)? nodes[u].first_out : edges[prev.n].next_out;
alpar@774
  1373
      while(e!=-1 && edges[e].tail!=v) e = edges[e].next_out;
alpar@774
  1374
      prev.n=e;
alpar@774
  1375
      return prev;
alpar@774
  1376
    }
alpar@774
  1377
    
alpar@400
  1378
  private:
alpar@400
  1379
    void eraseEdge(int n) {
alpar@400
  1380
      
alpar@400
  1381
      if(edges[n].next_in!=-1)
alpar@400
  1382
	edges[edges[n].next_in].prev_in = edges[n].prev_in;
alpar@400
  1383
      if(edges[n].prev_in!=-1)
alpar@400
  1384
	edges[edges[n].prev_in].next_in = edges[n].next_in;
alpar@400
  1385
      else nodes[edges[n].head].first_in = edges[n].next_in;
alpar@400
  1386
      
alpar@400
  1387
      if(edges[n].next_out!=-1)
alpar@400
  1388
	edges[edges[n].next_out].prev_out = edges[n].prev_out;
alpar@400
  1389
      if(edges[n].prev_out!=-1)
alpar@400
  1390
	edges[edges[n].prev_out].next_out = edges[n].next_out;
alpar@400
  1391
      else nodes[edges[n].tail].first_out = edges[n].next_out;
alpar@400
  1392
      
alpar@400
  1393
      edges[n].next_in = first_free_edge;
alpar@400
  1394
      first_free_edge = -1;      
alpar@400
  1395
alpar@400
  1396
      //Update dynamic maps
deba@782
  1397
      Edge e; e.n = n;
deba@782
  1398
      edge_maps.erase(e);
alpar@400
  1399
    }
alpar@400
  1400
      
alpar@400
  1401
  public:
alpar@400
  1402
alpar@400
  1403
    void erase(Edge e) { eraseEdge(e.n); }
alpar@400
  1404
alpar@579
  1405
    ///Clear all edges. (Doesn't clear the nodes!)
alpar@579
  1406
    void clear() {
deba@782
  1407
      edge_maps.clear();
alpar@579
  1408
      edges.clear();
alpar@579
  1409
      first_free_edge=-1;
alpar@579
  1410
    }
alpar@579
  1411
alpar@579
  1412
alpar@400
  1413
    class Edge {
alpar@579
  1414
    public:
alpar@400
  1415
      friend class EdgeSet;
alpar@400
  1416
      template <typename T> friend class EdgeMap;
alpar@400
  1417
alpar@400
  1418
      friend class Node;
alpar@400
  1419
      friend class NodeIt;
alpar@905
  1420
    protected:
alpar@579
  1421
      int n;
alpar@400
  1422
      friend int EdgeSet::id(Edge e) const;
alpar@400
  1423
alpar@400
  1424
      Edge(int nn) {n=nn;}
alpar@400
  1425
    public:
alpar@400
  1426
      Edge() { }
alpar@400
  1427
      Edge (Invalid) { n=-1; }
alpar@400
  1428
      bool operator==(const Edge i) const {return n==i.n;}
alpar@400
  1429
      bool operator!=(const Edge i) const {return n!=i.n;}
alpar@400
  1430
      bool operator<(const Edge i) const {return n<i.n;}
alpar@400
  1431
    };
alpar@400
  1432
    
alpar@400
  1433
    class EdgeIt : public Edge {
alpar@400
  1434
      friend class EdgeSet;
alpar@579
  1435
      template <typename T> friend class EdgeMap;
alpar@579
  1436
    
alpar@774
  1437
      const EdgeSet *G;
alpar@400
  1438
    public:
alpar@774
  1439
      EdgeIt(const EdgeSet& _G) : Edge(), G(&_G) {
alpar@503
  1440
        NodeIt m;
alpar@774
  1441
	for(G->first(m);
alpar@774
  1442
	    m!=INVALID && G->nodes[m].first_in == -1;  ++m);
alpar@774
  1443
	///\bug AJJAJ! This is a non sense!!!!!!!
alpar@774
  1444
	this->n = m!=INVALID?-1:G->nodes[m].first_in;
alpar@400
  1445
      }
alpar@774
  1446
      EdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
alpar@400
  1447
      EdgeIt (Invalid i) : Edge(i) { }
alpar@400
  1448
      EdgeIt() : Edge() { }
alpar@774
  1449
      ///.
alpar@774
  1450
      
alpar@774
  1451
      ///\bug UNIMPLEMENTED!!!!!
alpar@774
  1452
      //
alpar@774
  1453
      EdgeIt &operator++() {
alpar@774
  1454
	return *this;
alpar@774
  1455
      }
alpar@400
  1456
    };
alpar@400
  1457
    
alpar@400
  1458
    class OutEdgeIt : public Edge {
alpar@774
  1459
      const EdgeSet *G;
alpar@400
  1460
      friend class EdgeSet;
alpar@400
  1461
    public: 
alpar@400
  1462
      OutEdgeIt() : Edge() { }
alpar@400
  1463
      OutEdgeIt (Invalid i) : Edge(i) { }
alpar@774
  1464
      OutEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
alpar@400
  1465
alpar@774
  1466
      OutEdgeIt(const EdgeSet& _G,const Node v) :
alpar@774
  1467
	Edge(_G.nodes[v].first_out), G(&_G) { }
deba@844
  1468
      OutEdgeIt &operator++() { 
deba@844
  1469
	Edge::n = G->edges[Edge::n].next_out;
deba@844
  1470
	return *this; 
deba@844
  1471
      }
alpar@400
  1472
    };
alpar@400
  1473
    
alpar@400
  1474
    class InEdgeIt : public Edge {
alpar@774
  1475
      const EdgeSet *G;
alpar@400
  1476
      friend class EdgeSet;
alpar@400
  1477
    public: 
alpar@400
  1478
      InEdgeIt() : Edge() { }
alpar@400
  1479
      InEdgeIt (Invalid i) : Edge(i) { }
alpar@774
  1480
      InEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
alpar@774
  1481
      InEdgeIt(const EdgeSet& _G,Node v)
alpar@774
  1482
	: Edge(_G.nodes[v].first_in), G(&_G) { }
deba@844
  1483
      InEdgeIt &operator++() { 
deba@844
  1484
	Edge::n = G->edges[Edge::n].next_in; 
deba@844
  1485
	return *this; 
deba@844
  1486
      }
alpar@400
  1487
    };
deba@782
  1488
    
alpar@400
  1489
  };
alpar@406
  1490
alpar@579
  1491
  template<typename GG>
alpar@579
  1492
  inline int EdgeSet<GG>::id(Node v) const { return G.id(v); }
alpar@531
  1493
alpar@406
  1494
/// @}  
alpar@406
  1495
alpar@395
  1496
} //namespace hugo
alpar@395
  1497
alpar@405
  1498
#endif //HUGO_LIST_GRAPH_H