alpar@105: // -*- mode:C++ -*- alpar@105: alpar@104: #ifndef SMART_GRAPH_H alpar@104: #define SMART_GRAPH_H alpar@104: alpar@104: #include alpar@129: #include alpar@104: alpar@164: #include alpar@157: alpar@105: namespace hugo { alpar@104: alpar@104: class SmartGraph { alpar@104: alpar@104: struct NodeT alpar@104: { alpar@104: int first_in,first_out; alpar@157: NodeT() : first_in(-1), first_out(-1) {} alpar@104: }; alpar@104: struct EdgeT alpar@104: { alpar@104: int head, tail, next_in, next_out; alpar@104: //FIXME: is this necessary? alpar@157: EdgeT() : next_in(-1), next_out(-1) {} alpar@104: }; alpar@104: alpar@104: std::vector nodes; alpar@129: alpar@104: std::vector edges; alpar@104: alpar@108: template class DynMapBase alpar@108: { alpar@108: protected: alpar@108: SmartGraph* G; alpar@108: public: alpar@108: virtual void add(const Key k) = NULL; alpar@108: virtual void erase(const Key k) = NULL; alpar@157: DynMapBase(const SmartGraph &_G) : G(&_G) {} alpar@108: virtual ~DynMapBase() {} alpar@108: friend class SmartGraph; alpar@108: }; alpar@104: public: alpar@108: template class DynEdgeMap; alpar@108: template class DynEdgeMap; alpar@104: alpar@164: class Node; alpar@164: class Edge; alpar@108: alpar@108: protected: alpar@164: mutable std::vector * > dyn_node_maps; alpar@164: mutable std::vector * > dyn_edge_maps; alpar@108: alpar@108: public: alpar@108: alpar@164: class NodeIt; alpar@164: class EdgeIt; alpar@104: class OutEdgeIt; alpar@104: class InEdgeIt; alpar@104: alpar@164: // class Node { int n; }; alpar@164: // class NodeIt : public Node { }; alpar@164: // class Edge { int n; }; alpar@164: // class EdgeIt : public Edge {}; alpar@164: // class OutEdgeIt : public Edge {}; alpar@164: // class InEdgeIt : public Edge {}; alpar@164: // class SymEdge; alpar@105: alpar@105: template class NodeMap; alpar@104: template class EdgeMap; alpar@104: alpar@104: public: alpar@104: alpar@104: /* default constructor */ alpar@104: alpar@104: SmartGraph() : nodes(), edges() { } alpar@136: SmartGraph(const SmartGraph &_g) : nodes(_g.nodes), edges(_g.edges) { } alpar@104: alpar@108: ~SmartGraph() alpar@108: { alpar@164: for(std::vector * >::iterator i=dyn_node_maps.begin(); alpar@108: i!=dyn_node_maps.end(); ++i) (**i).G=NULL; alpar@164: for(std::vector * >::iterator i=dyn_edge_maps.begin(); alpar@108: i!=dyn_edge_maps.end(); ++i) (**i).G=NULL; alpar@108: } alpar@104: alpar@104: int nodeNum() const { return nodes.size(); } //FIXME: What is this? alpar@104: int edgeNum() const { return edges.size(); } //FIXME: What is this? alpar@104: alpar@108: int maxNodeId() const { return nodes.size(); } //FIXME: What is this? alpar@108: int maxEdgeId() const { return edges.size(); } //FIXME: What is this? alpar@108: alpar@108: alpar@164: Node tail(Edge e) const { return edges[e.n].tail; } alpar@164: Node head(Edge e) const { return edges[e.n].head; } alpar@104: marci@174: // Marci marci@174: Node aNode(OutEdgeIt e) const { return edges[e.n].tail; } marci@174: Node aNode(InEdgeIt e) const { return edges[e.n].head; } alpar@164: // //Node aNode(const SymEdge& e) const { return e.aNode(); } alpar@104: marci@174: // Marci marci@174: Node bNode(OutEdgeIt e) const { return edges[e.n].head; } marci@174: Node bNode(InEdgeIt e) const { return edges[e.n].tail; } alpar@164: // //Node bNode(const SymEdge& e) const { return e.bNode(); } alpar@104: alpar@164: NodeIt& first(NodeIt& v) const { alpar@164: v=NodeIt(*this); return v; } alpar@164: EdgeIt& first(EdgeIt& e) const { alpar@164: e=EdgeIt(*this); return e; } alpar@164: OutEdgeIt& first(OutEdgeIt& e, const Node v) const { alpar@104: e=OutEdgeIt(*this,v); return e; } alpar@164: InEdgeIt& first(InEdgeIt& e, const Node v) const { alpar@104: e=InEdgeIt(*this,v); return e; } alpar@104: alpar@104: template< typename It > alpar@177: It first() const { It e; first(e); return e; } alpar@104: alpar@104: template< typename It > alpar@177: It first(Node v) const { It e; first(e,v); return e; } alpar@104: alpar@164: bool valid(Edge e) const { return e.n!=-1; } alpar@164: bool valid(Node n) const { return n.n!=-1; } alpar@104: alpar@164: void setInvalid(Edge &e) { e.n=-1; } alpar@164: void setInvalid(Node &n) { n.n=-1; } alpar@129: alpar@157: template It getNext(It it) const alpar@157: { It tmp(it); return next(tmp); } alpar@104: marci@174: NodeIt& next(NodeIt& it) const { marci@174: it.n=(it.n+2)%(nodes.size()+1)-1; marci@174: return it; marci@174: } alpar@157: OutEdgeIt& next(OutEdgeIt& it) const alpar@104: { it.n=edges[it.n].next_out; return it; } alpar@157: InEdgeIt& next(InEdgeIt& it) const alpar@104: { it.n=edges[it.n].next_in; return it; } alpar@164: EdgeIt& next(EdgeIt& it) const { --it.n; return it; } alpar@104: alpar@164: int id(Node v) const { return v.n; } alpar@164: int id(Edge e) const { return e.n; } alpar@104: alpar@164: Node addNode() { alpar@164: Node n; n.n=nodes.size(); alpar@104: nodes.push_back(NodeT()); //FIXME: Hmmm... alpar@108: alpar@164: for(std::vector * >::iterator i=dyn_node_maps.begin(); alpar@108: i!=dyn_node_maps.end(); ++i) (**i).add(n.n); alpar@108: alpar@104: return n; alpar@104: } alpar@108: alpar@164: Edge addEdge(Node u, Node v) { alpar@164: Edge e; e.n=edges.size(); edges.push_back(EdgeT()); //FIXME: Hmmm... alpar@104: edges[e.n].tail=u.n; edges[e.n].head=v.n; alpar@104: edges[e.n].next_out=nodes[u.n].first_out; alpar@104: edges[e.n].next_in=nodes[v.n].first_in; alpar@104: nodes[u.n].first_out=nodes[v.n].first_in=e.n; alpar@108: alpar@164: for(std::vector * >::iterator i=dyn_edge_maps.begin(); alpar@157: i!=dyn_edge_maps.end(); ++i) (**i).add(e); alpar@108: alpar@104: return e; alpar@104: } alpar@104: alpar@104: void clear() {nodes.clear();edges.clear();} alpar@104: alpar@164: class Node { alpar@104: friend class SmartGraph; alpar@104: template friend class NodeMap; alpar@108: template friend class DynNodeMap; alpar@104: alpar@164: friend class Edge; alpar@104: friend class OutEdgeIt; alpar@104: friend class InEdgeIt; alpar@164: friend class SymEdge; alpar@104: alpar@104: protected: alpar@104: int n; alpar@164: friend int SmartGraph::id(Node v) const; alpar@164: Node(int nn) {n=nn;} alpar@104: public: alpar@164: Node() {} alpar@164: Node (Invalid i) { n=-1; } alpar@164: bool operator==(const Node i) const {return n==i.n;} alpar@164: bool operator!=(const Node i) const {return n!=i.n;} alpar@164: bool operator<(const Node i) const {return n friend class EdgeMap; alpar@108: template friend class DynEdgeMap; alpar@104: alpar@164: friend class Node; alpar@104: friend class NodeIt; alpar@104: protected: alpar@104: int n; alpar@164: friend int SmartGraph::id(Edge e) const; alpar@157: alpar@164: Edge(int nn) {n=nn;} alpar@104: public: alpar@164: Edge() { } marci@174: Edge (Invalid) { n=-1; } alpar@164: bool operator==(const Edge i) const {return n==i.n;} alpar@164: bool operator!=(const Edge i) const {return n!=i.n;} alpar@164: bool operator<(const Edge i) const {return n alpar@105: class NodeMap { alpar@105: const SmartGraph& G; alpar@105: std::vector container; alpar@105: public: alpar@105: typedef T ValueType; alpar@164: typedef Node KeyType; alpar@108: NodeMap(const SmartGraph& _G) : G(_G), container(G.maxNodeId()) { } alpar@105: NodeMap(const SmartGraph& _G, T a) : alpar@108: G(_G), container(G.maxNodeId(), a) { } alpar@164: void set(Node n, T a) { container[n.n]=a; } alpar@164: T get(Node n) const { return container[n.n]; } alpar@164: T& operator[](Node n) { return container[n.n]; } alpar@164: const T& operator[](Node n) const { return container[n.n]; } alpar@108: void update() { container.resize(G.maxNodeId()); } alpar@108: void update(T a) { container.resize(G.maxNodeId(), a); } alpar@105: }; alpar@105: alpar@105: template alpar@105: class EdgeMap { alpar@105: const SmartGraph& G; alpar@105: std::vector container; alpar@105: public: alpar@105: typedef T ValueType; alpar@164: typedef Edge KeyType; alpar@108: EdgeMap(const SmartGraph& _G) : G(_G), container(G.maxEdgeId()) { } alpar@105: EdgeMap(const SmartGraph& _G, T a) : alpar@108: G(_G), container(G.maxEdgeId(), a) { } alpar@164: void set(Edge e, T a) { container[e.n]=a; } alpar@164: T get(Edge e) const { return container[e.n]; } alpar@164: T& operator[](Edge e) { return container[e.n]; } alpar@164: const T& operator[](Edge e) const { return container[e.n]; } alpar@108: void update() { container.resize(G.maxEdgeId()); } alpar@108: void update(T a) { container.resize(G.maxEdgeId(), a); } alpar@105: }; alpar@105: alpar@164: template class DynNodeMap : public DynMapBase alpar@108: { alpar@108: std::vector container; alpar@105: alpar@108: public: alpar@108: typedef T ValueType; alpar@164: typedef Node KeyType; alpar@105: alpar@157: DynNodeMap(const SmartGraph &_G) : alpar@164: DynMapBase(_G), container(_G.maxNodeId()) alpar@108: { alpar@108: //FIXME: What if there are empty Id's? alpar@115: //FIXME: Can I use 'this' in a constructor? alpar@108: G->dyn_node_maps.push_back(this); alpar@108: } alpar@108: ~DynNodeMap() alpar@108: { alpar@108: if(G) { alpar@164: std::vector* >::iterator i; alpar@108: for(i=G->dyn_node_maps.begin(); alpar@108: i!=G->dyn_node_maps.end() && *i!=this; ++i) ; alpar@115: //if(*i==this) G->dyn_node_maps.erase(i); //FIXME: Way too slow... alpar@115: //A better way to do that: (Is this really important?) alpar@115: if(*i==this) { alpar@116: *i=G->dyn_node_maps.back(); alpar@115: G->dyn_node_maps.pop_back(); alpar@115: } alpar@108: } alpar@108: } alpar@105: alpar@164: void add(const Node k) alpar@108: { alpar@108: if(k.n>=container.size()) container.resize(k.n+1); alpar@108: } alpar@177: alpar@164: // void erase(const Node k) alpar@157: // { alpar@157: // //FIXME: Please implement me. alpar@157: // } alpar@164: // void erase(const Edge k) alpar@157: // { alpar@157: // //FIXME: Please implement me. alpar@157: // } alpar@108: alpar@164: void set(Node n, T a) { container[n.n]=a; } alpar@164: T get(Node n) const { return container[n.n]; } alpar@164: T& operator[](Node n) { return container[n.n]; } alpar@164: const T& operator[](Node n) const { return container[n.n]; } alpar@108: alpar@108: void update() {} //Useless for DynMaps alpar@108: void update(T a) {} //Useless for DynMaps alpar@108: }; alpar@108: alpar@164: template class DynEdgeMap : public DynMapBase alpar@108: { alpar@108: std::vector container; alpar@108: alpar@108: public: alpar@108: typedef T ValueType; alpar@164: typedef Edge KeyType; alpar@108: alpar@157: DynEdgeMap(const SmartGraph &_G) : alpar@164: DynMapBase(_G), container(_G.maxEdgeId()) alpar@108: { alpar@108: //FIXME: What if there are empty Id's? alpar@115: //FIXME: Can I use 'this' in a constructor? alpar@108: G->dyn_edge_maps.push_back(this); alpar@108: } alpar@108: ~DynEdgeMap() alpar@108: { alpar@108: if(G) { alpar@164: std::vector* >::iterator i; alpar@108: for(i=G->dyn_edge_maps.begin(); alpar@108: i!=G->dyn_edge_maps.end() && *i!=this; ++i) ; alpar@115: //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow... alpar@115: //A better way to do that: (Is this really important?) alpar@115: if(*i==this) { alpar@116: *i=G->dyn_edge_maps.back(); alpar@115: G->dyn_edge_maps.pop_back(); alpar@115: } alpar@108: } alpar@108: } alpar@115: alpar@164: void add(const Edge k) alpar@108: { alpar@108: if(k.n>=int(container.size())) container.resize(k.n+1); alpar@108: } alpar@164: void erase(const Edge k) alpar@108: { alpar@108: //FIXME: Please implement me. alpar@108: } alpar@108: alpar@164: void set(Edge n, T a) { container[n.n]=a; } alpar@164: T get(Edge n) const { return container[n.n]; } alpar@164: T& operator[](Edge n) { return container[n.n]; } alpar@164: const T& operator[](Edge n) const { return container[n.n]; } alpar@108: alpar@108: void update() {} //Useless for DynMaps alpar@108: void update(T a) {} //Useless for DynMaps alpar@108: }; alpar@108: alpar@104: }; alpar@105: } //namespace hugo alpar@104: alpar@157: alpar@157: alpar@157: alpar@104: #endif //SMART_GRAPH_H