00001 #ifndef DDD_graph_h
00002 #define DDD_graph_h
00003
00004 #include <vector>
00005 #include <map>
00006 #include <iostream>
00007
00008
00009
00010
00011 template <class N, class E>
00012 class graph
00013 {
00014 public:
00015 typedef std::vector<double>::size_type index_type;
00016
00017 typedef std::pair<index_type, index_type> edge_type;
00018
00019 typedef std::vector<edge_type> edge_list;
00020
00021 typedef std::vector<edge_list> adj_list;
00022
00023 class const_iterator
00024 {
00025 friend class graph<N, E>;
00026 public:
00027 typedef typename graph::index_type index_type;
00028 typedef typename graph::adj_list adj_list;
00029 typedef typename graph::edge_list edge_list;
00030
00031 struct value_type
00032 {
00033 friend class graph<N,E>::const_iterator;
00034 value_type( const graph & g, index_type a, index_type e )
00035 : gr_( g ), a_( a ), e_( e )
00036 { }
00037
00038 const N & from( void ) const { return gr_.nodeData( a_ ); }
00039 const N & to( void ) const { return gr_.nodeData( gr_.adjl_[a_][e_].first ); }
00040 const E & edge( void ) const { return gr_.edgeData( gr_.adjl_[a_][e_].second ); }
00041
00042 private:
00043 const graph & gr_;
00044 index_type a_, e_;
00045 };
00046
00047 typedef value_type& reference;
00048 typedef value_type* pointer;
00049
00050 bool operator==( const const_iterator & i ) const {
00051 return (( vt_.a_ == i.vt_.a_ ) && ( vt_.e_ == i.vt_.e_ )) ? true : false;
00052 }
00053
00054 bool operator!=( const const_iterator & i ) const {
00055 return (( vt_.a_ == i.vt_.a_ ) && ( vt_.e_ == i.vt_.e_ )) ? false : true;
00056 }
00057
00058 void operator++() {
00059 while( vt_.gr_.size() > vt_.a_ )
00060 {
00061 index_type i = vt_.gr_.adjl_[vt_.a_].size();
00062 if( i > vt_.e_+1 )
00063 {
00064 ++vt_.e_;
00065 return;
00066 }
00067 vt_.e_=0;
00068 ++vt_.a_;
00069 while( vt_.gr_.size() > vt_.a_ )
00070 {
00071 if( vt_.gr_.adjl_[vt_.a_].size())
00072 {
00073 return;
00074 }
00075 ++vt_.a_;
00076 }
00077 }
00078 }
00079
00080 const value_type & operator*() const {
00081 return vt_;
00082 }
00083
00084 const value_type * operator->() const {
00085 return &vt_;
00086 }
00087
00088 private:
00089 explicit const_iterator( const graph & g )
00090 : vt_( g, 0, 0 )
00091 {}
00092
00093 const_iterator( const graph & g, index_type ait, index_type eit )
00094 : vt_( g, ait, eit )
00095 {}
00096
00097 value_type vt_;
00098
00099 bool operator<( const const_iterator & i ) const {
00100 return ( vt_.a_ < i.vt_.a_ ) && ( vt_.e_ < i.vt_.e_ );
00101 }
00102
00103 bool operator>(const const_iterator & i) const {
00104 return ( vt_.a_ > i.vt_.a_ ) && ( vt_.e_ > i.vt_.e_ );
00105 }
00106 };
00107
00108 void dump_graph( void ) const;
00109
00110
00111 struct value_type {
00112 value_type(const N & n, const E & e) : first(n), second(e) { }
00113 const N & first;
00114 const E & second;
00115 N firstToValue() const { return first; }
00116 E secondToValue() const { return second; }
00117 };
00118
00119
00120 typedef std::vector<N> node_list;
00121 typedef std::vector<E> edge_store;
00122
00123
00124 typedef typename adj_list::iterator adj_iterator;
00125 typedef typename adj_list::const_iterator const_adj_iterator;
00126
00127
00128
00129 typedef std::map<N, index_type> indexer_type;
00130 typedef typename indexer_type::iterator indexer_iterator;
00131 typedef typename indexer_type::const_iterator const_indexer_iterator;
00132
00133
00134 typedef typename edge_list::iterator edge_iterator;
00135
00136 typedef typename edge_list::const_iterator const_edge_iterator;
00137
00138 typedef std::pair<edge_iterator,edge_iterator> edge_range;
00139
00140 typedef std::pair<const_edge_iterator, const_edge_iterator> const_edge_range;
00141
00142 typedef std::pair<index_type, bool> index_result;
00143
00144 public:
00145
00146 graph() : edges_(1) { }
00147 ~graph() { }
00148
00149
00150
00151
00152 index_type addNode(const N &);
00153
00154 void addEdge(const N & from, const N & to, const E & edge);
00155
00156
00157
00158
00159
00160
00161 inline index_result nodeIndex(const N &) const;
00162
00163
00164
00165
00166 inline edge_range edges(index_type nodeIndex);
00167 inline const_edge_range edges(index_type nodeIndex) const;
00168
00169
00170 inline edge_range edges(const N &);
00171 inline const_edge_range edges(const N &) const;
00172
00173 inline const N & nodeData(const edge_type &) const;
00174 inline const N & nodeData(index_type) const;
00175 inline const N & nodeData(const const_adj_iterator &) const;
00176
00177
00178 bool replace(const N & oldNode , const N & newNode );
00179
00180
00181 bool replaceEdge(const E & ldEdge, const E &newEdge );
00182
00183 const E & edgeData(index_type i) const { return edges_[i]; }
00184
00185
00186
00188 void clear();
00189
00190 const_iterator begin_iter() const { return const_iterator(*this); }
00191
00192 const_iterator end_iter() const { return const_iterator(*this, adjl_.size(),0); }
00193
00194 size_t edge_size() const { return edges_.size(); }
00195
00196
00197 adj_iterator begin() { return adjl_.begin(); }
00198 const_adj_iterator begin() const { return adjl_.begin(); }
00199 adj_iterator end() { return adjl_.end(); }
00200 const_adj_iterator end() const { return adjl_.end(); }
00201 typename adj_list::size_type size() const { return adjl_.size(); }
00202
00203
00204 void findRoots(edge_list &) const;
00205
00206
00207 void invert(graph & g) const;
00208
00209 void swap( graph<N, E> & );
00210
00211
00212 private:
00213
00214
00215 adj_list adjl_;
00216
00217
00218 node_list nodes_;
00219
00220
00221 edge_store edges_;
00222
00223
00224 indexer_type indexer_;
00225
00226
00227 edge_list emptyEdges_;
00228
00229 };
00230
00231
00232
00233 template<class N, class E>
00234 typename graph<N,E>::index_type graph<N,E>::addNode(const N & node)
00235 {
00236 index_type idx = indexer_.size() ;
00237 std::pair<indexer_iterator,bool> result
00238 = indexer_.insert(typename indexer_type::value_type(node,idx));
00239
00240 if ( result.second ) {
00241 nodes_.push_back(node);
00242 adjl_.push_back(edge_list());
00243 }
00244 else {
00245 idx = result.first->second;
00246 }
00247 return idx;
00248 }
00249
00250
00251 template<class N, class E>
00252 typename graph<N,E>::index_result graph<N,E>::nodeIndex(const N & node) const
00253 {
00254 typename indexer_type::const_iterator result = indexer_.find(node);
00255 index_type idx = 0;
00256 bool flag = false;
00257 if (result != indexer_.end()) {
00258 flag = true;
00259 idx = result->second;
00260 }
00261 return index_result(idx, flag);
00262 }
00263
00264
00265 template<class N, class E>
00266 void graph<N,E>::addEdge(const N & from, const N & to, const E & edge)
00267 {
00268 index_type iFrom = addNode(from);
00269 index_type iTo = addNode(to);
00270
00271 adjl_[iFrom].push_back(edge_type(iTo,edges_.size()));
00272 edges_.push_back(edge);
00273 }
00274
00275
00276 template<class N, class E>
00277 typename graph<N,E>::edge_range graph<N,E>::edges(index_type nodeIndex)
00278 {
00279 edge_list & edges = adjl_[nodeIndex];
00280 return edge_range(edges.begin(), edges.end());
00281 }
00282
00283
00284 template<class N, class E>
00285 typename graph<N,E>::const_edge_range graph<N,E>::edges(index_type nodeIndex) const
00286 {
00287 const edge_list & edges = adjl_[nodeIndex];
00288 return const_edge_range(edges.begin(), edges.end());
00289 }
00290
00291
00292 template<class N, class E>
00293 typename graph<N,E>::edge_range graph<N,E>::edges(const N & node)
00294 {
00295 index_result idxResult = nodeIndex(node);
00296 edge_range result(emptyEdges_.begin(),emptyEdges_.end());
00297 if (idxResult.second) {
00298 result = edges(idxResult.first);
00299 }
00300 return result;
00301 }
00302
00303
00304 template<class N, class E>
00305 typename graph<N,E>::const_edge_range graph<N,E>::edges(const N & node) const
00306 {
00307 index_result idxResult = nodeIndex(node);
00308 const_edge_range result(emptyEdges_.begin(),emptyEdges_.end());
00309 if (idxResult.second) {
00310 result = edges(idxResult.first);
00311 }
00312 return result;
00313 }
00314
00315
00316 template<class N, class E>
00317 const N & graph<N,E>::nodeData(const edge_type & edge) const
00318 {
00319 return nodes_[edge.first];
00320 }
00321
00322
00323 template<class N, class E>
00324 const N & graph<N,E>::nodeData(index_type i) const
00325 {
00326 return nodes_[i];
00327 }
00328
00329
00330 template<class N, class E>
00331 const N & graph<N,E>::nodeData(const const_adj_iterator & it) const
00332 {
00333 return nodes_[it-adjl_.begin()];
00334 }
00335
00336 template<class N, class E>
00337 void graph<N,E>::findRoots(edge_list & result) const
00338 {
00339 result.clear();
00340
00341 const_adj_iterator it = begin();
00342 const_adj_iterator ed = end();
00343 std::vector<bool> rootCandidate(size(), true);
00344
00345 for (; it != ed; ++it) {
00346 const edge_list & el = *it;
00347 typename edge_list::const_iterator el_it = el.begin();
00348 typename edge_list::const_iterator el_ed = el.end();
00349 for (; el_it != el_ed; ++el_it) {
00350 rootCandidate[el_it->first]=false;
00351
00352
00353
00354 }
00355 }
00356 std::vector<bool>::size_type v_sz = 0;
00357 std::vector<bool>::size_type v_ed = rootCandidate.size();
00358 for (; v_sz < v_ed; ++v_sz) {
00359 if (rootCandidate[v_sz]) {
00360
00361 result.push_back(edge_type(v_sz,0));
00362 }
00363 }
00364 }
00365
00366 template<class N, class E>
00367 bool graph<N,E>::replace(const N & oldNode, const N & newNode)
00368 {
00369 typename indexer_type::iterator it = indexer_.find(oldNode);
00370 if (it != indexer_.end()) {
00371 index_type oldIndex = it->second;
00372 nodes_[oldIndex]=newNode;
00373 indexer_[newNode]=oldIndex;
00374 indexer_.erase(it);
00375 }
00376 else throw(oldNode);
00377 return true;
00378 }
00379
00380 template<class N, class E>
00381 bool graph<N,E>::replaceEdge(const E & oldEdge, const E & newEdge)
00382 {
00383 typename edge_store::size_type it = 0;
00384 typename edge_store::size_type ed = edges_.size();
00385 bool result = false;
00386
00387 for (; it < ed; ++it) {
00388
00389 if ( edges_[it] == oldEdge ) {
00390
00391 result = true;
00392 edges_[it] = newEdge;
00393 break;
00394 }
00395 }
00396
00397 return result;
00398 }
00399
00400 template<class N, class E>
00401 void graph<N,E>::clear()
00402 {
00403 adjl_.clear();
00404 nodes_.clear();
00405 edges_.clear();
00406 indexer_.clear();
00407 }
00408
00409 template<class N, class E>
00410 void graph<N,E>::dump_graph() const
00411 {
00412
00413
00414
00415
00416
00417
00418
00419
00420 }
00421
00422
00423 template<class N, class E>
00424 void graph<N,E>::invert(graph<N,E> & g) const
00425 {
00426 adj_list::size_type it = 0;
00427 adj_list::size_type ed = adjl_.size();
00428
00429 for (; it < ed; ++it) {
00430 const edge_list & el = adjl_[it];
00431 edge_list::size_type eit = 0;
00432 edge_list::size_type eed = el.size();
00433
00434 for (; eit < eed; ++eit) {
00435 const edge_type & e = el[eit];
00436 g.addEdge(nodeData(e.first), nodeData(it), edgeData(e.second));
00437 }
00438 }
00439 }
00440
00441 template<class N, class E>
00442 void graph<N,E>::swap( graph<N, E> & g) {
00443 adjl_.swap(g.adjl_);
00444 nodes_.swap(g.nodes_);
00445 edges_.swap(g.edges_);
00446 indexer_.swap(g.indexer_);
00447 emptyEdges_.swap(g.emptyEdges_);
00448 }
00449
00450 template<typename T> std::ostream & operator<<(std::ostream & o, const std::vector< std::vector<std::pair<T,T> > > v)
00451 {
00452 typedef typename std::vector<std::vector<std::pair<T,T> > > v_t;
00453 typedef typename std::vector<std::pair<T,T> > i_t;
00454
00455 typename v_t::const_iterator it(v.begin()), ed(v.end());
00456 for (; it != ed; ++it) {
00457 typename i_t::const_iterator iit(it->begin()), ied(it->end());
00458 for(; iit != ied; ++iit) {
00459 o << iit->first << ':' << iit->second << std::endl;
00460 }
00461 }
00462 return o;
00463 }
00464 #endif