3 #ifndef HUGO_LIST_GRAPH_H
4 #define HUGO_LIST_GRAPH_H
8 ///\brief ListGraph, SymListGraph, NodeSet and EdgeSet classes.
15 #include "vector_map_factory.h"
16 #include "map_registry.h"
18 #include "map_defines.h"
22 /// \addtogroup graphs
25 ///A list graph class.
27 ///This is a simple and fast erasable graph implementation.
29 ///It conforms to the graph interface documented under
30 ///the description of \ref GraphSkeleton.
31 ///\sa \ref GraphSkeleton.
34 //Nodes are double linked.
35 //The free nodes are only single linked using the "next" field.
38 int first_in,first_out;
42 //Edges are double linked.
43 //The free edges are only single linked using the "next_in" field.
47 int prev_in, prev_out;
48 int next_in, next_out;
49 //FIXME: is this necessary?
50 // EdgeT() : next_in(-1), next_out(-1) prev_in(-1), prev_out(-1) {}
53 std::vector<NodeT> nodes;
58 std::vector<EdgeT> edges;
69 typedef ListGraph Graph;
78 CREATE_MAP_REGISTRIES;
79 CREATE_MAPS(VectorMapFactory);
83 ListGraph() : nodes(), first_node(-1),
84 first_free_node(-1), edges(), first_free_edge(-1) {}
85 ListGraph(const ListGraph &_g) : nodes(_g.nodes), first_node(_g.first_node),
86 first_free_node(_g.first_free_node),
88 first_free_edge(_g.first_free_edge) {}
91 int nodeNum() const { return nodes.size(); } //FIXME: What is this?
92 int edgeNum() const { return edges.size(); } //FIXME: What is this?
94 ///Set the expected number of edges
96 ///With this function, it is possible to set the expected number of edges.
97 ///The use of this fasten the building of the graph and makes
98 ///it possible to avoid the superfluous memory allocation.
99 void reserveEdge(int n) { edges.reserve(n); };
101 ///\bug This function does something different than
102 ///its name would suggests...
103 int maxNodeId() const { return nodes.size(); } //FIXME: What is this?
104 ///\bug This function does something different than
105 ///its name would suggests...
106 int maxEdgeId() const { return edges.size(); } //FIXME: What is this?
108 Node tail(Edge e) const { return edges[e.n].tail; }
109 Node head(Edge e) const { return edges[e.n].head; }
111 Node aNode(OutEdgeIt e) const { return edges[e.n].tail; }
112 Node aNode(InEdgeIt e) const { return edges[e.n].head; }
114 Node bNode(OutEdgeIt e) const { return edges[e.n].head; }
115 Node bNode(InEdgeIt e) const { return edges[e.n].tail; }
117 NodeIt& first(NodeIt& v) const {
118 v=NodeIt(*this); return v; }
119 EdgeIt& first(EdgeIt& e) const {
120 e=EdgeIt(*this); return e; }
121 OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
122 e=OutEdgeIt(*this,v); return e; }
123 InEdgeIt& first(InEdgeIt& e, const Node v) const {
124 e=InEdgeIt(*this,v); return e; }
126 // template< typename It >
127 // It first() const { It e; first(e); return e; }
129 // template< typename It >
130 // It first(Node v) const { It e; first(e,v); return e; }
132 bool valid(Edge e) const { return e.n!=-1; }
133 bool valid(Node n) const { return n.n!=-1; }
135 void setInvalid(Edge &e) { e.n=-1; }
136 void setInvalid(Node &n) { n.n=-1; }
138 template <typename It> It getNext(It it) const
139 { It tmp(it); return next(tmp); }
141 NodeIt& next(NodeIt& it) const {
142 it.n=nodes[it.n].next;
145 OutEdgeIt& next(OutEdgeIt& it) const
146 { it.n=edges[it.n].next_out; return it; }
147 InEdgeIt& next(InEdgeIt& it) const
148 { it.n=edges[it.n].next_in; return it; }
149 EdgeIt& next(EdgeIt& it) const {
150 if(edges[it.n].next_in!=-1) {
151 it.n=edges[it.n].next_in;
155 for(n=nodes[edges[it.n].head].next;
156 n!=-1 && nodes[n].first_in == -1;
158 it.n = (n==-1)?-1:nodes[n].first_in;
163 int id(Node v) const { return v.n; }
164 int id(Edge e) const { return e.n; }
166 /// Adds a new node to the graph.
168 /// \todo It adds the nodes in a reversed order.
169 /// (i.e. the lastly added node becomes the first.)
173 if(first_free_node==-1)
176 nodes.push_back(NodeT());
180 first_free_node = nodes[n].next;
183 nodes[n].next = first_node;
184 if(first_node != -1) nodes[first_node].prev = n;
188 nodes[n].first_in = nodes[n].first_out = -1;
192 //Update dynamic maps
198 Edge addEdge(Node u, Node v) {
201 if(first_free_edge==-1)
204 edges.push_back(EdgeT());
208 first_free_edge = edges[n].next_in;
211 edges[n].tail = u.n; edges[n].head = v.n;
213 edges[n].next_out = nodes[u.n].first_out;
214 if(nodes[u.n].first_out != -1) edges[nodes[u.n].first_out].prev_out = n;
215 edges[n].next_in = nodes[v.n].first_in;
216 if(nodes[v.n].first_in != -1) edges[nodes[v.n].first_in].prev_in = n;
217 edges[n].prev_in = edges[n].prev_out = -1;
219 nodes[u.n].first_out = nodes[v.n].first_in = n;
223 //Update dynamic maps
230 void eraseEdge(int n) {
232 if(edges[n].next_in!=-1)
233 edges[edges[n].next_in].prev_in = edges[n].prev_in;
234 if(edges[n].prev_in!=-1)
235 edges[edges[n].prev_in].next_in = edges[n].next_in;
236 else nodes[edges[n].head].first_in = edges[n].next_in;
238 if(edges[n].next_out!=-1)
239 edges[edges[n].next_out].prev_out = edges[n].prev_out;
240 if(edges[n].prev_out!=-1)
241 edges[edges[n].prev_out].next_out = edges[n].next_out;
242 else nodes[edges[n].tail].first_out = edges[n].next_out;
244 edges[n].next_in = first_free_edge;
247 //Update dynamic maps
253 void erase(Node nn) {
257 while((m=nodes[n].first_in)!=-1) eraseEdge(m);
258 while((m=nodes[n].first_out)!=-1) eraseEdge(m);
260 if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
261 if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
262 else first_node = nodes[n].next;
264 nodes[n].next = first_free_node;
267 //Update dynamic maps
276 ///\bug Dynamic maps must be updated!
279 nodes.clear();edges.clear();
280 first_node=first_free_node=first_free_edge=-1;
284 friend class ListGraph;
285 template <typename T> friend class NodeMap;
288 friend class OutEdgeIt;
289 friend class InEdgeIt;
290 friend class SymEdge;
294 friend int ListGraph::id(Node v) const;
298 Node (Invalid) { n=-1; }
299 bool operator==(const Node i) const {return n==i.n;}
300 bool operator!=(const Node i) const {return n!=i.n;}
301 bool operator<(const Node i) const {return n<i.n;}
304 class NodeIt : public Node {
305 friend class ListGraph;
307 NodeIt() : Node() { }
308 NodeIt(Invalid i) : Node(i) { }
309 NodeIt(const ListGraph& G) : Node(G.first_node) { }
310 ///\todo Undocumented conversion Node -\> NodeIt.
311 NodeIt(const ListGraph& G, const Node &n) : Node(n) { }
315 friend class ListGraph;
316 template <typename T> friend class EdgeMap;
318 //template <typename T> friend class SymListGraph::SymEdgeMap;
319 //friend Edge SymListGraph::opposite(Edge) const;
325 friend int ListGraph::id(Edge e) const;
330 Edge (Invalid) { n=-1; }
331 bool operator==(const Edge i) const {return n==i.n;}
332 bool operator!=(const Edge i) const {return n!=i.n;}
333 bool operator<(const Edge i) const {return n<i.n;}
334 ///\bug This is a workaround until somebody tells me how to
335 ///make class \c SymListGraph::SymEdgeMap friend of Edge
336 int &idref() {return n;}
337 const int &idref() const {return n;}
340 class EdgeIt : public Edge {
341 friend class ListGraph;
343 EdgeIt(const ListGraph& G) : Edge() {
346 m!=-1 && G.nodes[m].first_in == -1; m = G.nodes[m].next);
347 n = (m==-1)?-1:G.nodes[m].first_in;
349 EdgeIt (Invalid i) : Edge(i) { }
350 EdgeIt() : Edge() { }
351 ///\bug This is a workaround until somebody tells me how to
352 ///make class \c SymListGraph::SymEdgeMap friend of Edge
353 int &idref() {return n;}
356 class OutEdgeIt : public Edge {
357 friend class ListGraph;
359 OutEdgeIt() : Edge() { }
360 OutEdgeIt (Invalid i) : Edge(i) { }
362 OutEdgeIt(const ListGraph& G,const Node v)
363 : Edge(G.nodes[v.n].first_out) {}
366 class InEdgeIt : public Edge {
367 friend class ListGraph;
369 InEdgeIt() : Edge() { }
370 InEdgeIt (Invalid i) : Edge(i) { }
371 InEdgeIt(const ListGraph& G,Node v) :Edge(G.nodes[v.n].first_in) {}
376 ///Graph for bidirectional edges.
378 ///The purpose of this graph structure is to handle graphs
379 ///having bidirectional edges. Here the function \c addEdge(u,v) adds a pair
380 ///of oppositely directed edges.
381 ///There is a new edge map type called
382 ///\ref SymListGraph::SymEdgeMap "SymEdgeMap"
383 ///that complements this
385 ///storing shared values for the edge pairs. The usual
386 ///\ref GraphSkeleton::EdgeMap "EdgeMap"
390 ///The oppositely directed edge can also be obtained easily
391 ///using \ref opposite.
393 ///Here erase(Edge) deletes a pair of edges.
395 ///\todo this date structure need some reconsiderations. Maybe it
396 ///should be implemented independently from ListGraph.
401 ///A graph class containing only nodes.
403 ///This class implements a graph structure without edges.
404 ///The most useful application of this class is to be the node set of an
405 ///\ref EdgeSet class.
407 ///It conforms to the graph interface documented under
408 ///the description of \ref GraphSkeleton with the exception that you cannot
409 ///add (or delete) edges. The usual edge iterators are exists, but they are
410 ///always \ref INVALID.
411 ///\sa \ref GraphSkeleton
415 //Nodes are double linked.
416 //The free nodes are only single linked using the "next" field.
419 int first_in,first_out;
424 std::vector<NodeT> nodes;
427 //The first free node
432 template <typename Key> class DynMapBase
437 virtual void add(const Key k) = 0;
438 virtual void erase(const Key k) = 0;
439 DynMapBase(const NodeSet &_G) : G(&_G) {}
440 virtual ~DynMapBase() {}
441 friend class NodeSet;
445 template <typename T> class EdgeMap;
446 template <typename T> class NodeMap;
454 ///\bug It must be public because of SymEdgeMap.
456 mutable std::vector<DynMapBase<Node> * > dyn_node_maps;
457 //mutable std::vector<DynMapBase<Edge> * > dyn_edge_maps;
466 template <typename T> class NodeMap;
467 template <typename T> class EdgeMap;
471 ///Default constructor
472 NodeSet() : nodes(), first_node(-1),
473 first_free_node(-1) {}
475 NodeSet(const NodeSet &_g) : nodes(_g.nodes), first_node(_g.first_node),
476 first_free_node(_g.first_free_node) {}
480 for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
481 i!=dyn_node_maps.end(); ++i) (**i).G=NULL;
482 //for(std::vector<DynMapBase<Edge> * >::iterator i=dyn_edge_maps.begin();
483 // i!=dyn_edge_maps.end(); ++i) (**i).G=NULL;
486 int nodeNum() const { return nodes.size(); } //FIXME: What is this?
487 int edgeNum() const { return 0; } //FIXME: What is this?
489 ///\bug This function does something different than
490 ///its name would suggests...
491 int maxNodeId() const { return nodes.size(); } //FIXME: What is this?
492 ///\bug This function does something different than
493 ///its name would suggests...
494 int maxEdgeId() const { return 0; } //FIXME: What is this?
496 Node tail(Edge e) const { return INVALID; }
497 Node head(Edge e) const { return INVALID; }
499 Node aNode(OutEdgeIt e) const { return INVALID; }
500 Node aNode(InEdgeIt e) const { return INVALID; }
502 Node bNode(OutEdgeIt e) const { return INVALID; }
503 Node bNode(InEdgeIt e) const { return INVALID; }
505 NodeIt& first(NodeIt& v) const {
506 v=NodeIt(*this); return v; }
507 EdgeIt& first(EdgeIt& e) const {
508 e=EdgeIt(*this); return e; }
509 OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
510 e=OutEdgeIt(*this,v); return e; }
511 InEdgeIt& first(InEdgeIt& e, const Node v) const {
512 e=InEdgeIt(*this,v); return e; }
514 // template< typename It >
515 // It first() const { It e; first(e); return e; }
517 // template< typename It >
518 // It first(Node v) const { It e; first(e,v); return e; }
520 bool valid(Edge e) const { return false; }
521 bool valid(Node n) const { return n.n!=-1; }
523 void setInvalid(Edge &e) { }
524 void setInvalid(Node &n) { n.n=-1; }
526 template <typename It> It getNext(It it) const
527 { It tmp(it); return next(tmp); }
529 NodeIt& next(NodeIt& it) const {
530 it.n=nodes[it.n].next;
533 OutEdgeIt& next(OutEdgeIt& it) const { return it; }
534 InEdgeIt& next(InEdgeIt& it) const { return it; }
535 EdgeIt& next(EdgeIt& it) const { return it; }
537 int id(Node v) const { return v.n; }
538 int id(Edge e) const { return -1; }
540 /// Adds a new node to the graph.
542 /// \todo It adds the nodes in a reversed order.
543 /// (i.e. the lastly added node becomes the first.)
547 if(first_free_node==-1)
550 nodes.push_back(NodeT());
554 first_free_node = nodes[n].next;
557 nodes[n].next = first_node;
558 if(first_node != -1) nodes[first_node].prev = n;
562 nodes[n].first_in = nodes[n].first_out = -1;
566 //Update dynamic maps
567 for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
568 i!=dyn_node_maps.end(); ++i) (**i).add(nn);
573 void erase(Node nn) {
576 if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev;
577 if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next;
578 else first_node = nodes[n].next;
580 nodes[n].next = first_free_node;
583 //Update dynamic maps
584 for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
585 i!=dyn_node_maps.end(); ++i) (**i).erase(nn);
588 ///\bug Dynamic maps must be updated!
592 first_node = first_free_node = -1;
596 friend class NodeSet;
597 template <typename T> friend class NodeMap;
600 friend class OutEdgeIt;
601 friend class InEdgeIt;
605 friend int NodeSet::id(Node v) const;
609 Node (Invalid i) { n=-1; }
610 bool operator==(const Node i) const {return n==i.n;}
611 bool operator!=(const Node i) const {return n!=i.n;}
612 bool operator<(const Node i) const {return n<i.n;}
615 class NodeIt : public Node {
616 friend class NodeSet;
618 NodeIt() : Node() { }
619 NodeIt(Invalid i) : Node(i) { }
620 NodeIt(const NodeSet& G) : Node(G.first_node) { }
621 ///\todo Undocumented conversion Node -\> NodeIt.
622 NodeIt(const NodeSet& G, const Node &n) : Node(n) { }
627 //friend class NodeSet;
628 //template <typename T> friend class EdgeMap;
630 //template <typename T> friend class SymNodeSet::SymEdgeMap;
631 //friend Edge SymNodeSet::opposite(Edge) const;
633 // friend class Node;
634 // friend class NodeIt;
636 //friend int NodeSet::id(Edge e) const;
641 bool operator==(const Edge i) const {return true;}
642 bool operator!=(const Edge i) const {return false;}
643 bool operator<(const Edge i) const {return false;}
644 ///\bug This is a workaround until somebody tells me how to
645 ///make class \c SymNodeSet::SymEdgeMap friend of Edge
646 // int idref() {return -1;}
647 // int idref() const {return -1;}
650 class EdgeIt : public Edge {
651 //friend class NodeSet;
653 EdgeIt(const NodeSet& G) : Edge() { }
654 EdgeIt (Invalid i) : Edge(i) { }
655 EdgeIt() : Edge() { }
656 ///\bug This is a workaround until somebody tells me how to
657 ///make class \c SymNodeSet::SymEdgeMap friend of Edge
658 // int idref() {return -1;}
661 class OutEdgeIt : public Edge {
662 friend class NodeSet;
664 OutEdgeIt() : Edge() { }
665 OutEdgeIt (Invalid i) : Edge(i) { }
666 OutEdgeIt(const NodeSet& G,const Node v) : Edge() {}
669 class InEdgeIt : public Edge {
670 friend class NodeSet;
672 InEdgeIt() : Edge() { }
673 InEdgeIt (Invalid i) : Edge(i) { }
674 InEdgeIt(const NodeSet& G,Node v) :Edge() {}
677 template <typename T> class NodeMap : public DynMapBase<Node>
679 std::vector<T> container;
683 typedef Node KeyType;
685 NodeMap(const NodeSet &_G) :
686 DynMapBase<Node>(_G), container(_G.maxNodeId())
688 G->dyn_node_maps.push_back(this);
690 NodeMap(const NodeSet &_G,const T &t) :
691 DynMapBase<Node>(_G), container(_G.maxNodeId(),t)
693 G->dyn_node_maps.push_back(this);
696 NodeMap(const NodeMap<T> &m) :
697 DynMapBase<Node>(*m.G), container(m.container)
699 G->dyn_node_maps.push_back(this);
702 template<typename TT> friend class NodeMap;
704 ///\todo It can copy between different types.
706 template<typename TT> NodeMap(const NodeMap<TT> &m) :
707 DynMapBase<Node>(*m.G), container(m.container.size())
709 G->dyn_node_maps.push_back(this);
710 typename std::vector<TT>::const_iterator i;
711 for(typename std::vector<TT>::const_iterator i=m.container.begin();
712 i!=m.container.end();
714 container.push_back(*i);
719 std::vector<DynMapBase<Node>* >::iterator i;
720 for(i=G->dyn_node_maps.begin();
721 i!=G->dyn_node_maps.end() && *i!=this; ++i) ;
722 //if(*i==this) G->dyn_node_maps.erase(i); //FIXME: Way too slow...
723 //A better way to do that: (Is this really important?)
725 *i=G->dyn_node_maps.back();
726 G->dyn_node_maps.pop_back();
731 void add(const Node k)
733 if(k.n>=int(container.size())) container.resize(k.n+1);
736 void erase(const Node) { }
738 void set(Node n, T a) { container[n.n]=a; }
739 //'T& operator[](Node n)' would be wrong here
740 typename std::vector<T>::reference
741 operator[](Node n) { return container[n.n]; }
742 //'const T& operator[](Node n)' would be wrong here
743 typename std::vector<T>::const_reference
744 operator[](Node n) const { return container[n.n]; }
746 ///\warning There is no safety check at all!
747 ///Using operator = between maps attached to different graph may
748 ///cause serious problem.
749 ///\todo Is this really so?
750 ///\todo It can copy between different types.
751 const NodeMap<T>& operator=(const NodeMap<T> &m)
753 container = m.container;
756 template<typename TT>
757 const NodeMap<T>& operator=(const NodeMap<TT> &m)
759 std::copy(m.container.begin(), m.container.end(), container.begin());
763 void update() {} //Useless for Dynamic Maps
764 void update(T a) {} //Useless for Dynamic Maps
767 template <typename T> class EdgeMap
771 typedef Edge KeyType;
773 EdgeMap(const NodeSet &) { }
774 EdgeMap(const NodeSet &,const T &) { }
775 EdgeMap(const EdgeMap<T> &) { }
776 // template<typename TT> friend class EdgeMap;
778 ///\todo It can copy between different types.
780 template<typename TT> EdgeMap(const EdgeMap<TT> &) { }
783 void add(const Edge ) { }
784 void erase(const Edge) { }
786 void set(Edge, T) { }
787 //T get(Edge n) const { return container[n.n]; }
788 ValueType &operator[](Edge) { return *((T*)(NULL)); }
789 const ValueType &operator[](Edge) const { return *((T*)(NULL)); }
791 const EdgeMap<T>& operator=(const EdgeMap<T> &) { return *this; }
793 template<typename TT>
794 const EdgeMap<T>& operator=(const EdgeMap<TT> &m) { return *this; }
803 ///Graph structure using a node set of another graph.
805 ///This structure can be used to establish another graph over a node set
806 /// of an existing one. The node iterator will go through the nodes of the
807 /// original graph, and the NodeMap's of both graphs will convert to
810 ///\warning Adding or deleting nodes from the graph is not safe if an
811 ///\ref EdgeSet is currently attached to it!
813 ///\todo Make it possible to add/delete edges from the base graph
814 ///(and from \ref EdgeSet, as well)
816 ///\param GG The type of the graph which shares its node set with this class.
817 ///Its interface must conform with \ref GraphSkeleton.
819 ///It conforms to the graph interface documented under
820 ///the description of \ref GraphSkeleton.
821 ///\sa \ref GraphSkeleton.
823 template<typename GG>
826 typedef GG NodeGraphType;
832 int id(Node v) const;
834 class Node : public NodeGraphType::Node {
835 friend class EdgeSet;
836 // template <typename T> friend class NodeMap;
839 friend class OutEdgeIt;
840 friend class InEdgeIt;
841 friend class SymEdge;
844 friend int EdgeSet::id(Node v) const;
845 // Node(int nn) {n=nn;}
847 Node() : NodeGraphType::Node() {}
848 Node (Invalid i) : NodeGraphType::Node(i) {}
849 Node(const typename NodeGraphType::Node &n) : NodeGraphType::Node(n) {}
852 class NodeIt : public NodeGraphType::NodeIt {
853 friend class EdgeSet;
855 NodeIt() : NodeGraphType::NodeIt() { }
856 NodeIt (Invalid i) : NodeGraphType::NodeIt(i) {}
857 NodeIt(const EdgeSet& _G) : NodeGraphType::NodeIt(_G.G) { }
858 NodeIt(const typename NodeGraphType::NodeIt &n)
859 : NodeGraphType::NodeIt(n) {}
860 ///\todo Undocumented conversion Node -\> NodeIt.
861 NodeIt(const EdgeSet& _G, const Node &n)
862 : NodeGraphType::NodeIt(_G.G,n) { }
864 operator Node() { return Node(*this);}
868 //Edges are double linked.
869 //The free edges are only single linked using the "next_in" field.
872 int first_in,first_out;
873 NodeT() : first_in(-1), first_out(-1) { }
879 int prev_in, prev_out;
880 int next_in, next_out;
884 typename NodeGraphType::template NodeMap<NodeT> nodes;
886 std::vector<EdgeT> edges;
887 //The first free edge
892 template <typename Key> class DynMapBase
897 virtual void add(const Key k) = 0;
898 virtual void erase(const Key k) = 0;
899 DynMapBase(const EdgeSet &_G) : G(&_G) {}
900 virtual ~DynMapBase() {}
901 friend class EdgeSet;
905 //template <typename T> class NodeMap;
906 template <typename T> class EdgeMap;
914 // mutable std::vector<DynMapBase<Node> * > dyn_node_maps;
915 ///\bug It must be public because of SymEdgeMap.
917 mutable std::vector<DynMapBase<Edge> * > dyn_edge_maps;
926 template <typename T> class NodeMap;
927 template <typename T> class EdgeMap;
933 ///Construates a new graph based on the nodeset of an existing one.
934 ///\param _G the base graph.
935 ///\todo It looks like a copy constructor, but it isn't.
936 EdgeSet(NodeGraphType &_G) : G(_G),
938 first_free_edge(-1) { }
941 ///Makes a copy of an EdgeSet.
942 ///It will be based on the same graph.
943 EdgeSet(const EdgeSet &_g) : G(_g.G), nodes(_g.G), edges(_g.edges),
944 first_free_edge(_g.first_free_edge) { }
948 // for(std::vector<DynMapBase<Node> * >::iterator i=dyn_node_maps.begin();
949 // i!=dyn_node_maps.end(); ++i) (**i).G=NULL;
950 for(typename std::vector<DynMapBase<Edge> * >::iterator
951 i=dyn_edge_maps.begin();
952 i!=dyn_edge_maps.end(); ++i) (**i).G=NULL;
955 int nodeNum() const { return G.nodeNum(); } //FIXME: What is this?
956 int edgeNum() const { return edges.size(); } //FIXME: What is this?
958 ///\bug This function does something different than
959 ///its name would suggests...
960 int maxNodeId() const { return G.maxNodeId(); } //FIXME: What is this?
961 ///\bug This function does something different than
962 ///its name would suggests...
963 int maxEdgeId() const { return edges.size(); } //FIXME: What is this?
965 Node tail(Edge e) const { return edges[e.n].tail; }
966 Node head(Edge e) const { return edges[e.n].head; }
968 Node aNode(OutEdgeIt e) const { return edges[e.n].tail; }
969 Node aNode(InEdgeIt e) const { return edges[e.n].head; }
971 Node bNode(OutEdgeIt e) const { return edges[e.n].head; }
972 Node bNode(InEdgeIt e) const { return edges[e.n].tail; }
974 NodeIt& first(NodeIt& v) const {
975 v=NodeIt(*this); return v; }
976 EdgeIt& first(EdgeIt& e) const {
977 e=EdgeIt(*this); return e; }
978 OutEdgeIt& first(OutEdgeIt& e, const Node v) const {
979 e=OutEdgeIt(*this,v); return e; }
980 InEdgeIt& first(InEdgeIt& e, const Node v) const {
981 e=InEdgeIt(*this,v); return e; }
983 // template< typename It >
984 // It first() const { It e; first(e); return e; }
986 // template< typename It >
987 // It first(Node v) const { It e; first(e,v); return e; }
989 bool valid(Edge e) const { return e.n!=-1; }
990 bool valid(Node n) const { return G.valid(n); }
992 void setInvalid(Edge &e) { e.n=-1; }
993 void setInvalid(Node &n) { G.setInvalid(n); }
995 template <typename It> It getNext(It it) const
996 { It tmp(it); return next(tmp); }
998 NodeIt& next(NodeIt& it) const { G.next(it); return it; }
999 OutEdgeIt& next(OutEdgeIt& it) const
1000 { it.n=edges[it.n].next_out; return it; }
1001 InEdgeIt& next(InEdgeIt& it) const
1002 { it.n=edges[it.n].next_in; return it; }
1003 EdgeIt& next(EdgeIt& it) const {
1004 if(edges[it.n].next_in!=-1) {
1005 it.n=edges[it.n].next_in;
1008 NodeIt n(*this,edges[it.n].head);
1010 valid(n) && nodes[n].first_in == -1;
1012 it.n = (valid(n))?-1:nodes[n].first_in;
1017 int id(Edge e) const { return e.n; }
1019 /// Adds a new node to the graph.
1020 Node addNode() { return G.addNode(); }
1022 Edge addEdge(Node u, Node v) {
1025 if(first_free_edge==-1)
1028 edges.push_back(EdgeT());
1031 n = first_free_edge;
1032 first_free_edge = edges[n].next_in;
1035 edges[n].tail = u; edges[n].head = v;
1037 edges[n].next_out = nodes[u].first_out;
1038 if(nodes[u].first_out != -1) edges[nodes[u].first_out].prev_out = n;
1039 edges[n].next_in = nodes[v].first_in;
1040 if(nodes[v].first_in != -1) edges[nodes[v].first_in].prev_in = n;
1041 edges[n].prev_in = edges[n].prev_out = -1;
1043 nodes[u].first_out = nodes[v].first_in = n;
1047 //Update dynamic maps
1048 for(typename std::vector<DynMapBase<Edge> * >::iterator
1049 i=dyn_edge_maps.begin();
1050 i!=dyn_edge_maps.end(); ++i) (**i).add(e);
1056 void eraseEdge(int n) {
1058 if(edges[n].next_in!=-1)
1059 edges[edges[n].next_in].prev_in = edges[n].prev_in;
1060 if(edges[n].prev_in!=-1)
1061 edges[edges[n].prev_in].next_in = edges[n].next_in;
1062 else nodes[edges[n].head].first_in = edges[n].next_in;
1064 if(edges[n].next_out!=-1)
1065 edges[edges[n].next_out].prev_out = edges[n].prev_out;
1066 if(edges[n].prev_out!=-1)
1067 edges[edges[n].prev_out].next_out = edges[n].next_out;
1068 else nodes[edges[n].tail].first_out = edges[n].next_out;
1070 edges[n].next_in = first_free_edge;
1071 first_free_edge = -1;
1073 //Update dynamic maps
1075 for(typename std::vector<DynMapBase<Edge> * >::iterator
1076 i=dyn_edge_maps.begin();
1077 i!=dyn_edge_maps.end(); ++i) (**i).erase(e);
1082 // void erase(Node nn) {
1085 // while((m=nodes[n].first_in)!=-1) eraseEdge(m);
1086 // while((m=nodes[n].first_out)!=-1) eraseEdge(m);
1089 void erase(Edge e) { eraseEdge(e.n); }
1091 ///Clear all edges. (Doesn't clear the nodes!)
1098 // //\bug Dynamic maps must be updated!
1101 // nodes.clear();edges.clear();
1102 // first_node=first_free_node=first_free_edge=-1;
1106 template <typename T> class EdgeMap;
1111 friend class EdgeSet;
1112 template <typename T> friend class EdgeMap;
1115 friend class NodeIt;
1117 ///\bug It shoud be at least protected
1121 friend int EdgeSet::id(Edge e) const;
1123 Edge(int nn) {n=nn;}
1126 Edge (Invalid) { n=-1; }
1127 bool operator==(const Edge i) const {return n==i.n;}
1128 bool operator!=(const Edge i) const {return n!=i.n;}
1129 bool operator<(const Edge i) const {return n<i.n;}
1130 ///\bug This is a workaround until somebody tells me how to
1131 ///make class \c SymEdgeSet::SymEdgeMap friend of Edge
1132 int &idref() {return n;}
1133 const int &idref() const {return n;}
1136 class EdgeIt : public Edge {
1137 friend class EdgeSet;
1138 template <typename T> friend class EdgeMap;
1142 EdgeIt(const EdgeSet& G) : Edge() {
1143 // typename NodeGraphType::Node m;
1146 G.valid(m) && G.nodes[m].first_in == -1; G.next(m));
1147 //AJJAJ! This is a non sense!!!!!!!
1148 this->n = G.valid(m)?-1:G.nodes[m].first_in;
1150 EdgeIt (Invalid i) : Edge(i) { }
1151 EdgeIt() : Edge() { }
1152 ///\bug This is a workaround until somebody tells me how to
1153 ///make class \c SymEdgeSet::SymEdgeMap friend of Edge
1154 int &idref() {return this->n;}
1157 class OutEdgeIt : public Edge {
1158 friend class EdgeSet;
1160 OutEdgeIt() : Edge() { }
1161 OutEdgeIt (Invalid i) : Edge(i) { }
1163 OutEdgeIt(const EdgeSet& G,const Node v) : Edge(G.nodes[v].first_out) { }
1166 class InEdgeIt : public Edge {
1167 friend class EdgeSet;
1169 InEdgeIt() : Edge() { }
1170 InEdgeIt (Invalid i) : Edge(i) { }
1171 InEdgeIt(const EdgeSet& G,Node v) :Edge(G.nodes[v].first_in) { }
1174 template <typename T> class NodeMap :
1175 public NodeGraphType::template NodeMap<T>
1177 //This is a must, the constructors need it.
1178 typedef typename NodeGraphType::template NodeMap<T> ParentNodeMap;
1180 NodeMap(const EdgeSet &_G) : ParentNodeMap(_G.G) { }
1181 NodeMap(const EdgeSet &_G,const T &t) : ParentNodeMap(_G.G,t) { }
1183 NodeMap(const typename NodeGraphType::template NodeMap<T> &m) :
1184 ParentNodeMap(m) { }
1186 ///\todo It can copy between different types.
1188 template<typename TT>
1189 NodeMap(const typename NodeGraphType::template NodeMap<TT> &m)
1190 : ParentNodeMap(m) { }
1194 template <typename T> class EdgeMap : public DynMapBase<Edge>
1198 ///\bug It should be at least protected
1200 std::vector<T> container;
1203 typedef T ValueType;
1204 typedef Edge KeyType;
1206 EdgeMap(const EdgeSet &_G) :
1207 DynMapBase<Edge>(_G), container(_G.maxEdgeId())
1209 //FIXME: What if there are empty Id's?
1210 //FIXME: Can I use 'this' in a constructor?
1211 G->dyn_edge_maps.push_back(this);
1213 EdgeMap(const EdgeSet &_G,const T &t) :
1214 DynMapBase<Edge>(_G), container(_G.maxEdgeId(),t)
1216 G->dyn_edge_maps.push_back(this);
1218 EdgeMap(const EdgeMap<T> &m) :
1219 DynMapBase<Edge>(*m.G), container(m.container)
1221 G->dyn_edge_maps.push_back(this);
1224 template<typename TT> friend class EdgeMap;
1226 ///\todo It can copy between different types.
1228 template<typename TT> EdgeMap(const EdgeMap<TT> &m) :
1229 DynMapBase<Edge>(*m.G), container(m.container.size())
1231 G->dyn_edge_maps.push_back(this);
1232 typename std::vector<TT>::const_iterator i;
1233 for(typename std::vector<TT>::const_iterator i=m.container.begin();
1234 i!=m.container.end();
1236 container.push_back(*i);
1241 typename std::vector<DynMapBase<Edge>* >::iterator i;
1242 for(i=G->dyn_edge_maps.begin();
1243 i!=G->dyn_edge_maps.end() && *i!=this; ++i) ;
1244 //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow...
1245 //A better way to do that: (Is this really important?)
1247 *i=G->dyn_edge_maps.back();
1248 G->dyn_edge_maps.pop_back();
1253 void add(const Edge k)
1255 if(k.n>=int(container.size())) container.resize(k.n+1);
1257 void erase(const Edge) { }
1259 ///\bug This doesn't work. Why?
1260 /// void set(Edge n, T a) { container[n.n]=a; }
1261 void set(Edge n, T a) { container[G->id(n)]=a; }
1262 //T get(Edge n) const { return container[n.n]; }
1263 typename std::vector<T>::reference
1264 ///\bug This doesn't work. Why?
1265 /// operator[](Edge n) { return container[n.n]; }
1266 operator[](Edge n) { return container[G->id(n)]; }
1267 typename std::vector<T>::const_reference
1268 ///\bug This doesn't work. Why?
1269 /// operator[](Edge n) const { return container[n.n]; }
1270 operator[](Edge n) const { return container[G->id(n)]; }
1272 ///\warning There is no safety check at all!
1273 ///Using operator = between maps attached to different graph may
1274 ///cause serious problem.
1275 ///\todo Is this really so?
1276 ///\todo It can copy between different types.
1277 const EdgeMap<T>& operator=(const EdgeMap<T> &m)
1279 container = m.container;
1283 template<typename TT> friend class EdgeMap;
1285 template<typename TT>
1286 const EdgeMap<T>& operator=(const EdgeMap<TT> &m)
1288 std::copy(m.container.begin(), m.container.end(), container.begin());
1292 void update() {} //Useless for DynMaps
1293 void update(T a) {} //Useless for DynMaps
1298 template<typename GG>
1299 inline int EdgeSet<GG>::id(Node v) const { return G.id(v); }
1305 #endif //HUGO_LIST_GRAPH_H