Main   Class Hierarchy   Classes   Compound List   Files   Compound Members   File Members   Pages  

graph.h

Go to the documentation of this file.
00001 //-----------------------------------------------------------------------------
00002 /** @file graph.h
00003     Graph class.
00004 
00005     $Id: graph_8h-source.html,v 1.1.1.1 2003/08/07 19:41:39 emarkus Exp $
00006     $Source: /usr/cvsroot/www_pathfind/libpathfind/0.1.0/doc/graph_8h-source.html,v $
00007 */
00008 //-----------------------------------------------------------------------------
00009 
00010 #ifndef PATHFIND_GRAPH_H
00011 #define PATHFIND_GRAPH_H
00012 
00013 #include <assert.h>
00014 #include <vector>
00015 
00016 //-----------------------------------------------------------------------------
00017 
00018 namespace PathFind
00019 {
00020     using namespace std;
00021 
00022     /** %Graph with generic data attached to nodes and edges. */
00023     template<class NODEINFO, class EDGEINFO>
00024     class Graph
00025     {
00026     public:
00027         /** %Edge in a graph with generic data attached. */
00028         class Edge
00029         {
00030         public:
00031             Edge();
00032 
00033             Edge(int targetNodeId, const EDGEINFO& info)
00034                 : m_targetNodeId(targetNodeId),
00035                   m_info(info)
00036             { }
00037 
00038             int getTargetNodeId() const
00039             {
00040                 return m_targetNodeId;
00041             }
00042 
00043             EDGEINFO& getInfo()
00044             {
00045                 return m_info;
00046             }
00047 
00048             const EDGEINFO& getInfo() const
00049             {
00050                 return m_info;
00051             }
00052 
00053         private:
00054             int m_targetNodeId;
00055 
00056             EDGEINFO m_info;
00057         };
00058 
00059         /** %Node in a graph with generic data attached. */
00060         class Node
00061         {
00062         public:
00063             Node()
00064                 : m_nodeId(-1)
00065             { }
00066 
00067             Node(int nodeId, const NODEINFO& info)
00068                 : m_nodeId(nodeId),
00069                   m_info(info)
00070             { }
00071 
00072             void addOutEdge(const Edge& edge)
00073             {
00074                 m_outEdges.push_back(edge);
00075             }
00076 
00077             void removeOutEdge(int targetNodeId);
00078 
00079             void clearOutEdges()
00080             {
00081                 m_outEdges.clear();
00082             }
00083 
00084             NODEINFO& getInfo()
00085             {
00086                 return m_info;
00087             }
00088 
00089             const NODEINFO& getInfo() const
00090             {
00091                 return m_info;
00092             }
00093 
00094             const vector<Edge>& getOutEdges() const
00095             {
00096                 return m_outEdges;
00097             }
00098 
00099         private:
00100             int m_nodeId;
00101 
00102             vector<Edge> m_outEdges;
00103 
00104             NODEINFO m_info;
00105         };
00106 
00107         void addNode(int nodeId, const NODEINFO& info);
00108 
00109         void addOutEdge(int sourceNodeId, int targetNodeId,
00110                         const EDGEINFO& info);
00111 
00112         void removeNodeEdges(int nodeId);
00113 
00114         void removeLastNode()
00115         {
00116             m_nodes.erase(m_nodes.end());
00117         }
00118 
00119         void removeOutEdge(int sourceNodeId, int targetNodeId);
00120 
00121         void clear()
00122         {
00123             m_nodes.clear();
00124         }
00125 
00126         const Node& getNode(int nodeId) const
00127         {
00128             assert(isValidNodeId(nodeId));
00129             return m_nodes[nodeId];
00130         }
00131 
00132         NODEINFO& getNodeInfo(int nodeId)
00133         {
00134             return getNode(nodeId).getInfo();
00135         }
00136 
00137         const NODEINFO& getNodeInfo(int nodeId) const
00138         {
00139             return getNode(nodeId).getInfo();
00140         }
00141 
00142         const vector<Edge>& getOutEdges(int nodeId) const
00143         {
00144             assert(isValidNodeId(nodeId));
00145             return m_nodes[nodeId].getOutEdges();
00146         }
00147 
00148     private:
00149         vector<Node> m_nodes;
00150 
00151         Node& getNode(int nodeId)
00152         {
00153             assert(isValidNodeId(nodeId));
00154             return m_nodes[nodeId];
00155         }
00156 
00157         bool isValidNodeId(int nodeId) const;
00158     };
00159 }
00160 
00161 //-----------------------------------------------------------------------------
00162 
00163 namespace PathFind
00164 {
00165     using namespace std;
00166 
00167     template<class NODEINFO, class EDGEINFO>
00168     void Graph<NODEINFO, EDGEINFO>::Node::removeOutEdge(int targetNodeId)
00169     {
00170         for (typename vector<Edge>::iterator i = m_outEdges.begin();
00171              i != m_outEdges.end(); ++i)
00172         {
00173             if (i->getTargetNodeId() == targetNodeId)
00174             {
00175                 m_outEdges.erase(i);
00176                 break;
00177             }
00178         }
00179     }
00180 
00181     template<class NODEINFO, class EDGEINFO>
00182     void Graph<NODEINFO, EDGEINFO>::addNode(int nodeId, const NODEINFO& info)
00183     {
00184         assert(nodeId >= 0);
00185         unsigned int size = static_cast<unsigned int>(nodeId + 1);
00186         if (m_nodes.size() < size)
00187             m_nodes.resize(size);
00188         m_nodes[nodeId] = Node(nodeId, info);
00189     }
00190 
00191     template<class NODEINFO, class EDGEINFO>
00192     void Graph<NODEINFO, EDGEINFO>::removeNodeEdges(int nodeId)
00193     {
00194         const vector<Edge>& edges = m_nodes[nodeId].getOutEdges();
00195         for (typename vector<Edge>::const_iterator i = edges.begin();
00196              i != edges.end(); ++i)
00197         {
00198             m_nodes[i->getTargetNodeId()].removeOutEdge(nodeId);
00199         }
00200         m_nodes[nodeId].clearOutEdges();
00201     }
00202 
00203     template<class NODEINFO, class EDGEINFO>
00204     void Graph<NODEINFO, EDGEINFO>::addOutEdge(int sourceNodeId,
00205                                                int targetNodeId,
00206                                                const EDGEINFO& info)
00207     {
00208         assert(isValidNodeId(sourceNodeId));
00209         assert(isValidNodeId(targetNodeId));
00210         m_nodes[sourceNodeId].addOutEdge(Edge(targetNodeId, info));
00211     }
00212 
00213     template<class NODEINFO, class EDGEINFO>
00214     bool Graph<NODEINFO, EDGEINFO>::isValidNodeId(int nodeId) const
00215     {
00216         return nodeId >= 0
00217             && static_cast<unsigned int>(nodeId) < m_nodes.size();
00218     }
00219 }
00220 
00221 //-----------------------------------------------------------------------------
00222 
00223 #endif


Generated on Thu Aug 7 13:04:49 2003 by Doxygen1.3.1