Main   Namespaces   Classes   Hierarchy   Annotated   Files   Compound   Global   Pages  

Digraph.hpp

Go to the documentation of this file.
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


6 Jan 2011 Doxygen 1.6.3