Many of ckeckCompileXYZ()'s are now in the corresponding skeleton headers.
(Tests for Symmetric Graphs are still to be moved)
2 * src/lemon/list_graph.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Combinatorial Optimization Research Group, EGRES).
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.
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
17 #ifndef LEMON_LIST_GRAPH_H
18 #define LEMON_LIST_GRAPH_H
22 ///\brief ListGraph, SymListGraph, NodeSet and EdgeSet classes.
27 #include <lemon/invalid.h>
29 #include <lemon/map_registry.h>
30 #include <lemon/array_map.h>
32 #include <lemon/map_defines.h>
37 /// \addtogroup graphs
40 ///A list graph class.
42 ///This is a simple and fast erasable graph implementation.
45 ///\ref skeleton::ErasableGraph "ErasableGraph" concept.
46 ///\sa skeleton::ErasableGraph.
49 //Nodes are double linked.
50 //The free nodes are only single linked using the "next" field.
53 int first_in,first_out;
56 //Edges are double linked.
57 //The free edges are only single linked using the "next_in" field.
61 int prev_in, prev_out;
62 int next_in, next_out;
65 std::vector<NodeT> nodes;
70 std::vector<EdgeT> edges;
76 typedef ListGraph Graph;
89 // Create map registries.
90 CREATE_MAP_REGISTRIES;
91 // Create node and edge maps.
92 CREATE_MAPS(ArrayMap);
97 : nodes(), first_node(-1),
98 first_free_node(-1), edges(), first_free_edge(-1) {}
100 ListGraph(const ListGraph &_g)
101 : nodes(_g.nodes), first_node(_g.first_node),
102 first_free_node(_g.first_free_node), edges(_g.edges),
103 first_free_edge(_g.first_free_edge) {}
105 /// \bug In the vector can be hole if a node is erased from the graph.
107 int nodeNum() const { return nodes.size(); }
109 int edgeNum() const { return edges.size(); }
111 ///Set the expected maximum number of edges.
113 ///With this function, it is possible to set the expected number of edges.
114 ///The use of this fasten the building of the graph and makes
115 ///it possible to avoid the superfluous memory allocation.
116 void reserveEdge(int n) { edges.reserve(n); };
122 int maxNodeId() const { return nodes.size()-1; }
127 int maxEdgeId() const { return edges.size()-1; }
129 Node tail(Edge e) const { return edges[e.n].tail; }
130 Node head(Edge e) const { return edges[e.n].head; }
132 NodeIt& first(NodeIt& v) const {
133 v=NodeIt(*this); return v; }
134 EdgeIt& first(EdgeIt& e) const {
135 e=EdgeIt(*this); return e; }
136 OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
137 e=OutEdgeIt(*this,v); return e; }
138 InEdgeIt& first(InEdgeIt& e, const Node v) const {
139 e=InEdgeIt(*this,v); return e; }
143 /// The ID of a valid Node is a nonnegative integer not greater than
144 /// \ref maxNodeId(). The range of the ID's is not surely continuous
145 /// and the greatest node ID can be actually less then \ref maxNodeId().
147 /// The ID of the \ref INVALID node is -1.
148 ///\return The ID of the node \c v.
149 static int id(Node v) { return v.n; }
152 /// The ID of a valid Edge is a nonnegative integer not greater than
153 /// \ref maxEdgeId(). The range of the ID's is not surely continuous
154 /// and the greatest edge ID can be actually less then \ref maxEdgeId().
156 /// The ID of the \ref INVALID edge is -1.
157 ///\return The ID of the edge \c e.
158 static int id(Edge e) { return e.n; }
160 /// Adds a new node to the graph.
162 /// \warning It adds the new node to the front of the list.
163 /// (i.e. the lastly added node becomes the first.)
167 if(first_free_node==-1)
170 nodes.push_back(NodeT());
174 first_free_node = nodes[n].next;
177 nodes[n].next = first_node;
178 if(first_node != -1) nodes[first_node].prev = n;
182 nodes[n].first_in = nodes[n].first_out = -1;
186 //Update dynamic maps
192 Edge addEdge(Node u, Node v) {
195 if(first_free_edge==-1)
198 edges.push_back(EdgeT());
202 first_free_edge = edges[n].next_in;
205 edges[n].tail = u.n; edges[n].head = v.n;
207 edges[n].next_out = nodes[u.n].first_out;
208 if(nodes[u.n].first_out != -1) edges[nodes[u.n].first_out].prev_out = n;
209 edges[n].next_in = nodes[v.n].first_in;
210 if(nodes[v.n].first_in != -1) edges[nodes[v.n].first_in].prev_in = n;
211 edges[n].prev_in = edges[n].prev_out = -1;
213 nodes[u.n].first_out = nodes[v.n].first_in = n;
217 //Update dynamic maps
223 /// Finds an edge between two nodes.
225 /// Finds an edge from node \c u to node \c v.
227 /// If \c prev is \ref INVALID (this is the default value), then
228 /// It finds the first edge from \c u to \c v. Otherwise it looks for
229 /// the next edge from \c u to \c v after \c prev.
230 /// \return The found edge or INVALID if there is no such an edge.
231 Edge findEdge(Node u,Node v, Edge prev = INVALID)
233 int e = (prev.n==-1)? nodes[u.n].first_out : edges[prev.n].next_out;
234 while(e!=-1 && edges[e].tail!=v.n) e = edges[e].next_out;
240 void eraseEdge(int n) {
242 if(edges[n].next_in!=-1)
243 edges[edges[n].next_in].prev_in = edges[n].prev_in;
244 if(edges[n].prev_in!=-1)
245 edges[edges[n].prev_in].next_in = edges[n].next_in;
246 else nodes[edges[n].head].first_in = edges[n].next_in;
248 if(edges[n].next_out!=-1)
249 edges[edges[n].next_out].prev_out = edges[n].prev_out;
250 if(edges[n].prev_out!=-1)
251 edges[edges[n].prev_out].next_out = edges[n].next_out;
252 else nodes[edges[n].tail].first_out = edges[n].next_out;
254 edges[n].next_in = first_free_edge;
257 //Update dynamic maps
265 void erase(Node nn) {
269 while((m=nodes[n].first_in)!=-1) eraseEdge(m);
270 while((m=nodes[n].first_out)!=-1) eraseEdge(m);
272 if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
273 if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
274 else first_node = nodes[n].next;
276 nodes[n].next = first_free_node;
279 //Update dynamic maps
284 void erase(Edge e) { eraseEdge(e.n); }
291 first_node=first_free_node=first_free_edge=-1;
295 friend class ListGraph;
296 template <typename T> friend class NodeMap;
299 friend class OutEdgeIt;
300 friend class InEdgeIt;
301 friend class SymEdge;
305 friend int ListGraph::id(Node v);
309 Node (Invalid) { n=-1; }
310 bool operator==(const Node i) const {return n==i.n;}
311 bool operator!=(const Node i) const {return n!=i.n;}
312 bool operator<(const Node i) const {return n<i.n;}
314 // operator bool() { return n!=-1; }
317 class NodeIt : public Node {
319 friend class ListGraph;
321 NodeIt() : Node() { }
322 NodeIt(Invalid i) : Node(i) { }
323 NodeIt(const ListGraph& _G) : Node(_G.first_node), G(&_G) { }
324 NodeIt(const ListGraph& _G,Node n) : Node(n), G(&_G) { }
325 NodeIt &operator++() {
330 // operator bool() { return Node::operator bool(); }
334 friend class ListGraph;
335 template <typename T> friend class EdgeMap;
337 friend class SymListGraph;
343 friend int ListGraph::id(Edge e);
346 /// An Edge with id \c n.
348 /// \bug It should be
349 /// obtained by a member function of the Graph.
353 Edge (Invalid) { n=-1; }
354 bool operator==(const Edge i) const {return n==i.n;}
355 bool operator!=(const Edge i) const {return n!=i.n;}
356 bool operator<(const Edge i) const {return n<i.n;}
358 // operator bool() { return n!=-1; }
361 class EdgeIt : public Edge {
363 friend class ListGraph;
365 EdgeIt(const ListGraph& _G) : Edge(), G(&_G) {
368 m!=-1 && _G.nodes[m].first_in == -1; m = _G.nodes[m].next);
369 n = (m==-1)?-1:_G.nodes[m].first_in;
371 EdgeIt (Invalid i) : Edge(i) { }
372 EdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
373 EdgeIt() : Edge() { }
374 EdgeIt &operator++() {
375 if(G->edges[n].next_in!=-1) n=G->edges[n].next_in;
378 for(nn=G->nodes[G->edges[n].head].next;
379 nn!=-1 && G->nodes[nn].first_in == -1;
380 nn = G->nodes[nn].next) ;
381 n = (nn==-1)?-1:G->nodes[nn].first_in;
386 // operator bool() { return Edge::operator bool(); }
389 class OutEdgeIt : public Edge {
391 friend class ListGraph;
393 OutEdgeIt() : Edge() { }
394 OutEdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
395 OutEdgeIt (Invalid i) : Edge(i) { }
397 OutEdgeIt(const ListGraph& _G,const Node v)
398 : Edge(_G.nodes[v.n].first_out), G(&_G) {}
399 OutEdgeIt &operator++() { n=G->edges[n].next_out; return *this; }
401 // operator bool() { return Edge::operator bool(); }
404 class InEdgeIt : public Edge {
406 friend class ListGraph;
408 InEdgeIt() : Edge() { }
409 InEdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
410 InEdgeIt (Invalid i) : Edge(i) { }
411 InEdgeIt(const ListGraph& _G,Node v)
412 : Edge(_G.nodes[v.n].first_in), G(&_G) { }
413 InEdgeIt &operator++() { n=G->edges[n].next_in; return *this; }
415 // operator bool() { return Edge::operator bool(); }
419 ///Graph for bidirectional edges.
421 ///The purpose of this graph structure is to handle graphs
422 ///having bidirectional edges. Here the function \c addEdge(u,v) adds a pair
423 ///of oppositely directed edges.
424 ///There is a new edge map type called
425 ///\ref lemon::SymListGraph::SymEdgeMap "SymEdgeMap"
426 ///that complements this
428 ///storing shared values for the edge pairs. The usual
429 ///\ref lemon::skeleton::StaticGraph::EdgeMap "EdgeMap"
433 ///The oppositely directed edge can also be obtained easily
434 ///using \ref lemon::SymListGraph::opposite() "opposite()" member function.
436 ///Here erase(Edge) deletes a pair of edges.
438 ///\todo this date structure need some reconsiderations. Maybe it
439 ///should be implemented independently from ListGraph.
441 class SymListGraph : public ListGraph
445 typedef SymListGraph Graph;
447 // Create symmetric map registry.
448 CREATE_SYM_EDGE_MAP_REGISTRY;
449 // Create symmetric edge map.
450 CREATE_SYM_EDGE_MAP(ArrayMap);
452 SymListGraph() : ListGraph() { }
453 SymListGraph(const ListGraph &_g) : ListGraph(_g) { }
454 ///Adds a pair of oppositely directed edges to the graph.
455 Edge addEdge(Node u, Node v)
457 Edge e = ListGraph::addEdge(u,v);
458 Edge f = ListGraph::addEdge(v,u);
459 sym_edge_maps.add(e);
460 sym_edge_maps.add(f);
465 void erase(Node n) { ListGraph::erase(n);}
466 ///The oppositely directed edge.
468 ///Returns the oppositely directed
469 ///pair of the edge \c e.
470 static Edge opposite(Edge e)
473 f.n = e.n - 2*(e.n%2) + 1;
477 ///Removes a pair of oppositely directed edges to the graph.
479 Edge f = opposite(e);
480 sym_edge_maps.erase(e);
481 sym_edge_maps.erase(f);
487 class SymListGraph : public ListGraph {
488 typedef ListGraph Parent;
491 typedef SymListGraph Graph;
493 typedef ListGraph::Node Node;
494 typedef ListGraph::NodeIt NodeIt;
504 template <typename Value>
505 class NodeMap : public Parent::NodeMap<Value> {
507 NodeMap(const SymListGraph& g)
508 : SymListGraph::Parent::NodeMap<Value>(g) {}
509 NodeMap(const SymListGraph& g, Value v)
510 : SymListGraph::Parent::NodeMap<Value>(g, v) {}
511 template<typename TT>
512 NodeMap(const NodeMap<TT>& copy)
513 : SymListGraph::Parent::NodeMap<Value>(copy) { }
516 template <typename Value>
517 class SymEdgeMap : public Parent::EdgeMap<Value> {
519 typedef SymEdge KeyType;
521 SymEdgeMap(const SymListGraph& g)
522 : SymListGraph::Parent::EdgeMap<Value>(g) {}
523 SymEdgeMap(const SymListGraph& g, Value v)
524 : SymListGraph::Parent::EdgeMap<Value>(g, v) {}
525 template<typename TT>
526 SymEdgeMap(const SymEdgeMap<TT>& copy)
527 : SymListGraph::Parent::EdgeMap<Value>(copy) { }
531 // Create edge map registry.
532 CREATE_EDGE_MAP_REGISTRY;
534 CREATE_EDGE_MAP(ArrayMap);
537 friend class SymListGraph;
538 friend class SymListGraph::EdgeIt;
539 friend class SymListGraph::OutEdgeIt;
540 friend class SymListGraph::InEdgeIt;
545 Edge(int pid) { id = pid; }
548 /// An Edge with id \c n.
551 Edge (Invalid) { id = -1; }
553 operator SymEdge(){ return SymEdge(id >> 1);}
555 bool operator==(const Edge i) const {return id == i.id;}
556 bool operator!=(const Edge i) const {return id != i.id;}
557 bool operator<(const Edge i) const {return id < i.id;}
559 // operator bool() { return n!=-1; }
562 class SymEdge : public ListGraph::Edge {
563 friend class SymListGraph;
564 friend class SymListGraph::Edge;
565 typedef ListGraph::Edge Parent;
568 SymEdge(int pid) : Parent(pid) {}
572 SymEdge(const ListGraph::Edge& i) : Parent(i) {}
573 SymEdge (Invalid) : Parent(INVALID) {}
578 Parent::OutEdgeIt out;
582 OutEdgeIt(const SymListGraph& g, Edge e) {
583 if ((e.id & 1) == 0) {
584 out = Parent::OutEdgeIt(g, SymEdge(e));
585 in = Parent::InEdgeIt(g, g.tail(e));
587 out = Parent::OutEdgeIt(INVALID);
588 in = Parent::InEdgeIt(g, SymEdge(e));
591 OutEdgeIt (Invalid i) : out(INVALID), in(INVALID) { }
593 OutEdgeIt(const SymListGraph& g, const Node v)
594 : out(g, v), in(g, v) {}
595 OutEdgeIt &operator++() {
596 if (out != INVALID) {
604 operator Edge() const {
605 if (out == INVALID && in == INVALID) return INVALID;
606 return out != INVALID ? forward(out) : backward(in);
609 bool operator==(const Edge i) const {return Edge(*this) == i;}
610 bool operator!=(const Edge i) const {return Edge(*this) != i;}
611 bool operator<(const Edge i) const {return Edge(*this) < i;}
615 Parent::OutEdgeIt out;
619 InEdgeIt(const SymListGraph& g, Edge e) {
620 if ((e.id & 1) == 0) {
621 out = Parent::OutEdgeIt(g, SymEdge(e));
622 in = Parent::InEdgeIt(g, g.tail(e));
624 out = Parent::OutEdgeIt(INVALID);
625 in = Parent::InEdgeIt(g, SymEdge(e));
628 InEdgeIt (Invalid i) : out(INVALID), in(INVALID) { }
630 InEdgeIt(const SymListGraph& g, const Node v)
631 : out(g, v), in(g, v) {}
633 InEdgeIt &operator++() {
634 if (out != INVALID) {
642 operator Edge() const {
643 if (out == INVALID && in == INVALID) return INVALID;
644 return out != INVALID ? backward(out) : forward(in);
647 bool operator==(const Edge i) const {return Edge(*this) == i;}
648 bool operator!=(const Edge i) const {return Edge(*this) != i;}
649 bool operator<(const Edge i) const {return Edge(*this) < i;}
652 class SymEdgeIt : public Parent::EdgeIt {
657 SymEdgeIt(const SymListGraph& g)
658 : SymListGraph::Parent::EdgeIt(g) {}
660 SymEdgeIt(const SymListGraph& g, SymEdge e)
661 : SymListGraph::Parent::EdgeIt(g, e) {}
664 : SymListGraph::Parent::EdgeIt(INVALID) {}
666 SymEdgeIt& operator++() {
667 SymListGraph::Parent::EdgeIt::operator++();
671 operator SymEdge() const {
673 (static_cast<const SymListGraph::Parent::EdgeIt&>(*this));
675 bool operator==(const SymEdge i) const {return SymEdge(*this) == i;}
676 bool operator!=(const SymEdge i) const {return SymEdge(*this) != i;}
677 bool operator<(const SymEdge i) const {return SymEdge(*this) < i;}
684 EdgeIt(const SymListGraph& g) : it(g), fw(true) {}
685 EdgeIt (Invalid i) : it(i) { }
686 EdgeIt(const SymListGraph& g, Edge e)
687 : it(g, SymEdge(e)), fw(id(e) & 1 == 0) { }
689 EdgeIt& operator++() {
694 operator Edge() const {
695 if (it == INVALID) return INVALID;
696 return fw ? forward(it) : backward(it);
698 bool operator==(const Edge i) const {return Edge(*this) == i;}
699 bool operator!=(const Edge i) const {return Edge(*this) != i;}
700 bool operator<(const Edge i) const {return Edge(*this) < i;}
705 int nodeNum() const { return Parent::nodeNum(); }
707 int edgeNum() const { return 2*Parent::edgeNum(); }
708 ///Number of symmetric edges.
709 int symEdgeNum() const { return Parent::edgeNum(); }
711 ///Set the expected maximum number of edges.
713 ///With this function, it is possible to set the expected number of edges.
714 ///The use of this fasten the building of the graph and makes
715 ///it possible to avoid the superfluous memory allocation.
716 void reserveSymEdge(int n) { Parent::reserveEdge(n); };
722 int maxNodeId() const { return Parent::maxNodeId(); }
727 int maxEdgeId() const { return 2*Parent::maxEdgeId(); }
728 /// Maximum symmetric edge ID.
730 /// Maximum symmetric edge ID.
732 int maxSymEdgeId() const { return Parent::maxEdgeId(); }
735 Node tail(Edge e) const {
736 return (e.id & 1) == 0 ?
737 Parent::tail(SymEdge(e)) : Parent::head(SymEdge(e));
740 Node head(Edge e) const {
741 return (e.id & 1) == 0 ?
742 Parent::head(SymEdge(e)) : Parent::tail(SymEdge(e));
745 Node tail(SymEdge e) const {
746 return Parent::tail(e);
749 Node head(SymEdge e) const {
750 return Parent::head(e);
753 NodeIt& first(NodeIt& v) const {
754 v=NodeIt(*this); return v; }
755 EdgeIt& first(EdgeIt& e) const {
756 e=EdgeIt(*this); return e; }
757 SymEdgeIt& first(SymEdgeIt& e) const {
758 e=SymEdgeIt(*this); return e; }
759 OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
760 e=OutEdgeIt(*this,v); return e; }
761 InEdgeIt& first(InEdgeIt& e, const Node v) const {
762 e=InEdgeIt(*this,v); return e; }
766 /// The ID of a valid Node is a nonnegative integer not greater than
767 /// \ref maxNodeId(). The range of the ID's is not surely continuous
768 /// and the greatest node ID can be actually less then \ref maxNodeId().
770 /// The ID of the \ref INVALID node is -1.
771 ///\return The ID of the node \c v.
772 static int id(Node v) { return Parent::id(v); }
775 /// The ID of a valid Edge is a nonnegative integer not greater than
776 /// \ref maxEdgeId(). The range of the ID's is not surely continuous
777 /// and the greatest edge ID can be actually less then \ref maxEdgeId().
779 /// The ID of the \ref INVALID edge is -1.
780 ///\return The ID of the edge \c e.
781 static int id(Edge e) { return e.id; }
783 /// The ID of a valid SymEdge is a nonnegative integer not greater than
784 /// \ref maxSymEdgeId(). The range of the ID's is not surely continuous
785 /// and the greatest edge ID can be actually less then \ref maxSymEdgeId().
787 /// The ID of the \ref INVALID symmetric edge is -1.
788 ///\return The ID of the edge \c e.
789 static int id(SymEdge e) { return Parent::id(e); }
791 /// Adds a new node to the graph.
793 /// \warning It adds the new node to the front of the list.
794 /// (i.e. the lastly added node becomes the first.)
796 return Parent::addNode();
799 SymEdge addEdge(Node u, Node v) {
800 SymEdge se = Parent::addEdge(u, v);
801 edge_maps.add(forward(se));
802 edge_maps.add(backward(se));
806 /// Finds an edge between two nodes.
808 /// Finds an edge from node \c u to node \c v.
810 /// If \c prev is \ref INVALID (this is the default value), then
811 /// It finds the first edge from \c u to \c v. Otherwise it looks for
812 /// the next edge from \c u to \c v after \c prev.
813 /// \return The found edge or INVALID if there is no such an edge.
814 Edge findEdge(Node u, Node v, Edge prev = INVALID)
816 if (prev == INVALID || id(prev) & 1 == 0) {
817 SymEdge se = Parent::findEdge(u, v, SymEdge(prev));
818 if (se != INVALID) return forward(se);
820 SymEdge se = Parent::findEdge(v, u, SymEdge(prev));
821 if (se != INVALID) return backward(se);
826 // /// Finds an symmetric edge between two nodes.
828 // /// Finds an symmetric edge from node \c u to node \c v.
830 // /// If \c prev is \ref INVALID (this is the default value), then
831 // /// It finds the first edge from \c u to \c v. Otherwise it looks for
832 // /// the next edge from \c u to \c v after \c prev.
833 // /// \return The found edge or INVALID if there is no such an edge.
835 // SymEdge findEdge(Node u, Node v, SymEdge prev = INVALID)
837 // if (prev == INVALID || id(prev) & 1 == 0) {
838 // SymEdge se = Parent::findEdge(u, v, SymEdge(prev));
839 // if (se != INVALID) return se;
841 // SymEdge se = Parent::findEdge(v, u, SymEdge(prev));
842 // if (se != INVALID) return se;
850 for (OutEdgeIt it(*this, n); it != INVALID; ++it) {
852 edge_maps.erase(opposite(it));
857 void erase(SymEdge e) {
858 edge_maps.erase(forward(e));
859 edge_maps.erase(backward(e));
868 static Edge opposite(Edge e) {
869 return Edge(id(e) ^ 1);
872 static Edge forward(SymEdge e) {
873 return Edge(id(e) << 1);
876 static Edge backward(SymEdge e) {
877 return Edge((id(e) << 1) | 1);
882 ///A graph class containing only nodes.
884 ///This class implements a graph structure without edges.
885 ///The most useful application of this class is to be the node set of an
886 ///\ref EdgeSet class.
889 ///the \ref skeleton::ExtendableGraph "ExtendableGraph" concept
890 ///with the exception that you cannot
891 ///add (or delete) edges. The usual edge iterators are exists, but they are
892 ///always \ref INVALID.
893 ///\sa skeleton::ExtendableGraph
897 //Nodes are double linked.
898 //The free nodes are only single linked using the "next" field.
901 int first_in,first_out;
906 std::vector<NodeT> nodes;
909 //The first free node
914 typedef NodeSet Graph;
926 // Create node map registry.
927 CREATE_NODE_MAP_REGISTRY;
929 CREATE_NODE_MAP(ArrayMap);
931 /// Creating empty map structure for edges.
932 template <typename Value>
935 EdgeMap(const Graph&) {}
936 EdgeMap(const Graph&, const Value&) {}
938 EdgeMap(const EdgeMap&) {}
939 template <typename CMap> EdgeMap(const CMap&) {}
941 EdgeMap& operator=(const EdgeMap&) {}
942 template <typename CMap> EdgeMap& operator=(const CMap&) {}
944 class ConstIterator {
946 bool operator==(const ConstIterator&) {return true;}
947 bool operator!=(const ConstIterator&) {return false;}
950 typedef ConstIterator Iterator;
952 Iterator begin() { return Iterator();}
953 Iterator end() { return Iterator();}
955 ConstIterator begin() const { return ConstIterator();}
956 ConstIterator end() const { return ConstIterator();}
962 ///Default constructor
964 : nodes(), first_node(-1), first_free_node(-1) {}
966 NodeSet(const NodeSet &_g)
967 : nodes(_g.nodes), first_node(_g.first_node),
968 first_free_node(_g.first_free_node) {}
971 int nodeNum() const { return nodes.size(); }
973 int edgeNum() const { return 0; }
979 int maxNodeId() const { return nodes.size()-1; }
984 int maxEdgeId() const { return 0; }
986 Node tail(Edge e) const { return INVALID; }
987 Node head(Edge e) const { return INVALID; }
989 NodeIt& first(NodeIt& v) const {
990 v=NodeIt(*this); return v; }
991 EdgeIt& first(EdgeIt& e) const {
992 e=EdgeIt(*this); return e; }
993 OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
994 e=OutEdgeIt(*this,v); return e; }
995 InEdgeIt& first(InEdgeIt& e, const Node v) const {
996 e=InEdgeIt(*this,v); return e; }
1000 /// The ID of a valid Node is a nonnegative integer not greater than
1001 /// \ref maxNodeId(). The range of the ID's is not surely continuous
1002 /// and the greatest node ID can be actually less then \ref maxNodeId().
1004 /// The ID of the \ref INVALID node is -1.
1005 ///\return The ID of the node \c v.
1006 static int id(Node v) { return v.n; }
1009 /// The ID of a valid Edge is a nonnegative integer not greater than
1010 /// \ref maxEdgeId(). The range of the ID's is not surely continuous
1011 /// and the greatest edge ID can be actually less then \ref maxEdgeId().
1013 /// The ID of the \ref INVALID edge is -1.
1014 ///\return The ID of the edge \c e.
1015 static int id(Edge e) { return -1; }
1017 /// Adds a new node to the graph.
1019 /// \warning It adds the new node to the front of the list.
1020 /// (i.e. the lastly added node becomes the first.)
1024 if(first_free_node==-1)
1027 nodes.push_back(NodeT());
1030 n = first_free_node;
1031 first_free_node = nodes[n].next;
1034 nodes[n].next = first_node;
1035 if(first_node != -1) nodes[first_node].prev = n;
1039 nodes[n].first_in = nodes[n].first_out = -1;
1043 //Update dynamic maps
1049 void erase(Node nn) {
1052 if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
1053 if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
1054 else first_node = nodes[n].next;
1056 nodes[n].next = first_free_node;
1057 first_free_node = n;
1059 //Update dynamic maps
1060 node_maps.erase(nn);
1064 Edge findEdge(Node u,Node v, Edge prev = INVALID)
1072 first_node = first_free_node = -1;
1076 friend class NodeSet;
1077 template <typename T> friend class NodeMap;
1080 friend class OutEdgeIt;
1081 friend class InEdgeIt;
1085 friend int NodeSet::id(Node v);
1086 Node(int nn) {n=nn;}
1089 Node (Invalid i) { n=-1; }
1090 bool operator==(const Node i) const {return n==i.n;}
1091 bool operator!=(const Node i) const {return n!=i.n;}
1092 bool operator<(const Node i) const {return n<i.n;}
1095 class NodeIt : public Node {
1097 friend class NodeSet;
1099 NodeIt() : Node() { }
1100 NodeIt(const NodeSet& _G,Node n) : Node(n), G(&_G) { }
1101 NodeIt(Invalid i) : Node(i) { }
1102 NodeIt(const NodeSet& _G) : Node(_G.first_node), G(&_G) { }
1103 NodeIt &operator++() {
1113 bool operator==(const Edge i) const {return true;}
1114 bool operator!=(const Edge i) const {return false;}
1115 bool operator<(const Edge i) const {return false;}
1118 class EdgeIt : public Edge {
1120 EdgeIt(const NodeSet& G) : Edge() { }
1121 EdgeIt(const NodeSet&, Edge) : Edge() { }
1122 EdgeIt (Invalid i) : Edge(i) { }
1123 EdgeIt() : Edge() { }
1124 EdgeIt operator++() { return INVALID; }
1127 class OutEdgeIt : public Edge {
1128 friend class NodeSet;
1130 OutEdgeIt() : Edge() { }
1131 OutEdgeIt(const NodeSet&, Edge) : Edge() { }
1132 OutEdgeIt (Invalid i) : Edge(i) { }
1133 OutEdgeIt(const NodeSet& G,const Node v) : Edge() {}
1134 OutEdgeIt operator++() { return INVALID; }
1137 class InEdgeIt : public Edge {
1138 friend class NodeSet;
1140 InEdgeIt() : Edge() { }
1141 InEdgeIt(const NodeSet&, Edge) : Edge() { }
1142 InEdgeIt (Invalid i) : Edge(i) { }
1143 InEdgeIt(const NodeSet& G,Node v) :Edge() {}
1144 InEdgeIt operator++() { return INVALID; }
1151 ///Graph structure using a node set of another graph.
1153 ///This structure can be used to establish another graph over a node set
1154 /// of an existing one. The node iterator will go through the nodes of the
1155 /// original graph, and the NodeMap's of both graphs will convert to
1158 ///\warning Adding or deleting nodes from the graph is not safe if an
1159 ///\ref EdgeSet is currently attached to it!
1161 ///\todo Make it possible to add/delete edges from the base graph
1162 ///(and from \ref EdgeSet, as well)
1164 ///\param GG The type of the graph which shares its node set with this class.
1165 ///Its interface must conform to the
1166 ///\ref skeleton::StaticGraph "StaticGraph" concept.
1168 ///It conforms to the
1169 ///\ref skeleton::ExtendableGraph "ExtendableGraph" concept.
1170 ///\sa skeleton::ExtendableGraph.
1172 template<typename GG>
1175 typedef GG NodeGraphType;
1187 typedef EdgeSet Graph;
1189 int id(Node v) const;
1191 class Node : public NodeGraphType::Node {
1192 friend class EdgeSet;
1195 friend class OutEdgeIt;
1196 friend class InEdgeIt;
1197 friend class SymEdge;
1200 friend int EdgeSet::id(Node v) const;
1202 Node() : NodeGraphType::Node() {}
1203 Node (Invalid i) : NodeGraphType::Node(i) {}
1204 Node(const typename NodeGraphType::Node &n) : NodeGraphType::Node(n) {}
1207 class NodeIt : public NodeGraphType::NodeIt {
1208 friend class EdgeSet;
1210 NodeIt() : NodeGraphType::NodeIt() { }
1211 NodeIt(const EdgeSet& _G,Node n) : NodeGraphType::NodeIt(_G.G,n) { }
1212 NodeIt (Invalid i) : NodeGraphType::NodeIt(i) {}
1213 NodeIt(const EdgeSet& _G) : NodeGraphType::NodeIt(_G.G) { }
1214 NodeIt(const typename NodeGraphType::NodeIt &n)
1215 : NodeGraphType::NodeIt(n) {}
1217 operator Node() { return Node(*this);}
1218 NodeIt &operator++()
1219 { this->NodeGraphType::NodeIt::operator++(); return *this;}
1223 //Edges are double linked.
1224 //The free edges are only single linked using the "next_in" field.
1227 int first_in,first_out;
1228 NodeT() : first_in(-1), first_out(-1) { }
1234 int prev_in, prev_out;
1235 int next_in, next_out;
1239 typename NodeGraphType::template NodeMap<NodeT> nodes;
1241 std::vector<EdgeT> edges;
1242 //The first free edge
1243 int first_free_edge;
1256 // Create edge map registry.
1257 CREATE_EDGE_MAP_REGISTRY;
1258 // Create edge maps.
1259 CREATE_EDGE_MAP(ArrayMap);
1261 // Import node maps from the NodeGraphType.
1262 IMPORT_NODE_MAP(NodeGraphType, graph.G, EdgeSet, graph);
1269 ///Construates a new graph based on the nodeset of an existing one.
1270 ///\param _G the base graph.
1271 explicit EdgeSet(NodeGraphType &_G)
1272 : G(_G), nodes(_G), edges(),
1273 first_free_edge(-1) {}
1276 ///Makes a copy of an EdgeSet.
1277 ///It will be based on the same graph.
1278 explicit EdgeSet(const EdgeSet &_g)
1279 : G(_g.G), nodes(_g.G), edges(_g.edges),
1280 first_free_edge(_g.first_free_edge) {}
1283 int nodeNum() const { return G.nodeNum(); }
1285 int edgeNum() const { return edges.size(); }
1287 /// Maximum node ID.
1289 /// Maximum node ID.
1291 int maxNodeId() const { return G.maxNodeId(); }
1292 /// Maximum edge ID.
1294 /// Maximum edge ID.
1296 int maxEdgeId() const { return edges.size()-1; }
1298 Node tail(Edge e) const { return edges[e.n].tail; }
1299 Node head(Edge e) const { return edges[e.n].head; }
1301 NodeIt& first(NodeIt& v) const {
1302 v=NodeIt(*this); return v; }
1303 EdgeIt& first(EdgeIt& e) const {
1304 e=EdgeIt(*this); return e; }
1305 OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
1306 e=OutEdgeIt(*this,v); return e; }
1307 InEdgeIt& first(InEdgeIt& e, const Node v) const {
1308 e=InEdgeIt(*this,v); return e; }
1312 /// The ID of a valid Node is a nonnegative integer not greater than
1313 /// \ref maxNodeId(). The range of the ID's is not surely continuous
1314 /// and the greatest node ID can be actually less then \ref maxNodeId().
1316 /// The ID of the \ref INVALID node is -1.
1317 ///\return The ID of the node \c v.
1318 int id(Node v) { return G.id(v); }
1321 /// The ID of a valid Edge is a nonnegative integer not greater than
1322 /// \ref maxEdgeId(). The range of the ID's is not surely continuous
1323 /// and the greatest edge ID can be actually less then \ref maxEdgeId().
1325 /// The ID of the \ref INVALID edge is -1.
1326 ///\return The ID of the edge \c e.
1327 static int id(Edge e) { return e.n; }
1329 /// Adds a new node to the graph.
1330 Node addNode() { return G.addNode(); }
1332 Edge addEdge(Node u, Node v) {
1335 if(first_free_edge==-1)
1338 edges.push_back(EdgeT());
1341 n = first_free_edge;
1342 first_free_edge = edges[n].next_in;
1345 edges[n].tail = u; edges[n].head = v;
1347 edges[n].next_out = nodes[u].first_out;
1348 if(nodes[u].first_out != -1) edges[nodes[u].first_out].prev_out = n;
1349 edges[n].next_in = nodes[v].first_in;
1350 if(nodes[v].first_in != -1) edges[nodes[v].first_in].prev_in = n;
1351 edges[n].prev_in = edges[n].prev_out = -1;
1353 nodes[u].first_out = nodes[v].first_in = n;
1357 //Update dynamic maps
1363 /// Finds an edge between two nodes.
1365 /// Finds an edge from node \c u to node \c v.
1367 /// If \c prev is \ref INVALID (this is the default value), then
1368 /// It finds the first edge from \c u to \c v. Otherwise it looks for
1369 /// the next edge from \c u to \c v after \c prev.
1370 /// \return The found edge or INVALID if there is no such an edge.
1371 Edge findEdge(Node u,Node v, Edge prev = INVALID)
1373 int e = (prev.n==-1)? nodes[u].first_out : edges[prev.n].next_out;
1374 while(e!=-1 && edges[e].tail!=v) e = edges[e].next_out;
1380 void eraseEdge(int n) {
1382 if(edges[n].next_in!=-1)
1383 edges[edges[n].next_in].prev_in = edges[n].prev_in;
1384 if(edges[n].prev_in!=-1)
1385 edges[edges[n].prev_in].next_in = edges[n].next_in;
1386 else nodes[edges[n].head].first_in = edges[n].next_in;
1388 if(edges[n].next_out!=-1)
1389 edges[edges[n].next_out].prev_out = edges[n].prev_out;
1390 if(edges[n].prev_out!=-1)
1391 edges[edges[n].prev_out].next_out = edges[n].next_out;
1392 else nodes[edges[n].tail].first_out = edges[n].next_out;
1394 edges[n].next_in = first_free_edge;
1395 first_free_edge = -1;
1397 //Update dynamic maps
1404 void erase(Edge e) { eraseEdge(e.n); }
1406 ///Clear all edges. (Doesn't clear the nodes!)
1416 friend class EdgeSet;
1417 template <typename T> friend class EdgeMap;
1420 friend class NodeIt;
1423 friend int EdgeSet::id(Edge e) const;
1425 Edge(int nn) {n=nn;}
1428 Edge (Invalid) { n=-1; }
1429 bool operator==(const Edge i) const {return n==i.n;}
1430 bool operator!=(const Edge i) const {return n!=i.n;}
1431 bool operator<(const Edge i) const {return n<i.n;}
1434 class EdgeIt : public Edge {
1435 friend class EdgeSet;
1436 template <typename T> friend class EdgeMap;
1440 EdgeIt(const EdgeSet& _G) : Edge(), G(&_G) {
1443 m!=INVALID && G->nodes[m].first_in == -1; ++m);
1444 ///\bug AJJAJ! This is a non sense!!!!!!!
1445 this->n = m!=INVALID?-1:G->nodes[m].first_in;
1447 EdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
1448 EdgeIt (Invalid i) : Edge(i) { }
1449 EdgeIt() : Edge() { }
1452 ///\bug UNIMPLEMENTED!!!!!
1454 EdgeIt &operator++() {
1459 class OutEdgeIt : public Edge {
1461 friend class EdgeSet;
1463 OutEdgeIt() : Edge() { }
1464 OutEdgeIt (Invalid i) : Edge(i) { }
1465 OutEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
1467 OutEdgeIt(const EdgeSet& _G,const Node v) :
1468 Edge(_G.nodes[v].first_out), G(&_G) { }
1469 OutEdgeIt &operator++() {
1470 Edge::n = G->edges[Edge::n].next_out;
1475 class InEdgeIt : public Edge {
1477 friend class EdgeSet;
1479 InEdgeIt() : Edge() { }
1480 InEdgeIt (Invalid i) : Edge(i) { }
1481 InEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
1482 InEdgeIt(const EdgeSet& _G,Node v)
1483 : Edge(_G.nodes[v].first_in), G(&_G) { }
1484 InEdgeIt &operator++() {
1485 Edge::n = G->edges[Edge::n].next_in;
1492 template<typename GG>
1493 inline int EdgeSet<GG>::id(Node v) const { return G.id(v); }
1499 #endif //LEMON_LIST_GRAPH_H