COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/hugo/list_graph.h @ 904:b40afcf42a4d

Last change on this file since 904:b40afcf42a4d was 904:b40afcf42a4d, checked in by Alpar Juttner, 20 years ago

Do not document registry and map defines.

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