00001 //---------------------------------------------------------------------------- 00002 /** @file 00003 */ 00004 //---------------------------------------------------------------------------- 00005 00006 #ifndef DIGRAPH_H 00007 #define DIGRAPH_H 00008 00009 #include <map> 00010 #include <set> 00011 #include <vector> 00012 #include <iostream> 00013 #include <cassert> 00014 #include "Benzene.hpp" 00015 00016 _BEGIN_BENZENE_NAMESPACE_ 00017 00018 //---------------------------------------------------------------------------- 00019 00020 /** Generic directed graph. */ 00021 template <typename T> 00022 class Digraph 00023 { 00024 public: 00025 00026 /** Constructor. */ 00027 Digraph(); 00028 00029 /** Destructor. */ 00030 ~Digraph(); 00031 00032 //------------------------------------------------------------------------ 00033 00034 typedef typename std::map<T, std::set<T> > MapType; 00035 00036 typedef typename std::set<T>::iterator iterator; 00037 typedef typename std::set<T>::const_iterator const_iterator; 00038 00039 //------------------------------------------------------------------------ 00040 00041 /** Returns number of vertices in graph. */ 00042 int NumVertices() const; 00043 00044 /** Returns the vertex set. */ 00045 const std::set<T>& Vertices() const; 00046 00047 /** Returns true if vertex exists in graph. */ 00048 bool VertexExists(const T& vertex) const; 00049 00050 /** Returns true if vertex has no outgoing or incoming edges. */ 00051 bool IsIsolated(const T& vertex) const; 00052 00053 /** Returns the vertices with out-degree>0 and in-degree==0. */ 00054 std::set<T> Sources() const; 00055 00056 /** Returns the vertices with out-degree==0 and in-degree>0. */ 00057 std::set<T> Sinks() const; 00058 00059 /** Returns the number of edges entering target. */ 00060 int InDegree(const T& target) const; 00061 00062 /** Returns the number of edges leaving source. */ 00063 int OutDegree(const T& source) const; 00064 00065 /** Returns true if there is an edge (x->y). */ 00066 bool IsEdge(const T& x, const T& y) const; 00067 00068 /** Returns the transpose of this graph (ie, the graph with 00069 edge directions reversed). */ 00070 void Transpose(Digraph<T>& out) const; 00071 00072 //------------------------------------------------------------------------ 00073 00074 /** Returns set of nodes pointed to by source. */ 00075 const std::set<T>& OutSet(const T& source) const; 00076 00077 /** Stores all targets of vertices in source. */ 00078 void OutSet(const std::set<T>& source, std::set<T>& out) const; 00079 00080 /** Returns nodes pointing to target. */ 00081 const std::set<T>& InSet(const T& target) const; 00082 00083 /** Stores all sources of edges into any member of target. */ 00084 void InSet(const std::set<T>& target, std::set<T>& out) const; 00085 00086 //------------------------------------------------------------------------ 00087 00088 /** Stores all vertices that are on a two cycle in cycles. */ 00089 void FindTwoCycles(std::set<T>& cycles) const; 00090 00091 /** Stores the strongly connected components in out. */ 00092 void FindStronglyConnectedComponents(std::vector< std::set<T> >& out) const; 00093 00094 //------------------------------------------------------------------------ 00095 00096 const_iterator out_begin(const T& source) const; 00097 const_iterator out_end(const T& source) const; 00098 00099 const_iterator in_begin(const T& target) const; 00100 const_iterator in_end(const T& target) const; 00101 00102 //------------------------------------------------------------------------ 00103 00104 /** Clears the graph. */ 00105 void Clear(); 00106 00107 /** Adds edge from source to target. */ 00108 void AddEdge(const T& source, const T& target); 00109 00110 /** Adds edges from source to each of the targets. */ 00111 void AddEdges(const T& source, const std::set<T>& targets); 00112 00113 /** Removes edge from source to target. */ 00114 void RemoveEdge(const T& source, const T& target); 00115 00116 /** Removes vertex from the graph. */ 00117 void RemoveVertex(const T& vertex); 00118 00119 private: 00120 00121 //------------------------------------------------------------------------ 00122 00123 typedef std::pair<int, T> ScoreNodePair; 00124 typedef std::set<ScoreNodePair, std::greater<ScoreNodePair> > OrderedChildren; 00125 00126 void OrderChildren(const std::set<T>& children, 00127 std::map<T, int>& tiebreaker, 00128 std::map<T, int>& finished, 00129 OrderedChildren& out) const; 00130 00131 void DFS(int& step, 00132 const T& vertex, 00133 std::map<T, int>& tiebreaker, 00134 std::map<T, int>& finished, 00135 std::set<T>& visited) const; 00136 00137 //------------------------------------------------------------------------ 00138 00139 mutable MapType m_out; 00140 mutable MapType m_in; 00141 std::set<T> m_vertices; 00142 }; 00143 00144 //---------------------------------------------------------------------------- 00145 00146 template<typename T> 00147 Digraph<T>::Digraph() 00148 { 00149 } 00150 00151 template<typename T> 00152 Digraph<T>::~Digraph() 00153 { 00154 } 00155 00156 //---------------------------------------------------------------------------- 00157 00158 template<typename T> 00159 int Digraph<T>::NumVertices() const 00160 { 00161 return m_vertices.size(); 00162 } 00163 00164 template<typename T> 00165 const std::set<T>& Digraph<T>::Vertices() const 00166 { 00167 return m_vertices; 00168 } 00169 00170 template<typename T> 00171 std::set<T> Digraph<T>::Sources() const 00172 { 00173 std::set<T> ret; 00174 for (typename MapType::const_iterator x=m_out.begin(); x!=m_out.end(); ++x) { 00175 if (m_in[x->first].empty()) 00176 ret.insert(x->first); 00177 } 00178 return ret; 00179 } 00180 00181 template<typename T> 00182 std::set<T> Digraph<T>::Sinks() const 00183 { 00184 std::set<T> ret; 00185 for (typename MapType::const_iterator x=m_in.begin(); x!=m_in.end(); ++x) { 00186 if (m_out[x->first].empty()) 00187 ret.insert(x->first); 00188 } 00189 return ret; 00190 } 00191 00192 template<typename T> 00193 int Digraph<T>::InDegree(const T& target) const 00194 { 00195 assert(VertexExists(target)); 00196 return m_in[target].size(); 00197 } 00198 00199 template<typename T> 00200 bool Digraph<T>::IsIsolated(const T& vertex) const 00201 { 00202 return (m_in[vertex].empty() && m_out[vertex].empty()); 00203 } 00204 00205 template<typename T> 00206 int Digraph<T>::OutDegree(const T& source) const 00207 { 00208 assert(VertexExists(source)); 00209 return m_out[source].size(); 00210 } 00211 00212 template<typename T> 00213 bool Digraph<T>::IsEdge(const T& source, const T& target) const 00214 { 00215 return m_out[source].count(target); 00216 } 00217 00218 template<typename T> 00219 const std::set<T>& Digraph<T>::OutSet(const T& source) const 00220 { 00221 assert(VertexExists(source)); 00222 return m_out[source]; 00223 } 00224 00225 template<typename T> 00226 void Digraph<T>::OutSet(const std::set<T>& source, std::set<T>& out) const 00227 { 00228 out.clear(); 00229 for (const_iterator x=source.begin(); x!=source.end(); ++x) { 00230 assert(VertexExists(*x)); 00231 out.insert(out_begin(*x), out_end(*x)); 00232 } 00233 } 00234 00235 template<typename T> 00236 const std::set<T>& Digraph<T>::InSet(const T& target) const 00237 { 00238 assert(VertexExists(target)); 00239 return m_in[target]; 00240 } 00241 00242 template<typename T> 00243 void Digraph<T>::InSet(const std::set<T>& target, std::set<T>& out) const 00244 { 00245 out.clear(); 00246 for (const_iterator x=target.begin(); x!=target.end(); ++x) { 00247 assert(VertexExists(*x)); 00248 out.insert(in_begin(*x), in_end(*x)); 00249 } 00250 } 00251 00252 template<typename T> 00253 void Digraph<T>::Transpose(Digraph<T>& out) const 00254 { 00255 out.m_vertices = m_vertices; 00256 out.m_out = m_in; 00257 out.m_in = m_out; 00258 } 00259 00260 //---------------------------------------------------------------------------- 00261 00262 template<typename T> 00263 void Digraph<T>::FindTwoCycles(std::set<T>& loops) const 00264 { 00265 loops.clear(); 00266 for (const_iterator x=m_vertices.begin(); x!=m_vertices.end(); ++x) { 00267 for (const_iterator y=out_begin(*x); y!=out_end(*x); ++y) { 00268 for (const_iterator z=out_begin(*y); z!=out_end(*y); ++z) { 00269 if (*z == *x) { 00270 loops.insert(*x); 00271 loops.insert(*y); 00272 break; 00273 } 00274 } 00275 } 00276 } 00277 } 00278 00279 //---------------------------------------------------------------------------- 00280 00281 template<typename T> 00282 typename Digraph<T>::const_iterator Digraph<T>::out_begin(const T& source) const 00283 { 00284 assert(VertexExists(source)); 00285 return m_out[source].begin(); 00286 } 00287 00288 template<typename T> 00289 typename Digraph<T>::const_iterator Digraph<T>::out_end(const T& source) const 00290 { 00291 assert(VertexExists(source)); 00292 return m_out[source].end(); 00293 } 00294 00295 template<typename T> 00296 typename Digraph<T>::const_iterator Digraph<T>::in_begin(const T& target) const 00297 { 00298 assert(VertexExists(target)); 00299 return m_in[target].begin(); 00300 } 00301 00302 template<typename T> 00303 typename Digraph<T>::const_iterator Digraph<T>::in_end(const T& target) const 00304 { 00305 assert(VertexExists(target)); 00306 return m_in[target].end(); 00307 } 00308 00309 //---------------------------------------------------------------------------- 00310 00311 template<typename T> 00312 void Digraph<T>::Clear() 00313 { 00314 m_in.clear(); 00315 m_out.clear(); 00316 m_vertices.clear(); 00317 } 00318 00319 template<typename T> 00320 void Digraph<T>::AddEdge(const T& source, const T& target) 00321 { 00322 m_vertices.insert(source); 00323 m_vertices.insert(target); 00324 00325 m_out[source].insert(target); 00326 m_in[target].insert(source); 00327 } 00328 00329 template<typename T> 00330 void Digraph<T>::AddEdges(const T& source, const std::set<T>& targets) 00331 { 00332 for (const_iterator x=targets.begin(); x!=targets.end(); ++x) { 00333 AddEdge(source, *x); 00334 } 00335 } 00336 00337 template<typename T> 00338 void Digraph<T>::RemoveEdge(const T& source, const T& target) 00339 { 00340 m_out[source].erase(target); 00341 m_in[target].erase(source); 00342 } 00343 00344 //---------------------------------------------------------------------------- 00345 00346 template<typename T> 00347 void Digraph<T>::RemoveVertex(const T& v) 00348 { 00349 if (!VertexExists(v)) 00350 return; 00351 00352 // remove all outgoing edges 00353 for (iterator t = m_out[v].begin(); t != m_out[v].end(); ++t) { 00354 m_in[*t].erase(v); 00355 } 00356 m_out.erase(v); 00357 00358 // remove all incoming edges 00359 for (iterator s = m_in[v].begin(); s != m_in[v].end(); ++s) { 00360 m_out[*s].erase(v); 00361 } 00362 m_in.erase(v); 00363 00364 m_vertices.erase(v); 00365 } 00366 00367 //---------------------------------------------------------------------------- 00368 00369 template<typename T> 00370 bool Digraph<T>::VertexExists(const T& v) const 00371 { 00372 typename std::set<T>::const_iterator it = m_vertices.find(v); 00373 return (it != m_vertices.end()); 00374 } 00375 00376 //---------------------------------------------------------------------------- 00377 00378 template<typename T> 00379 void Digraph<T>::OrderChildren(const std::set<T>& children, 00380 std::map<T, int>& tiebreaker, 00381 std::map<T, int>& finished, 00382 OrderedChildren& out) const 00383 { 00384 // consider vertices that have not been visited/expanded 00385 for (const_iterator p = children.begin(); p != children.end(); ++p) { 00386 if (finished[*p] == 0) { 00387 out.insert(std::make_pair(tiebreaker[*p], *p)); 00388 } 00389 } 00390 } 00391 00392 template<typename T> 00393 void Digraph<T>::DFS(int& step, 00394 const T& vertex, 00395 std::map<T, int>& tiebreaker, 00396 std::map<T, int>& finished, 00397 std::set<T>& visited) const 00398 { 00399 finished[vertex] = -1; // mark as expanded, but not finished. 00400 00401 // visit children in order determined by tiebreaker 00402 OrderedChildren children; 00403 OrderChildren(m_out[vertex], tiebreaker, finished, children); 00404 00405 typename OrderedChildren::iterator it; 00406 for (it = children.begin(); it != children.end(); ++it) { 00407 const T& child = it->second; 00408 DFS(++step, child, tiebreaker, finished, visited); 00409 } 00410 00411 // mark vertex as finished, add it to the set of visited vertices 00412 finished[vertex] = ++step; 00413 visited.insert(vertex); 00414 } 00415 00416 template<typename T> 00417 void 00418 Digraph<T>::FindStronglyConnectedComponents(std::vector< std::set<T> >& out) 00419 const 00420 { 00421 // finishing times of each vertex in first dfs; used as the 00422 // tiebreaker in the second dfs. 00423 typename std::map<T, int> finished; 00424 00425 { 00426 int step = 1; 00427 typename std::map<T, int> tiebreaker; 00428 for (const_iterator p = m_vertices.begin(); p != m_vertices.end(); ++p) { 00429 if (finished[*p] > 0) continue; 00430 std::set<T> visited; 00431 this->DFS(step, *p, tiebreaker, finished, visited); 00432 } 00433 } 00434 00435 Digraph<T> t; 00436 Transpose(t); 00437 out.clear(); 00438 00439 { 00440 int step = 1; 00441 typename std::map<T, int> finished2; 00442 00443 // visit children in order determined by tiebreaker 00444 OrderedChildren children; 00445 OrderChildren(m_vertices, finished, finished2, children); 00446 00447 typename OrderedChildren::iterator it; 00448 for (it = children.begin(); it != children.end(); ++it) { 00449 const T& child = it->second; 00450 if (finished2[child] > 0) continue; 00451 00452 std::set<T> visited; 00453 t.DFS(step, child, finished, finished2, visited); 00454 out.push_back(visited); 00455 } 00456 } 00457 } 00458 00459 //---------------------------------------------------------------------------- 00460 00461 _END_BENZENE_NAMESPACE_ 00462 00463 #endif // DIGRAPH_H