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