COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/hugo/list_graph.h @ 813:65144c52969c

Last change on this file since 813:65144c52969c was 813:65144c52969c, checked in by Alpar Juttner, 20 years ago
  • maxEdgeId() and maxNodeId() now works as their names suggest.
  • maxEdgeId(), maxNodeId(), nodeNum() and edgeNum() are documented.
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_factory.h>
17
18#include <hugo/sym_map_factory.h>
19
20#include <hugo/map_defines.h>
21
22
23namespace hugo {
24
25/// \addtogroup graphs
26/// @{
27
28//  class SymListGraph;
29
30  ///A list graph class.
31
32  ///This is a simple and fast erasable graph implementation.
33  ///
34  ///It conforms to the graph interface documented under
35  ///the description of \ref GraphSkeleton.
36  ///\sa \ref GraphSkeleton.
37  class ListGraph {
38
39    //Nodes are double linked.
40    //The free nodes are only single linked using the "next" field.
41    struct NodeT
42    {
43      int first_in,first_out;
44      int prev, next;
45      //      NodeT() {}
46    };
47    //Edges are double linked.
48    //The free edges are only single linked using the "next_in" field.
49    struct EdgeT
50    {
51      int head, tail;
52      int prev_in, prev_out;
53      int next_in, next_out;
54      //FIXME: is this necessary?
55      //      EdgeT() : next_in(-1), next_out(-1) prev_in(-1), prev_out(-1) {} 
56    };
57
58    std::vector<NodeT> nodes;
59    //The first node
60    int first_node;
61    //The first free node
62    int first_free_node;
63    std::vector<EdgeT> edges;
64    //The first free edge
65    int first_free_edge;
66   
67  public:
68   
69    typedef ListGraph Graph;
70   
71    class Node;
72    class Edge;
73
74   
75  public:
76
77    class NodeIt;
78    class EdgeIt;
79    class OutEdgeIt;
80    class InEdgeIt;
81
82    CREATE_MAP_REGISTRIES;
83    CREATE_MAPS(DefaultMapFactory);
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      ///\todo Undocumented conversion Node -\> NodeIt.
315      NodeIt(const ListGraph& _G,Node n) : Node(n), G(&_G) { }
316      NodeIt &operator++() {
317        n=G->nodes[n].next;
318        return *this;
319      }
320      //      ///Validity check
321      //      operator bool() { return Node::operator bool(); }     
322    };
323
324    class Edge {
325      friend class ListGraph;
326      template <typename T> friend class EdgeMap;
327
328      //template <typename T> friend class SymListGraph::SymEdgeMap;     
329      //friend Edge SymListGraph::opposite(Edge) const;
330     
331      friend class Node;
332      friend class NodeIt;
333    protected:
334      int n;
335      friend int ListGraph::id(Edge e);
336
337    public:
338      /// An Edge with id \c n.
339
340      /// \bug It should be
341      /// obtained by a member function of the Graph.
342      Edge(int nn) {n=nn;}
343
344      Edge() { }
345      Edge (Invalid) { n=-1; }
346      bool operator==(const Edge i) const {return n==i.n;}
347      bool operator!=(const Edge i) const {return n!=i.n;}
348      bool operator<(const Edge i) const {return n<i.n;}
349      ///\bug This is a workaround until somebody tells me how to
350      ///make class \c SymListGraph::SymEdgeMap friend of Edge
351      int &idref() {return n;}
352      const int &idref() const {return n;}
353      //      ///Validity check
354      //      operator bool() { return n!=-1; }
355   };
356   
357    class EdgeIt : public Edge {
358      const ListGraph *G;
359      friend class ListGraph;
360    public:
361      EdgeIt(const ListGraph& _G) : Edge(), G(&_G) {
362        int m;
363        for(m=_G.first_node;
364            m!=-1 && _G.nodes[m].first_in == -1; m = _G.nodes[m].next);
365        n = (m==-1)?-1:_G.nodes[m].first_in;
366      }
367      EdgeIt (Invalid i) : Edge(i) { }
368      EdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
369      EdgeIt() : Edge() { }
370      ///\bug This is a workaround until somebody tells me how to
371      ///make class \c SymListGraph::SymEdgeMap friend of Edge
372      int &idref() {return n;}
373      EdgeIt &operator++() {
374        if(G->edges[n].next_in!=-1) n=G->edges[n].next_in;
375        else {
376          int nn;
377          for(nn=G->nodes[G->edges[n].head].next;
378              nn!=-1 && G->nodes[nn].first_in == -1;
379              nn = G->nodes[nn].next) ;
380          n = (nn==-1)?-1:G->nodes[nn].first_in;
381        }
382        return *this;
383      }
384      //      ///Validity check
385      //      operator bool() { return Edge::operator bool(); }     
386    };
387   
388    class OutEdgeIt : public Edge {
389      const ListGraph *G;
390      friend class ListGraph;
391    public:
392      OutEdgeIt() : Edge() { }
393      OutEdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
394      OutEdgeIt (Invalid i) : Edge(i) { }
395
396      OutEdgeIt(const ListGraph& _G,const Node v)
397        : Edge(_G.nodes[v.n].first_out), G(&_G) {}
398      OutEdgeIt &operator++() { n=G->edges[n].next_out; return *this; }
399      //      ///Validity check
400      //      operator bool() { return Edge::operator bool(); }     
401    };
402   
403    class InEdgeIt : public Edge {
404      const ListGraph *G;
405      friend class ListGraph;
406    public:
407      InEdgeIt() : Edge() { }
408      InEdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
409      InEdgeIt (Invalid i) : Edge(i) { }
410      InEdgeIt(const ListGraph& _G,Node v)
411        : Edge(_G.nodes[v.n].first_in), G(&_G) { }
412      InEdgeIt &operator++() { n=G->edges[n].next_in; return *this; }
413      //      ///Validity check
414      //      operator bool() { return Edge::operator bool(); }     
415    };
416  };
417
418  ///Graph for bidirectional edges.
419
420  ///The purpose of this graph structure is to handle graphs
421  ///having bidirectional edges. Here the function \c addEdge(u,v) adds a pair
422  ///of oppositely directed edges.
423  ///There is a new edge map type called
424  ///\ref SymListGraph::SymEdgeMap "SymEdgeMap"
425  ///that complements this
426  ///feature by
427  ///storing shared values for the edge pairs. The usual
428  ///\ref GraphSkeleton::EdgeMap "EdgeMap"
429  ///can be used
430  ///as well.
431  ///
432  ///The oppositely directed edge can also be obtained easily
433  ///using \ref opposite.
434  ///
435  ///Here erase(Edge) deletes a pair of edges.
436  ///
437  ///\todo this date structure need some reconsiderations. Maybe it
438  ///should be implemented independently from ListGraph.
439 
440  class SymListGraph : public ListGraph
441  {
442  public:
443
444    typedef SymListGraph Graph;
445
446    KEEP_NODE_MAP(ListGraph);
447    KEEP_EDGE_MAP(ListGraph);
448
449    CREATE_SYM_EDGE_MAP_REGISTRY;
450    CREATE_SYM_EDGE_MAP_FACTORY(DefaultMapFactory);
451    IMPORT_SYM_EDGE_MAP(SymEdgeMapFactory);
452
453    SymListGraph() : ListGraph() { }
454    SymListGraph(const ListGraph &_g) : ListGraph(_g) { }
455    ///Adds a pair of oppositely directed edges to the graph.
456    Edge addEdge(Node u, Node v)
457    {
458      Edge e = ListGraph::addEdge(u,v);
459      Edge f = ListGraph::addEdge(v,u);
460      sym_edge_maps.add(e);
461      sym_edge_maps.add(f);
462     
463      return e;
464    }
465
466    void erase(Node n) { ListGraph::erase(n);}
467    ///The oppositely directed edge.
468
469    ///Returns the oppositely directed
470    ///pair of the edge \c e.
471    static Edge opposite(Edge e)
472    {
473      Edge f;
474      f.idref() = e.idref() - 2*(e.idref()%2) + 1;
475      return f;
476    }
477   
478    ///Removes a pair of oppositely directed edges to the graph.
479    void erase(Edge e) {
480      Edge f = opposite(e);
481      sym_edge_maps.erase(e);
482      sym_edge_maps.erase(f);
483      ListGraph::erase(f);
484      ListGraph::erase(e);
485    }   
486  };
487
488
489  ///A graph class containing only nodes.
490
491  ///This class implements a graph structure without edges.
492  ///The most useful application of this class is to be the node set of an
493  ///\ref EdgeSet class.
494  ///
495  ///It conforms to the graph interface documented under
496  ///the description of \ref GraphSkeleton with the exception that you cannot
497  ///add (or delete) edges. The usual edge iterators are exists, but they are
498  ///always \ref INVALID.
499  ///\sa \ref GraphSkeleton
500  ///\sa \ref EdgeSet
501  class NodeSet {
502
503    //Nodes are double linked.
504    //The free nodes are only single linked using the "next" field.
505    struct NodeT
506    {
507      int first_in,first_out;
508      int prev, next;
509      //      NodeT() {}
510    };
511
512    std::vector<NodeT> nodes;
513    //The first node
514    int first_node;
515    //The first free node
516    int first_free_node;
517   
518  public:
519
520    typedef NodeSet Graph;
521   
522    class Node;
523    class Edge;
524
525  public:
526
527    class NodeIt;
528    class EdgeIt;
529    class OutEdgeIt;
530    class InEdgeIt;
531   
532    CREATE_MAP_REGISTRIES;
533    CREATE_MAPS(DefaultMapFactory);
534   
535  public:
536
537    ///Default constructor
538    NodeSet()
539      : nodes(), first_node(-1), first_free_node(-1) {}
540    ///Copy constructor
541    NodeSet(const NodeSet &_g)
542      : nodes(_g.nodes), first_node(_g.first_node),
543        first_free_node(_g.first_free_node) {}
544   
545    ///Number of nodes.
546    int nodeNum() const { return nodes.size(); }
547    ///Number of edges.
548    int edgeNum() const { return 0; }
549
550    /// Maximum node ID.
551   
552    /// Maximum node ID.
553    ///\sa id(Node)
554    int maxNodeId() const { return nodes.size()-1; }
555    /// Maximum edge ID.
556   
557    /// Maximum edge ID.
558    ///\sa id(Edge)
559    int maxEdgeId() const { return 0; }
560
561    Node tail(Edge e) const { return INVALID; }
562    Node head(Edge e) const { return INVALID; }
563
564    NodeIt& first(NodeIt& v) const {
565      v=NodeIt(*this); return v; }
566    EdgeIt& first(EdgeIt& e) const {
567      e=EdgeIt(*this); return e; }
568    OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
569      e=OutEdgeIt(*this,v); return e; }
570    InEdgeIt& first(InEdgeIt& e, const Node v) const {
571      e=InEdgeIt(*this,v); return e; }
572
573    /// Node ID.
574   
575    /// The ID of a valid Node is a nonnegative integer not greater than
576    /// \ref maxNodeId(). The range of the ID's is not surely continuous
577    /// and the greatest node ID can be actually less then \ref maxNodeId().
578    ///
579    /// The ID of the \ref INVALID node is -1.
580    ///\return The ID of the node \c v.
581    int id(Node v) const { return v.n; }
582    /// Edge ID.
583   
584    /// The ID of a valid Edge is a nonnegative integer not greater than
585    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
586    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
587    ///
588    /// The ID of the \ref INVALID edge is -1.
589    ///\return The ID of the edge \c e.
590    int id(Edge e) const { return -1; }
591
592    /// Adds a new node to the graph.
593
594    /// \warning It adds the new node to the front of the list.
595    /// (i.e. the lastly added node becomes the first.)
596    Node addNode() {
597      int n;
598     
599      if(first_free_node==-1)
600        {
601          n = nodes.size();
602          nodes.push_back(NodeT());
603        }
604      else {
605        n = first_free_node;
606        first_free_node = nodes[n].next;
607      }
608     
609      nodes[n].next = first_node;
610      if(first_node != -1) nodes[first_node].prev = n;
611      first_node = n;
612      nodes[n].prev = -1;
613     
614      nodes[n].first_in = nodes[n].first_out = -1;
615     
616      Node nn; nn.n=n;
617
618      //Update dynamic maps
619      node_maps.add(nn);
620
621      return nn;
622    }
623   
624    void erase(Node nn) {
625      int n=nn.n;
626     
627      if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
628      if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
629      else first_node = nodes[n].next;
630     
631      nodes[n].next = first_free_node;
632      first_free_node = n;
633
634      //Update dynamic maps
635      node_maps.erase(nn);
636    }
637   
638       
639    Edge findEdge(Node u,Node v, Edge prev = INVALID)
640    {
641      return INVALID;
642    }
643   
644    void clear() {
645      node_maps.clear();
646      nodes.clear();
647      first_node = first_free_node = -1;
648    }
649
650    class Node {
651      friend class NodeSet;
652      template <typename T> friend class NodeMap;
653     
654      friend class Edge;
655      friend class OutEdgeIt;
656      friend class InEdgeIt;
657
658    protected:
659      int n;
660      friend int NodeSet::id(Node v) const;
661      Node(int nn) {n=nn;}
662    public:
663      Node() {}
664      Node (Invalid i) { n=-1; }
665      bool operator==(const Node i) const {return n==i.n;}
666      bool operator!=(const Node i) const {return n!=i.n;}
667      bool operator<(const Node i) const {return n<i.n;}
668    };
669   
670    class NodeIt : public Node {
671      const NodeSet *G;
672      friend class NodeSet;
673    public:
674      NodeIt() : Node() { }
675      NodeIt(const NodeSet& _G,Node n) : Node(n), G(&_G) { }
676      NodeIt(Invalid i) : Node(i) { }
677      NodeIt(const NodeSet& _G) : Node(_G.first_node), G(&_G) { }
678      NodeIt &operator++() {
679        n=G->nodes[n].next;
680        return *this;
681      }
682    };
683
684    class Edge {
685      //friend class NodeSet;
686      //template <typename T> friend class EdgeMap;
687
688      //template <typename T> friend class SymNodeSet::SymEdgeMap;     
689      //friend Edge SymNodeSet::opposite(Edge) const;
690     
691      //      friend class Node;
692      //      friend class NodeIt;
693    protected:
694      //friend int NodeSet::id(Edge e) const;
695      //      Edge(int nn) {}
696    public:
697      Edge() { }
698      Edge (Invalid) { }
699      bool operator==(const Edge i) const {return true;}
700      bool operator!=(const Edge i) const {return false;}
701      bool operator<(const Edge i) const {return false;}
702      ///\bug This is a workaround until somebody tells me how to
703      ///make class \c SymNodeSet::SymEdgeMap friend of Edge
704      //      int idref() {return -1;}
705      //      int idref() const {return -1;}
706    };
707   
708    class EdgeIt : public Edge {
709      //friend class NodeSet;
710    public:
711      EdgeIt(const NodeSet& G) : Edge() { }
712      EdgeIt(const NodeSet&, Edge) : Edge() { }
713      EdgeIt (Invalid i) : Edge(i) { }
714      EdgeIt() : Edge() { }
715      ///\bug This is a workaround until somebody tells me how to
716      ///make class \c SymNodeSet::SymEdgeMap friend of Edge
717      //      int idref() {return -1;}
718      EdgeIt operator++() { return INVALID; }
719    };
720   
721    class OutEdgeIt : public Edge {
722      friend class NodeSet;
723    public:
724      OutEdgeIt() : Edge() { }
725      OutEdgeIt(const NodeSet&, Edge) : Edge() { }
726      OutEdgeIt (Invalid i) : Edge(i) { }
727      OutEdgeIt(const NodeSet& G,const Node v)  : Edge() {}
728      OutEdgeIt operator++() { return INVALID; }
729    };
730   
731    class InEdgeIt : public Edge {
732      friend class NodeSet;
733    public:
734      InEdgeIt() : Edge() { }
735      InEdgeIt(const NodeSet&, Edge) : Edge() { }
736      InEdgeIt (Invalid i) : Edge(i) { }
737      InEdgeIt(const NodeSet& G,Node v) :Edge() {}
738      InEdgeIt operator++() { return INVALID; }
739    };
740
741  };
742
743
744
745  ///Graph structure using a node set of another graph.
746
747  ///This structure can be used to establish another graph over a node set
748  /// of an existing one. The node iterator will go through the nodes of the
749  /// original graph, and the NodeMap's of both graphs will convert to
750  /// each other.
751  ///
752  ///\warning Adding or deleting nodes from the graph is not safe if an
753  ///\ref EdgeSet is currently attached to it!
754  ///
755  ///\todo Make it possible to add/delete edges from the base graph
756  ///(and from \ref EdgeSet, as well)
757  ///
758  ///\param GG The type of the graph which shares its node set with this class.
759  ///Its interface must conform with \ref GraphSkeleton.
760  ///
761  ///It conforms to the graph interface documented under
762  ///the description of \ref GraphSkeleton.
763  ///\sa \ref GraphSkeleton.
764  ///\sa \ref NodeSet.
765  template<typename GG>
766  class EdgeSet {
767
768    typedef GG NodeGraphType;
769
770    NodeGraphType &G;
771
772  public:
773
774    class Node;
775    class Edge;
776    class OutEdgeIt;
777    class InEdgeIt;
778    class SymEdge;
779
780    typedef EdgeSet Graph;
781
782    int id(Node v) const;
783
784    class Node : public NodeGraphType::Node {
785      friend class EdgeSet;
786      //      template <typename T> friend class NodeMap;
787     
788      friend class Edge;
789      friend class OutEdgeIt;
790      friend class InEdgeIt;
791      friend class SymEdge;
792
793    public:
794      friend int EdgeSet::id(Node v) const;
795      //      Node(int nn) {n=nn;}
796    public:
797      Node() : NodeGraphType::Node() {}
798      Node (Invalid i) : NodeGraphType::Node(i) {}
799      Node(const typename NodeGraphType::Node &n) : NodeGraphType::Node(n) {}
800    };
801   
802    class NodeIt : public NodeGraphType::NodeIt {
803      friend class EdgeSet;
804    public:
805      NodeIt() : NodeGraphType::NodeIt() { }
806      NodeIt(const EdgeSet& _G,Node n) : NodeGraphType::NodeIt(_G.G,n) { }
807      NodeIt (Invalid i) : NodeGraphType::NodeIt(i) {}
808      NodeIt(const EdgeSet& _G) : NodeGraphType::NodeIt(_G.G) { }
809      NodeIt(const typename NodeGraphType::NodeIt &n)
810        : NodeGraphType::NodeIt(n) {}
811
812      operator Node() { return Node(*this);}
813      NodeIt &operator++()
814      { this->NodeGraphType::NodeIt::operator++(); return *this;}
815    };
816
817  private:
818    //Edges are double linked.
819    //The free edges are only single linked using the "next_in" field.
820    struct NodeT
821    {
822      int first_in,first_out;
823      NodeT() : first_in(-1), first_out(-1) { }
824    };
825
826    struct EdgeT
827    {
828      Node head, tail;
829      int prev_in, prev_out;
830      int next_in, next_out;
831    };
832
833   
834    typename NodeGraphType::template NodeMap<NodeT> nodes;
835   
836    std::vector<EdgeT> edges;
837    //The first free edge
838    int first_free_edge;
839   
840  public:
841   
842    class Node;
843    class Edge;
844
845    class NodeIt;
846    class EdgeIt;
847    class OutEdgeIt;
848    class InEdgeIt;
849
850
851    CREATE_EDGE_MAP_REGISTRY;
852    CREATE_EDGE_MAP_FACTORY(DefaultMapFactory);
853    IMPORT_EDGE_MAP(EdgeMapFactory);
854   
855   
856  public:
857
858    ///Constructor
859   
860    ///Construates a new graph based on the nodeset of an existing one.
861    ///\param _G the base graph.
862    ///\todo It looks like a copy constructor, but it isn't.
863    EdgeSet(NodeGraphType &_G)
864      : G(_G), nodes(_G), edges(),
865        first_free_edge(-1) {}
866    ///Copy constructor
867
868    ///Makes a copy of an EdgeSet.
869    ///It will be based on the same graph.
870    EdgeSet(const EdgeSet &_g)
871      : G(_g.G), nodes(_g.G), edges(_g.edges),
872        first_free_edge(_g.first_free_edge) {}
873   
874    ///Number of nodes.
875    int nodeNum() const { return G.nodeNum(); }
876    ///Number of edges.
877    int edgeNum() const { return edges.size(); }
878
879    /// Maximum node ID.
880   
881    /// Maximum node ID.
882    ///\sa id(Node)
883    int maxNodeId() const { return G.maxNodeId(); }
884    /// Maximum edge ID.
885   
886    /// Maximum edge ID.
887    ///\sa id(Edge)
888    int maxEdgeId() const { return edges.size()-1; }
889
890    Node tail(Edge e) const { return edges[e.n].tail; }
891    Node head(Edge e) const { return edges[e.n].head; }
892
893    NodeIt& first(NodeIt& v) const {
894      v=NodeIt(*this); return v; }
895    EdgeIt& first(EdgeIt& e) const {
896      e=EdgeIt(*this); return e; }
897    OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
898      e=OutEdgeIt(*this,v); return e; }
899    InEdgeIt& first(InEdgeIt& e, const Node v) const {
900      e=InEdgeIt(*this,v); return e; }
901
902    /// Node ID.
903   
904    /// The ID of a valid Node is a nonnegative integer not greater than
905    /// \ref maxNodeId(). The range of the ID's is not surely continuous
906    /// and the greatest node ID can be actually less then \ref maxNodeId().
907    ///
908    /// The ID of the \ref INVALID node is -1.
909    ///\return The ID of the node \c v.
910    int id(Node v) { return G.id(v); }
911    /// Edge ID.
912   
913    /// The ID of a valid Edge is a nonnegative integer not greater than
914    /// \ref maxEdgeId(). The range of the ID's is not surely continuous
915    /// and the greatest edge ID can be actually less then \ref maxEdgeId().
916    ///
917    /// The ID of the \ref INVALID edge is -1.
918    ///\return The ID of the edge \c e.
919    int id(Edge e) const { return e.n; }
920
921    /// Adds a new node to the graph.
922    Node addNode() { return G.addNode(); }
923   
924    Edge addEdge(Node u, Node v) {
925      int n;
926     
927      if(first_free_edge==-1)
928        {
929          n = edges.size();
930          edges.push_back(EdgeT());
931        }
932      else {
933        n = first_free_edge;
934        first_free_edge = edges[n].next_in;
935      }
936     
937      edges[n].tail = u; edges[n].head = v;
938
939      edges[n].next_out = nodes[u].first_out;
940      if(nodes[u].first_out != -1) edges[nodes[u].first_out].prev_out = n;
941      edges[n].next_in = nodes[v].first_in;
942      if(nodes[v].first_in != -1) edges[nodes[v].first_in].prev_in = n;
943      edges[n].prev_in = edges[n].prev_out = -1;
944       
945      nodes[u].first_out = nodes[v].first_in = n;
946
947      Edge e; e.n=n;
948
949      //Update dynamic maps
950      edge_maps.add(e);
951
952      return e;
953    }
954
955    /// Finds an edge between two nodes.
956
957    /// Finds an edge from node \c u to node \c v.
958    ///
959    /// If \c prev is \ref INVALID (this is the default value), then
960    /// It finds the first edge from \c u to \c v. Otherwise it looks for
961    /// the next edge from \c u to \c v after \c prev.
962    /// \return The found edge or INVALID if there is no such an edge.
963    Edge findEdge(Node u,Node v, Edge prev = INVALID)
964    {
965      int e = (prev.n==-1)? nodes[u].first_out : edges[prev.n].next_out;
966      while(e!=-1 && edges[e].tail!=v) e = edges[e].next_out;
967      prev.n=e;
968      return prev;
969    }
970   
971  private:
972    void eraseEdge(int n) {
973     
974      if(edges[n].next_in!=-1)
975        edges[edges[n].next_in].prev_in = edges[n].prev_in;
976      if(edges[n].prev_in!=-1)
977        edges[edges[n].prev_in].next_in = edges[n].next_in;
978      else nodes[edges[n].head].first_in = edges[n].next_in;
979     
980      if(edges[n].next_out!=-1)
981        edges[edges[n].next_out].prev_out = edges[n].prev_out;
982      if(edges[n].prev_out!=-1)
983        edges[edges[n].prev_out].next_out = edges[n].next_out;
984      else nodes[edges[n].tail].first_out = edges[n].next_out;
985     
986      edges[n].next_in = first_free_edge;
987      first_free_edge = -1;     
988
989      //Update dynamic maps
990      Edge e; e.n = n;
991      edge_maps.erase(e);
992    }
993     
994  public:
995
996//     void erase(Node nn) {
997//       int n=nn.n;
998//       int m;
999//       while((m=nodes[n].first_in)!=-1) eraseEdge(m);
1000//       while((m=nodes[n].first_out)!=-1) eraseEdge(m);
1001//     }
1002   
1003    void erase(Edge e) { eraseEdge(e.n); }
1004
1005    ///Clear all edges. (Doesn't clear the nodes!)
1006    void clear() {
1007      edge_maps.clear();
1008      edges.clear();
1009      first_free_edge=-1;
1010    }
1011
1012
1013    class Edge {
1014    public:
1015      friend class EdgeSet;
1016      template <typename T> friend class EdgeMap;
1017
1018      friend class Node;
1019      friend class NodeIt;
1020    public:
1021      ///\bug It should be at least protected
1022      ///
1023      int n;
1024    protected:
1025      friend int EdgeSet::id(Edge e) const;
1026
1027      Edge(int nn) {n=nn;}
1028    public:
1029      Edge() { }
1030      Edge (Invalid) { n=-1; }
1031      bool operator==(const Edge i) const {return n==i.n;}
1032      bool operator!=(const Edge i) const {return n!=i.n;}
1033      bool operator<(const Edge i) const {return n<i.n;}
1034      ///\bug This is a workaround until somebody tells me how to
1035      ///make class \c SymEdgeSet::SymEdgeMap friend of Edge
1036      int &idref() {return n;}
1037      const int &idref() const {return n;}
1038    };
1039   
1040    class EdgeIt : public Edge {
1041      friend class EdgeSet;
1042      template <typename T> friend class EdgeMap;
1043   
1044      const EdgeSet *G;
1045    public:
1046      EdgeIt(const EdgeSet& _G) : Edge(), G(&_G) {
1047        //              typename NodeGraphType::Node m;
1048        NodeIt m;
1049        for(G->first(m);
1050            m!=INVALID && G->nodes[m].first_in == -1;  ++m);
1051        ///\bug AJJAJ! This is a non sense!!!!!!!
1052        this->n = m!=INVALID?-1:G->nodes[m].first_in;
1053      }
1054      EdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
1055      EdgeIt (Invalid i) : Edge(i) { }
1056      EdgeIt() : Edge() { }
1057      ///.
1058     
1059      ///\bug UNIMPLEMENTED!!!!!
1060      //
1061      EdgeIt &operator++() {
1062        return *this;
1063      }
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 this->n;}
1067    };
1068   
1069    class OutEdgeIt : public Edge {
1070      const EdgeSet *G;
1071      friend class EdgeSet;
1072    public:
1073      OutEdgeIt() : Edge() { }
1074      OutEdgeIt (Invalid i) : Edge(i) { }
1075      OutEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
1076
1077      OutEdgeIt(const EdgeSet& _G,const Node v) :
1078        Edge(_G.nodes[v].first_out), G(&_G) { }
1079      OutEdgeIt &operator++() { n = G->edges[n].next_out; return *this; }
1080    };
1081   
1082    class InEdgeIt : public Edge {
1083      const EdgeSet *G;
1084      friend class EdgeSet;
1085    public:
1086      InEdgeIt() : Edge() { }
1087      InEdgeIt (Invalid i) : Edge(i) { }
1088      InEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
1089      InEdgeIt(const EdgeSet& _G,Node v)
1090        : Edge(_G.nodes[v].first_in), G(&_G) { }
1091      InEdgeIt &operator++() { n=G->edges[n].next_in; return *this; }
1092    };
1093
1094   
1095    template <typename V> class NodeMap
1096      : public NodeGraphType::template NodeMap<V>
1097    {
1098      //This is a must, the constructors need it.
1099      typedef typename NodeGraphType::template NodeMap<V> MapImpl;
1100      typedef V Value;
1101    public:
1102      NodeMap() : MapImpl() {}
1103     
1104      NodeMap(const EdgeSet& graph)
1105        : MapImpl(graph.G) { }
1106
1107      NodeMap(const EdgeSet& graph, const Value& value)
1108        : MapImpl(graph.G, value) { }
1109
1110      NodeMap(const NodeMap& copy)
1111        : MapImpl(static_cast<const MapImpl&>(copy)) {}
1112
1113      template<typename CMap>
1114      NodeMap(const CMap& copy)
1115        : MapImpl(copy) { }
1116
1117      NodeMap& operator=(const NodeMap& copy) {
1118        MapImpl::operator=(static_cast<const MapImpl&>(copy));
1119        return *this;
1120      }
1121
1122      template <typename CMap>
1123      NodeMap& operator=(const CMap& copy) {
1124        MapImpl::operator=(copy);
1125        return *this;
1126      }
1127
1128    };
1129  };
1130
1131  template<typename GG>
1132  inline int EdgeSet<GG>::id(Node v) const { return G.id(v); }
1133
1134/// @} 
1135
1136} //namespace hugo
1137
1138#endif //HUGO_LIST_GRAPH_H
Note: See TracBrowser for help on using the repository browser.