00001
00002
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
00021 template <typename T>
00022 class Digraph
00023 {
00024 public:
00025
00026
00027 Digraph();
00028
00029
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
00042 int NumVertices() const;
00043
00044
00045 const std::set<T>& Vertices() const;
00046
00047
00048 bool VertexExists(const T& vertex) const;
00049
00050
00051 bool IsIsolated(const T& vertex) const;
00052
00053
00054 std::set<T> Sources() const;
00055
00056
00057 std::set<T> Sinks() const;
00058
00059
00060 int InDegree(const T& target) const;
00061
00062
00063 int OutDegree(const T& source) const;
00064
00065
00066 bool IsEdge(const T& x, const T& y) const;
00067
00068
00069
00070 void Transpose(Digraph<T>& out) const;
00071
00072
00073
00074
00075 const std::set<T>& OutSet(const T& source) const;
00076
00077
00078 void OutSet(const std::set<T>& source, std::set<T>& out) const;
00079
00080
00081 const std::set<T>& InSet(const T& target) const;
00082
00083
00084 void InSet(const std::set<T>& target, std::set<T>& out) const;
00085
00086
00087
00088
00089 void FindTwoCycles(std::set<T>& cycles) const;
00090
00091
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
00105 void Clear();
00106
00107
00108 void AddEdge(const T& source, const T& target);
00109
00110
00111 void AddEdges(const T& source, const std::set<T>& targets);
00112
00113
00114 void RemoveEdge(const T& source, const T& target);
00115
00116
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
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
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
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;
00400
00401
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
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
00422
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
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