diff -r bb77eaa8fa0e -r 6153d9cf78c6 src/hugo/list_graph.h --- a/src/hugo/list_graph.h Wed Sep 29 10:35:35 2004 +0000 +++ b/src/hugo/list_graph.h Wed Sep 29 14:02:14 2004 +0000 @@ -29,6 +29,8 @@ #include #include +#include + #include @@ -102,7 +104,6 @@ first_free_node(_g.first_free_node), edges(_g.edges), first_free_edge(_g.first_free_edge) {} - /// \bug In the vector can be hole if a node is erased from the graph. ///Number of nodes. int nodeNum() const { return nodes.size(); } ///Number of edges. @@ -437,7 +438,7 @@ /// ///\todo this date structure need some reconsiderations. Maybe it ///should be implemented independently from ListGraph. - /* + class SymListGraph : public ListGraph { public: @@ -482,402 +483,8 @@ ListGraph::erase(f); ListGraph::erase(e); } - };*/ + }; - class SymListGraph : public ListGraph { - typedef ListGraph Parent; - public: - - typedef SymListGraph Graph; - - typedef ListGraph::Node Node; - typedef ListGraph::NodeIt NodeIt; - - class SymEdge; - class SymEdgeIt; - - class Edge; - class EdgeIt; - class OutEdgeIt; - class InEdgeIt; - - template - class NodeMap : public Parent::NodeMap { - public: - NodeMap(const SymListGraph& g) - : SymListGraph::Parent::NodeMap(g) {} - NodeMap(const SymListGraph& g, Value v) - : SymListGraph::Parent::NodeMap(g, v) {} - template - NodeMap(const NodeMap& copy) - : SymListGraph::Parent::NodeMap(copy) { } - }; - - template - class SymEdgeMap : public Parent::EdgeMap { - public: - typedef SymEdge KeyType; - - SymEdgeMap(const SymListGraph& g) - : SymListGraph::Parent::EdgeMap(g) {} - SymEdgeMap(const SymListGraph& g, Value v) - : SymListGraph::Parent::EdgeMap(g, v) {} - template - SymEdgeMap(const SymEdgeMap& copy) - : SymListGraph::Parent::EdgeMap(copy) { } - - }; - - // Create edge map registry. - CREATE_EDGE_MAP_REGISTRY; - // Create edge maps. - CREATE_EDGE_MAP(ArrayMap); - - class Edge { - friend class SymListGraph; - friend class SymListGraph::EdgeIt; - friend class SymListGraph::OutEdgeIt; - friend class SymListGraph::InEdgeIt; - - protected: - int id; - - Edge(int pid) { id = pid; } - - public: - /// An Edge with id \c n. - - Edge() { } - Edge (Invalid) { id = -1; } - - operator SymEdge(){ return SymEdge(id >> 1);} - - bool operator==(const Edge i) const {return id == i.id;} - bool operator!=(const Edge i) const {return id != i.id;} - bool operator<(const Edge i) const {return id < i.id;} - // ///Validity check - // operator bool() { return n!=-1; } - }; - - class SymEdge : public ListGraph::Edge { - friend class SymListGraph; - friend class SymListGraph::Edge; - typedef ListGraph::Edge Parent; - - protected: - SymEdge(int pid) : Parent(pid) {} - public: - - SymEdge() { } - SymEdge(const ListGraph::Edge& i) : Parent(i) {} - SymEdge (Invalid) : Parent(INVALID) {} - - }; - - class OutEdgeIt { - Parent::OutEdgeIt out; - Parent::InEdgeIt in; - public: - OutEdgeIt() {} - OutEdgeIt(const SymListGraph& g, Edge e) { - if ((e.id & 1) == 0) { - out = Parent::OutEdgeIt(g, SymEdge(e)); - in = Parent::InEdgeIt(g, g.tail(e)); - } else { - out = Parent::OutEdgeIt(INVALID); - in = Parent::InEdgeIt(g, SymEdge(e)); - } - } - OutEdgeIt (Invalid i) : out(INVALID), in(INVALID) { } - - OutEdgeIt(const SymListGraph& g, const Node v) - : out(g, v), in(g, v) {} - OutEdgeIt &operator++() { - if (out != INVALID) { - ++out; - } else { - ++in; - } - return *this; - } - - operator Edge() const { - if (out == INVALID && in == INVALID) return INVALID; - return out != INVALID ? forward(out) : backward(in); - } - - bool operator==(const Edge i) const {return Edge(*this) == i;} - bool operator!=(const Edge i) const {return Edge(*this) != i;} - bool operator<(const Edge i) const {return Edge(*this) < i;} - }; - - class InEdgeIt { - Parent::OutEdgeIt out; - Parent::InEdgeIt in; - public: - InEdgeIt() {} - InEdgeIt(const SymListGraph& g, Edge e) { - if ((e.id & 1) == 0) { - out = Parent::OutEdgeIt(g, SymEdge(e)); - in = Parent::InEdgeIt(g, g.tail(e)); - } else { - out = Parent::OutEdgeIt(INVALID); - in = Parent::InEdgeIt(g, SymEdge(e)); - } - } - InEdgeIt (Invalid i) : out(INVALID), in(INVALID) { } - - InEdgeIt(const SymListGraph& g, const Node v) - : out(g, v), in(g, v) {} - - InEdgeIt &operator++() { - if (out != INVALID) { - ++out; - } else { - ++in; - } - return *this; - } - - operator Edge() const { - if (out == INVALID && in == INVALID) return INVALID; - return out != INVALID ? backward(out) : forward(in); - } - - bool operator==(const Edge i) const {return Edge(*this) == i;} - bool operator!=(const Edge i) const {return Edge(*this) != i;} - bool operator<(const Edge i) const {return Edge(*this) < i;} - }; - - class SymEdgeIt : public Parent::EdgeIt { - - public: - SymEdgeIt() {} - - SymEdgeIt(const SymListGraph& g) - : SymListGraph::Parent::EdgeIt(g) {} - - SymEdgeIt(const SymListGraph& g, SymEdge e) - : SymListGraph::Parent::EdgeIt(g, e) {} - - SymEdgeIt(Invalid i) - : SymListGraph::Parent::EdgeIt(INVALID) {} - - SymEdgeIt& operator++() { - SymListGraph::Parent::EdgeIt::operator++(); - return *this; - } - - operator SymEdge() const { - return SymEdge - (static_cast(*this)); - } - bool operator==(const SymEdge i) const {return SymEdge(*this) == i;} - bool operator!=(const SymEdge i) const {return SymEdge(*this) != i;} - bool operator<(const SymEdge i) const {return SymEdge(*this) < i;} - }; - - class EdgeIt { - SymEdgeIt it; - bool fw; - public: - EdgeIt(const SymListGraph& g) : it(g), fw(true) {} - EdgeIt (Invalid i) : it(i) { } - EdgeIt(const SymListGraph& g, Edge e) - : it(g, SymEdge(e)), fw(id(e) & 1 == 0) { } - EdgeIt() { } - EdgeIt& operator++() { - fw = !fw; - if (fw) ++it; - return *this; - } - operator Edge() const { - if (it == INVALID) return INVALID; - return fw ? forward(it) : backward(it); - } - bool operator==(const Edge i) const {return Edge(*this) == i;} - bool operator!=(const Edge i) const {return Edge(*this) != i;} - bool operator<(const Edge i) const {return Edge(*this) < i;} - - }; - - ///Number of nodes. - int nodeNum() const { return Parent::nodeNum(); } - ///Number of edges. - int edgeNum() const { return 2*Parent::edgeNum(); } - ///Number of symmetric edges. - int symEdgeNum() const { return Parent::edgeNum(); } - - ///Set the expected maximum number of edges. - - ///With this function, it is possible to set the expected number of edges. - ///The use of this fasten the building of the graph and makes - ///it possible to avoid the superfluous memory allocation. - void reserveSymEdge(int n) { Parent::reserveEdge(n); }; - - /// Maximum node ID. - - /// Maximum node ID. - ///\sa id(Node) - int maxNodeId() const { return Parent::maxNodeId(); } - /// Maximum edge ID. - - /// Maximum edge ID. - ///\sa id(Edge) - int maxEdgeId() const { return 2*Parent::maxEdgeId(); } - /// Maximum symmetric edge ID. - - /// Maximum symmetric edge ID. - ///\sa id(SymEdge) - int maxSymEdgeId() const { return Parent::maxEdgeId(); } - - - Node tail(Edge e) const { - return (e.id & 1) == 0 ? - Parent::tail(SymEdge(e)) : Parent::head(SymEdge(e)); - } - - Node head(Edge e) const { - return (e.id & 1) == 0 ? - Parent::head(SymEdge(e)) : Parent::tail(SymEdge(e)); - } - - Node tail(SymEdge e) const { - return Parent::tail(e); - } - - Node head(SymEdge e) const { - return Parent::head(e); - } - - NodeIt& first(NodeIt& v) const { - v=NodeIt(*this); return v; } - EdgeIt& first(EdgeIt& e) const { - e=EdgeIt(*this); return e; } - SymEdgeIt& first(SymEdgeIt& e) const { - e=SymEdgeIt(*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; } - - /// Node ID. - - /// The ID of a valid Node is a nonnegative integer not greater than - /// \ref maxNodeId(). The range of the ID's is not surely continuous - /// and the greatest node ID can be actually less then \ref maxNodeId(). - /// - /// The ID of the \ref INVALID node is -1. - ///\return The ID of the node \c v. - static int id(Node v) { return Parent::id(v); } - /// Edge ID. - - /// The ID of a valid Edge is a nonnegative integer not greater than - /// \ref maxEdgeId(). The range of the ID's is not surely continuous - /// and the greatest edge ID can be actually less then \ref maxEdgeId(). - /// - /// The ID of the \ref INVALID edge is -1. - ///\return The ID of the edge \c e. - static int id(Edge e) { return e.id; } - - /// The ID of a valid SymEdge is a nonnegative integer not greater than - /// \ref maxSymEdgeId(). The range of the ID's is not surely continuous - /// and the greatest edge ID can be actually less then \ref maxSymEdgeId(). - /// - /// The ID of the \ref INVALID symmetric edge is -1. - ///\return The ID of the edge \c e. - static int id(SymEdge e) { return Parent::id(e); } - - /// Adds a new node to the graph. - - /// \warning It adds the new node to the front of the list. - /// (i.e. the lastly added node becomes the first.) - Node addNode() { - return Parent::addNode(); - } - - SymEdge addEdge(Node u, Node v) { - SymEdge se = Parent::addEdge(u, v); - edge_maps.add(forward(se)); - edge_maps.add(backward(se)); - return se; - } - - /// Finds an edge between two nodes. - - /// Finds an edge from node \c u to node \c v. - /// - /// If \c prev is \ref INVALID (this is the default value), then - /// It finds the first edge from \c u to \c v. Otherwise it looks for - /// the next edge from \c u to \c v after \c prev. - /// \return The found edge or INVALID if there is no such an edge. - Edge findEdge(Node u, Node v, Edge prev = INVALID) - { - if (prev == INVALID || id(prev) & 1 == 0) { - SymEdge se = Parent::findEdge(u, v, SymEdge(prev)); - if (se != INVALID) return forward(se); - } else { - SymEdge se = Parent::findEdge(v, u, SymEdge(prev)); - if (se != INVALID) return backward(se); - } - return INVALID; - } - -// /// Finds an symmetric edge between two nodes. - -// /// Finds an symmetric edge from node \c u to node \c v. -// /// -// /// If \c prev is \ref INVALID (this is the default value), then -// /// It finds the first edge from \c u to \c v. Otherwise it looks for -// /// the next edge from \c u to \c v after \c prev. -// /// \return The found edge or INVALID if there is no such an edge. - -// SymEdge findEdge(Node u, Node v, SymEdge prev = INVALID) -// { -// if (prev == INVALID || id(prev) & 1 == 0) { -// SymEdge se = Parent::findEdge(u, v, SymEdge(prev)); -// if (se != INVALID) return se; -// } else { -// SymEdge se = Parent::findEdge(v, u, SymEdge(prev)); -// if (se != INVALID) return se; -// } -// return INVALID; -// } - - public: - - void erase(Node n) { - for (OutEdgeIt it(*this, n); it != INVALID; ++it) { - edge_maps.erase(it); - edge_maps.erase(opposite(it)); - } - Parent::erase(n); - } - - void erase(SymEdge e) { - edge_maps.erase(forward(e)); - edge_maps.erase(backward(e)); - Parent::erase(e); - }; - - void clear() { - edge_maps.clear(); - Parent::clear(); - } - - static Edge opposite(Edge e) { - return Edge(id(e) ^ 1); - } - - static Edge forward(SymEdge e) { - return Edge(id(e) << 1); - } - - static Edge backward(SymEdge e) { - return Edge((id(e) << 1) | 1); - } - - }; ///A graph class containing only nodes.