beginning of a modular, generic merge_graph_wrapper...
2 * src/hugo/list_graph.h - Part of HUGOlib, 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 HUGO_LIST_GRAPH_H
18 #define HUGO_LIST_GRAPH_H
22 ///\brief ListGraph, SymListGraph, NodeSet and EdgeSet classes.
27 #include <hugo/invalid.h>
29 #include <hugo/map_registry.h>
30 #include <hugo/array_map.h>
32 #include <hugo/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) {}
106 int nodeNum() const { return nodes.size(); }
108 int edgeNum() const { return edges.size(); }
110 ///Set the expected maximum number of edges.
112 ///With this function, it is possible to set the expected number of edges.
113 ///The use of this fasten the building of the graph and makes
114 ///it possible to avoid the superfluous memory allocation.
115 void reserveEdge(int n) { edges.reserve(n); };
121 int maxNodeId() const { return nodes.size()-1; }
126 int maxEdgeId() const { return edges.size()-1; }
128 Node tail(Edge e) const { return edges[e.n].tail; }
129 Node head(Edge e) const { return edges[e.n].head; }
131 NodeIt& first(NodeIt& v) const {
132 v=NodeIt(*this); return v; }
133 EdgeIt& first(EdgeIt& e) const {
134 e=EdgeIt(*this); return e; }
135 OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
136 e=OutEdgeIt(*this,v); return e; }
137 InEdgeIt& first(InEdgeIt& e, const Node v) const {
138 e=InEdgeIt(*this,v); return e; }
142 /// The ID of a valid Node is a nonnegative integer not greater than
143 /// \ref maxNodeId(). The range of the ID's is not surely continuous
144 /// and the greatest node ID can be actually less then \ref maxNodeId().
146 /// The ID of the \ref INVALID node is -1.
147 ///\return The ID of the node \c v.
148 static int id(Node v) { return v.n; }
151 /// The ID of a valid Edge is a nonnegative integer not greater than
152 /// \ref maxEdgeId(). The range of the ID's is not surely continuous
153 /// and the greatest edge ID can be actually less then \ref maxEdgeId().
155 /// The ID of the \ref INVALID edge is -1.
156 ///\return The ID of the edge \c e.
157 static int id(Edge e) { return e.n; }
159 /// Adds a new node to the graph.
161 /// \warning It adds the new node to the front of the list.
162 /// (i.e. the lastly added node becomes the first.)
166 if(first_free_node==-1)
169 nodes.push_back(NodeT());
173 first_free_node = nodes[n].next;
176 nodes[n].next = first_node;
177 if(first_node != -1) nodes[first_node].prev = n;
181 nodes[n].first_in = nodes[n].first_out = -1;
185 //Update dynamic maps
191 Edge addEdge(Node u, Node v) {
194 if(first_free_edge==-1)
197 edges.push_back(EdgeT());
201 first_free_edge = edges[n].next_in;
204 edges[n].tail = u.n; edges[n].head = v.n;
206 edges[n].next_out = nodes[u.n].first_out;
207 if(nodes[u.n].first_out != -1) edges[nodes[u.n].first_out].prev_out = n;
208 edges[n].next_in = nodes[v.n].first_in;
209 if(nodes[v.n].first_in != -1) edges[nodes[v.n].first_in].prev_in = n;
210 edges[n].prev_in = edges[n].prev_out = -1;
212 nodes[u.n].first_out = nodes[v.n].first_in = n;
216 //Update dynamic maps
222 /// Finds an edge between two nodes.
224 /// Finds an edge from node \c u to node \c v.
226 /// If \c prev is \ref INVALID (this is the default value), then
227 /// It finds the first edge from \c u to \c v. Otherwise it looks for
228 /// the next edge from \c u to \c v after \c prev.
229 /// \return The found edge or INVALID if there is no such an edge.
230 Edge findEdge(Node u,Node v, Edge prev = INVALID)
232 int e = (prev.n==-1)? nodes[u.n].first_out : edges[prev.n].next_out;
233 while(e!=-1 && edges[e].tail!=v.n) e = edges[e].next_out;
239 void eraseEdge(int n) {
241 if(edges[n].next_in!=-1)
242 edges[edges[n].next_in].prev_in = edges[n].prev_in;
243 if(edges[n].prev_in!=-1)
244 edges[edges[n].prev_in].next_in = edges[n].next_in;
245 else nodes[edges[n].head].first_in = edges[n].next_in;
247 if(edges[n].next_out!=-1)
248 edges[edges[n].next_out].prev_out = edges[n].prev_out;
249 if(edges[n].prev_out!=-1)
250 edges[edges[n].prev_out].next_out = edges[n].next_out;
251 else nodes[edges[n].tail].first_out = edges[n].next_out;
253 edges[n].next_in = first_free_edge;
256 //Update dynamic maps
264 void erase(Node nn) {
268 while((m=nodes[n].first_in)!=-1) eraseEdge(m);
269 while((m=nodes[n].first_out)!=-1) eraseEdge(m);
271 if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
272 if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
273 else first_node = nodes[n].next;
275 nodes[n].next = first_free_node;
278 //Update dynamic maps
283 void erase(Edge e) { eraseEdge(e.n); }
290 first_node=first_free_node=first_free_edge=-1;
294 friend class ListGraph;
295 template <typename T> friend class NodeMap;
298 friend class OutEdgeIt;
299 friend class InEdgeIt;
300 friend class SymEdge;
304 friend int ListGraph::id(Node v);
308 Node (Invalid) { n=-1; }
309 bool operator==(const Node i) const {return n==i.n;}
310 bool operator!=(const Node i) const {return n!=i.n;}
311 bool operator<(const Node i) const {return n<i.n;}
313 // operator bool() { return n!=-1; }
316 class NodeIt : public Node {
318 friend class ListGraph;
320 NodeIt() : Node() { }
321 NodeIt(Invalid i) : Node(i) { }
322 NodeIt(const ListGraph& _G) : Node(_G.first_node), G(&_G) { }
323 NodeIt(const ListGraph& _G,Node n) : Node(n), G(&_G) { }
324 NodeIt &operator++() {
329 // operator bool() { return Node::operator bool(); }
333 friend class ListGraph;
334 template <typename T> friend class EdgeMap;
336 friend class SymListGraph;
342 friend int ListGraph::id(Edge e);
345 /// An Edge with id \c n.
347 /// \bug It should be
348 /// obtained by a member function of the Graph.
352 Edge (Invalid) { n=-1; }
353 bool operator==(const Edge i) const {return n==i.n;}
354 bool operator!=(const Edge i) const {return n!=i.n;}
355 bool operator<(const Edge i) const {return n<i.n;}
357 // operator bool() { return n!=-1; }
360 class EdgeIt : public Edge {
362 friend class ListGraph;
364 EdgeIt(const ListGraph& _G) : Edge(), G(&_G) {
367 m!=-1 && _G.nodes[m].first_in == -1; m = _G.nodes[m].next);
368 n = (m==-1)?-1:_G.nodes[m].first_in;
370 EdgeIt (Invalid i) : Edge(i) { }
371 EdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
372 EdgeIt() : Edge() { }
373 EdgeIt &operator++() {
374 if(G->edges[n].next_in!=-1) n=G->edges[n].next_in;
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;
385 // operator bool() { return Edge::operator bool(); }
388 class OutEdgeIt : public Edge {
390 friend class ListGraph;
392 OutEdgeIt() : Edge() { }
393 OutEdgeIt(const ListGraph& _G, Edge e) : Edge(e), G(&_G) { }
394 OutEdgeIt (Invalid i) : Edge(i) { }
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; }
400 // operator bool() { return Edge::operator bool(); }
403 class InEdgeIt : public Edge {
405 friend class ListGraph;
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; }
414 // operator bool() { return Edge::operator bool(); }
418 ///Graph for bidirectional edges.
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 hugo::SymListGraph::SymEdgeMap "SymEdgeMap"
425 ///that complements this
427 ///storing shared values for the edge pairs. The usual
428 ///\ref hugo::skeleton::StaticGraph::EdgeMap "EdgeMap"
432 ///The oppositely directed edge can also be obtained easily
433 ///using \ref hugo::SymListGraph::opposite() "opposite()" member function.
435 ///Here erase(Edge) deletes a pair of edges.
437 ///\todo this date structure need some reconsiderations. Maybe it
438 ///should be implemented independently from ListGraph.
440 class SymListGraph : public ListGraph
444 typedef SymListGraph Graph;
446 // Create symmetric map registry.
447 CREATE_SYM_EDGE_MAP_REGISTRY;
448 // Create symmetric edge map.
449 CREATE_SYM_EDGE_MAP(ArrayMap);
451 SymListGraph() : ListGraph() { }
452 SymListGraph(const ListGraph &_g) : ListGraph(_g) { }
453 ///Adds a pair of oppositely directed edges to the graph.
454 Edge addEdge(Node u, Node v)
456 Edge e = ListGraph::addEdge(u,v);
457 Edge f = ListGraph::addEdge(v,u);
458 sym_edge_maps.add(e);
459 sym_edge_maps.add(f);
464 void erase(Node n) { ListGraph::erase(n);}
465 ///The oppositely directed edge.
467 ///Returns the oppositely directed
468 ///pair of the edge \c e.
469 static Edge opposite(Edge e)
472 f.n = e.n - 2*(e.n%2) + 1;
476 ///Removes a pair of oppositely directed edges to the graph.
478 Edge f = opposite(e);
479 sym_edge_maps.erase(e);
480 sym_edge_maps.erase(f);
486 class SymListGraph : public ListGraph {
487 typedef ListGraph Parent;
490 typedef SymListGraph Graph;
492 typedef ListGraph::Node Node;
493 typedef ListGraph::NodeIt NodeIt;
503 template <typename Value>
504 class NodeMap : public Parent::NodeMap<Value> {
506 NodeMap(const SymListGraph& g)
507 : SymListGraph::Parent::NodeMap<Value>(g) {}
508 NodeMap(const SymListGraph& g, Value v)
509 : SymListGraph::Parent::NodeMap<Value>(g, v) {}
510 template<typename TT>
511 NodeMap(const NodeMap<TT>& copy)
512 : SymListGraph::Parent::NodeMap<Value>(copy) { }
515 template <typename Value>
516 class SymEdgeMap : public Parent::EdgeMap<Value> {
518 typedef SymEdge KeyType;
520 SymEdgeMap(const SymListGraph& g)
521 : SymListGraph::Parent::EdgeMap<Value>(g) {}
522 SymEdgeMap(const SymListGraph& g, Value v)
523 : SymListGraph::Parent::EdgeMap<Value>(g, v) {}
524 template<typename TT>
525 SymEdgeMap(const SymEdgeMap<TT>& copy)
526 : SymListGraph::Parent::EdgeMap<Value>(copy) { }
530 // Create edge map registry.
531 CREATE_EDGE_MAP_REGISTRY;
533 CREATE_EDGE_MAP(ArrayMap);
536 friend class SymListGraph;
537 friend class SymListGraph::EdgeIt;
538 friend class SymListGraph::OutEdgeIt;
539 friend class SymListGraph::InEdgeIt;
544 Edge(int pid) { id = pid; }
547 /// An Edge with id \c n.
550 Edge (Invalid) { id = -1; }
552 operator SymEdge(){ return SymEdge(id >> 1);}
554 bool operator==(const Edge i) const {return id == i.id;}
555 bool operator!=(const Edge i) const {return id != i.id;}
556 bool operator<(const Edge i) const {return id < i.id;}
558 // operator bool() { return n!=-1; }
561 class SymEdge : public ListGraph::Edge {
562 friend class SymListGraph;
563 friend class SymListGraph::Edge;
564 typedef ListGraph::Edge Parent;
567 SymEdge(int pid) : Parent(pid) {}
571 SymEdge(const ListGraph::Edge& i) : Parent(i) {}
572 SymEdge (Invalid) : Parent(INVALID) {}
577 Parent::OutEdgeIt out;
581 OutEdgeIt(const SymListGraph& g, Edge e) {
583 out = Parent::OutEdgeIt(g, SymEdge(e));
584 in = Parent::InEdgeIt(g, g.tail(e));
586 out = Parent::OutEdgeIt(INVALID);
587 in = Parent::InEdgeIt(g, SymEdge(e));
590 OutEdgeIt (Invalid i) : out(INVALID), in(INVALID) { }
592 OutEdgeIt(const SymListGraph& g, const Node v)
593 : out(g, v), in(g, v) {}
594 OutEdgeIt &operator++() {
595 if (out != INVALID) {
603 operator Edge() const {
604 if (out == INVALID && in == INVALID) return INVALID;
605 return out != INVALID ? forward(out) : backward(in);
608 bool operator==(const Edge i) const {return Edge(*this) == i;}
609 bool operator!=(const Edge i) const {return Edge(*this) != i;}
610 bool operator<(const Edge i) const {return Edge(*this) < i;}
614 Parent::OutEdgeIt out;
618 InEdgeIt(const SymListGraph& g, Edge e) {
620 out = Parent::OutEdgeIt(g, SymEdge(e));
621 in = Parent::InEdgeIt(g, g.tail(e));
623 out = Parent::OutEdgeIt(INVALID);
624 in = Parent::InEdgeIt(g, SymEdge(e));
627 InEdgeIt (Invalid i) : out(INVALID), in(INVALID) { }
629 InEdgeIt(const SymListGraph& g, const Node v)
630 : out(g, v), in(g, v) {}
632 InEdgeIt &operator++() {
633 if (out != INVALID) {
641 operator Edge() const {
642 if (out == INVALID && in == INVALID) return INVALID;
643 return out != INVALID ? backward(out) : forward(in);
646 bool operator==(const Edge i) const {return Edge(*this) == i;}
647 bool operator!=(const Edge i) const {return Edge(*this) != i;}
648 bool operator<(const Edge i) const {return Edge(*this) < i;}
651 class SymEdgeIt : public Parent::EdgeIt {
656 SymEdgeIt(const SymListGraph& g)
657 : SymListGraph::Parent::EdgeIt(g) {}
659 SymEdgeIt(const SymListGraph& g, SymEdge e)
660 : SymListGraph::Parent::EdgeIt(g, e) {}
663 : SymListGraph::Parent::EdgeIt(INVALID) {}
665 SymEdgeIt& operator++() {
666 SymListGraph::Parent::EdgeIt::operator++();
670 operator SymEdge() const {
672 (static_cast<const SymListGraph::Parent::EdgeIt&>(*this));
674 bool operator==(const SymEdge i) const {return SymEdge(*this) == i;}
675 bool operator!=(const SymEdge i) const {return SymEdge(*this) != i;}
676 bool operator<(const SymEdge i) const {return SymEdge(*this) < i;}
683 EdgeIt(const SymListGraph& g) : it(g), fw(true) {}
684 EdgeIt (Invalid i) : it(i) { }
685 EdgeIt(const SymListGraph& g, Edge e)
686 : it(g, SymEdge(e)), fw(id(e) & 1 == 0) { }
688 EdgeIt& operator++() {
693 operator Edge() const {
694 if (it == INVALID) return INVALID;
695 return fw ? forward(it) : backward(it);
697 bool operator==(const Edge i) const {return Edge(*this) == i;}
698 bool operator!=(const Edge i) const {return Edge(*this) != i;}
699 bool operator<(const Edge i) const {return Edge(*this) < i;}
704 int nodeNum() const { return Parent::nodeNum(); }
706 int edgeNum() const { return 2*Parent::edgeNum(); }
707 ///Number of symmetric edges.
708 int symEdgeNum() const { return Parent::edgeNum(); }
710 ///Set the expected maximum number of edges.
712 ///With this function, it is possible to set the expected number of edges.
713 ///The use of this fasten the building of the graph and makes
714 ///it possible to avoid the superfluous memory allocation.
715 void reserveSymEdge(int n) { Parent::reserveEdge(n); };
721 int maxNodeId() const { return Parent::maxNodeId(); }
726 int maxEdgeId() const { return 2*Parent::maxEdgeId(); }
727 /// Maximum symmetric edge ID.
729 /// Maximum symmetric edge ID.
731 int maxSymEdgeId() const { return Parent::maxEdgeId(); }
734 Node tail(Edge e) const {
735 return e.id & 1 == 0 ?
736 Parent::tail(SymEdge(e)) : Parent::head(SymEdge(e));
739 Node head(Edge e) const {
740 return e.id & 1 == 0 ?
741 Parent::head(SymEdge(e)) : Parent::tail(SymEdge(e));
744 Node tail(SymEdge e) const {
745 return Parent::tail(e);
748 Node head(SymEdge e) const {
749 return Parent::head(e);
752 NodeIt& first(NodeIt& v) const {
753 v=NodeIt(*this); return v; }
754 EdgeIt& first(EdgeIt& e) const {
755 e=EdgeIt(*this); return e; }
756 SymEdgeIt& first(SymEdgeIt& e) const {
757 e=SymEdgeIt(*this); return e; }
758 OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
759 e=OutEdgeIt(*this,v); return e; }
760 InEdgeIt& first(InEdgeIt& e, const Node v) const {
761 e=InEdgeIt(*this,v); return e; }
765 /// The ID of a valid Node is a nonnegative integer not greater than
766 /// \ref maxNodeId(). The range of the ID's is not surely continuous
767 /// and the greatest node ID can be actually less then \ref maxNodeId().
769 /// The ID of the \ref INVALID node is -1.
770 ///\return The ID of the node \c v.
771 static int id(Node v) { return Parent::id(v); }
774 /// The ID of a valid Edge is a nonnegative integer not greater than
775 /// \ref maxEdgeId(). The range of the ID's is not surely continuous
776 /// and the greatest edge ID can be actually less then \ref maxEdgeId().
778 /// The ID of the \ref INVALID edge is -1.
779 ///\return The ID of the edge \c e.
780 static int id(Edge e) { return e.id; }
782 /// The ID of a valid SymEdge is a nonnegative integer not greater than
783 /// \ref maxSymEdgeId(). The range of the ID's is not surely continuous
784 /// and the greatest edge ID can be actually less then \ref maxSymEdgeId().
786 /// The ID of the \ref INVALID symmetric edge is -1.
787 ///\return The ID of the edge \c e.
788 static int id(SymEdge e) { return Parent::id(e); }
790 /// Adds a new node to the graph.
792 /// \warning It adds the new node to the front of the list.
793 /// (i.e. the lastly added node becomes the first.)
795 return Parent::addNode();
798 SymEdge addEdge(Node u, Node v) {
799 SymEdge se = Parent::addEdge(u, v);
800 edge_maps.add(forward(se));
801 edge_maps.add(backward(se));
805 /// Finds an edge between two nodes.
807 /// Finds an edge from node \c u to node \c v.
809 /// If \c prev is \ref INVALID (this is the default value), then
810 /// It finds the first edge from \c u to \c v. Otherwise it looks for
811 /// the next edge from \c u to \c v after \c prev.
812 /// \return The found edge or INVALID if there is no such an edge.
813 Edge findEdge(Node u, Node v, Edge prev = INVALID)
815 if (prev == INVALID || id(prev) & 1 == 0) {
816 SymEdge se = Parent::findEdge(u, v, SymEdge(prev));
817 if (se != INVALID) return forward(se);
819 SymEdge se = Parent::findEdge(v, u, SymEdge(prev));
820 if (se != INVALID) return backward(se);
825 /// Finds an symmetric edge between two nodes.
827 /// Finds an symmetric edge from node \c u to node \c v.
829 /// If \c prev is \ref INVALID (this is the default value), then
830 /// It finds the first edge from \c u to \c v. Otherwise it looks for
831 /// the next edge from \c u to \c v after \c prev.
832 /// \return The found edge or INVALID if there is no such an edge.
834 // SymEdge findEdge(Node u, Node v, SymEdge prev = INVALID)
836 // if (prev == INVALID || id(prev) & 1 == 0) {
837 // SymEdge se = Parent::findEdge(u, v, SymEdge(prev));
838 // if (se != INVALID) return se;
840 // SymEdge se = Parent::findEdge(v, u, SymEdge(prev));
841 // if (se != INVALID) return se;
849 for (OutEdgeIt it(*this, n); it != INVALID; ++it) {
851 edge_maps.erase(opposite(it));
856 void erase(SymEdge e) {
857 edge_maps.erase(forward(e));
858 edge_maps.erase(backward(e));
867 static Edge opposite(Edge e) {
868 return Edge(id(e) ^ 1);
871 static Edge forward(SymEdge e) {
872 return Edge(id(e) << 1);
875 static Edge backward(SymEdge e) {
876 return Edge((id(e) << 1) & 1);
881 ///A graph class containing only nodes.
883 ///This class implements a graph structure without edges.
884 ///The most useful application of this class is to be the node set of an
885 ///\ref EdgeSet class.
888 ///the \ref skeleton::ExtendableGraph "ExtendableGraph" concept
889 ///with the exception that you cannot
890 ///add (or delete) edges. The usual edge iterators are exists, but they are
891 ///always \ref INVALID.
892 ///\sa skeleton::ExtendableGraph
896 //Nodes are double linked.
897 //The free nodes are only single linked using the "next" field.
900 int first_in,first_out;
905 std::vector<NodeT> nodes;
908 //The first free node
913 typedef NodeSet Graph;
925 // Create node map registry.
926 CREATE_NODE_MAP_REGISTRY;
928 CREATE_NODE_MAP(ArrayMap);
930 /// Creating empty map structure for edges.
931 template <typename Value>
934 EdgeMap(const Graph&) {}
935 EdgeMap(const Graph&, const Value&) {}
937 EdgeMap(const EdgeMap&) {}
938 template <typename CMap> EdgeMap(const CMap&) {}
940 EdgeMap& operator=(const EdgeMap&) {}
941 template <typename CMap> EdgeMap& operator=(const CMap&) {}
943 class ConstIterator {
945 bool operator==(const ConstIterator&) {return true;}
946 bool operator!=(const ConstIterator&) {return false;}
949 typedef ConstIterator Iterator;
951 Iterator begin() { return Iterator();}
952 Iterator end() { return Iterator();}
954 ConstIterator begin() const { return ConstIterator();}
955 ConstIterator end() const { return ConstIterator();}
961 ///Default constructor
963 : nodes(), first_node(-1), first_free_node(-1) {}
965 NodeSet(const NodeSet &_g)
966 : nodes(_g.nodes), first_node(_g.first_node),
967 first_free_node(_g.first_free_node) {}
970 int nodeNum() const { return nodes.size(); }
972 int edgeNum() const { return 0; }
978 int maxNodeId() const { return nodes.size()-1; }
983 int maxEdgeId() const { return 0; }
985 Node tail(Edge e) const { return INVALID; }
986 Node head(Edge e) const { return INVALID; }
988 NodeIt& first(NodeIt& v) const {
989 v=NodeIt(*this); return v; }
990 EdgeIt& first(EdgeIt& e) const {
991 e=EdgeIt(*this); return e; }
992 OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
993 e=OutEdgeIt(*this,v); return e; }
994 InEdgeIt& first(InEdgeIt& e, const Node v) const {
995 e=InEdgeIt(*this,v); return e; }
999 /// The ID of a valid Node is a nonnegative integer not greater than
1000 /// \ref maxNodeId(). The range of the ID's is not surely continuous
1001 /// and the greatest node ID can be actually less then \ref maxNodeId().
1003 /// The ID of the \ref INVALID node is -1.
1004 ///\return The ID of the node \c v.
1005 static int id(Node v) { return v.n; }
1008 /// The ID of a valid Edge is a nonnegative integer not greater than
1009 /// \ref maxEdgeId(). The range of the ID's is not surely continuous
1010 /// and the greatest edge ID can be actually less then \ref maxEdgeId().
1012 /// The ID of the \ref INVALID edge is -1.
1013 ///\return The ID of the edge \c e.
1014 static int id(Edge e) { return -1; }
1016 /// Adds a new node to the graph.
1018 /// \warning It adds the new node to the front of the list.
1019 /// (i.e. the lastly added node becomes the first.)
1023 if(first_free_node==-1)
1026 nodes.push_back(NodeT());
1029 n = first_free_node;
1030 first_free_node = nodes[n].next;
1033 nodes[n].next = first_node;
1034 if(first_node != -1) nodes[first_node].prev = n;
1038 nodes[n].first_in = nodes[n].first_out = -1;
1042 //Update dynamic maps
1048 void erase(Node nn) {
1051 if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
1052 if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
1053 else first_node = nodes[n].next;
1055 nodes[n].next = first_free_node;
1056 first_free_node = n;
1058 //Update dynamic maps
1059 node_maps.erase(nn);
1063 Edge findEdge(Node u,Node v, Edge prev = INVALID)
1071 first_node = first_free_node = -1;
1075 friend class NodeSet;
1076 template <typename T> friend class NodeMap;
1079 friend class OutEdgeIt;
1080 friend class InEdgeIt;
1084 friend int NodeSet::id(Node v);
1085 Node(int nn) {n=nn;}
1088 Node (Invalid i) { n=-1; }
1089 bool operator==(const Node i) const {return n==i.n;}
1090 bool operator!=(const Node i) const {return n!=i.n;}
1091 bool operator<(const Node i) const {return n<i.n;}
1094 class NodeIt : public Node {
1096 friend class NodeSet;
1098 NodeIt() : Node() { }
1099 NodeIt(const NodeSet& _G,Node n) : Node(n), G(&_G) { }
1100 NodeIt(Invalid i) : Node(i) { }
1101 NodeIt(const NodeSet& _G) : Node(_G.first_node), G(&_G) { }
1102 NodeIt &operator++() {
1112 bool operator==(const Edge i) const {return true;}
1113 bool operator!=(const Edge i) const {return false;}
1114 bool operator<(const Edge i) const {return false;}
1117 class EdgeIt : public Edge {
1119 EdgeIt(const NodeSet& G) : Edge() { }
1120 EdgeIt(const NodeSet&, Edge) : Edge() { }
1121 EdgeIt (Invalid i) : Edge(i) { }
1122 EdgeIt() : Edge() { }
1123 EdgeIt operator++() { return INVALID; }
1126 class OutEdgeIt : public Edge {
1127 friend class NodeSet;
1129 OutEdgeIt() : Edge() { }
1130 OutEdgeIt(const NodeSet&, Edge) : Edge() { }
1131 OutEdgeIt (Invalid i) : Edge(i) { }
1132 OutEdgeIt(const NodeSet& G,const Node v) : Edge() {}
1133 OutEdgeIt operator++() { return INVALID; }
1136 class InEdgeIt : public Edge {
1137 friend class NodeSet;
1139 InEdgeIt() : Edge() { }
1140 InEdgeIt(const NodeSet&, Edge) : Edge() { }
1141 InEdgeIt (Invalid i) : Edge(i) { }
1142 InEdgeIt(const NodeSet& G,Node v) :Edge() {}
1143 InEdgeIt operator++() { return INVALID; }
1150 ///Graph structure using a node set of another graph.
1152 ///This structure can be used to establish another graph over a node set
1153 /// of an existing one. The node iterator will go through the nodes of the
1154 /// original graph, and the NodeMap's of both graphs will convert to
1157 ///\warning Adding or deleting nodes from the graph is not safe if an
1158 ///\ref EdgeSet is currently attached to it!
1160 ///\todo Make it possible to add/delete edges from the base graph
1161 ///(and from \ref EdgeSet, as well)
1163 ///\param GG The type of the graph which shares its node set with this class.
1164 ///Its interface must conform to the
1165 ///\ref skeleton::StaticGraph "StaticGraph" concept.
1167 ///It conforms to the
1168 ///\ref skeleton::ExtendableGraph "ExtendableGraph" concept.
1169 ///\sa skeleton::ExtendableGraph.
1171 template<typename GG>
1174 typedef GG NodeGraphType;
1186 typedef EdgeSet Graph;
1188 int id(Node v) const;
1190 class Node : public NodeGraphType::Node {
1191 friend class EdgeSet;
1194 friend class OutEdgeIt;
1195 friend class InEdgeIt;
1196 friend class SymEdge;
1199 friend int EdgeSet::id(Node v) const;
1201 Node() : NodeGraphType::Node() {}
1202 Node (Invalid i) : NodeGraphType::Node(i) {}
1203 Node(const typename NodeGraphType::Node &n) : NodeGraphType::Node(n) {}
1206 class NodeIt : public NodeGraphType::NodeIt {
1207 friend class EdgeSet;
1209 NodeIt() : NodeGraphType::NodeIt() { }
1210 NodeIt(const EdgeSet& _G,Node n) : NodeGraphType::NodeIt(_G.G,n) { }
1211 NodeIt (Invalid i) : NodeGraphType::NodeIt(i) {}
1212 NodeIt(const EdgeSet& _G) : NodeGraphType::NodeIt(_G.G) { }
1213 NodeIt(const typename NodeGraphType::NodeIt &n)
1214 : NodeGraphType::NodeIt(n) {}
1216 operator Node() { return Node(*this);}
1217 NodeIt &operator++()
1218 { this->NodeGraphType::NodeIt::operator++(); return *this;}
1222 //Edges are double linked.
1223 //The free edges are only single linked using the "next_in" field.
1226 int first_in,first_out;
1227 NodeT() : first_in(-1), first_out(-1) { }
1233 int prev_in, prev_out;
1234 int next_in, next_out;
1238 typename NodeGraphType::template NodeMap<NodeT> nodes;
1240 std::vector<EdgeT> edges;
1241 //The first free edge
1242 int first_free_edge;
1255 // Create edge map registry.
1256 CREATE_EDGE_MAP_REGISTRY;
1257 // Create edge maps.
1258 CREATE_EDGE_MAP(ArrayMap);
1260 // Import node maps from the NodeGraphType.
1261 IMPORT_NODE_MAP(NodeGraphType, graph.G, EdgeSet, graph);
1268 ///Construates a new graph based on the nodeset of an existing one.
1269 ///\param _G the base graph.
1270 explicit EdgeSet(NodeGraphType &_G)
1271 : G(_G), nodes(_G), edges(),
1272 first_free_edge(-1) {}
1275 ///Makes a copy of an EdgeSet.
1276 ///It will be based on the same graph.
1277 explicit EdgeSet(const EdgeSet &_g)
1278 : G(_g.G), nodes(_g.G), edges(_g.edges),
1279 first_free_edge(_g.first_free_edge) {}
1282 int nodeNum() const { return G.nodeNum(); }
1284 int edgeNum() const { return edges.size(); }
1286 /// Maximum node ID.
1288 /// Maximum node ID.
1290 int maxNodeId() const { return G.maxNodeId(); }
1291 /// Maximum edge ID.
1293 /// Maximum edge ID.
1295 int maxEdgeId() const { return edges.size()-1; }
1297 Node tail(Edge e) const { return edges[e.n].tail; }
1298 Node head(Edge e) const { return edges[e.n].head; }
1300 NodeIt& first(NodeIt& v) const {
1301 v=NodeIt(*this); return v; }
1302 EdgeIt& first(EdgeIt& e) const {
1303 e=EdgeIt(*this); return e; }
1304 OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
1305 e=OutEdgeIt(*this,v); return e; }
1306 InEdgeIt& first(InEdgeIt& e, const Node v) const {
1307 e=InEdgeIt(*this,v); return e; }
1311 /// The ID of a valid Node is a nonnegative integer not greater than
1312 /// \ref maxNodeId(). The range of the ID's is not surely continuous
1313 /// and the greatest node ID can be actually less then \ref maxNodeId().
1315 /// The ID of the \ref INVALID node is -1.
1316 ///\return The ID of the node \c v.
1317 int id(Node v) { return G.id(v); }
1320 /// The ID of a valid Edge is a nonnegative integer not greater than
1321 /// \ref maxEdgeId(). The range of the ID's is not surely continuous
1322 /// and the greatest edge ID can be actually less then \ref maxEdgeId().
1324 /// The ID of the \ref INVALID edge is -1.
1325 ///\return The ID of the edge \c e.
1326 static int id(Edge e) { return e.n; }
1328 /// Adds a new node to the graph.
1329 Node addNode() { return G.addNode(); }
1331 Edge addEdge(Node u, Node v) {
1334 if(first_free_edge==-1)
1337 edges.push_back(EdgeT());
1340 n = first_free_edge;
1341 first_free_edge = edges[n].next_in;
1344 edges[n].tail = u; edges[n].head = v;
1346 edges[n].next_out = nodes[u].first_out;
1347 if(nodes[u].first_out != -1) edges[nodes[u].first_out].prev_out = n;
1348 edges[n].next_in = nodes[v].first_in;
1349 if(nodes[v].first_in != -1) edges[nodes[v].first_in].prev_in = n;
1350 edges[n].prev_in = edges[n].prev_out = -1;
1352 nodes[u].first_out = nodes[v].first_in = n;
1356 //Update dynamic maps
1362 /// Finds an edge between two nodes.
1364 /// Finds an edge from node \c u to node \c v.
1366 /// If \c prev is \ref INVALID (this is the default value), then
1367 /// It finds the first edge from \c u to \c v. Otherwise it looks for
1368 /// the next edge from \c u to \c v after \c prev.
1369 /// \return The found edge or INVALID if there is no such an edge.
1370 Edge findEdge(Node u,Node v, Edge prev = INVALID)
1372 int e = (prev.n==-1)? nodes[u].first_out : edges[prev.n].next_out;
1373 while(e!=-1 && edges[e].tail!=v) e = edges[e].next_out;
1379 void eraseEdge(int n) {
1381 if(edges[n].next_in!=-1)
1382 edges[edges[n].next_in].prev_in = edges[n].prev_in;
1383 if(edges[n].prev_in!=-1)
1384 edges[edges[n].prev_in].next_in = edges[n].next_in;
1385 else nodes[edges[n].head].first_in = edges[n].next_in;
1387 if(edges[n].next_out!=-1)
1388 edges[edges[n].next_out].prev_out = edges[n].prev_out;
1389 if(edges[n].prev_out!=-1)
1390 edges[edges[n].prev_out].next_out = edges[n].next_out;
1391 else nodes[edges[n].tail].first_out = edges[n].next_out;
1393 edges[n].next_in = first_free_edge;
1394 first_free_edge = -1;
1396 //Update dynamic maps
1403 void erase(Edge e) { eraseEdge(e.n); }
1405 ///Clear all edges. (Doesn't clear the nodes!)
1415 friend class EdgeSet;
1416 template <typename T> friend class EdgeMap;
1419 friend class NodeIt;
1422 friend int EdgeSet::id(Edge e) const;
1424 Edge(int nn) {n=nn;}
1427 Edge (Invalid) { n=-1; }
1428 bool operator==(const Edge i) const {return n==i.n;}
1429 bool operator!=(const Edge i) const {return n!=i.n;}
1430 bool operator<(const Edge i) const {return n<i.n;}
1433 class EdgeIt : public Edge {
1434 friend class EdgeSet;
1435 template <typename T> friend class EdgeMap;
1439 EdgeIt(const EdgeSet& _G) : Edge(), G(&_G) {
1442 m!=INVALID && G->nodes[m].first_in == -1; ++m);
1443 ///\bug AJJAJ! This is a non sense!!!!!!!
1444 this->n = m!=INVALID?-1:G->nodes[m].first_in;
1446 EdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
1447 EdgeIt (Invalid i) : Edge(i) { }
1448 EdgeIt() : Edge() { }
1451 ///\bug UNIMPLEMENTED!!!!!
1453 EdgeIt &operator++() {
1458 class OutEdgeIt : public Edge {
1460 friend class EdgeSet;
1462 OutEdgeIt() : Edge() { }
1463 OutEdgeIt (Invalid i) : Edge(i) { }
1464 OutEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
1466 OutEdgeIt(const EdgeSet& _G,const Node v) :
1467 Edge(_G.nodes[v].first_out), G(&_G) { }
1468 OutEdgeIt &operator++() {
1469 Edge::n = G->edges[Edge::n].next_out;
1474 class InEdgeIt : public Edge {
1476 friend class EdgeSet;
1478 InEdgeIt() : Edge() { }
1479 InEdgeIt (Invalid i) : Edge(i) { }
1480 InEdgeIt(const EdgeSet& _G, Edge e) : Edge(e), G(&_G) { }
1481 InEdgeIt(const EdgeSet& _G,Node v)
1482 : Edge(_G.nodes[v].first_in), G(&_G) { }
1483 InEdgeIt &operator++() {
1484 Edge::n = G->edges[Edge::n].next_in;
1491 template<typename GG>
1492 inline int EdgeSet<GG>::id(Node v) const { return G.id(v); }
1498 #endif //HUGO_LIST_GRAPH_H