COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/list_graph.h @ 924:ccb657556d84

Last change on this file since 924:ccb657556d84 was 921:818510fa3d99, checked in by Alpar Juttner, 20 years ago

hugo -> lemon

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