# HG changeset patch # User alpar # Date 1083936436 0 # Node ID 159f1cbf8a4558bdfb520eca6f1e87fc353a2d0d # Parent e8703f0a6e2fb5c24c2c5ef0a4908b85e3aeaa3d src/work/alpar/list_graph.h moved to /src/hugo. diff -r e8703f0a6e2f -r 159f1cbf8a45 doc/Doxyfile --- a/doc/Doxyfile Fri May 07 11:57:34 2004 +0000 +++ b/doc/Doxyfile Fri May 07 13:27:16 2004 +0000 @@ -396,7 +396,6 @@ groups.dox \ ../src/hugo \ ../src/hugo/skeletons \ - ../src/work/alpar/list_graph.h \ ../src/work/athos/minlengthpaths.h \ ../src/work/klao/path.h \ ../src/work/jacint/max_flow.h \ diff -r e8703f0a6e2f -r 159f1cbf8a45 src/hugo/Makefile.am --- a/src/hugo/Makefile.am Fri May 07 11:57:34 2004 +0000 +++ b/src/hugo/Makefile.am Fri May 07 13:27:16 2004 +0000 @@ -5,6 +5,7 @@ error.h \ fib_heap.h \ invalid.h \ + list_graph.h \ maps.h \ smart_graph.h \ time_measure.h \ diff -r e8703f0a6e2f -r 159f1cbf8a45 src/hugo/list_graph.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/hugo/list_graph.h Fri May 07 13:27:16 2004 +0000 @@ -0,0 +1,1597 @@ +// -*- mode:C++ -*- + +#ifndef HUGO_LIST_GRAPH_H +#define HUGO_LIST_GRAPH_H + +///\ingroup graphs +///\file +///\brief ListGraph, SymListGraph, NodeSet and EdgeSet classes. + +#include +#include + +#include + +namespace hugo { + +/// \addtogroup graphs +/// @{ + + class SymListGraph; + + ///A list graph class. + + ///This is a simple and fast erasable graph implementation. + /// + ///It conforms to the graph interface documented under + ///the description of \ref GraphSkeleton. + ///\sa \ref GraphSkeleton. + class ListGraph { + + //Nodes are double linked. + //The free nodes are only single linked using the "next" field. + struct NodeT + { + int first_in,first_out; + int prev, next; + // NodeT() {} + }; + //Edges are double linked. + //The free edges are only single linked using the "next_in" field. + struct EdgeT + { + int head, tail; + int prev_in, prev_out; + int next_in, next_out; + //FIXME: is this necessary? + // EdgeT() : next_in(-1), next_out(-1) prev_in(-1), prev_out(-1) {} + }; + + std::vector nodes; + //The first node + int first_node; + //The first free node + int first_free_node; + std::vector edges; + //The first free edge + int first_free_edge; + + protected: + + template class DynMapBase + { + protected: + const ListGraph* G; + public: + virtual void add(const Key k) = 0; + virtual void erase(const Key k) = 0; + DynMapBase(const ListGraph &_G) : G(&_G) {} + virtual ~DynMapBase() {} + friend class ListGraph; + }; + + public: + template class EdgeMap; + template class NodeMap; + + class Node; + class Edge; + + // protected: + // HELPME: + protected: + ///\bug It must be public because of SymEdgeMap. + /// + mutable std::vector * > dyn_node_maps; + ///\bug It must be public because of SymEdgeMap. + /// + mutable std::vector * > dyn_edge_maps; + + public: + + class NodeIt; + class EdgeIt; + class OutEdgeIt; + class InEdgeIt; + + template class NodeMap; + template class EdgeMap; + + public: + + ListGraph() : nodes(), first_node(-1), + first_free_node(-1), edges(), first_free_edge(-1) {} + ListGraph(const ListGraph &_g) : nodes(_g.nodes), first_node(_g.first_node), + first_free_node(_g.first_free_node), + edges(_g.edges), + first_free_edge(_g.first_free_edge) {} + + ~ListGraph() + { + for(std::vector * >::iterator i=dyn_node_maps.begin(); + i!=dyn_node_maps.end(); ++i) (**i).G=NULL; + for(std::vector * >::iterator i=dyn_edge_maps.begin(); + i!=dyn_edge_maps.end(); ++i) (**i).G=NULL; + } + + int nodeNum() const { return nodes.size(); } //FIXME: What is this? + int edgeNum() const { return edges.size(); } //FIXME: What is this? + + ///\bug This function does something different than + ///its name would suggests... + int maxNodeId() const { return nodes.size(); } //FIXME: What is this? + ///\bug This function does something different than + ///its name would suggests... + int maxEdgeId() const { return edges.size(); } //FIXME: What is this? + + Node tail(Edge e) const { return edges[e.n].tail; } + Node head(Edge e) const { return edges[e.n].head; } + + Node aNode(OutEdgeIt e) const { return edges[e.n].tail; } + Node aNode(InEdgeIt e) const { return edges[e.n].head; } + + Node bNode(OutEdgeIt e) const { return edges[e.n].head; } + Node bNode(InEdgeIt e) const { return edges[e.n].tail; } + + NodeIt& first(NodeIt& v) const { + v=NodeIt(*this); return v; } + EdgeIt& first(EdgeIt& e) const { + e=EdgeIt(*this); return e; } + OutEdgeIt& first(OutEdgeIt& e, const Node v) const { + e=OutEdgeIt(*this,v); return e; } + InEdgeIt& first(InEdgeIt& e, const Node v) const { + e=InEdgeIt(*this,v); return e; } + +// template< typename It > +// It first() const { It e; first(e); return e; } + +// template< typename It > +// It first(Node v) const { It e; first(e,v); return e; } + + bool valid(Edge e) const { return e.n!=-1; } + bool valid(Node n) const { return n.n!=-1; } + + void setInvalid(Edge &e) { e.n=-1; } + void setInvalid(Node &n) { n.n=-1; } + + template It getNext(It it) const + { It tmp(it); return next(tmp); } + + NodeIt& next(NodeIt& it) const { + it.n=nodes[it.n].next; + return it; + } + OutEdgeIt& next(OutEdgeIt& it) const + { it.n=edges[it.n].next_out; return it; } + InEdgeIt& next(InEdgeIt& it) const + { it.n=edges[it.n].next_in; return it; } + EdgeIt& next(EdgeIt& it) const { + if(edges[it.n].next_in!=-1) { + it.n=edges[it.n].next_in; + } + else { + int n; + for(n=nodes[edges[it.n].head].next; + n!=-1 && nodes[n].first_in == -1; + n = nodes[n].next) ; + it.n = (n==-1)?-1:nodes[n].first_in; + } + return it; + } + + int id(Node v) const { return v.n; } + int id(Edge e) const { return e.n; } + + /// Adds a new node to the graph. + + /// \todo It adds the nodes in a reversed order. + /// (i.e. the lastly added node becomes the first.) + Node addNode() { + int n; + + if(first_free_node==-1) + { + n = nodes.size(); + nodes.push_back(NodeT()); + } + else { + n = first_free_node; + first_free_node = nodes[n].next; + } + + nodes[n].next = first_node; + if(first_node != -1) nodes[first_node].prev = n; + first_node = n; + nodes[n].prev = -1; + + nodes[n].first_in = nodes[n].first_out = -1; + + Node nn; nn.n=n; + + //Update dynamic maps + for(std::vector * >::iterator i=dyn_node_maps.begin(); + i!=dyn_node_maps.end(); ++i) (**i).add(nn); + + return nn; + } + + Edge addEdge(Node u, Node v) { + int n; + + if(first_free_edge==-1) + { + n = edges.size(); + edges.push_back(EdgeT()); + } + else { + n = first_free_edge; + first_free_edge = edges[n].next_in; + } + + edges[n].tail = u.n; edges[n].head = v.n; + + edges[n].next_out = nodes[u.n].first_out; + if(nodes[u.n].first_out != -1) edges[nodes[u.n].first_out].prev_out = n; + edges[n].next_in = nodes[v.n].first_in; + if(nodes[v.n].first_in != -1) edges[nodes[v.n].first_in].prev_in = n; + edges[n].prev_in = edges[n].prev_out = -1; + + nodes[u.n].first_out = nodes[v.n].first_in = n; + + Edge e; e.n=n; + + //Update dynamic maps + for(std::vector * >::iterator i=dyn_edge_maps.begin(); + i!=dyn_edge_maps.end(); ++i) (**i).add(e); + + return e; + } + + private: + void eraseEdge(int n) { + + if(edges[n].next_in!=-1) + edges[edges[n].next_in].prev_in = edges[n].prev_in; + if(edges[n].prev_in!=-1) + edges[edges[n].prev_in].next_in = edges[n].next_in; + else nodes[edges[n].head].first_in = edges[n].next_in; + + if(edges[n].next_out!=-1) + edges[edges[n].next_out].prev_out = edges[n].prev_out; + if(edges[n].prev_out!=-1) + edges[edges[n].prev_out].next_out = edges[n].next_out; + else nodes[edges[n].tail].first_out = edges[n].next_out; + + edges[n].next_in = first_free_edge; + first_free_edge = -1; + + //Update dynamic maps + Edge e; e.n=n; + for(std::vector * >::iterator i=dyn_edge_maps.begin(); + i!=dyn_edge_maps.end(); ++i) (**i).erase(e); + } + + public: + + void erase(Node nn) { + int n=nn.n; + + int m; + while((m=nodes[n].first_in)!=-1) eraseEdge(m); + while((m=nodes[n].first_out)!=-1) eraseEdge(m); + + if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev; + if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next; + else first_node = nodes[n].next; + + nodes[n].next = first_free_node; + first_free_node = n; + + //Update dynamic maps + for(std::vector * >::iterator i=dyn_node_maps.begin(); + i!=dyn_node_maps.end(); ++i) (**i).erase(nn); + } + + void erase(Edge e) { eraseEdge(e.n); } + + ///\bug Dynamic maps must be updated! + /// + void clear() { + nodes.clear();edges.clear(); + first_node=first_free_node=first_free_edge=-1; + } + + class Node { + friend class ListGraph; + template friend class NodeMap; + + friend class Edge; + friend class OutEdgeIt; + friend class InEdgeIt; + friend class SymEdge; + + protected: + int n; + friend int ListGraph::id(Node v) const; + Node(int nn) {n=nn;} + public: + Node() {} + Node (Invalid) { n=-1; } + bool operator==(const Node i) const {return n==i.n;} + bool operator!=(const Node i) const {return n!=i.n;} + bool operator<(const Node i) const {return n friend class EdgeMap; + + //template friend class SymListGraph::SymEdgeMap; + //friend Edge SymListGraph::opposite(Edge) const; + + friend class Node; + friend class NodeIt; + protected: + int n; + friend int ListGraph::id(Edge e) const; + + Edge(int nn) {n=nn;} + public: + Edge() { } + Edge (Invalid) { n=-1; } + bool operator==(const Edge i) const {return n==i.n;} + bool operator!=(const Edge i) const {return n!=i.n;} + bool operator<(const Edge i) const {return n class NodeMap : public DynMapBase + { + std::vector container; + + public: + typedef T ValueType; + typedef Node KeyType; + + NodeMap(const ListGraph &_G) : + DynMapBase(_G), container(_G.maxNodeId()) + { + G->dyn_node_maps.push_back(this); + } + NodeMap(const ListGraph &_G,const T &t) : + DynMapBase(_G), container(_G.maxNodeId(),t) + { + G->dyn_node_maps.push_back(this); + } + + NodeMap(const NodeMap &m) : + DynMapBase(*m.G), container(m.container) + { + G->dyn_node_maps.push_back(this); + } + + template friend class NodeMap; + + ///\todo It can copy between different types. + /// + template NodeMap(const NodeMap &m) : + DynMapBase(*m.G) + { + G->dyn_node_maps.push_back(this); + typename std::vector::const_iterator i; + for(typename std::vector::const_iterator i=m.container.begin(); + i!=m.container.end(); + i++) + container.push_back(*i); + } + ~NodeMap() + { + if(G) { + std::vector* >::iterator i; + for(i=G->dyn_node_maps.begin(); + i!=G->dyn_node_maps.end() && *i!=this; ++i) ; + //if(*i==this) G->dyn_node_maps.erase(i); //FIXME: Way too slow... + //A better way to do that: (Is this really important?) + if(*i==this) { + *i=G->dyn_node_maps.back(); + G->dyn_node_maps.pop_back(); + } + } + } + + void add(const Node k) + { + if(k.n>=int(container.size())) container.resize(k.n+1); + } + + void erase(const Node) { } + + void set(Node n, T a) { container[n.n]=a; } + //'T& operator[](Node n)' would be wrong here + typename std::vector::reference + operator[](Node n) { return container[n.n]; } + //'const T& operator[](Node n)' would be wrong here + typename std::vector::const_reference + operator[](Node n) const { return container[n.n]; } + + ///\warning There is no safety check at all! + ///Using operator = between maps attached to different graph may + ///cause serious problem. + ///\todo Is this really so? + ///\todo It can copy between different types. + const NodeMap& operator=(const NodeMap &m) + { + container = m.container; + return *this; + } + template + const NodeMap& operator=(const NodeMap &m) + { + std::copy(m.container.begin(), m.container.end(), container.begin()); + return *this; + } + + void update() {} //Useless for Dynamic Maps + void update(T a) {} //Useless for Dynamic Maps + }; + + template class EdgeMap : public DynMapBase + { + std::vector container; + + public: + typedef T ValueType; + typedef Edge KeyType; + + EdgeMap(const ListGraph &_G) : + DynMapBase(_G), container(_G.maxEdgeId()) + { + //FIXME: What if there are empty Id's? + //FIXME: Can I use 'this' in a constructor? + G->dyn_edge_maps.push_back(this); + } + EdgeMap(const ListGraph &_G,const T &t) : + DynMapBase(_G), container(_G.maxEdgeId(),t) + { + G->dyn_edge_maps.push_back(this); + } + EdgeMap(const EdgeMap &m) : + DynMapBase(*m.G), container(m.container) + { + G->dyn_edge_maps.push_back(this); + } + + template friend class EdgeMap; + + ///\todo It can copy between different types. + /// + template EdgeMap(const EdgeMap &m) : + DynMapBase(*m.G) + { + G->dyn_edge_maps.push_back(this); + typename std::vector::const_iterator i; + for(typename std::vector::const_iterator i=m.container.begin(); + i!=m.container.end(); + i++) + container.push_back(*i); + } + ~EdgeMap() + { + if(G) { + std::vector* >::iterator i; + for(i=G->dyn_edge_maps.begin(); + i!=G->dyn_edge_maps.end() && *i!=this; ++i) ; + //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow... + //A better way to do that: (Is this really important?) + if(*i==this) { + *i=G->dyn_edge_maps.back(); + G->dyn_edge_maps.pop_back(); + } + } + } + + void add(const Edge k) + { + if(k.n>=int(container.size())) container.resize(k.n+1); + } + void erase(const Edge) { } + + void set(Edge n, T a) { container[n.n]=a; } + //T get(Edge n) const { return container[n.n]; } + typename std::vector::reference + operator[](Edge n) { return container[n.n]; } + typename std::vector::const_reference + operator[](Edge n) const { return container[n.n]; } + + ///\warning There is no safety check at all! + ///Using operator = between maps attached to different graph may + ///cause serious problem. + ///\todo Is this really so? + ///\todo It can copy between different types. + const EdgeMap& operator=(const EdgeMap &m) + { + container = m.container; + return *this; + } + template + const EdgeMap& operator=(const EdgeMap &m) + { + std::copy(m.container.begin(), m.container.end(), container.begin()); + return *this; + } + + void update() {} //Useless for DynMaps + void update(T a) {} //Useless for DynMaps + }; + + }; + + ///Graph for bidirectional edges. + + ///The purpose of this graph structure is to handle graphs + ///having bidirectional edges. Here the function \c addEdge(u,v) adds a pair + ///of oppositely directed edges. + ///There is a new edge map type called + ///\ref SymListGraph::SymEdgeMap "SymEdgeMap" + ///that complements this + ///feature by + ///storing shared values for the edge pairs. The usual + ///\ref GraphSkeleton::EdgeMap "EdgeMap" + ///can be used + ///as well. + /// + ///The oppositely directed edge can also be obtained easily + ///using \ref opposite. + /// + ///Here erase(Edge) deletes a pair of edges. + /// + ///\todo this date structure need some reconsiderations. Maybe it + ///should be implemented independently from ListGraph. + + class SymListGraph : public ListGraph + { + public: + template class SymEdgeMap; + template friend class SymEdgeMap; + + SymListGraph() : ListGraph() { } + SymListGraph(const ListGraph &_g) : ListGraph(_g) { } + ///Adds a pair of oppositely directed edges to the graph. + Edge addEdge(Node u, Node v) + { + Edge e = ListGraph::addEdge(u,v); + ListGraph::addEdge(v,u); + return e; + } + + void erase(Node n) { ListGraph::erase(n); } + ///The oppositely directed edge. + + ///Returns the oppositely directed + ///pair of the edge \c e. + Edge opposite(Edge e) const + { + Edge f; + f.idref() = e.idref() - 2*(e.idref()%2) + 1; + return f; + } + + ///Removes a pair of oppositely directed edges to the graph. + void erase(Edge e) { + ListGraph::erase(opposite(e)); + ListGraph::erase(e); + } + + ///Common data storage for the edge pairs. + + ///This map makes it possible to store data shared by the oppositely + ///directed pairs of edges. + template class SymEdgeMap : public DynMapBase + { + std::vector container; + + public: + typedef T ValueType; + typedef Edge KeyType; + + SymEdgeMap(const SymListGraph &_G) : + DynMapBase(_G), container(_G.maxEdgeId()/2) + { + static_cast(G)->dyn_edge_maps.push_back(this); + } + SymEdgeMap(const SymListGraph &_G,const T &t) : + DynMapBase(_G), container(_G.maxEdgeId()/2,t) + { + G->dyn_edge_maps.push_back(this); + } + + SymEdgeMap(const SymEdgeMap &m) : + DynMapBase(*m.G), container(m.container) + { + G->dyn_node_maps.push_back(this); + } + + // template friend class SymEdgeMap; + + ///\todo It can copy between different types. + /// + + template SymEdgeMap(const SymEdgeMap &m) : + DynMapBase(*m.G) + { + G->dyn_node_maps.push_back(this); + typename std::vector::const_iterator i; + for(typename std::vector::const_iterator i=m.container.begin(); + i!=m.container.end(); + i++) + container.push_back(*i); + } + + ~SymEdgeMap() + { + if(G) { + std::vector* >::iterator i; + for(i=static_cast(G)->dyn_edge_maps.begin(); + i!=static_cast(G)->dyn_edge_maps.end() + && *i!=this; ++i) ; + //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow... + //A better way to do that: (Is this really important?) + if(*i==this) { + *i=static_cast(G)->dyn_edge_maps.back(); + static_cast(G)->dyn_edge_maps.pop_back(); + } + } + } + + void add(const Edge k) + { + if(!k.idref()%2&&k.idref()/2>=int(container.size())) + container.resize(k.idref()/2+1); + } + void erase(const Edge k) { } + + void set(Edge n, T a) { container[n.idref()/2]=a; } + //T get(Edge n) const { return container[n.idref()/2]; } + typename std::vector::reference + operator[](Edge n) { return container[n.idref()/2]; } + typename std::vector::const_reference + operator[](Edge n) const { return container[n.idref()/2]; } + + ///\warning There is no safety check at all! + ///Using operator = between maps attached to different graph may + ///cause serious problem. + ///\todo Is this really so? + ///\todo It can copy between different types. + const SymEdgeMap& operator=(const SymEdgeMap &m) + { + container = m.container; + return *this; + } + template + const SymEdgeMap& operator=(const SymEdgeMap &m) + { + std::copy(m.container.begin(), m.container.end(), container.begin()); + return *this; + } + + void update() {} //Useless for DynMaps + void update(T a) {} //Useless for DynMaps + + }; + + }; + + + ///A graph class containing only nodes. + + ///This class implements a graph structure without edges. + ///The most useful application of this class is to be the node set of an + ///\ref EdgeSet class. + /// + ///It conforms to the graph interface documented under + ///the description of \ref GraphSkeleton with the exception that you cannot + ///add (or delete) edges. The usual edge iterators are exists, but they are + ///always \ref INVALID. + ///\sa \ref GraphSkeleton + ///\sa \ref EdgeSet + class NodeSet { + + //Nodes are double linked. + //The free nodes are only single linked using the "next" field. + struct NodeT + { + int first_in,first_out; + int prev, next; + // NodeT() {} + }; + + std::vector nodes; + //The first node + int first_node; + //The first free node + int first_free_node; + + protected: + + template class DynMapBase + { + protected: + const NodeSet* G; + public: + virtual void add(const Key k) = 0; + virtual void erase(const Key k) = 0; + DynMapBase(const NodeSet &_G) : G(&_G) {} + virtual ~DynMapBase() {} + friend class NodeSet; + }; + + public: + template class EdgeMap; + template class NodeMap; + + class Node; + class Edge; + + // protected: + // HELPME: + protected: + ///\bug It must be public because of SymEdgeMap. + /// + mutable std::vector * > dyn_node_maps; + //mutable std::vector * > dyn_edge_maps; + + public: + + class NodeIt; + class EdgeIt; + class OutEdgeIt; + class InEdgeIt; + + template class NodeMap; + template class EdgeMap; + + public: + + ///Default constructor + NodeSet() : nodes(), first_node(-1), + first_free_node(-1) {} + ///Copy constructor + NodeSet(const NodeSet &_g) : nodes(_g.nodes), first_node(_g.first_node), + first_free_node(_g.first_free_node) {} + + ~NodeSet() + { + for(std::vector * >::iterator i=dyn_node_maps.begin(); + i!=dyn_node_maps.end(); ++i) (**i).G=NULL; + //for(std::vector * >::iterator i=dyn_edge_maps.begin(); + // i!=dyn_edge_maps.end(); ++i) (**i).G=NULL; + } + + int nodeNum() const { return nodes.size(); } //FIXME: What is this? + int edgeNum() const { return 0; } //FIXME: What is this? + + ///\bug This function does something different than + ///its name would suggests... + int maxNodeId() const { return nodes.size(); } //FIXME: What is this? + ///\bug This function does something different than + ///its name would suggests... + int maxEdgeId() const { return 0; } //FIXME: What is this? + + Node tail(Edge e) const { return INVALID; } + Node head(Edge e) const { return INVALID; } + + Node aNode(OutEdgeIt e) const { return INVALID; } + Node aNode(InEdgeIt e) const { return INVALID; } + + Node bNode(OutEdgeIt e) const { return INVALID; } + Node bNode(InEdgeIt e) const { return INVALID; } + + NodeIt& first(NodeIt& v) const { + v=NodeIt(*this); return v; } + EdgeIt& first(EdgeIt& e) const { + e=EdgeIt(*this); return e; } + OutEdgeIt& first(OutEdgeIt& e, const Node v) const { + e=OutEdgeIt(*this,v); return e; } + InEdgeIt& first(InEdgeIt& e, const Node v) const { + e=InEdgeIt(*this,v); return e; } + +// template< typename It > +// It first() const { It e; first(e); return e; } + +// template< typename It > +// It first(Node v) const { It e; first(e,v); return e; } + + bool valid(Edge e) const { return false; } + bool valid(Node n) const { return n.n!=-1; } + + void setInvalid(Edge &e) { } + void setInvalid(Node &n) { n.n=-1; } + + template It getNext(It it) const + { It tmp(it); return next(tmp); } + + NodeIt& next(NodeIt& it) const { + it.n=nodes[it.n].next; + return it; + } + OutEdgeIt& next(OutEdgeIt& it) const { return it; } + InEdgeIt& next(InEdgeIt& it) const { return it; } + EdgeIt& next(EdgeIt& it) const { return it; } + + int id(Node v) const { return v.n; } + int id(Edge e) const { return -1; } + + /// Adds a new node to the graph. + + /// \todo It adds the nodes in a reversed order. + /// (i.e. the lastly added node becomes the first.) + Node addNode() { + int n; + + if(first_free_node==-1) + { + n = nodes.size(); + nodes.push_back(NodeT()); + } + else { + n = first_free_node; + first_free_node = nodes[n].next; + } + + nodes[n].next = first_node; + if(first_node != -1) nodes[first_node].prev = n; + first_node = n; + nodes[n].prev = -1; + + nodes[n].first_in = nodes[n].first_out = -1; + + Node nn; nn.n=n; + + //Update dynamic maps + for(std::vector * >::iterator i=dyn_node_maps.begin(); + i!=dyn_node_maps.end(); ++i) (**i).add(nn); + + return nn; + } + + void erase(Node nn) { + int n=nn.n; + + if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev; + if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next; + else first_node = nodes[n].next; + + nodes[n].next = first_free_node; + first_free_node = n; + + //Update dynamic maps + for(std::vector * >::iterator i=dyn_node_maps.begin(); + i!=dyn_node_maps.end(); ++i) (**i).erase(nn); + } + + ///\bug Dynamic maps must be updated! + /// + void clear() { + nodes.clear(); + first_node = first_free_node = -1; + } + + class Node { + friend class NodeSet; + template friend class NodeMap; + + friend class Edge; + friend class OutEdgeIt; + friend class InEdgeIt; + + protected: + int n; + friend int NodeSet::id(Node v) const; + Node(int nn) {n=nn;} + public: + Node() {} + Node (Invalid i) { n=-1; } + bool operator==(const Node i) const {return n==i.n;} + bool operator!=(const Node i) const {return n!=i.n;} + bool operator<(const Node i) const {return n friend class EdgeMap; + + //template friend class SymNodeSet::SymEdgeMap; + //friend Edge SymNodeSet::opposite(Edge) const; + + // friend class Node; + // friend class NodeIt; + protected: + //friend int NodeSet::id(Edge e) const; + // Edge(int nn) {} + public: + Edge() { } + Edge (Invalid) { } + bool operator==(const Edge i) const {return true;} + bool operator!=(const Edge i) const {return false;} + bool operator<(const Edge i) const {return false;} + ///\bug This is a workaround until somebody tells me how to + ///make class \c SymNodeSet::SymEdgeMap friend of Edge + // int idref() {return -1;} + // int idref() const {return -1;} + }; + + class EdgeIt : public Edge { + //friend class NodeSet; + public: + EdgeIt(const NodeSet& G) : Edge() { } + EdgeIt (Invalid i) : Edge(i) { } + EdgeIt() : Edge() { } + ///\bug This is a workaround until somebody tells me how to + ///make class \c SymNodeSet::SymEdgeMap friend of Edge + // int idref() {return -1;} + }; + + class OutEdgeIt : public Edge { + friend class NodeSet; + public: + OutEdgeIt() : Edge() { } + OutEdgeIt (Invalid i) : Edge(i) { } + OutEdgeIt(const NodeSet& G,const Node v) : Edge() {} + }; + + class InEdgeIt : public Edge { + friend class NodeSet; + public: + InEdgeIt() : Edge() { } + InEdgeIt (Invalid i) : Edge(i) { } + InEdgeIt(const NodeSet& G,Node v) :Edge() {} + }; + + template class NodeMap : public DynMapBase + { + std::vector container; + + public: + typedef T ValueType; + typedef Node KeyType; + + NodeMap(const NodeSet &_G) : + DynMapBase(_G), container(_G.maxNodeId()) + { + G->dyn_node_maps.push_back(this); + } + NodeMap(const NodeSet &_G,const T &t) : + DynMapBase(_G), container(_G.maxNodeId(),t) + { + G->dyn_node_maps.push_back(this); + } + + NodeMap(const NodeMap &m) : + DynMapBase(*m.G), container(m.container) + { + G->dyn_node_maps.push_back(this); + } + + template friend class NodeMap; + + ///\todo It can copy between different types. + /// + template NodeMap(const NodeMap &m) : + DynMapBase(*m.G) + { + G->dyn_node_maps.push_back(this); + typename std::vector::const_iterator i; + for(typename std::vector::const_iterator i=m.container.begin(); + i!=m.container.end(); + i++) + container.push_back(*i); + } + ~NodeMap() + { + if(G) { + std::vector* >::iterator i; + for(i=G->dyn_node_maps.begin(); + i!=G->dyn_node_maps.end() && *i!=this; ++i) ; + //if(*i==this) G->dyn_node_maps.erase(i); //FIXME: Way too slow... + //A better way to do that: (Is this really important?) + if(*i==this) { + *i=G->dyn_node_maps.back(); + G->dyn_node_maps.pop_back(); + } + } + } + + void add(const Node k) + { + if(k.n>=int(container.size())) container.resize(k.n+1); + } + + void erase(const Node) { } + + void set(Node n, T a) { container[n.n]=a; } + //'T& operator[](Node n)' would be wrong here + typename std::vector::reference + operator[](Node n) { return container[n.n]; } + //'const T& operator[](Node n)' would be wrong here + typename std::vector::const_reference + operator[](Node n) const { return container[n.n]; } + + ///\warning There is no safety check at all! + ///Using operator = between maps attached to different graph may + ///cause serious problem. + ///\todo Is this really so? + ///\todo It can copy between different types. + const NodeMap& operator=(const NodeMap &m) + { + container = m.container; + return *this; + } + template + const NodeMap& operator=(const NodeMap &m) + { + std::copy(m.container.begin(), m.container.end(), container.begin()); + return *this; + } + + void update() {} //Useless for Dynamic Maps + void update(T a) {} //Useless for Dynamic Maps + }; + + template class EdgeMap + { + public: + typedef T ValueType; + typedef Edge KeyType; + + EdgeMap(const NodeSet &) { } + EdgeMap(const NodeSet &,const T &) { } + EdgeMap(const EdgeMap &) { } + // template friend class EdgeMap; + + ///\todo It can copy between different types. + /// + template EdgeMap(const EdgeMap &) { } + ~EdgeMap() { } + + void add(const Edge ) { } + void erase(const Edge) { } + + void set(Edge, T) { } + //T get(Edge n) const { return container[n.n]; } + ValueType &operator[](Edge) { return *((T*)(NULL)); } + const ValueType &operator[](Edge) const { return *((T*)(NULL)); } + + const EdgeMap& operator=(const EdgeMap &) { return *this; } + + template + const EdgeMap& operator=(const EdgeMap &m) { return *this; } + + void update() {} + void update(T a) {} + }; + }; + + + + ///Graph structure using a node set of another graph. + + ///This structure can be used to establish another graph over a node set + /// of an existing one. The node iterator will go through the nodes of the + /// original graph, and the NodeMap's of both graphs will convert to + /// each other. + /// + ///\warning Adding or deleting nodes from the graph is not safe if an + ///\ref EdgeSet is currently attached to it! + /// + ///\todo Make it possible to add/delete edges from the base graph + ///(and from \ref EdgeSet, as well) + /// + ///\param GG The type of the graph which shares its node set with this class. + ///Its interface must conform with \ref GraphSkeleton. + /// + ///It conforms to the graph interface documented under + ///the description of \ref GraphSkeleton. + ///\sa \ref GraphSkeleton. + ///\sa \ref NodeSet. + template + class EdgeSet { + + typedef GG NodeGraphType; + + NodeGraphType &G; + + public: + class Node; + int id(Node v) const; + + class Node : public NodeGraphType::Node { + friend class EdgeSet; + // template friend class NodeMap; + + friend class Edge; + friend class OutEdgeIt; + friend class InEdgeIt; + friend class SymEdge; + + public: + friend int EdgeSet::id(Node v) const; + // Node(int nn) {n=nn;} + public: + Node() : NodeGraphType::Node() {} + Node (Invalid i) : NodeGraphType::Node(i) {} + Node(const typename NodeGraphType::Node &n) : NodeGraphType::Node(n) {} + }; + + class NodeIt : public NodeGraphType::NodeIt { + friend class EdgeSet; + public: + NodeIt() : NodeGraphType::NodeIt() { } + NodeIt (Invalid i) : NodeGraphType::NodeIt(i) {} + NodeIt(const EdgeSet& _G) : NodeGraphType::NodeIt(_G.G) { } + NodeIt(const typename NodeGraphType::NodeIt &n) + : NodeGraphType::NodeIt(n) {} + operator Node() { return Node(*this);} + }; + + private: + //Edges are double linked. + //The free edges are only single linked using the "next_in" field. + struct NodeT + { + int first_in,first_out; + NodeT() : first_in(-1), first_out(-1) { } + }; + + struct EdgeT + { + Node head, tail; + int prev_in, prev_out; + int next_in, next_out; + }; + + + typename NodeGraphType::template NodeMap nodes; + + std::vector edges; + //The first free edge + int first_free_edge; + + protected: + + template class DynMapBase + { + protected: + const EdgeSet* G; + public: + virtual void add(const Key k) = 0; + virtual void erase(const Key k) = 0; + DynMapBase(const EdgeSet &_G) : G(&_G) {} + virtual ~DynMapBase() {} + friend class EdgeSet; + }; + + public: + //template class NodeMap; + template class EdgeMap; + + class Node; + class Edge; + + // protected: + // HELPME: + protected: + // mutable std::vector * > dyn_node_maps; + ///\bug It must be public because of SymEdgeMap. + /// + mutable std::vector * > dyn_edge_maps; + + public: + + class NodeIt; + class EdgeIt; + class OutEdgeIt; + class InEdgeIt; + + template class NodeMap; + template class EdgeMap; + + public: + + ///Constructor + + ///Construates a new graph based on the nodeset of an existing one. + ///\param _G the base graph. + ///\todo It looks like a copy constructor, but it isn't. + EdgeSet(NodeGraphType &_G) : G(_G), + nodes(_G), edges(), + first_free_edge(-1) { } + ///Copy constructor + + ///Makes a copy of an EdgeSet. + ///It will be based on the same graph. + EdgeSet(const EdgeSet &_g) : G(_g.G), nodes(_g.G), edges(_g.edges), + first_free_edge(_g.first_free_edge) { } + + ~EdgeSet() + { + // for(std::vector * >::iterator i=dyn_node_maps.begin(); + // i!=dyn_node_maps.end(); ++i) (**i).G=NULL; + for(typename std::vector * >::iterator + i=dyn_edge_maps.begin(); + i!=dyn_edge_maps.end(); ++i) (**i).G=NULL; + } + + int nodeNum() const { return G.nodeNum(); } //FIXME: What is this? + int edgeNum() const { return edges.size(); } //FIXME: What is this? + + ///\bug This function does something different than + ///its name would suggests... + int maxNodeId() const { return G.maxNodeId(); } //FIXME: What is this? + ///\bug This function does something different than + ///its name would suggests... + int maxEdgeId() const { return edges.size(); } //FIXME: What is this? + + Node tail(Edge e) const { return edges[e.n].tail; } + Node head(Edge e) const { return edges[e.n].head; } + + Node aNode(OutEdgeIt e) const { return edges[e.n].tail; } + Node aNode(InEdgeIt e) const { return edges[e.n].head; } + + Node bNode(OutEdgeIt e) const { return edges[e.n].head; } + Node bNode(InEdgeIt e) const { return edges[e.n].tail; } + + NodeIt& first(NodeIt& v) const { + v=NodeIt(*this); return v; } + EdgeIt& first(EdgeIt& e) const { + e=EdgeIt(*this); return e; } + OutEdgeIt& first(OutEdgeIt& e, const Node v) const { + e=OutEdgeIt(*this,v); return e; } + InEdgeIt& first(InEdgeIt& e, const Node v) const { + e=InEdgeIt(*this,v); return e; } + +// template< typename It > +// It first() const { It e; first(e); return e; } + +// template< typename It > +// It first(Node v) const { It e; first(e,v); return e; } + + bool valid(Edge e) const { return e.n!=-1; } + bool valid(Node n) const { return G.valid(n); } + + void setInvalid(Edge &e) { e.n=-1; } + void setInvalid(Node &n) { G.setInvalid(n); } + + template It getNext(It it) const + { It tmp(it); return next(tmp); } + + NodeIt& next(NodeIt& it) const { G.next(it); return it; } + OutEdgeIt& next(OutEdgeIt& it) const + { it.n=edges[it.n].next_out; return it; } + InEdgeIt& next(InEdgeIt& it) const + { it.n=edges[it.n].next_in; return it; } + EdgeIt& next(EdgeIt& it) const { + if(edges[it.n].next_in!=-1) { + it.n=edges[it.n].next_in; + } + else { + NodeIt n; + for(n=next(edges[it.n].head); + valid(n) && nodes[n].first_in == -1; + next(n)) ; + it.n = (valid(n))?-1:nodes[n].first_in; + } + return it; + } + + int id(Edge e) const { return e.n; } + + /// Adds a new node to the graph. + Node addNode() { return G.AddNode(); } + + Edge addEdge(Node u, Node v) { + int n; + + if(first_free_edge==-1) + { + n = edges.size(); + edges.push_back(EdgeT()); + } + else { + n = first_free_edge; + first_free_edge = edges[n].next_in; + } + + edges[n].tail = u; edges[n].head = v; + + edges[n].next_out = nodes[u].first_out; + if(nodes[u].first_out != -1) edges[nodes[u].first_out].prev_out = n; + edges[n].next_in = nodes[v].first_in; + if(nodes[v].first_in != -1) edges[nodes[v].first_in].prev_in = n; + edges[n].prev_in = edges[n].prev_out = -1; + + nodes[u].first_out = nodes[v].first_in = n; + + Edge e; e.n=n; + + //Update dynamic maps + for(typename std::vector * >::iterator + i=dyn_edge_maps.begin(); + i!=dyn_edge_maps.end(); ++i) (**i).add(e); + + return e; + } + + private: + void eraseEdge(int n) { + + if(edges[n].next_in!=-1) + edges[edges[n].next_in].prev_in = edges[n].prev_in; + if(edges[n].prev_in!=-1) + edges[edges[n].prev_in].next_in = edges[n].next_in; + else nodes[edges[n].head].first_in = edges[n].next_in; + + if(edges[n].next_out!=-1) + edges[edges[n].next_out].prev_out = edges[n].prev_out; + if(edges[n].prev_out!=-1) + edges[edges[n].prev_out].next_out = edges[n].next_out; + else nodes[edges[n].tail].first_out = edges[n].next_out; + + edges[n].next_in = first_free_edge; + first_free_edge = -1; + + //Update dynamic maps + Edge e; e.n=n; + for(typename std::vector * >::iterator + i=dyn_edge_maps.begin(); + i!=dyn_edge_maps.end(); ++i) (**i).erase(e); + } + + public: + +// void erase(Node nn) { +// int n=nn.n; +// int m; +// while((m=nodes[n].first_in)!=-1) eraseEdge(m); +// while((m=nodes[n].first_out)!=-1) eraseEdge(m); +// } + + void erase(Edge e) { eraseEdge(e.n); } + +// //\bug Dynamic maps must be updated! +// // +// void clear() { +// nodes.clear();edges.clear(); +// first_node=first_free_node=first_free_edge=-1; +// } + + class Edge { + friend class EdgeSet; + template friend class EdgeMap; + + //template friend class SymEdgeSet::SymEdgeMap; + //friend Edge SymEdgeSet::opposite(Edge) const; + + friend class Node; + friend class NodeIt; + protected: + int n; + friend int EdgeSet::id(Edge e) const; + + Edge(int nn) {n=nn;} + public: + Edge() { } + Edge (Invalid) { n=-1; } + bool operator==(const Edge i) const {return n==i.n;} + bool operator!=(const Edge i) const {return n!=i.n;} + bool operator<(const Edge i) const {return nn = G.valid(m)?-1:G.nodes[m].first_in; + } + EdgeIt (Invalid i) : Edge(i) { } + EdgeIt() : Edge() { } + ///\bug This is a workaround until somebody tells me how to + ///make class \c SymEdgeSet::SymEdgeMap friend of Edge + int &idref() {return this->n;} + }; + + class OutEdgeIt : public Edge { + friend class EdgeSet; + public: + OutEdgeIt() : Edge() { } + OutEdgeIt (Invalid i) : Edge(i) { } + + OutEdgeIt(const EdgeSet& G,const Node v) : Edge(nodes[v].first_out) { } + }; + + class InEdgeIt : public Edge { + friend class EdgeSet; + public: + InEdgeIt() : Edge() { } + InEdgeIt (Invalid i) : Edge(i) { } + InEdgeIt(const EdgeSet& G,Node v) :Edge(nodes[v].first_in) { } + }; + + template class NodeMap : + public NodeGraphType::template NodeMap + { + public: + NodeMap(const EdgeSet &_G) : + NodeGraphType::NodeMap(_G.G) { } //AJAJJ would be wrong!!! + NodeMap(const EdgeSet &_G,const T &t) : + NodeGraphType::NodeMap(_G.G,t) { } + //It is unnecessary + NodeMap(const typename NodeGraphType::template NodeMap &m) : + NodeGraphType::NodeMap(m) { } + + ///\todo It can copy between different types. + /// + template + NodeMap(const typename NodeGraphType::template NodeMap &m) + : NodeGraphType::NodeMap(m) { } + }; + + template class EdgeMap : public DynMapBase + { + std::vector container; + + public: + typedef T ValueType; + typedef Edge KeyType; + + EdgeMap(const EdgeSet &_G) : + DynMapBase(_G), container(_G.maxEdgeId()) + { + //FIXME: What if there are empty Id's? + //FIXME: Can I use 'this' in a constructor? + G->dyn_edge_maps.push_back(this); + } + EdgeMap(const EdgeSet &_G,const T &t) : + DynMapBase(_G), container(_G.maxEdgeId(),t) + { + G->dyn_edge_maps.push_back(this); + } + EdgeMap(const EdgeMap &m) : + DynMapBase(*m.G), container(m.container) + { + G->dyn_edge_maps.push_back(this); + } + + template friend class EdgeMap; + + ///\todo It can copy between different types. + /// + template EdgeMap(const EdgeMap &m) : + DynMapBase(*m.G) + { + G->dyn_edge_maps.push_back(this); + typename std::vector::const_iterator i; + for(typename std::vector::const_iterator i=m.container.begin(); + i!=m.container.end(); + i++) + container.push_back(*i); + } + ~EdgeMap() + { + if(G) { + typename std::vector* >::iterator i; + for(i=G->dyn_edge_maps.begin(); + i!=G->dyn_edge_maps.end() && *i!=this; ++i) ; + //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow... + //A better way to do that: (Is this really important?) + if(*i==this) { + *i=G->dyn_edge_maps.back(); + G->dyn_edge_maps.pop_back(); + } + } + } + + void add(const Edge k) + { + if(k.n>=int(container.size())) container.resize(k.n+1); + } + void erase(const Edge) { } + + void set(Edge n, T a) { container[n.n]=a; } + //T get(Edge n) const { return container[n.n]; } + typename std::vector::reference + operator[](Edge n) { return container[n.n]; } + typename std::vector::const_reference + operator[](Edge n) const { return container[n.n]; } + + ///\warning There is no safety check at all! + ///Using operator = between maps attached to different graph may + ///cause serious problem. + ///\todo Is this really so? + ///\todo It can copy between different types. + const EdgeMap& operator=(const EdgeMap &m) + { + container = m.container; + return *this; + } + template + const EdgeMap& operator=(const EdgeMap &m) + { + std::copy(m.container.begin(), m.container.end(), container.begin()); + return *this; + } + + void update() {} //Useless for DynMaps + void update(T a) {} //Useless for DynMaps + }; + + }; + + template< typename GG> + int EdgeSet::id(Node v) const { return G.id(v); } + +/// @} + +} //namespace hugo + +#endif //HUGO_LIST_GRAPH_H diff -r e8703f0a6e2f -r 159f1cbf8a45 src/test/dijkstra_test.cc --- a/src/test/dijkstra_test.cc Fri May 07 11:57:34 2004 +0000 +++ b/src/test/dijkstra_test.cc Fri May 07 13:27:16 2004 +0000 @@ -1,4 +1,4 @@ -#include +#include "test_tools.h" #include #include @@ -59,7 +59,7 @@ Node s, t; LengthMap cap(G); PetStruct ps = addPetersen(G,PET_SIZE); - + for(int i=0;i #include #include +#include + #include"test_tools.h" -//#include<../work/alpar/list_graph.h> - /* This test makes consistency checks of list graph structures. @@ -242,8 +242,8 @@ template void checkCompile(GraphSkeleton &); template void checkCompile(SmartGraph &); template void checkCompile(SymSmartGraph &); -//template void checkCompile(ListGraph &); -//template void checkCompile(SymListGraph &); +template void checkCompile(ListGraph &); +template void checkCompile(SymListGraph &); //Due to some mysterious and some conceptual problems it does not work. //template void checkCompile >(EdgeSet &); @@ -256,22 +256,22 @@ bidirPetersen(G); checkPetersen(G); } -// { -// ListGraph G; -// addPetersen(G); -// bidirPetersen(G); -// checkPetersen(G); -// } + { + ListGraph G; + addPetersen(G); + bidirPetersen(G); + checkPetersen(G); + } { SymSmartGraph G; addPetersen(G); checkPetersen(G); } -// { -// SymListGraph G; -// addPetersen(G); -// checkPetersen(G); -// } + { + SymListGraph G; + addPetersen(G); + checkPetersen(G); + } //\todo map tests. //\todo copy constr tests. diff -r e8703f0a6e2f -r 159f1cbf8a45 src/work/alpar/list_graph.h --- a/src/work/alpar/list_graph.h Fri May 07 11:57:34 2004 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1597 +0,0 @@ -// -*- mode:C++ -*- - -#ifndef HUGO_LIST_GRAPH_H -#define HUGO_LIST_GRAPH_H - -///\ingroup graphs -///\file -///\brief ListGraph, SymListGraph, NodeSet and EdgeSet classes. - -#include -#include - -#include - -namespace hugo { - -/// \addtogroup graphs -/// @{ - - class SymListGraph; - - ///A list graph class. - - ///This is a simple and fast erasable graph implementation. - /// - ///It conforms to the graph interface documented under - ///the description of \ref GraphSkeleton. - ///\sa \ref GraphSkeleton. - class ListGraph { - - //Nodes are double linked. - //The free nodes are only single linked using the "next" field. - struct NodeT - { - int first_in,first_out; - int prev, next; - // NodeT() {} - }; - //Edges are double linked. - //The free edges are only single linked using the "next_in" field. - struct EdgeT - { - int head, tail; - int prev_in, prev_out; - int next_in, next_out; - //FIXME: is this necessary? - // EdgeT() : next_in(-1), next_out(-1) prev_in(-1), prev_out(-1) {} - }; - - std::vector nodes; - //The first node - int first_node; - //The first free node - int first_free_node; - std::vector edges; - //The first free edge - int first_free_edge; - - protected: - - template class DynMapBase - { - protected: - const ListGraph* G; - public: - virtual void add(const Key k) = 0; - virtual void erase(const Key k) = 0; - DynMapBase(const ListGraph &_G) : G(&_G) {} - virtual ~DynMapBase() {} - friend class ListGraph; - }; - - public: - template class EdgeMap; - template class NodeMap; - - class Node; - class Edge; - - // protected: - // HELPME: - protected: - ///\bug It must be public because of SymEdgeMap. - /// - mutable std::vector * > dyn_node_maps; - ///\bug It must be public because of SymEdgeMap. - /// - mutable std::vector * > dyn_edge_maps; - - public: - - class NodeIt; - class EdgeIt; - class OutEdgeIt; - class InEdgeIt; - - template class NodeMap; - template class EdgeMap; - - public: - - ListGraph() : nodes(), first_node(-1), - first_free_node(-1), edges(), first_free_edge(-1) {} - ListGraph(const ListGraph &_g) : nodes(_g.nodes), first_node(_g.first_node), - first_free_node(_g.first_free_node), - edges(_g.edges), - first_free_edge(_g.first_free_edge) {} - - ~ListGraph() - { - for(std::vector * >::iterator i=dyn_node_maps.begin(); - i!=dyn_node_maps.end(); ++i) (**i).G=NULL; - for(std::vector * >::iterator i=dyn_edge_maps.begin(); - i!=dyn_edge_maps.end(); ++i) (**i).G=NULL; - } - - int nodeNum() const { return nodes.size(); } //FIXME: What is this? - int edgeNum() const { return edges.size(); } //FIXME: What is this? - - ///\bug This function does something different than - ///its name would suggests... - int maxNodeId() const { return nodes.size(); } //FIXME: What is this? - ///\bug This function does something different than - ///its name would suggests... - int maxEdgeId() const { return edges.size(); } //FIXME: What is this? - - Node tail(Edge e) const { return edges[e.n].tail; } - Node head(Edge e) const { return edges[e.n].head; } - - Node aNode(OutEdgeIt e) const { return edges[e.n].tail; } - Node aNode(InEdgeIt e) const { return edges[e.n].head; } - - Node bNode(OutEdgeIt e) const { return edges[e.n].head; } - Node bNode(InEdgeIt e) const { return edges[e.n].tail; } - - NodeIt& first(NodeIt& v) const { - v=NodeIt(*this); return v; } - EdgeIt& first(EdgeIt& e) const { - e=EdgeIt(*this); return e; } - OutEdgeIt& first(OutEdgeIt& e, const Node v) const { - e=OutEdgeIt(*this,v); return e; } - InEdgeIt& first(InEdgeIt& e, const Node v) const { - e=InEdgeIt(*this,v); return e; } - -// template< typename It > -// It first() const { It e; first(e); return e; } - -// template< typename It > -// It first(Node v) const { It e; first(e,v); return e; } - - bool valid(Edge e) const { return e.n!=-1; } - bool valid(Node n) const { return n.n!=-1; } - - void setInvalid(Edge &e) { e.n=-1; } - void setInvalid(Node &n) { n.n=-1; } - - template It getNext(It it) const - { It tmp(it); return next(tmp); } - - NodeIt& next(NodeIt& it) const { - it.n=nodes[it.n].next; - return it; - } - OutEdgeIt& next(OutEdgeIt& it) const - { it.n=edges[it.n].next_out; return it; } - InEdgeIt& next(InEdgeIt& it) const - { it.n=edges[it.n].next_in; return it; } - EdgeIt& next(EdgeIt& it) const { - if(edges[it.n].next_in!=-1) { - it.n=edges[it.n].next_in; - } - else { - int n; - for(n=nodes[edges[it.n].head].next; - n!=-1 && nodes[n].first_in == -1; - n = nodes[n].next) ; - it.n = (n==-1)?-1:nodes[n].first_in; - } - return it; - } - - int id(Node v) const { return v.n; } - int id(Edge e) const { return e.n; } - - /// Adds a new node to the graph. - - /// \todo It adds the nodes in a reversed order. - /// (i.e. the lastly added node becomes the first.) - Node addNode() { - int n; - - if(first_free_node==-1) - { - n = nodes.size(); - nodes.push_back(NodeT()); - } - else { - n = first_free_node; - first_free_node = nodes[n].next; - } - - nodes[n].next = first_node; - if(first_node != -1) nodes[first_node].prev = n; - first_node = n; - nodes[n].prev = -1; - - nodes[n].first_in = nodes[n].first_out = -1; - - Node nn; nn.n=n; - - //Update dynamic maps - for(std::vector * >::iterator i=dyn_node_maps.begin(); - i!=dyn_node_maps.end(); ++i) (**i).add(nn); - - return nn; - } - - Edge addEdge(Node u, Node v) { - int n; - - if(first_free_edge==-1) - { - n = edges.size(); - edges.push_back(EdgeT()); - } - else { - n = first_free_edge; - first_free_edge = edges[n].next_in; - } - - edges[n].tail = u.n; edges[n].head = v.n; - - edges[n].next_out = nodes[u.n].first_out; - if(nodes[u.n].first_out != -1) edges[nodes[u.n].first_out].prev_out = n; - edges[n].next_in = nodes[v.n].first_in; - if(nodes[v.n].first_in != -1) edges[nodes[v.n].first_in].prev_in = n; - edges[n].prev_in = edges[n].prev_out = -1; - - nodes[u.n].first_out = nodes[v.n].first_in = n; - - Edge e; e.n=n; - - //Update dynamic maps - for(std::vector * >::iterator i=dyn_edge_maps.begin(); - i!=dyn_edge_maps.end(); ++i) (**i).add(e); - - return e; - } - - private: - void eraseEdge(int n) { - - if(edges[n].next_in!=-1) - edges[edges[n].next_in].prev_in = edges[n].prev_in; - if(edges[n].prev_in!=-1) - edges[edges[n].prev_in].next_in = edges[n].next_in; - else nodes[edges[n].head].first_in = edges[n].next_in; - - if(edges[n].next_out!=-1) - edges[edges[n].next_out].prev_out = edges[n].prev_out; - if(edges[n].prev_out!=-1) - edges[edges[n].prev_out].next_out = edges[n].next_out; - else nodes[edges[n].tail].first_out = edges[n].next_out; - - edges[n].next_in = first_free_edge; - first_free_edge = -1; - - //Update dynamic maps - Edge e; e.n=n; - for(std::vector * >::iterator i=dyn_edge_maps.begin(); - i!=dyn_edge_maps.end(); ++i) (**i).erase(e); - } - - public: - - void erase(Node nn) { - int n=nn.n; - - int m; - while((m=nodes[n].first_in)!=-1) eraseEdge(m); - while((m=nodes[n].first_out)!=-1) eraseEdge(m); - - if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev; - if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next; - else first_node = nodes[n].next; - - nodes[n].next = first_free_node; - first_free_node = n; - - //Update dynamic maps - for(std::vector * >::iterator i=dyn_node_maps.begin(); - i!=dyn_node_maps.end(); ++i) (**i).erase(nn); - } - - void erase(Edge e) { eraseEdge(e.n); } - - ///\bug Dynamic maps must be updated! - /// - void clear() { - nodes.clear();edges.clear(); - first_node=first_free_node=first_free_edge=-1; - } - - class Node { - friend class ListGraph; - template friend class NodeMap; - - friend class Edge; - friend class OutEdgeIt; - friend class InEdgeIt; - friend class SymEdge; - - protected: - int n; - friend int ListGraph::id(Node v) const; - Node(int nn) {n=nn;} - public: - Node() {} - Node (Invalid) { n=-1; } - bool operator==(const Node i) const {return n==i.n;} - bool operator!=(const Node i) const {return n!=i.n;} - bool operator<(const Node i) const {return n friend class EdgeMap; - - //template friend class SymListGraph::SymEdgeMap; - //friend Edge SymListGraph::opposite(Edge) const; - - friend class Node; - friend class NodeIt; - protected: - int n; - friend int ListGraph::id(Edge e) const; - - Edge(int nn) {n=nn;} - public: - Edge() { } - Edge (Invalid) { n=-1; } - bool operator==(const Edge i) const {return n==i.n;} - bool operator!=(const Edge i) const {return n!=i.n;} - bool operator<(const Edge i) const {return n class NodeMap : public DynMapBase - { - std::vector container; - - public: - typedef T ValueType; - typedef Node KeyType; - - NodeMap(const ListGraph &_G) : - DynMapBase(_G), container(_G.maxNodeId()) - { - G->dyn_node_maps.push_back(this); - } - NodeMap(const ListGraph &_G,const T &t) : - DynMapBase(_G), container(_G.maxNodeId(),t) - { - G->dyn_node_maps.push_back(this); - } - - NodeMap(const NodeMap &m) : - DynMapBase(*m.G), container(m.container) - { - G->dyn_node_maps.push_back(this); - } - - template friend class NodeMap; - - ///\todo It can copy between different types. - /// - template NodeMap(const NodeMap &m) : - DynMapBase(*m.G) - { - G->dyn_node_maps.push_back(this); - typename std::vector::const_iterator i; - for(typename std::vector::const_iterator i=m.container.begin(); - i!=m.container.end(); - i++) - container.push_back(*i); - } - ~NodeMap() - { - if(G) { - std::vector* >::iterator i; - for(i=G->dyn_node_maps.begin(); - i!=G->dyn_node_maps.end() && *i!=this; ++i) ; - //if(*i==this) G->dyn_node_maps.erase(i); //FIXME: Way too slow... - //A better way to do that: (Is this really important?) - if(*i==this) { - *i=G->dyn_node_maps.back(); - G->dyn_node_maps.pop_back(); - } - } - } - - void add(const Node k) - { - if(k.n>=int(container.size())) container.resize(k.n+1); - } - - void erase(const Node) { } - - void set(Node n, T a) { container[n.n]=a; } - //'T& operator[](Node n)' would be wrong here - typename std::vector::reference - operator[](Node n) { return container[n.n]; } - //'const T& operator[](Node n)' would be wrong here - typename std::vector::const_reference - operator[](Node n) const { return container[n.n]; } - - ///\warning There is no safety check at all! - ///Using operator = between maps attached to different graph may - ///cause serious problem. - ///\todo Is this really so? - ///\todo It can copy between different types. - const NodeMap& operator=(const NodeMap &m) - { - container = m.container; - return *this; - } - template - const NodeMap& operator=(const NodeMap &m) - { - std::copy(m.container.begin(), m.container.end(), container.begin()); - return *this; - } - - void update() {} //Useless for Dynamic Maps - void update(T a) {} //Useless for Dynamic Maps - }; - - template class EdgeMap : public DynMapBase - { - std::vector container; - - public: - typedef T ValueType; - typedef Edge KeyType; - - EdgeMap(const ListGraph &_G) : - DynMapBase(_G), container(_G.maxEdgeId()) - { - //FIXME: What if there are empty Id's? - //FIXME: Can I use 'this' in a constructor? - G->dyn_edge_maps.push_back(this); - } - EdgeMap(const ListGraph &_G,const T &t) : - DynMapBase(_G), container(_G.maxEdgeId(),t) - { - G->dyn_edge_maps.push_back(this); - } - EdgeMap(const EdgeMap &m) : - DynMapBase(*m.G), container(m.container) - { - G->dyn_edge_maps.push_back(this); - } - - template friend class EdgeMap; - - ///\todo It can copy between different types. - /// - template EdgeMap(const EdgeMap &m) : - DynMapBase(*m.G) - { - G->dyn_edge_maps.push_back(this); - typename std::vector::const_iterator i; - for(typename std::vector::const_iterator i=m.container.begin(); - i!=m.container.end(); - i++) - container.push_back(*i); - } - ~EdgeMap() - { - if(G) { - std::vector* >::iterator i; - for(i=G->dyn_edge_maps.begin(); - i!=G->dyn_edge_maps.end() && *i!=this; ++i) ; - //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow... - //A better way to do that: (Is this really important?) - if(*i==this) { - *i=G->dyn_edge_maps.back(); - G->dyn_edge_maps.pop_back(); - } - } - } - - void add(const Edge k) - { - if(k.n>=int(container.size())) container.resize(k.n+1); - } - void erase(const Edge) { } - - void set(Edge n, T a) { container[n.n]=a; } - //T get(Edge n) const { return container[n.n]; } - typename std::vector::reference - operator[](Edge n) { return container[n.n]; } - typename std::vector::const_reference - operator[](Edge n) const { return container[n.n]; } - - ///\warning There is no safety check at all! - ///Using operator = between maps attached to different graph may - ///cause serious problem. - ///\todo Is this really so? - ///\todo It can copy between different types. - const EdgeMap& operator=(const EdgeMap &m) - { - container = m.container; - return *this; - } - template - const EdgeMap& operator=(const EdgeMap &m) - { - std::copy(m.container.begin(), m.container.end(), container.begin()); - return *this; - } - - void update() {} //Useless for DynMaps - void update(T a) {} //Useless for DynMaps - }; - - }; - - ///Graph for bidirectional edges. - - ///The purpose of this graph structure is to handle graphs - ///having bidirectional edges. Here the function \c addEdge(u,v) adds a pair - ///of oppositely directed edges. - ///There is a new edge map type called - ///\ref SymListGraph::SymEdgeMap "SymEdgeMap" - ///that complements this - ///feature by - ///storing shared values for the edge pairs. The usual - ///\ref GraphSkeleton::EdgeMap "EdgeMap" - ///can be used - ///as well. - /// - ///The oppositely directed edge can also be obtained easily - ///using \ref opposite. - /// - ///Here erase(Edge) deletes a pair of edges. - /// - ///\todo this date structure need some reconsiderations. Maybe it - ///should be implemented independently from ListGraph. - - class SymListGraph : public ListGraph - { - public: - template class SymEdgeMap; - template friend class SymEdgeMap; - - SymListGraph() : ListGraph() { } - SymListGraph(const ListGraph &_g) : ListGraph(_g) { } - ///Adds a pair of oppositely directed edges to the graph. - Edge addEdge(Node u, Node v) - { - Edge e = ListGraph::addEdge(u,v); - ListGraph::addEdge(v,u); - return e; - } - - void erase(Node n) { ListGraph::erase(n); } - ///The oppositely directed edge. - - ///Returns the oppositely directed - ///pair of the edge \c e. - Edge opposite(Edge e) const - { - Edge f; - f.idref() = e.idref() - 2*(e.idref()%2) + 1; - return f; - } - - ///Removes a pair of oppositely directed edges to the graph. - void erase(Edge e) { - ListGraph::erase(opposite(e)); - ListGraph::erase(e); - } - - ///Common data storage for the edge pairs. - - ///This map makes it possible to store data shared by the oppositely - ///directed pairs of edges. - template class SymEdgeMap : public DynMapBase - { - std::vector container; - - public: - typedef T ValueType; - typedef Edge KeyType; - - SymEdgeMap(const SymListGraph &_G) : - DynMapBase(_G), container(_G.maxEdgeId()/2) - { - static_cast(G)->dyn_edge_maps.push_back(this); - } - SymEdgeMap(const SymListGraph &_G,const T &t) : - DynMapBase(_G), container(_G.maxEdgeId()/2,t) - { - G->dyn_edge_maps.push_back(this); - } - - SymEdgeMap(const SymEdgeMap &m) : - DynMapBase(*m.G), container(m.container) - { - G->dyn_node_maps.push_back(this); - } - - // template friend class SymEdgeMap; - - ///\todo It can copy between different types. - /// - - template SymEdgeMap(const SymEdgeMap &m) : - DynMapBase(*m.G) - { - G->dyn_node_maps.push_back(this); - typename std::vector::const_iterator i; - for(typename std::vector::const_iterator i=m.container.begin(); - i!=m.container.end(); - i++) - container.push_back(*i); - } - - ~SymEdgeMap() - { - if(G) { - std::vector* >::iterator i; - for(i=static_cast(G)->dyn_edge_maps.begin(); - i!=static_cast(G)->dyn_edge_maps.end() - && *i!=this; ++i) ; - //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow... - //A better way to do that: (Is this really important?) - if(*i==this) { - *i=static_cast(G)->dyn_edge_maps.back(); - static_cast(G)->dyn_edge_maps.pop_back(); - } - } - } - - void add(const Edge k) - { - if(!k.idref()%2&&k.idref()/2>=int(container.size())) - container.resize(k.idref()/2+1); - } - void erase(const Edge k) { } - - void set(Edge n, T a) { container[n.idref()/2]=a; } - //T get(Edge n) const { return container[n.idref()/2]; } - typename std::vector::reference - operator[](Edge n) { return container[n.idref()/2]; } - typename std::vector::const_reference - operator[](Edge n) const { return container[n.idref()/2]; } - - ///\warning There is no safety check at all! - ///Using operator = between maps attached to different graph may - ///cause serious problem. - ///\todo Is this really so? - ///\todo It can copy between different types. - const SymEdgeMap& operator=(const SymEdgeMap &m) - { - container = m.container; - return *this; - } - template - const SymEdgeMap& operator=(const SymEdgeMap &m) - { - std::copy(m.container.begin(), m.container.end(), container.begin()); - return *this; - } - - void update() {} //Useless for DynMaps - void update(T a) {} //Useless for DynMaps - - }; - - }; - - - ///A graph class containing only nodes. - - ///This class implements a graph structure without edges. - ///The most useful application of this class is to be the node set of an - ///\ref EdgeSet class. - /// - ///It conforms to the graph interface documented under - ///the description of \ref GraphSkeleton with the exception that you cannot - ///add (or delete) edges. The usual edge iterators are exists, but they are - ///always \ref INVALID. - ///\sa \ref GraphSkeleton - ///\sa \ref EdgeSet - class NodeSet { - - //Nodes are double linked. - //The free nodes are only single linked using the "next" field. - struct NodeT - { - int first_in,first_out; - int prev, next; - // NodeT() {} - }; - - std::vector nodes; - //The first node - int first_node; - //The first free node - int first_free_node; - - protected: - - template class DynMapBase - { - protected: - const NodeSet* G; - public: - virtual void add(const Key k) = 0; - virtual void erase(const Key k) = 0; - DynMapBase(const NodeSet &_G) : G(&_G) {} - virtual ~DynMapBase() {} - friend class NodeSet; - }; - - public: - template class EdgeMap; - template class NodeMap; - - class Node; - class Edge; - - // protected: - // HELPME: - protected: - ///\bug It must be public because of SymEdgeMap. - /// - mutable std::vector * > dyn_node_maps; - //mutable std::vector * > dyn_edge_maps; - - public: - - class NodeIt; - class EdgeIt; - class OutEdgeIt; - class InEdgeIt; - - template class NodeMap; - template class EdgeMap; - - public: - - ///Default constructor - NodeSet() : nodes(), first_node(-1), - first_free_node(-1) {} - ///Copy constructor - NodeSet(const NodeSet &_g) : nodes(_g.nodes), first_node(_g.first_node), - first_free_node(_g.first_free_node) {} - - ~NodeSet() - { - for(std::vector * >::iterator i=dyn_node_maps.begin(); - i!=dyn_node_maps.end(); ++i) (**i).G=NULL; - //for(std::vector * >::iterator i=dyn_edge_maps.begin(); - // i!=dyn_edge_maps.end(); ++i) (**i).G=NULL; - } - - int nodeNum() const { return nodes.size(); } //FIXME: What is this? - int edgeNum() const { return 0; } //FIXME: What is this? - - ///\bug This function does something different than - ///its name would suggests... - int maxNodeId() const { return nodes.size(); } //FIXME: What is this? - ///\bug This function does something different than - ///its name would suggests... - int maxEdgeId() const { return 0; } //FIXME: What is this? - - Node tail(Edge e) const { return INVALID; } - Node head(Edge e) const { return INVALID; } - - Node aNode(OutEdgeIt e) const { return INVALID; } - Node aNode(InEdgeIt e) const { return INVALID; } - - Node bNode(OutEdgeIt e) const { return INVALID; } - Node bNode(InEdgeIt e) const { return INVALID; } - - NodeIt& first(NodeIt& v) const { - v=NodeIt(*this); return v; } - EdgeIt& first(EdgeIt& e) const { - e=EdgeIt(*this); return e; } - OutEdgeIt& first(OutEdgeIt& e, const Node v) const { - e=OutEdgeIt(*this,v); return e; } - InEdgeIt& first(InEdgeIt& e, const Node v) const { - e=InEdgeIt(*this,v); return e; } - -// template< typename It > -// It first() const { It e; first(e); return e; } - -// template< typename It > -// It first(Node v) const { It e; first(e,v); return e; } - - bool valid(Edge e) const { return false; } - bool valid(Node n) const { return n.n!=-1; } - - void setInvalid(Edge &e) { } - void setInvalid(Node &n) { n.n=-1; } - - template It getNext(It it) const - { It tmp(it); return next(tmp); } - - NodeIt& next(NodeIt& it) const { - it.n=nodes[it.n].next; - return it; - } - OutEdgeIt& next(OutEdgeIt& it) const { return it; } - InEdgeIt& next(InEdgeIt& it) const { return it; } - EdgeIt& next(EdgeIt& it) const { return it; } - - int id(Node v) const { return v.n; } - int id(Edge e) const { return -1; } - - /// Adds a new node to the graph. - - /// \todo It adds the nodes in a reversed order. - /// (i.e. the lastly added node becomes the first.) - Node addNode() { - int n; - - if(first_free_node==-1) - { - n = nodes.size(); - nodes.push_back(NodeT()); - } - else { - n = first_free_node; - first_free_node = nodes[n].next; - } - - nodes[n].next = first_node; - if(first_node != -1) nodes[first_node].prev = n; - first_node = n; - nodes[n].prev = -1; - - nodes[n].first_in = nodes[n].first_out = -1; - - Node nn; nn.n=n; - - //Update dynamic maps - for(std::vector * >::iterator i=dyn_node_maps.begin(); - i!=dyn_node_maps.end(); ++i) (**i).add(nn); - - return nn; - } - - void erase(Node nn) { - int n=nn.n; - - if(nodes[n].next != -1) nodes[nodes[n].next].prev = nodes[n].prev; - if(nodes[n].prev != -1) nodes[nodes[n].prev].next = nodes[n].next; - else first_node = nodes[n].next; - - nodes[n].next = first_free_node; - first_free_node = n; - - //Update dynamic maps - for(std::vector * >::iterator i=dyn_node_maps.begin(); - i!=dyn_node_maps.end(); ++i) (**i).erase(nn); - } - - ///\bug Dynamic maps must be updated! - /// - void clear() { - nodes.clear(); - first_node = first_free_node = -1; - } - - class Node { - friend class NodeSet; - template friend class NodeMap; - - friend class Edge; - friend class OutEdgeIt; - friend class InEdgeIt; - - protected: - int n; - friend int NodeSet::id(Node v) const; - Node(int nn) {n=nn;} - public: - Node() {} - Node (Invalid i) { n=-1; } - bool operator==(const Node i) const {return n==i.n;} - bool operator!=(const Node i) const {return n!=i.n;} - bool operator<(const Node i) const {return n friend class EdgeMap; - - //template friend class SymNodeSet::SymEdgeMap; - //friend Edge SymNodeSet::opposite(Edge) const; - - // friend class Node; - // friend class NodeIt; - protected: - //friend int NodeSet::id(Edge e) const; - // Edge(int nn) {} - public: - Edge() { } - Edge (Invalid) { } - bool operator==(const Edge i) const {return true;} - bool operator!=(const Edge i) const {return false;} - bool operator<(const Edge i) const {return false;} - ///\bug This is a workaround until somebody tells me how to - ///make class \c SymNodeSet::SymEdgeMap friend of Edge - // int idref() {return -1;} - // int idref() const {return -1;} - }; - - class EdgeIt : public Edge { - //friend class NodeSet; - public: - EdgeIt(const NodeSet& G) : Edge() { } - EdgeIt (Invalid i) : Edge(i) { } - EdgeIt() : Edge() { } - ///\bug This is a workaround until somebody tells me how to - ///make class \c SymNodeSet::SymEdgeMap friend of Edge - // int idref() {return -1;} - }; - - class OutEdgeIt : public Edge { - friend class NodeSet; - public: - OutEdgeIt() : Edge() { } - OutEdgeIt (Invalid i) : Edge(i) { } - OutEdgeIt(const NodeSet& G,const Node v) : Edge() {} - }; - - class InEdgeIt : public Edge { - friend class NodeSet; - public: - InEdgeIt() : Edge() { } - InEdgeIt (Invalid i) : Edge(i) { } - InEdgeIt(const NodeSet& G,Node v) :Edge() {} - }; - - template class NodeMap : public DynMapBase - { - std::vector container; - - public: - typedef T ValueType; - typedef Node KeyType; - - NodeMap(const NodeSet &_G) : - DynMapBase(_G), container(_G.maxNodeId()) - { - G->dyn_node_maps.push_back(this); - } - NodeMap(const NodeSet &_G,const T &t) : - DynMapBase(_G), container(_G.maxNodeId(),t) - { - G->dyn_node_maps.push_back(this); - } - - NodeMap(const NodeMap &m) : - DynMapBase(*m.G), container(m.container) - { - G->dyn_node_maps.push_back(this); - } - - template friend class NodeMap; - - ///\todo It can copy between different types. - /// - template NodeMap(const NodeMap &m) : - DynMapBase(*m.G) - { - G->dyn_node_maps.push_back(this); - typename std::vector::const_iterator i; - for(typename std::vector::const_iterator i=m.container.begin(); - i!=m.container.end(); - i++) - container.push_back(*i); - } - ~NodeMap() - { - if(G) { - std::vector* >::iterator i; - for(i=G->dyn_node_maps.begin(); - i!=G->dyn_node_maps.end() && *i!=this; ++i) ; - //if(*i==this) G->dyn_node_maps.erase(i); //FIXME: Way too slow... - //A better way to do that: (Is this really important?) - if(*i==this) { - *i=G->dyn_node_maps.back(); - G->dyn_node_maps.pop_back(); - } - } - } - - void add(const Node k) - { - if(k.n>=int(container.size())) container.resize(k.n+1); - } - - void erase(const Node) { } - - void set(Node n, T a) { container[n.n]=a; } - //'T& operator[](Node n)' would be wrong here - typename std::vector::reference - operator[](Node n) { return container[n.n]; } - //'const T& operator[](Node n)' would be wrong here - typename std::vector::const_reference - operator[](Node n) const { return container[n.n]; } - - ///\warning There is no safety check at all! - ///Using operator = between maps attached to different graph may - ///cause serious problem. - ///\todo Is this really so? - ///\todo It can copy between different types. - const NodeMap& operator=(const NodeMap &m) - { - container = m.container; - return *this; - } - template - const NodeMap& operator=(const NodeMap &m) - { - std::copy(m.container.begin(), m.container.end(), container.begin()); - return *this; - } - - void update() {} //Useless for Dynamic Maps - void update(T a) {} //Useless for Dynamic Maps - }; - - template class EdgeMap - { - public: - typedef T ValueType; - typedef Edge KeyType; - - EdgeMap(const NodeSet &) { } - EdgeMap(const NodeSet &,const T &) { } - EdgeMap(const EdgeMap &) { } - // template friend class EdgeMap; - - ///\todo It can copy between different types. - /// - template EdgeMap(const EdgeMap &) { } - ~EdgeMap() { } - - void add(const Edge ) { } - void erase(const Edge) { } - - void set(Edge, T) { } - //T get(Edge n) const { return container[n.n]; } - ValueType &operator[](Edge) { return *((T*)(NULL)); } - const ValueType &operator[](Edge) const { return *((T*)(NULL)); } - - const EdgeMap& operator=(const EdgeMap &) { return *this; } - - template - const EdgeMap& operator=(const EdgeMap &m) { return *this; } - - void update() {} - void update(T a) {} - }; - }; - - - - ///Graph structure using a node set of another graph. - - ///This structure can be used to establish another graph over a node set - /// of an existing one. The node iterator will go through the nodes of the - /// original graph, and the NodeMap's of both graphs will convert to - /// each other. - /// - ///\warning Adding or deleting nodes from the graph is not safe if an - ///\ref EdgeSet is currently attached to it! - /// - ///\todo Make it possible to add/delete edges from the base graph - ///(and from \ref EdgeSet, as well) - /// - ///\param GG The type of the graph which shares its node set with this class. - ///Its interface must conform with \ref GraphSkeleton. - /// - ///It conforms to the graph interface documented under - ///the description of \ref GraphSkeleton. - ///\sa \ref GraphSkeleton. - ///\sa \ref NodeSet. - template - class EdgeSet { - - typedef GG NodeGraphType; - - NodeGraphType &G; - - public: - class Node; - int id(Node v) const; - - class Node : public NodeGraphType::Node { - friend class EdgeSet; - // template friend class NodeMap; - - friend class Edge; - friend class OutEdgeIt; - friend class InEdgeIt; - friend class SymEdge; - - public: - friend int EdgeSet::id(Node v) const; - // Node(int nn) {n=nn;} - public: - Node() : NodeGraphType::Node() {} - Node (Invalid i) : NodeGraphType::Node(i) {} - Node(const typename NodeGraphType::Node &n) : NodeGraphType::Node(n) {} - }; - - class NodeIt : public NodeGraphType::NodeIt { - friend class EdgeSet; - public: - NodeIt() : NodeGraphType::NodeIt() { } - NodeIt (Invalid i) : NodeGraphType::NodeIt(i) {} - NodeIt(const EdgeSet& _G) : NodeGraphType::NodeIt(_G.G) { } - NodeIt(const typename NodeGraphType::NodeIt &n) - : NodeGraphType::NodeIt(n) {} - operator Node() { return Node(*this);} - }; - - private: - //Edges are double linked. - //The free edges are only single linked using the "next_in" field. - struct NodeT - { - int first_in,first_out; - NodeT() : first_in(-1), first_out(-1) { } - }; - - struct EdgeT - { - Node head, tail; - int prev_in, prev_out; - int next_in, next_out; - }; - - - typename NodeGraphType::template NodeMap nodes; - - std::vector edges; - //The first free edge - int first_free_edge; - - protected: - - template class DynMapBase - { - protected: - const EdgeSet* G; - public: - virtual void add(const Key k) = 0; - virtual void erase(const Key k) = 0; - DynMapBase(const EdgeSet &_G) : G(&_G) {} - virtual ~DynMapBase() {} - friend class EdgeSet; - }; - - public: - //template class NodeMap; - template class EdgeMap; - - class Node; - class Edge; - - // protected: - // HELPME: - protected: - // mutable std::vector * > dyn_node_maps; - ///\bug It must be public because of SymEdgeMap. - /// - mutable std::vector * > dyn_edge_maps; - - public: - - class NodeIt; - class EdgeIt; - class OutEdgeIt; - class InEdgeIt; - - template class NodeMap; - template class EdgeMap; - - public: - - ///Constructor - - ///Construates a new graph based on the nodeset of an existing one. - ///\param _G the base graph. - ///\todo It looks like a copy constructor, but it isn't. - EdgeSet(NodeGraphType &_G) : G(_G), - nodes(_G), edges(), - first_free_edge(-1) { } - ///Copy constructor - - ///Makes a copy of an EdgeSet. - ///It will be based on the same graph. - EdgeSet(const EdgeSet &_g) : G(_g.G), nodes(_g.G), edges(_g.edges), - first_free_edge(_g.first_free_edge) { } - - ~EdgeSet() - { - // for(std::vector * >::iterator i=dyn_node_maps.begin(); - // i!=dyn_node_maps.end(); ++i) (**i).G=NULL; - for(typename std::vector * >::iterator - i=dyn_edge_maps.begin(); - i!=dyn_edge_maps.end(); ++i) (**i).G=NULL; - } - - int nodeNum() const { return G.nodeNum(); } //FIXME: What is this? - int edgeNum() const { return edges.size(); } //FIXME: What is this? - - ///\bug This function does something different than - ///its name would suggests... - int maxNodeId() const { return G.maxNodeId(); } //FIXME: What is this? - ///\bug This function does something different than - ///its name would suggests... - int maxEdgeId() const { return edges.size(); } //FIXME: What is this? - - Node tail(Edge e) const { return edges[e.n].tail; } - Node head(Edge e) const { return edges[e.n].head; } - - Node aNode(OutEdgeIt e) const { return edges[e.n].tail; } - Node aNode(InEdgeIt e) const { return edges[e.n].head; } - - Node bNode(OutEdgeIt e) const { return edges[e.n].head; } - Node bNode(InEdgeIt e) const { return edges[e.n].tail; } - - NodeIt& first(NodeIt& v) const { - v=NodeIt(*this); return v; } - EdgeIt& first(EdgeIt& e) const { - e=EdgeIt(*this); return e; } - OutEdgeIt& first(OutEdgeIt& e, const Node v) const { - e=OutEdgeIt(*this,v); return e; } - InEdgeIt& first(InEdgeIt& e, const Node v) const { - e=InEdgeIt(*this,v); return e; } - -// template< typename It > -// It first() const { It e; first(e); return e; } - -// template< typename It > -// It first(Node v) const { It e; first(e,v); return e; } - - bool valid(Edge e) const { return e.n!=-1; } - bool valid(Node n) const { return G.valid(n); } - - void setInvalid(Edge &e) { e.n=-1; } - void setInvalid(Node &n) { G.setInvalid(n); } - - template It getNext(It it) const - { It tmp(it); return next(tmp); } - - NodeIt& next(NodeIt& it) const { G.next(it); return it; } - OutEdgeIt& next(OutEdgeIt& it) const - { it.n=edges[it.n].next_out; return it; } - InEdgeIt& next(InEdgeIt& it) const - { it.n=edges[it.n].next_in; return it; } - EdgeIt& next(EdgeIt& it) const { - if(edges[it.n].next_in!=-1) { - it.n=edges[it.n].next_in; - } - else { - NodeIt n; - for(n=next(edges[it.n].head); - valid(n) && nodes[n].first_in == -1; - next(n)) ; - it.n = (valid(n))?-1:nodes[n].first_in; - } - return it; - } - - int id(Edge e) const { return e.n; } - - /// Adds a new node to the graph. - Node addNode() { return G.AddNode(); } - - Edge addEdge(Node u, Node v) { - int n; - - if(first_free_edge==-1) - { - n = edges.size(); - edges.push_back(EdgeT()); - } - else { - n = first_free_edge; - first_free_edge = edges[n].next_in; - } - - edges[n].tail = u; edges[n].head = v; - - edges[n].next_out = nodes[u].first_out; - if(nodes[u].first_out != -1) edges[nodes[u].first_out].prev_out = n; - edges[n].next_in = nodes[v].first_in; - if(nodes[v].first_in != -1) edges[nodes[v].first_in].prev_in = n; - edges[n].prev_in = edges[n].prev_out = -1; - - nodes[u].first_out = nodes[v].first_in = n; - - Edge e; e.n=n; - - //Update dynamic maps - for(typename std::vector * >::iterator - i=dyn_edge_maps.begin(); - i!=dyn_edge_maps.end(); ++i) (**i).add(e); - - return e; - } - - private: - void eraseEdge(int n) { - - if(edges[n].next_in!=-1) - edges[edges[n].next_in].prev_in = edges[n].prev_in; - if(edges[n].prev_in!=-1) - edges[edges[n].prev_in].next_in = edges[n].next_in; - else nodes[edges[n].head].first_in = edges[n].next_in; - - if(edges[n].next_out!=-1) - edges[edges[n].next_out].prev_out = edges[n].prev_out; - if(edges[n].prev_out!=-1) - edges[edges[n].prev_out].next_out = edges[n].next_out; - else nodes[edges[n].tail].first_out = edges[n].next_out; - - edges[n].next_in = first_free_edge; - first_free_edge = -1; - - //Update dynamic maps - Edge e; e.n=n; - for(typename std::vector * >::iterator - i=dyn_edge_maps.begin(); - i!=dyn_edge_maps.end(); ++i) (**i).erase(e); - } - - public: - -// void erase(Node nn) { -// int n=nn.n; -// int m; -// while((m=nodes[n].first_in)!=-1) eraseEdge(m); -// while((m=nodes[n].first_out)!=-1) eraseEdge(m); -// } - - void erase(Edge e) { eraseEdge(e.n); } - -// //\bug Dynamic maps must be updated! -// // -// void clear() { -// nodes.clear();edges.clear(); -// first_node=first_free_node=first_free_edge=-1; -// } - - class Edge { - friend class EdgeSet; - template friend class EdgeMap; - - //template friend class SymEdgeSet::SymEdgeMap; - //friend Edge SymEdgeSet::opposite(Edge) const; - - friend class Node; - friend class NodeIt; - protected: - int n; - friend int EdgeSet::id(Edge e) const; - - Edge(int nn) {n=nn;} - public: - Edge() { } - Edge (Invalid) { n=-1; } - bool operator==(const Edge i) const {return n==i.n;} - bool operator!=(const Edge i) const {return n!=i.n;} - bool operator<(const Edge i) const {return nn = G.valid(m)?-1:G.nodes[m].first_in; - } - EdgeIt (Invalid i) : Edge(i) { } - EdgeIt() : Edge() { } - ///\bug This is a workaround until somebody tells me how to - ///make class \c SymEdgeSet::SymEdgeMap friend of Edge - int &idref() {return this->n;} - }; - - class OutEdgeIt : public Edge { - friend class EdgeSet; - public: - OutEdgeIt() : Edge() { } - OutEdgeIt (Invalid i) : Edge(i) { } - - OutEdgeIt(const EdgeSet& G,const Node v) : Edge(nodes[v].first_out) { } - }; - - class InEdgeIt : public Edge { - friend class EdgeSet; - public: - InEdgeIt() : Edge() { } - InEdgeIt (Invalid i) : Edge(i) { } - InEdgeIt(const EdgeSet& G,Node v) :Edge(nodes[v].first_in) { } - }; - - template class NodeMap : - public NodeGraphType::template NodeMap - { - public: - NodeMap(const EdgeSet &_G) : - NodeGraphType::NodeMap(_G.G) { } //AJAJJ would be wrong!!! - NodeMap(const EdgeSet &_G,const T &t) : - NodeGraphType::NodeMap(_G.G,t) { } - //It is unnecessary - NodeMap(const typename NodeGraphType::template NodeMap &m) : - NodeGraphType::NodeMap(m) { } - - ///\todo It can copy between different types. - /// - template - NodeMap(const typename NodeGraphType::template NodeMap &m) - : NodeGraphType::NodeMap(m) { } - }; - - template class EdgeMap : public DynMapBase - { - std::vector container; - - public: - typedef T ValueType; - typedef Edge KeyType; - - EdgeMap(const EdgeSet &_G) : - DynMapBase(_G), container(_G.maxEdgeId()) - { - //FIXME: What if there are empty Id's? - //FIXME: Can I use 'this' in a constructor? - G->dyn_edge_maps.push_back(this); - } - EdgeMap(const EdgeSet &_G,const T &t) : - DynMapBase(_G), container(_G.maxEdgeId(),t) - { - G->dyn_edge_maps.push_back(this); - } - EdgeMap(const EdgeMap &m) : - DynMapBase(*m.G), container(m.container) - { - G->dyn_edge_maps.push_back(this); - } - - template friend class EdgeMap; - - ///\todo It can copy between different types. - /// - template EdgeMap(const EdgeMap &m) : - DynMapBase(*m.G) - { - G->dyn_edge_maps.push_back(this); - typename std::vector::const_iterator i; - for(typename std::vector::const_iterator i=m.container.begin(); - i!=m.container.end(); - i++) - container.push_back(*i); - } - ~EdgeMap() - { - if(G) { - typename std::vector* >::iterator i; - for(i=G->dyn_edge_maps.begin(); - i!=G->dyn_edge_maps.end() && *i!=this; ++i) ; - //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow... - //A better way to do that: (Is this really important?) - if(*i==this) { - *i=G->dyn_edge_maps.back(); - G->dyn_edge_maps.pop_back(); - } - } - } - - void add(const Edge k) - { - if(k.n>=int(container.size())) container.resize(k.n+1); - } - void erase(const Edge) { } - - void set(Edge n, T a) { container[n.n]=a; } - //T get(Edge n) const { return container[n.n]; } - typename std::vector::reference - operator[](Edge n) { return container[n.n]; } - typename std::vector::const_reference - operator[](Edge n) const { return container[n.n]; } - - ///\warning There is no safety check at all! - ///Using operator = between maps attached to different graph may - ///cause serious problem. - ///\todo Is this really so? - ///\todo It can copy between different types. - const EdgeMap& operator=(const EdgeMap &m) - { - container = m.container; - return *this; - } - template - const EdgeMap& operator=(const EdgeMap &m) - { - std::copy(m.container.begin(), m.container.end(), container.begin()); - return *this; - } - - void update() {} //Useless for DynMaps - void update(T a) {} //Useless for DynMaps - }; - - }; - - template< typename GG> - int EdgeSet::id(Node v) const { return G.id(v); } - -/// @} - -} //namespace hugo - -#endif //HUGO_LIST_GRAPH_H