alpar@105: // -*- mode:C++ -*- alpar@105: alpar@104: #ifndef SMART_GRAPH_H alpar@104: #define SMART_GRAPH_H alpar@104: alpar@104: #include alpar@104: #include alpar@104: alpar@105: namespace hugo { alpar@104: alpar@104: class SmartGraph { alpar@104: alpar@104: static const int INVALID=-1; alpar@104: alpar@104: struct NodeT alpar@104: { alpar@104: int first_in,first_out; alpar@104: NodeT() : first_in(INVALID), first_out(INVALID) {} alpar@104: }; alpar@104: struct EdgeT alpar@104: { alpar@104: int head, tail, next_in, next_out; alpar@104: //FIXME: is this necessary? alpar@104: EdgeT() : next_in(INVALID), next_out(INVALID) {} alpar@104: }; alpar@104: alpar@104: std::vector nodes; 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@108: DynMapBase(SmartGraph &_G) : G(&_G) {} alpar@108: virtual ~DynMapBase() {} alpar@108: friend class SmartGraph; alpar@108: }; alpar@104: alpar@104: public: alpar@108: template class DynEdgeMap; alpar@108: template class DynEdgeMap; alpar@104: alpar@104: class NodeIt; alpar@108: class EdgeIt; alpar@108: alpar@108: protected: alpar@108: std::vector * > dyn_node_maps; alpar@108: std::vector * > dyn_edge_maps; alpar@108: alpar@108: public: alpar@108: alpar@104: class EachNodeIt; alpar@104: class EachEdgeIt; alpar@104: class OutEdgeIt; alpar@104: class InEdgeIt; alpar@104: alpar@105: // class NodeIt { int n; }; alpar@105: // class EachNodeIt : public NodeIt { }; alpar@105: // class EdgeIt { int n; }; alpar@105: // class EachEdgeIt : public EdgeIt {}; alpar@105: // class OutEdgeIt : public EdgeIt {}; alpar@105: // class InEdgeIt : public EdgeIt {}; alpar@104: // class SymEdgeIt; 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@104: alpar@108: ~SmartGraph() alpar@108: { alpar@108: for(std::vector * >::iterator i=dyn_node_maps.begin(); alpar@108: i!=dyn_node_maps.end(); ++i) (**i).G=NULL; alpar@108: 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@104: NodeIt tail(EdgeIt e) const { return edges[e.n].tail; } alpar@104: NodeIt head(EdgeIt e) const { return edges[e.n].head; } alpar@104: alpar@104: NodeIt aNode(const OutEdgeIt& e) const { return tail(e); } alpar@104: NodeIt aNode(const InEdgeIt& e) const { return head(e); } alpar@104: //NodeIt aNode(const SymEdgeIt& e) const { return e.aNode(); } alpar@104: alpar@104: NodeIt bNode(const OutEdgeIt& e) const { return head(e); } alpar@104: NodeIt bNode(const InEdgeIt& e) const { return tail(e); } alpar@104: //NodeIt bNode(const SymEdgeIt& e) const { return e.bNode(); } alpar@104: alpar@104: EachNodeIt& getFirst(EachNodeIt& v) const { alpar@104: v=EachNodeIt(*this); return v; } alpar@104: EachEdgeIt& getFirst(EachEdgeIt& e) const { alpar@104: e=EachEdgeIt(*this); return e; } alpar@104: OutEdgeIt& getFirst(OutEdgeIt& e, const NodeIt v) const { alpar@104: e=OutEdgeIt(*this,v); return e; } alpar@104: InEdgeIt& getFirst(InEdgeIt& e, const NodeIt v) const { alpar@104: e=InEdgeIt(*this,v); return e; } alpar@104: alpar@104: template< typename It > alpar@104: It first() const { alpar@104: It e; alpar@104: getFirst(e); alpar@104: return e; alpar@104: } alpar@104: alpar@104: template< typename It > alpar@104: It first(NodeIt v) const { alpar@104: It e; alpar@104: getFirst(e, v); alpar@104: return e; alpar@104: } alpar@104: alpar@104: bool valid(EdgeIt e) const { return e.n!=INVALID; } alpar@104: bool valid(EachEdgeIt e) const { return e.n It next(It it) const alpar@105: // { It tmp(it); return goNext(tmp); } alpar@105: { It tmp; tmp.n=it.n+1; return tmp; } alpar@104: alpar@104: NodeIt& goNext(NodeIt& it) const { ++it.n; return it; } alpar@104: OutEdgeIt& goNext(OutEdgeIt& it) const alpar@104: { it.n=edges[it.n].next_out; return it; } alpar@104: InEdgeIt& goNext(InEdgeIt& it) const alpar@104: { it.n=edges[it.n].next_in; return it; } alpar@104: EachEdgeIt& goNext(EachEdgeIt& it) const { ++it.n; return it; } alpar@104: alpar@104: int id(NodeIt v) const { return v.n; } alpar@104: int id(EdgeIt e) const { return e.n; } alpar@104: alpar@104: NodeIt addNode() { alpar@104: NodeIt n; n.n=nodes.size(); alpar@104: nodes.push_back(NodeT()); //FIXME: Hmmm... alpar@108: alpar@108: 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@104: EdgeIt addEdge(NodeIt u, NodeIt v) { alpar@104: EdgeIt 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@108: for(std::vector * >::iterator i=dyn_edge_maps.begin(); alpar@108: i!=dyn_edge_maps.end(); ++i) (**i).add(e.n); alpar@108: alpar@104: return e; alpar@104: } alpar@104: alpar@104: void clear() {nodes.clear();edges.clear();} alpar@104: alpar@104: class NodeIt { alpar@104: friend class SmartGraph; alpar@104: template friend class NodeMap; alpar@108: template friend class DynNodeMap; alpar@104: alpar@104: friend class EdgeIt; alpar@104: friend class OutEdgeIt; alpar@104: friend class InEdgeIt; alpar@104: friend class SymEdgeIt; alpar@104: alpar@104: protected: alpar@104: int n; alpar@104: friend int SmartGraph::id(NodeIt v) const; alpar@104: public: alpar@104: NodeIt() {} alpar@104: NodeIt(int nn) {n=nn;} alpar@104: bool operator==(const NodeIt i) const {return n==i.n;} alpar@104: bool operator!=(const NodeIt i) const {return n!=i.n;} alpar@104: }; alpar@104: alpar@104: class EachNodeIt : public NodeIt { alpar@104: friend class SmartGraph; alpar@104: public: alpar@104: EachNodeIt(const SmartGraph& G) : NodeIt(0) { } alpar@104: EachNodeIt() : NodeIt() { } alpar@104: }; alpar@104: alpar@104: class EdgeIt { alpar@104: friend class SmartGraph; alpar@104: template friend class EdgeMap; alpar@108: template friend class DynEdgeMap; alpar@104: alpar@104: friend class NodeIt; alpar@104: friend class EachNodeIt; alpar@104: protected: alpar@104: int n; alpar@104: friend int SmartGraph::id(EdgeIt e) const; alpar@104: public: alpar@104: EdgeIt() { } alpar@104: EdgeIt(int nn) {n=nn;} alpar@104: bool operator==(const EdgeIt i) const {return n==i.n;} alpar@104: bool operator!=(const EdgeIt i) const {return n!=i.n;} alpar@104: }; alpar@104: alpar@104: class EachEdgeIt : public EdgeIt { alpar@104: friend class SmartGraph; alpar@104: public: alpar@104: EachEdgeIt(const SmartGraph& G) : EdgeIt(0) { } alpar@104: EachEdgeIt() : EdgeIt() { } alpar@104: }; alpar@104: alpar@104: class OutEdgeIt : public EdgeIt { alpar@104: friend class SmartGraph; alpar@104: public: alpar@104: OutEdgeIt() : EdgeIt() { } alpar@104: OutEdgeIt(const SmartGraph& G,const NodeIt v) alpar@104: : EdgeIt(G.nodes[v.n].first_out) {} alpar@104: }; alpar@104: alpar@104: class InEdgeIt : public EdgeIt { alpar@104: friend class SmartGraph; alpar@104: public: alpar@104: InEdgeIt() : EdgeIt() { } alpar@104: InEdgeIt(const SmartGraph& G,NodeIt v) :EdgeIt(G.nodes[v.n].first_in){} alpar@104: }; alpar@105: alpar@105: // Map types alpar@105: alpar@105: template alpar@105: class NodeMap { alpar@105: const SmartGraph& G; alpar@105: std::vector container; alpar@105: public: alpar@105: typedef T ValueType; alpar@105: typedef NodeIt 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@105: void set(NodeIt n, T a) { container[n.n]=a; } alpar@105: T get(NodeIt n) const { return container[n.n]; } alpar@105: T& operator[](NodeIt n) { return container[n.n]; } alpar@105: const T& operator[](NodeIt 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@105: typedef EdgeIt 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@105: void set(EdgeIt e, T a) { container[e.n]=a; } alpar@105: T get(EdgeIt e) const { return container[e.n]; } alpar@105: T& operator[](EdgeIt e) { return container[e.n]; } alpar@105: const T& operator[](EdgeIt 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@108: template class DynNodeMap : public DynMapBase alpar@108: { alpar@108: std::vector container; alpar@105: alpar@108: public: alpar@108: typedef T ValueType; alpar@108: typedef NodeIt KeyType; alpar@105: alpar@108: DynNodeMap(SmartGraph &_G) : alpar@108: 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@108: 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@108: void add(const NodeIt k) alpar@108: { alpar@108: if(k.n>=container.size()) container.resize(k.n+1); alpar@108: } alpar@108: void erase(const NodeIt k) alpar@108: { alpar@108: //FIXME: Please implement me. alpar@108: } alpar@108: alpar@108: void set(NodeIt n, T a) { container[n.n]=a; } alpar@108: T get(NodeIt n) const { return container[n.n]; } alpar@108: T& operator[](NodeIt n) { return container[n.n]; } alpar@108: const T& operator[](NodeIt 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@108: template class DynEdgeMap : public DynMapBase alpar@108: { alpar@108: std::vector container; alpar@108: alpar@108: public: alpar@108: typedef T ValueType; alpar@108: typedef EdgeIt KeyType; alpar@108: alpar@108: DynEdgeMap(SmartGraph &_G) : alpar@108: 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@108: 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@108: void add(const EdgeIt k) alpar@108: { alpar@108: if(k.n>=int(container.size())) container.resize(k.n+1); alpar@108: } alpar@108: void erase(const EdgeIt k) alpar@108: { alpar@108: //FIXME: Please implement me. alpar@108: } alpar@108: alpar@108: void set(EdgeIt n, T a) { container[n.n]=a; } alpar@108: T get(EdgeIt n) const { return container[n.n]; } alpar@108: T& operator[](EdgeIt n) { return container[n.n]; } alpar@108: const T& operator[](EdgeIt 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@104: #endif //SMART_GRAPH_H