00001 #ifndef PACKEDADJACENCYVECTORIMPL_H
00002 #define PACKEDADJACENCYVECTORIMPL_H
00003
00004 #include <Utilities/mersenneTwister.h>
00005 #include <vector>
00006
00007 template<typename Vtype, typename Etype>
00008 class PAVNode;
00009 template<typename Vtype, typename Etype>
00010 class PAVEdge;
00011
00012 template<typename Vtype, typename Etype>
00013 class PackedAdjacencyVectorImpl
00014 {
00015 public:
00016
00017 typedef unsigned int SizeType;
00018 typedef typename std::vector< PAVNode< Vtype, Etype> >::iterator NodeIterator;
00019 typedef typename std::vector< PAVEdge< Vtype, Etype> >::iterator EdgeIterator;
00020 typedef SizeType* NodeDescriptor;
00021 typedef SizeType* EdgeDescriptor;
00022
00023 AdjacencyVectorImpl()
00024 {
00025 jsw_seed(1);
00026 }
00027
00028 ~AdjacencyVectorImpl()
00029 {
00030 NodeIterator end = m_nodes.end();
00031 EdgeIterator e, end_edges;
00032
00033 for( NodeIterator u = m_nodes.begin(); u != end; ++u)
00034 {
00035 delete u->m_descriptor;
00036 end_edges = u->m_edges.end();
00037 for( e = u->m_edges.begin(); e != end_edges; ++e)
00038 {
00039 delete e->m_descriptor;
00040 }
00041 }
00042 }
00043
00044 const NodeDescriptor& insertNode()
00045 {
00046 m_auxNodeDescriptor = new SizeType();
00047 *m_auxNodeDescriptor = m_nodes.size();
00048
00049 PAVNode<Vtype,Etype> newNode;
00050 m_nodes.push_back( newNode);
00051 NodeIterator u = m_nodes.end() - 1;
00052 u->setDescriptor(m_auxNodeDescriptor);
00053 return m_auxNodeDescriptor;
00054 }
00055
00056 const EdgeDescriptor& insertEdge( const NodeDescriptor& uD, const NodeDescriptor& vD)
00057 {
00058 NodeIterator u = getNodeIterator( uD);
00059 NodeIterator v = getNodeIterator( vD);
00060
00061 PAVEdge<Vtype, Etype> newEdge;
00062
00063 newEdge.m_adjacentNode = v - m_nodes.begin();
00064 EdgeIterator e = endEdges(u);
00065 e = m_edges.insert( e, newEdge);
00066
00067 newEdge.m_adjacentNode = u - m_nodes.begin();
00068 EdgeIterator k = endBackEdges(v);
00069 k = m_backEdges.insert( e, newEdge);
00070
00071 EdgeIterator e = u->m_edges.end() - 1;
00072 EdgeIterator k = v->m_backEdges.end() - 1;
00073
00074 e->m_oppositeEdge = k - endBackEdges(v);
00075 k->m_oppositeEdge = e - endEdges(u);
00076
00077 e->m_isBackEdge = false;
00078 k->m_isBackEdge = true;
00079
00080 m_auxEdgeDescriptor = new SizeType( e - m_edges.begin());
00081 e->setDescriptor(m_auxEdgeDescriptor);
00082 k->setDescriptor(m_auxEdgeDescriptor);
00083
00084 return m_auxEdgeDescriptor;
00085 }
00086
00087 void eraseNode( NodeDescriptor descriptor)
00088 {
00089 NodeIterator u = getNodeIterator( descriptor);
00090 EdgeIterator e, k, end;
00091
00092 end = endEdges(u);
00093 for( EdgeIterator e = beginEdges(u); e!= end; ++e)
00094 {
00095 eraseEdge( (*e).id);
00096 }
00097
00098 end = endBackEdges(u);
00099 for( EdgeIterator e = beginBackEdges(u); e!= end; ++e)
00100 {
00101 k = getOppositeEdgeIterator( e);
00102 eraseEdge( (*k).id);
00103 }
00104
00105 delete descriptor;
00106
00107 NodeIterator v;
00108 NodeIterator end_nodes = m_nodes.end();
00109 for( v = m_nodes.erase(u); v != end_nodes; ++v)
00110 {
00111 sanitiseNode( v);
00112 }
00113 }
00114
00115 void eraseEdge( EdgeDescriptor descriptor)
00116 {
00117 EdgeIterator e = getEdgeIterator(descriptor);
00118 NodeIterator v = m_nodes.begin()+ e->m_adjacentNode;
00119 EdgeIterator k = v->m_backEdges.begin() + e->m_oppositeEdge;
00120 NodeIterator u = m_nodes.begin()+ k->m_adjacentNode;
00121
00122 EdgeIterator f,h,end;
00123 end = (*v).m_backEdges.end();
00124 for( f = (*v).m_backEdges.erase(k); f != end; ++f)
00125 {
00126 --(f->getDescriptor()->second);
00127 h = m_nodes[ f->m_adjacentNode].m_edges.begin() + f->m_oppositeEdge;
00128 --(h->m_adjacentNode);
00129 }
00130
00131 end = (*u).m_edges.end();
00132 for( f = (*u).m_edges.erase(e); f != end; ++f)
00133 {
00134 --(f->getDescriptor()->second);
00135 h = m_nodes[ f->m_adjacentNode].m_backEdges.begin() + f->m_oppositeEdge;
00136 --(h->m_adjacentNode);
00137 }
00138
00139 delete descriptor;
00140 }
00141
00142 void sanitiseNode( const NodeIterator& u)
00143 {
00144 SizeType position =*(u->getDescriptor());
00145 --position;
00146 *(u->getDescriptor()) = position;
00147
00148 EdgeIterator end,k;
00149 NodeIterator adjacentNode;
00150 SizeType adjacentNodePosition;
00151
00152 end = u->m_edges.end();
00153 for( EdgeIterator e = u->m_edges.begin(); e != end; ++e)
00154 {
00155 e->getDescriptor()->first = position;
00156 if( e->m_adjacentNode < position) continue;
00157
00158 --(e->m_adjacentNode);
00159 k = m_nodes[ e->m_adjacentNode].m_backEdges.begin() + e->m_oppositeEdge;
00160 k.m_adjacentNode = position;
00161 }
00162
00163 end = u->m_backEdges.end();
00164 for( EdgeIterator e = u->m_backEdges.begin(); e != end; ++e)
00165 {
00166 e->getDescriptor()->first = position;
00167 if( e->m_adjacentNode < position) continue;
00168
00169 --(e->m_adjacentNode);
00170 k = m_nodes[ e->m_adjacentNode].m_edges.begin() + e->m_oppositeEdge;
00171 k.m_adjacentNode = position;
00172 }
00173 }
00174
00175 const NodeIterator& beginNodes()
00176 {
00177 m_auxNodeIterator = m_nodes.begin();
00178 return m_auxNodeIterator;
00179 }
00180
00181 const NodeIterator& endNodes()
00182 {
00183 m_auxNodeIterator = m_nodes.end();
00184 return m_auxNodeIterator;
00185 }
00186
00187 const EdgeIterator& beginEdges( NodeIterator u)
00188 {
00189 m_auxEdgeIterator = u->m_edges.begin();
00190 return m_auxEdgeIterator;
00191 }
00192
00193 const EdgeIterator& endEdges( NodeIterator u)
00194 {
00195 m_auxEdgeIterator = u->m_edges.end();
00196 return m_auxEdgeIterator;
00197 }
00198
00199 const EdgeIterator& beginBackEdges( NodeIterator u)
00200 {
00201 m_auxEdgeIterator = u->m_backEdges.begin();
00202 return m_auxEdgeIterator;
00203 }
00204
00205 const EdgeIterator& endBackEdges( NodeIterator u)
00206 {
00207 m_auxEdgeIterator = u->m_backEdges.end();
00208 return m_auxEdgeIterator;
00209 }
00210
00211 const NodeIterator& chooseNode()
00212 {
00213 double random = ((double)jsw_rand()/std::numeric_limits<SizeType>::max());
00214 SizeType pos = m_nodes.size() * random;
00215
00216 m_auxNodeIterator = m_nodes.begin() + pos;
00217 return m_auxNodeIterator;
00218 }
00219
00220 const EdgeIterator& getEdgeIterator( const EdgeDescriptor& descriptor)
00221 {
00222 m_auxEdgeIterator = (m_nodes.begin() + descriptor->first)->m_edges.begin() + descriptor->second;
00223 return m_auxEdgeIterator;
00224 }
00225
00226 const NodeIterator& getNodeIterator( const NodeDescriptor& descriptor)
00227 {
00228 m_auxNodeIterator = m_nodes.begin()+(*descriptor);
00229 return m_auxNodeIterator;
00230 }
00231
00232 const NodeIterator& getOppositeNodeIterator( const EdgeIterator& e)
00233 {
00234 m_auxNodeIterator = m_nodes.begin();
00235 return m_auxNodeIterator;
00236 }
00237
00238 const NodeIterator& nilNode()
00239 {
00240 m_auxNodeIterator = m_nodes.end();
00241 return m_auxNodeIterator;
00242 }
00243
00244 const EdgeIterator& nilEdge()
00245 {
00246 m_auxEdgeIterator = m_edges.end();
00247 return m_auxEdgeIterator;
00248 }
00249
00250 private:
00251 std::vector< PAVNode< Vtype, Etype> > m_nodes;
00252 std::vector< PAVEdge< Vtype, Etype> > m_edges;
00253 std::vector< PAVEdge< Vtype, Etype> > m_backEdges;
00254
00255 NodeIterator m_auxNodeIterator;
00256 EdgeIterator m_auxEdgeIterator;
00257 NodeDescriptor m_auxNodeDescriptor;
00258 EdgeDescriptor m_auxEdgeDescriptor;
00259 };
00260
00261 template<typename Vtype, typename Etype>
00262 class PAVEdge : public GraphElement< Etype, typename PackedAdjacencyVectorImpl<Vtype,Etype>::EdgeDescriptor>
00263 {
00264
00265 public:
00266 typedef typename AdjacencyVectorImpl<Vtype,Etype>::EdgeDescriptor EdgeDescriptor;
00267 typedef typename AdjacencyVectorImpl<Vtype,Etype>::NodeDescriptor NodeDescriptor;
00268 typedef typename AdjacencyVectorImpl<Vtype,Etype>::SizeType SizeType;
00269
00270 PAVEdge( unsigned int init = 0): GraphElement< Etype, EdgeDescriptor>()
00271 {
00272 }
00273
00274 PAVEdge( NodeDescriptor adjacentNode , EdgeDescriptor oppositeEdge , NodeDescriptor descriptor = 0, Etype data = Etype()):
00275 GraphElement< Etype, EdgeDescriptor>(descriptor),
00276 m_adjacentNode(adjacentNode),
00277 m_oppositeEdge(oppositeEdge)
00278 {
00279 }
00280
00281 SizeType m_adjacentNode;
00282 SizeType m_oppositeEdge;
00283 bool m_isBackEdge;
00284 };
00285
00286 template<typename Vtype, typename Etype>
00287 class PAVNode : public GraphElement< Vtype, typename PackedAdjacencyVectorImpl<Vtype,Etype>::NodeDescriptor>
00288 {
00289 public:
00290 typedef typename AdjacencyVectorImpl<Vtype,Etype>::NodeDescriptor NodeDescriptor;
00291
00292 PAVNode():GraphElement< Vtype, NodeDescriptor>()
00293 {
00294 }
00295
00296 PAVNode( NodeDescriptor descriptor):GraphElement< Vtype, NodeDescriptor>(descriptor)
00297 {
00298 }
00299
00300 SizeType m_firstEdge;
00301 SizeType m_firstBackEdge;
00302 };
00303
00304
00305
00306 #endif //PACKEDADJACENCYVECTORIMPL_H