diff -r 2d6c8075d9d0 -r 818510fa3d99 src/hugo/smart_graph.h --- a/src/hugo/smart_graph.h Wed Sep 29 14:12:26 2004 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,364 +0,0 @@ -/* -*- C++ -*- - * src/hugo/smart_graph.h - Part of HUGOlib, a generic C++ optimization library - * - * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport - * (Egervary Combinatorial Optimization Research Group, EGRES). - * - * Permission to use, modify and distribute this software is granted - * provided that this copyright notice appears in all copies. For - * precise terms see the accompanying LICENSE file. - * - * This software is provided "AS IS" with no warranty of any kind, - * express or implied, and with no claim as to its suitability for any - * purpose. - * - */ - -#ifndef HUGO_SMART_GRAPH_H -#define HUGO_SMART_GRAPH_H - -///\ingroup graphs -///\file -///\brief SmartGraph and SymSmartGraph classes. - -#include -#include - -#include - -#include -#include - -#include - -#include - -namespace hugo { - -/// \addtogroup graphs -/// @{ -// class SymSmartGraph; - - ///A smart graph class. - - ///This is a simple and fast graph implementation. - ///It is also quite memory efficient, but at the price - ///that it does not support node and edge deletion. - ///It conforms to - ///the \ref skeleton::ExtendableGraph "ExtendableGraph" concept. - ///\sa skeleton::ExtendableGraph. - /// - ///\todo Some member functions could be \c static. - /// - ///\todo A possibly useful functionality: a function saveState() would - ///give back a data sturcture X and then the function restoreState(X) - ///would remove the nodes and edges added after the call of saveState(). - ///Of course it should be used as a stack. (Maybe X is not necessary.) - /// - ///\author Alpar Juttner - class SmartGraph { - - struct NodeT - { - int first_in,first_out; - NodeT() : first_in(-1), first_out(-1) {} - }; - struct EdgeT - { - int head, tail, next_in, next_out; - //FIXME: is this necessary? - EdgeT() : next_in(-1), next_out(-1) {} - }; - - std::vector nodes; - - std::vector edges; - - - public: - - typedef SmartGraph Graph; - - class Node; - class Edge; - - class NodeIt; - class EdgeIt; - class OutEdgeIt; - class InEdgeIt; - - // Create map registries. - CREATE_MAP_REGISTRIES; - // Create node and edge maps. - CREATE_MAPS(ArrayMap); - - public: - - SmartGraph() : nodes(), edges() { } - SmartGraph(const SmartGraph &_g) : nodes(_g.nodes), edges(_g.edges) { } - - ///Number of nodes. - int nodeNum() const { return nodes.size(); } - ///Number of edges. - int edgeNum() const { return edges.size(); } - - /// Maximum node ID. - - /// Maximum node ID. - ///\sa id(Node) - int maxNodeId() const { return nodes.size()-1; } - /// Maximum edge ID. - - /// Maximum edge ID. - ///\sa id(Edge) - int maxEdgeId() const { return edges.size()-1; } - - Node tail(Edge e) const { return edges[e.n].tail; } - Node head(Edge e) const { return edges[e.n].head; } - - 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; } - - /// 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 v.n; } - /// 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.n; } - - Node addNode() { - Node n; n.n=nodes.size(); - nodes.push_back(NodeT()); //FIXME: Hmmm... - - - node_maps.add(n); - return n; - } - - Edge addEdge(Node u, Node v) { - Edge e; e.n=edges.size(); edges.push_back(EdgeT()); //FIXME: Hmmm... - edges[e.n].tail=u.n; edges[e.n].head=v.n; - edges[e.n].next_out=nodes[u.n].first_out; - edges[e.n].next_in=nodes[v.n].first_in; - nodes[u.n].first_out=nodes[v.n].first_in=e.n; - - edge_maps.add(e); - - return e; - } - - /// 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) - { - int e = (prev.n==-1)? nodes[u.n].first_out : edges[prev.n].next_out; - while(e!=-1 && edges[e].tail!=v.n) e = edges[e].next_out; - prev.n=e; - return prev; - } - - void clear() { - edge_maps.clear(); - edges.clear(); - node_maps.clear(); - nodes.clear(); - } - - class Node { - friend class SmartGraph; - template friend class NodeMap; - - friend class Edge; - friend class OutEdgeIt; - friend class InEdgeIt; - friend class SymEdge; - - protected: - int n; - friend int SmartGraph::id(Node v); - 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 nnodes.size()+1)-1; - return *this; - } -// ///Validity check -// operator bool() { return Node::operator bool(); } - }; - - class Edge { - friend class SmartGraph; - template friend class EdgeMap; - - friend class SymSmartGraph; - - friend class Node; - friend class NodeIt; - protected: - int n; - friend int SmartGraph::id(Edge e); - Edge(int nn) {n=nn;} - public: - /// An Edge with id \c n. - - 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 nedges[n].next_out; return *this; } -// ///Validity check -// operator bool() { return Edge::operator bool(); } - }; - - class InEdgeIt : public Edge { - const SmartGraph *G; - friend class SmartGraph; - public: - InEdgeIt() : Edge() { } - InEdgeIt(const SmartGraph& _G, Edge e) : Edge(e), G(&_G) { } - InEdgeIt (Invalid i) : Edge(i) { } - InEdgeIt(const SmartGraph& _G,Node v) - : Edge(_G.nodes[v.n].first_in), G(&_G) { } - InEdgeIt &operator++() { n=G->edges[n].next_in; return *this; } -// ///Validity check -// operator bool() { return Edge::operator bool(); } - }; - - }; - - ///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 SymSmartGraph::SymEdgeMap "SymEdgeMap" - ///that complements this - ///feature by - ///storing shared values for the edge pairs. The usual - ///\ref Graph::EdgeMap "EdgeMap" - ///can be used - ///as well. - /// - ///The oppositely directed edge can also be obtained easily - ///using \ref opposite. - ///\warning It shares the similarity with \ref SmartGraph that - ///it is not possible to delete edges or nodes from the graph. - //\sa SmartGraph. - - class SymSmartGraph : public SmartGraph - { - public: - typedef SymSmartGraph Graph; - - // Create symmetric map registry. - CREATE_SYM_EDGE_MAP_REGISTRY; - // Create symmetric edge map. - CREATE_SYM_EDGE_MAP(ArrayMap); - - - SymSmartGraph() : SmartGraph() { } - SymSmartGraph(const SmartGraph &_g) : SmartGraph(_g) { } - ///Adds a pair of oppositely directed edges to the graph. - Edge addEdge(Node u, Node v) - { - Edge e = SmartGraph::addEdge(u,v); - Edge f = SmartGraph::addEdge(v,u); - sym_edge_maps.add(e); - sym_edge_maps.add(f); - return e; - } - - ///The oppositely directed edge. - - ///Returns the oppositely directed - ///pair of the edge \c e. - static Edge opposite(Edge e) - { - Edge f; - f.n = e.n - 2*(e.n%2) + 1; - return f; - } - - - }; - - /// @} -} //namespace hugo - - - - -#endif //HUGO_SMART_GRAPH_H