COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/hugo/list_graph.h @ 896:3a98a1aa5a8f

Last change on this file since 896:3a98a1aa5a8f 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
Line 
1// -*- mode:C++ -*-
2
3#ifndef HUGO_LIST_GRAPH_H
4#define HUGO_LIST_GRAPH_H
5
6///\ingroup graphs
7///\file
8///\brief ListGraph, SymListGraph, NodeSet and EdgeSet classes.
9
10#include <vector>
11#include <climits>
12
13#include <hugo/invalid.h>
14
15#include <hugo/map_registry.h>
16#include <hugo/default_map.h>
17
18#include <hugo/sym_map.h>
19
20#include <hugo/map_defines.h>
21
22
23namespace hugo {
24
25/// \addtogroup graphs
26/// @{
27
28  ///A list graph class.
29
30  ///This is a simple and fast erasable graph implementation.
31  ///
32  ///It conforms to the
33  ///\ref skeleton::ErasableGraph "ErasableGraph" concept.
34  ///\sa skeleton::ErasableGraph.
35  class ListGraph {
36
37    //Nodes are double linked.
38    //The free nodes are only single linked using the "next" field.
39    struct NodeT
40    {
41      int first_in,first_out;
42      int prev, next;
43    };
44    //Edges are double linked.
45    //The free edges are only single linked using the "next_in" field.
46    struct EdgeT
47    {
48      int head, tail;
49      int prev_in, prev_out;
50      int next_in, next_out;
51    };
52
53    std::vector<NodeT> nodes;
54    //The first node
55    int first_node;
56    //The first free node
57    int first_free_node;
58    std::vector<EdgeT> edges;
59    //The first free edge
60    int first_free_edge;
61   
62  public:
63   
64    typedef ListGraph Graph;
65   
66    class Node;
67    class Edge;
68
69   
70  public:
71
72    class NodeIt;
73    class EdgeIt;
74    class OutEdgeIt;
75    class InEdgeIt;
76
77    /// Creating map registries.
78    CREATE_MAP_REGISTRIES;
79    /// Creating node and edge maps.
80
81    /// \todo
82    /// It apears in the documentation as if it were a function definition.
83    CREATE_MAPS(DefaultMap);
84
85  public:
86
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) {}
95   
96    ///Number of nodes.
97    int nodeNum() const { return nodes.size(); }
98    ///Number of edges.
99    int edgeNum() const { return edges.size(); }
100
101    ///Set the expected maximum number of edges.
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   
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; }
118
119    Node tail(Edge e) const { return edges[e.n].tail; }
120    Node head(Edge e) const { return edges[e.n].head; }
121
122    NodeIt& first(NodeIt& v) const {
123      v=NodeIt(*this); return v; }
124    EdgeIt& first(EdgeIt& e) const {
125      e=EdgeIt(*this); return e; }
126    OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
127      e=OutEdgeIt(*this,v); return e; }
128    InEdgeIt& first(InEdgeIt& e, const Node v) const {
129      e=InEdgeIt(*this,v); return e; }
130
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.
139    static int id(Node v) { return v.n; }
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.
148    static int id(Edge e) { return e.n; }
149
150    /// Adds a new node to the graph.
151
152    /// \warning It adds the new node to the front of the list.
153    /// (i.e. the lastly added node becomes the first.)
154    Node addNode() {
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;
175
176      //Update dynamic maps
177      node_maps.add(nn);
178
179      return nn;
180    }
181   
182    Edge addEdge(Node u, Node v) {
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;
196
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
208      edge_maps.add(e);
209
210      return e;
211    }
212   
213    /// Finds an edge between two nodes.
214
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   
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;
245      first_free_edge = n;     
246
247      //Update dynamic maps
248      Edge e; e.n=n;
249      edge_maps.erase(e);
250
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
270      node_maps.erase(nn);
271
272    }
273   
274    void erase(Edge e) { eraseEdge(e.n); }
275
276    void clear() {
277      edge_maps.clear();
278      edges.clear();
279      node_maps.clear();
280      nodes.clear();
281      first_node=first_free_node=first_free_edge=-1;
282    }
283
284    class Node {
285      friend class ListGraph;
286      template <typename T> friend class NodeMap;
287       
288      friend class Edge;
289      friend class OutEdgeIt;
290      friend class InEdgeIt;
291      friend class SymEdge;
292
293    protected:
294      int n;
295      friend int ListGraph::id(Node v);
296      Node(int nn) {n=nn;}
297    public:
298      Node() {}
299      Node (Invalid) { n=-1; }
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;}
303      //      ///Validity check
304      //      operator bool() { return n!=-1; }
305    };
306   
307    class NodeIt : public Node {
308      const ListGraph *G;
309      friend class ListGraph;
310    public:
311      NodeIt() : Node() { }
312      NodeIt(Invalid i) : Node(i) { }
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(); }     
321    };
322
323    class Edge {
324      friend class ListGraph;
325      template <typename T> friend class EdgeMap;
326
327      //template <typename T> friend class SymListGraph::SymEdgeMap;     
328      //friend Edge SymListGraph::opposite(Edge) const;
329     
330      friend class Node;
331      friend class NodeIt;
332    protected:
333      int n;
334      friend int ListGraph::id(Edge e);
335
336    public:
337      /// An Edge with id \c n.
338
339      /// \bug It should be
340      /// obtained by a member function of the Graph.
341      Edge(int nn) {n=nn;}
342
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
349      ///make class \c SymListGraph::SymEdgeMap friend of Edge
350      int &idref() {return n;}
351      const int &idref() const {return n;}
352      //      ///Validity check
353      //      operator bool() { return n!=-1; }
354   };
355   
356    class EdgeIt : public Edge {
357      const ListGraph *G;
358      friend class ListGraph;
359    public:
360      EdgeIt(const ListGraph& _G) : Edge(), G(&_G) {
361        int m;
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;
365      }
366      EdgeIt (Invalid i) : Edge(i) { }
367      EdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
368      EdgeIt() : Edge() { }
369      ///\bug This is a workaround until somebody tells me how to
370      ///make class \c SymListGraph::SymEdgeMap friend of Edge
371      int &idref() {return n;}
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(); }     
385    };
386   
387    class OutEdgeIt : public Edge {
388      const ListGraph *G;
389      friend class ListGraph;
390    public:
391      OutEdgeIt() : Edge() { }
392      OutEdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
393      OutEdgeIt (Invalid i) : Edge(i) { }
394
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(); }     
400    };
401   
402    class InEdgeIt : public Edge {
403      const ListGraph *G;
404      friend class ListGraph;
405    public:
406      InEdgeIt() : Edge() { }
407      InEdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
408      InEdgeIt (Invalid i) : Edge(i) { }
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(); }     
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
423  ///\ref SymListGraph::SymEdgeMap "SymEdgeMap"
424  ///that complements this
425  ///feature by
426  ///storing shared values for the edge pairs. The usual
427  ///\ref Graph::EdgeMap "EdgeMap"
428  ///can be used
429  ///as well.
430  ///
431  ///The oppositely directed edge can also be obtained easily
432  ///using \ref opposite.
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.
438 
439  class SymListGraph : public ListGraph
440  {
441  public:
442
443    typedef SymListGraph Graph;
444
445    /// Creating symmetric map registry.
446    CREATE_SYM_EDGE_MAP_REGISTRY;
447    /// Creating symmetric edge map.
448    CREATE_SYM_EDGE_MAP(DefaultMap);
449
450    SymListGraph() : ListGraph() { }
451    SymListGraph(const ListGraph &_g) : ListGraph(_g) { }
452    ///Adds a pair of oppositely directed edges to the graph.
453    Edge addEdge(Node u, Node v)
454    {
455      Edge e = ListGraph::addEdge(u,v);
456      Edge f = ListGraph::addEdge(v,u);
457      sym_edge_maps.add(e);
458      sym_edge_maps.add(f);
459     
460      return e;
461    }
462
463    void erase(Node n) { ListGraph::erase(n);}
464    ///The oppositely directed edge.
465
466    ///Returns the oppositely directed
467    ///pair of the edge \c e.
468    static Edge opposite(Edge e)
469    {
470      Edge f;
471      f.idref() = e.idref() - 2*(e.idref()%2) + 1;
472      return f;
473    }
474   
475    ///Removes a pair of oppositely directed edges to the graph.
476    void erase(Edge e) {
477      Edge f = opposite(e);
478      sym_edge_maps.erase(e);
479      sym_edge_maps.erase(f);
480      ListGraph::erase(f);
481      ListGraph::erase(e);
482    }   
483  };
484
485
486  ///A graph class containing only nodes.
487
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.
491  ///
492  ///It conforms to
493  ///the \ref skeleton::ExtendableGraph "ExtendableGraph" concept
494  ///with the exception that you cannot
495  ///add (or delete) edges. The usual edge iterators are exists, but they are
496  ///always \ref INVALID.
497  ///\sa skeleton::ExtendableGraph
498  ///\sa EdgeSet
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:
517
518    typedef NodeSet Graph;
519   
520    class Node;
521    class Edge;
522
523  public:
524
525    class NodeIt;
526    class EdgeIt;
527    class OutEdgeIt;
528    class InEdgeIt;
529   
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    };
564   
565  public:
566
567    ///Default constructor
568    NodeSet()
569      : nodes(), first_node(-1), first_free_node(-1) {}
570    ///Copy constructor
571    NodeSet(const NodeSet &_g)
572      : nodes(_g.nodes), first_node(_g.first_node),
573        first_free_node(_g.first_free_node) {}
574   
575    ///Number of nodes.
576    int nodeNum() const { return nodes.size(); }
577    ///Number of edges.
578    int edgeNum() const { return 0; }
579
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; }
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
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.
611    int id(Node v) const { return v.n; }
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.
620    int id(Edge e) const { return -1; }
621
622    /// Adds a new node to the graph.
623
624    /// \warning It adds the new node to the front of the list.
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
649      node_maps.add(nn);
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
665      node_maps.erase(nn);
666    }
667   
668       
669    Edge findEdge(Node u,Node v, Edge prev = INVALID)
670    {
671      return INVALID;
672    }
673   
674    void clear() {
675      node_maps.clear();
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 {
701      const NodeSet *G;
702      friend class NodeSet;
703    public:
704      NodeIt() : Node() { }
705      NodeIt(const NodeSet& _G,Node n) : Node(n), G(&_G) { }
706      NodeIt(Invalid i) : Node(i) { }
707      NodeIt(const NodeSet& _G) : Node(_G.first_node), G(&_G) { }
708      NodeIt &operator++() {
709        n=G->nodes[n].next;
710        return *this;
711      }
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() { }
742      EdgeIt(const NodeSet&, Edge) : Edge() { }
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;}
748      EdgeIt operator++() { return INVALID; }
749    };
750   
751    class OutEdgeIt : public Edge {
752      friend class NodeSet;
753    public:
754      OutEdgeIt() : Edge() { }
755      OutEdgeIt(const NodeSet&, Edge) : Edge() { }
756      OutEdgeIt (Invalid i) : Edge(i) { }
757      OutEdgeIt(const NodeSet& G,const Node v)  : Edge() {}
758      OutEdgeIt operator++() { return INVALID; }
759    };
760   
761    class InEdgeIt : public Edge {
762      friend class NodeSet;
763    public:
764      InEdgeIt() : Edge() { }
765      InEdgeIt(const NodeSet&, Edge) : Edge() { }
766      InEdgeIt (Invalid i) : Edge(i) { }
767      InEdgeIt(const NodeSet& G,Node v) :Edge() {}
768      InEdgeIt operator++() { return INVALID; }
769    };
770
771  };
772
773
774
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  ///
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  ///
788  ///\param GG The type of the graph which shares its node set with this class.
789  ///Its interface must conform to the
790  ///\ref skeleton::StaticGraph "StaticGraph" concept.
791  ///
792  ///It conforms to the
793  ///\ref skeleton::ExtendableGraph "ExtendableGraph" concept.
794  ///\sa skeleton::ExtendableGraph.
795  ///\sa NodeSet.
796  template<typename GG>
797  class EdgeSet {
798
799    typedef GG NodeGraphType;
800
801    NodeGraphType &G;
802
803  public:
804
805    class Node;
806    class Edge;
807    class OutEdgeIt;
808    class InEdgeIt;
809    class SymEdge;
810
811    typedef EdgeSet Graph;
812
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() { }
837      NodeIt(const EdgeSet& _G,Node n) : NodeGraphType::NodeIt(_G.G,n) { }
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) {}
842
843      operator Node() { return Node(*this);}
844      NodeIt &operator++()
845      { this->NodeGraphType::NodeIt::operator++(); return *this;}
846    };
847
848  private:
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   
865    typename NodeGraphType::template NodeMap<NodeT> nodes;
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;
880
881
882    /// Creates edge map registry.
883    CREATE_EDGE_MAP_REGISTRY;
884    /// Creates edge maps.
885    CREATE_EDGE_MAP(DefaultMap);
886
887    /// Imports node maps from the NodeGraphType.
888    IMPORT_NODE_MAP(NodeGraphType, graph.G, EdgeSet, graph);
889   
890   
891  public:
892
893    ///Constructor
894   
895    ///Construates a new graph based on the nodeset of an existing one.
896    ///\param _G the base graph.
897    explicit EdgeSet(NodeGraphType &_G)
898      : G(_G), nodes(_G), edges(),
899        first_free_edge(-1) {}
900    ///Copy constructor
901
902    ///Makes a copy of an EdgeSet.
903    ///It will be based on the same graph.
904    explicit EdgeSet(const EdgeSet &_g)
905      : G(_g.G), nodes(_g.G), edges(_g.edges),
906        first_free_edge(_g.first_free_edge) {}
907   
908    ///Number of nodes.
909    int nodeNum() const { return G.nodeNum(); }
910    ///Number of edges.
911    int edgeNum() const { return edges.size(); }
912
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; }
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
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.
953    int id(Edge e) const { return e.n; }
954
955    /// Adds a new node to the graph.
956    Node addNode() { return G.addNode(); }
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     
971      edges[n].tail = u; edges[n].head = v;
972
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;
977      edges[n].prev_in = edges[n].prev_out = -1;
978       
979      nodes[u].first_out = nodes[v].first_in = n;
980
981      Edge e; e.n=n;
982
983      //Update dynamic maps
984      edge_maps.add(e);
985
986      return e;
987    }
988
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   
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
1024      Edge e; e.n = n;
1025      edge_maps.erase(e);
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
1039    ///Clear all edges. (Doesn't clear the nodes!)
1040    void clear() {
1041      edge_maps.clear();
1042      edges.clear();
1043      first_free_edge=-1;
1044    }
1045
1046
1047    class Edge {
1048    public:
1049      friend class EdgeSet;
1050      template <typename T> friend class EdgeMap;
1051
1052      friend class Node;
1053      friend class NodeIt;
1054    public:
1055      ///\bug It should be at least protected
1056      ///
1057      int n;
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;
1076      template <typename T> friend class EdgeMap;
1077   
1078      const EdgeSet *G;
1079    public:
1080      EdgeIt(const EdgeSet& _G) : Edge(), G(&_G) {
1081        //              typename NodeGraphType::Node m;
1082        NodeIt m;
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;
1087      }
1088      EdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
1089      EdgeIt (Invalid i) : Edge(i) { }
1090      EdgeIt() : Edge() { }
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
1099      ///make class \c SymEdgeSet::SymEdgeMap friend of Edge
1100      int &idref() {return this->n;}
1101    };
1102   
1103    class OutEdgeIt : public Edge {
1104      const EdgeSet *G;
1105      friend class EdgeSet;
1106    public:
1107      OutEdgeIt() : Edge() { }
1108      OutEdgeIt (Invalid i) : Edge(i) { }
1109      OutEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
1110
1111      OutEdgeIt(const EdgeSet& _G,const Node v) :
1112        Edge(_G.nodes[v].first_out), G(&_G) { }
1113      OutEdgeIt &operator++() {
1114        Edge::n = G->edges[Edge::n].next_out;
1115        return *this;
1116      }
1117    };
1118   
1119    class InEdgeIt : public Edge {
1120      const EdgeSet *G;
1121      friend class EdgeSet;
1122    public:
1123      InEdgeIt() : Edge() { }
1124      InEdgeIt (Invalid i) : Edge(i) { }
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) { }
1128      InEdgeIt &operator++() {
1129        Edge::n = G->edges[Edge::n].next_in;
1130        return *this;
1131      }
1132    };
1133   
1134  };
1135
1136  template<typename GG>
1137  inline int EdgeSet<GG>::id(Node v) const { return G.id(v); }
1138
1139/// @} 
1140
1141} //namespace hugo
1142
1143#endif //HUGO_LIST_GRAPH_H
Note: See TracBrowser for help on using the repository browser.