COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/hugo/list_graph.h @ 891:74589d20dbc3

Last change on this file since 891:74589d20dbc3 was 891:74589d20dbc3, checked in by Balazs Dezso, 20 years ago

template<typename CMap> Map(const CMap&) like constructors and
assigns are removed.

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