00001 #ifndef ADJACENCYLISTIMPL_H
00002 #define ADJACENCYLISTIMPL_H
00003
00004 #include <Structs/Graphs/dynamicGraph.h>
00005 #include <Utilities/mersenneTwister.h>
00006 #include <list>
00007
00008 template<typename Vtype, typename Etype>
00009 class ALNode;
00010 template<typename Vtype, typename Etype>
00011 class ALEdge;
00012 template<typename Vtype, typename Etype>
00013 class ALInEdge;
00014
00015
00016 template<typename Vtype, typename Etype>
00017 class AdjacencyListImpl
00018 {
00019 public:
00020
00021 typedef unsigned int SizeType;
00022 typedef typename std::list< ALNode< Vtype, Etype> >::iterator NodeIterator;
00023 typedef typename std::list< ALEdge< Vtype, Etype> >::iterator EdgeIterator;
00024 typedef typename std::list< ALInEdge< Vtype, Etype> >::iterator InEdgeIterator;
00025 typedef NodeIterator* NodeDescriptor;
00026 typedef EdgeIterator* EdgeDescriptor;
00027
00028 AdjacencyListImpl():m_numNodes(0),m_numEdges(0)
00029 {
00030 }
00031
00032 ~AdjacencyListImpl()
00033 {
00034 NodeIterator end = m_nodes.end();
00035 EdgeIterator e, end_edges;
00036
00037 for( NodeIterator u = m_nodes.begin(); u != end; ++u)
00038 {
00039 delete u->getDescriptor();
00040 for( e = beginEdges(u), end_edges = endEdges(u); e != end_edges; ++e)
00041 {
00042 delete e->getDescriptor();
00043 }
00044 }
00045 }
00046
00047 NodeDescriptor insertNode()
00048 {
00049
00050 ALNode<Vtype,Etype> newNode;
00051
00052 NodeDescriptor m_auxNodeDescriptor = new NodeIterator();
00053 newNode.setDescriptor( m_auxNodeDescriptor);
00054
00055
00056 m_nodes.push_back( newNode);
00057 NodeIterator m_auxNodeIterator = m_nodes.end();
00058 --m_auxNodeIterator;
00059
00060
00061 *m_auxNodeDescriptor = m_auxNodeIterator;
00062 ++m_numNodes;
00063 return m_auxNodeDescriptor;
00064 }
00065
00066 EdgeDescriptor insertEdge( const NodeDescriptor& uD, const NodeDescriptor& vD)
00067 {
00068 NodeIterator u = getNodeIterator( uD);
00069 NodeIterator v = getNodeIterator( vD);
00070
00071
00072 ALEdge<Vtype, Etype> newEdge;
00073
00074 ALInEdge<Vtype, Etype> newInEdge;
00075
00076
00077 EdgeDescriptor m_auxEdgeDescriptor = new EdgeIterator();
00078 newEdge.setDescriptor(m_auxEdgeDescriptor);
00079
00080
00081 (*u).m_edges.push_back( newEdge);
00082
00083
00084 (*v).m_InEdges.push_back( newInEdge);
00085
00086
00087 EdgeIterator e = u->m_edges.end();
00088 --e;
00089 InEdgeIterator k = v->m_InEdges.end();
00090 --k;
00091
00092
00093 e->m_adjacentNode = v;
00094 e->m_InEdge = k;
00095
00096 k->m_adjacentNode = u;
00097 k->m_edge = e;
00098
00099 *m_auxEdgeDescriptor = e;
00100
00101 ++m_numEdges;
00102 return m_auxEdgeDescriptor;
00103 }
00104
00105 void eraseNode( const NodeIterator& u)
00106 {
00107 NodeDescriptor descriptor = u->getDescriptor();
00108 delete descriptor;
00109 descriptor = 0;
00110 m_nodes.erase(u);
00111 --m_numNodes;
00112 }
00113
00114 void eraseEdge( const InEdgeIterator& k)
00115 {
00116 eraseEdge( getEdgeIterator(k));
00117 }
00118
00119 void eraseEdge( const EdgeIterator& e)
00120 {
00121 InEdgeIterator k = e->m_InEdge;
00122 NodeIterator u = k->m_adjacentNode;
00123 NodeIterator v = e->m_adjacentNode;
00124 EdgeDescriptor descriptor = e->getDescriptor();
00125 delete descriptor;
00126 descriptor = 0;
00127 (*v).m_InEdges.erase(k);
00128 (*u).m_edges.erase(e);
00129 --m_numEdges;
00130 }
00131
00132 NodeIterator beginNodes()
00133 {
00134 return m_nodes.begin();
00135 }
00136
00137 NodeIterator endNodes()
00138 {
00139 return m_nodes.end();
00140 }
00141
00142 EdgeIterator beginEdges( const NodeIterator& u)
00143 {
00144 return u->m_edges.begin();
00145 }
00146
00147 EdgeIterator endEdges( const NodeIterator& u)
00148 {
00149 return u->m_edges.end();
00150 }
00151
00152 InEdgeIterator beginInEdges( const NodeIterator& u)
00153 {
00154 return u->m_InEdges.begin();
00155 }
00156
00157 InEdgeIterator endInEdges( const NodeIterator& u)
00158 {
00159 return u->m_InEdges.end();
00160 }
00161
00162 NodeIterator chooseNode()
00163 {
00164 double random = m_random.getRandomNormalizedDouble();
00165 SizeType pos = m_nodes.size() * random;
00166
00167 NodeIterator m_auxNodeIterator = m_nodes.begin();
00168
00169 std::advance( m_auxNodeIterator, pos);
00170 return m_auxNodeIterator;
00171 }
00172
00173 EdgeDescriptor getDescriptor( const InEdgeIterator& k) const
00174 {
00175 return getEdgeIterator(k)->getDescriptor();
00176 }
00177
00178 EdgeDescriptor getDescriptor( const EdgeIterator& e) const
00179 {
00180 return e->getDescriptor();
00181 }
00182
00183 NodeDescriptor getDescriptor( const NodeIterator& u) const
00184 {
00185 return u->getDescriptor();
00186 }
00187
00188 EdgeIterator getEdgeIterator( const EdgeDescriptor& descriptor) const
00189 {
00190 return *descriptor;
00191 }
00192
00193 NodeIterator getNodeIterator( const NodeDescriptor& descriptor) const
00194 {
00195 return *descriptor;
00196 }
00197
00198 NodeIterator getAdjacentNodeIterator( const EdgeIterator& e)
00199 {
00200 return e->m_adjacentNode;
00201 }
00202
00203 NodeIterator getAdjacentNodeIterator( const InEdgeIterator& k)
00204 {
00205 return k->m_adjacentNode;
00206 }
00207
00208 EdgeIterator getEdgeIterator( const InEdgeIterator& k) const
00209 {
00210 return k->m_edge;
00211 }
00212
00213 InEdgeIterator getInEdgeIterator( const EdgeIterator& e)
00214 {
00215 return e->m_InEdge;
00216 }
00217
00218
00219
00220
00221
00222
00223 bool hasEdges( const NodeIterator& u)
00224 {
00225 return !(*u).m_edges.empty();
00226 }
00227
00228 bool hasInEdges( const NodeIterator& u)
00229 {
00230 return !(*u).m_InEdges.empty();
00231 }
00232
00233 bool hasEdge( const EdgeDescriptor& descriptor)
00234 {
00235 return descriptor != 0;
00236 }
00237
00238 bool hasNode( const NodeDescriptor& descriptor)
00239 {
00240 return descriptor != 0;
00241 }
00242
00243 NodeIterator nilNode() const
00244 {
00245 return m_nodes.end();
00246 }
00247
00248 EdgeIterator nilEdge() const
00249 {
00250 return (*m_nodes.begin()).m_edges.end();
00251 }
00252
00253 SizeType memUsage()
00254 {
00255 std::cout << "Nodes:\t\t" << m_numNodes << "\n";
00256 std::cout << "Edges:\t\t" << m_numEdges << "\n";
00257 std::cout << "InEdges:\t" << m_numEdges << "\n";
00258 std::cout << "Node Size:\t" << ALNode< Vtype, Etype>::memUsage() << "bytes" << std::endl;
00259 std::cout << "Edge Size:\t" << ALEdge< Vtype, Etype>::memUsage() << "bytes" << std::endl;
00260 std::cout << "BWEdge Size:\t" << ALInEdge< Vtype, Etype>::memUsage() << "bytes" << std::endl;
00261
00262 return m_numNodes * ALNode< Vtype, Etype>::memUsage() + m_numEdges * (ALEdge< Vtype, Etype>::memUsage() + ALInEdge< Vtype, Etype>::memUsage());
00263 }
00264
00265 SizeType getId( const NodeIterator& u)
00266 {
00267 return distance( m_nodes.begin(), u);
00268 }
00269
00270 void reserve( const SizeType& numNodes, const SizeType& numEdges)
00271 {
00272 return;
00273 }
00274
00275 SizeType indeg( const NodeIterator& u)
00276 {
00277 return distance( beginInEdges(u), endInEdges(u));
00278 }
00279
00280 SizeType outdeg( const NodeIterator& u)
00281 {
00282 return distance( beginEdges(u), endEdges(u));
00283 }
00284
00285 void clear()
00286 {
00287 m_nodes.clear();
00288 m_numNodes = 0;
00289 m_numEdges = 0;
00290 }
00291
00292 private:
00293 std::list< ALNode< Vtype, Etype> > m_nodes;
00294 MersenneTwister m_random;
00295 SizeType m_numNodes;
00296 SizeType m_numEdges;
00297 };
00298
00299
00300 template<typename Vtype, typename Etype>
00301 class ALEdge : public GraphElement< Etype, typename AdjacencyListImpl<Vtype,Etype>::EdgeDescriptor>
00302 {
00303
00304 public:
00305 typedef typename AdjacencyListImpl<Vtype,Etype>::InEdgeIterator InEdgeIterator;
00306 typedef typename AdjacencyListImpl<Vtype,Etype>::NodeIterator NodeIterator;
00307 typedef typename AdjacencyListImpl<Vtype,Etype>::EdgeDescriptor EdgeDescriptor;
00308 typedef typename AdjacencyListImpl<Vtype,Etype>::NodeDescriptor NodeDescriptor;
00309
00310 ALEdge( unsigned int init = 0): GraphElement< Etype, EdgeDescriptor>()
00311 {
00312 }
00313
00314 ALEdge( NodeIterator adjacentNode , InEdgeIterator oppositeEdge , NodeDescriptor descriptor = 0, Etype data = Etype()):
00315 GraphElement< Etype, EdgeDescriptor>( descriptor),
00316 m_adjacentNode(adjacentNode),
00317 m_InEdge(oppositeEdge)
00318 {
00319 }
00320
00321 static unsigned int memUsage()
00322 {
00323
00324 return sizeof(ALEdge);
00325 }
00326
00327 NodeIterator m_adjacentNode;
00328 InEdgeIterator m_InEdge;
00329 };
00330
00331
00332 template<typename Vtype, typename Etype>
00333 class ALInEdge : public Etype
00334 {
00335
00336 public:
00337 typedef typename AdjacencyListImpl<Vtype,Etype>::EdgeIterator EdgeIterator;
00338 typedef typename AdjacencyListImpl<Vtype,Etype>::NodeIterator NodeIterator;
00339 typedef typename AdjacencyListImpl<Vtype,Etype>::EdgeDescriptor EdgeDescriptor;
00340 typedef typename AdjacencyListImpl<Vtype,Etype>::NodeDescriptor NodeDescriptor;
00341
00342 ALInEdge( unsigned int init = 0): Etype()
00343 {
00344 }
00345
00346 ALInEdge( NodeIterator adjacentNode , EdgeIterator oppositeEdge , NodeDescriptor descriptor = 0, Etype data = Etype()):
00347 Etype(),
00348 m_adjacentNode(adjacentNode),
00349 m_edge(oppositeEdge)
00350 {
00351 }
00352
00353 static unsigned int memUsage()
00354 {
00355
00356 return sizeof(ALInEdge);
00357 }
00358
00359 NodeIterator m_adjacentNode;
00360 EdgeIterator m_edge;
00361 };
00362
00363 template<typename Vtype, typename Etype>
00364 class ALNode : public GraphElement< Vtype, typename AdjacencyListImpl<Vtype,Etype>::NodeDescriptor>
00365 {
00366 public:
00367 typedef typename AdjacencyListImpl<Vtype,Etype>::NodeDescriptor NodeDescriptor;
00368 typedef typename std::list<ALEdge< Vtype, Etype> >::iterator iterator;
00369 typedef typename std::list<ALInEdge< Vtype, Etype> >::iterator backIterator;
00370
00371 ALNode():GraphElement< Vtype, NodeDescriptor>()
00372 {
00373 }
00374
00375 ALNode( NodeDescriptor descriptor):GraphElement< Vtype, NodeDescriptor>( descriptor)
00376 {
00377 }
00378
00379 static unsigned int memUsage()
00380 {
00381 return sizeof(ALNode);
00382 }
00383
00384 std::list< ALEdge< Vtype, Etype> > m_edges;
00385 std::list< ALInEdge< Vtype, Etype> > m_InEdges;
00386
00387 };
00388
00389
00390
00391 #endif //ADJACENCYLISTIMPL_H