00001
00002
00003
00004
00005
00006
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
00023 template<class NODEINFO, class EDGEINFO>
00024 class Graph
00025 {
00026 public:
00027
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
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