00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00024 #ifndef SHGRAPHIMPL_HPP
00025 #define SHGRAPHIMPL_HPP
00026
00027 #include "ShGraph.hpp"
00028 #include <stack>
00029 #include <map>
00030
00031 namespace SH {
00032
00033
00034
00035
00036
00037 template<typename G>
00038 ShGraphVertex<G>::ShGraphVertex()
00039 : marked(false)
00040 {}
00041
00042 template<typename G>
00043 ShGraphVertex<G>::ShGraphVertex(const ShGraphVertex<G> &other)
00044 : marked(other.marked)
00045 {}
00046
00047 template<typename G>
00048 std::ostream& ShGraphVertex<G>::graphvizDump(std::ostream &out) const
00049 {
00050 out << " [label=\"\", shape=circle, height=0.25]";
00051 return out;
00052 }
00053
00054 template<typename G>
00055 ShGraphEdge<G>::ShGraphEdge()
00056 : start(0), end(0)
00057 {}
00058
00059 template<typename G>
00060 ShGraphEdge<G>::ShGraphEdge(typename G::Vertex *start, typename G::Vertex *end)
00061 : start(start), end(end)
00062 {}
00063
00064 template<typename G>
00065 ShGraphEdge<G>::ShGraphEdge(const ShGraphEdge<G> &other)
00066 : start(0), end(0)
00067 {}
00068
00069 template<typename G>
00070 std::ostream& ShGraphEdge<G>::graphvizDump(std::ostream &out) const
00071 {
00072 return out;
00073 }
00074
00075 template<typename G>
00076 ShGraph<G>::ShGraph()
00077 {}
00078
00079 template<typename G>
00080 ShGraph<G>::ShGraph(const ShGraph<G> &other)
00081 {
00082 *this = other;
00083 }
00084
00085 template<typename G>
00086 ShGraph<G>::~ShGraph()
00087 {
00088 clear();
00089 }
00090
00091 template<typename G>
00092 void ShGraph<G>::addVertex(typename G::Vertex *v)
00093 {
00094 verts.insert(v);
00095 }
00096
00097 template<typename G>
00098 void ShGraph<G>::addEdge(typename G::Edge *e)
00099 {
00100 edges.insert(e);
00101 e->start->edges.push_back(e);
00102 }
00103
00104 template<typename G>
00105 void ShGraph<G>::removeVertex(typename G::Vertex *v)
00106 {
00107 for(typename EdgeList::iterator E = v->edges.begin(); E != v->edges.end(); ++E) {
00108 edges.erase(*E);
00109 }
00110 verts.erase(v);
00111 }
00112
00113 template<typename G>
00114 void ShGraph<G>::removeEdge(typename G::Edge *e)
00115 {
00116 edges.erase(e);
00117 e->start->edges.remove(e);
00118 delete e;
00119 }
00120
00121 template<typename G>
00122 void ShGraph<G>::clear()
00123 {
00124 for(typename VertexSet::iterator V = verts.begin(); V != verts.end(); ++V) delete *V;
00125 for(typename EdgeSet::iterator E = edges.begin(); E != edges.end(); ++E) delete *E;
00126
00127 verts.clear();
00128 edges.clear();
00129 }
00130
00131 template<typename G>
00132 void ShGraph<G>::clearMarked()
00133 {
00134 for(typename VertexSet::iterator V = verts.begin(); V != verts.end(); ++V) (*V)->marked = false;
00135 }
00136
00137 template<typename G>
00138 ShGraph<G>& ShGraph<G>::operator=(const ShGraph<G> &other)
00139 {
00140 clear();
00141
00142 VertexMap<Vertex *> vmap;
00143
00144
00145 vmap[0] = 0;
00146
00147 for(typename VertexSet::const_iterator V = other.verts.begin(); V != other.verts.end(); ++V) {
00148 typename G::Vertex *newv = new Vertex(**V);
00149 vmap[*V] = newv;
00150 addVertex(newv);
00151 }
00152
00153 for(typename EdgeSet::const_iterator E = other.edges.begin(); E != other.edges.end(); ++E) {
00154 typename G::Edge *newe = new Edge(**E);
00155 newe->start = vmap[(*E)->start];
00156 newe->end = vmap[(*E)->end];
00157 addEdge(newe);
00158 }
00159
00160 return *this;
00161 }
00162
00163 template<typename G>
00164 template<typename F>
00165 void ShGraph<G>::dfs(typename G::Vertex *start, F &functor)
00166 {
00167 std::stack<typename G::Vertex *> worklist;
00168
00169 for(worklist.push(start); !worklist.empty(); worklist.pop()) {
00170 typename G::Vertex *workVertex = worklist.top();
00171 if(workVertex->marked) continue;
00172 workVertex->marked = true;
00173
00174 for(typename EdgeList::iterator E = workVertex->edges.begin(); E != workVertex->edges.end(); ++E) {
00175 worklist.push(E->end);
00176 }
00177 functor(workVertex);
00178 }
00179 }
00180
00181 template<typename G>
00182 template<typename W>
00183 typename W::WeightType ShGraph<G>::bellmanFord(typename G::Vertex *start, typename G::Vertex *end, W &weigher, EdgeList *path)
00184 {
00185
00186
00187 std::map<typename G::Vertex *, typename W::WeightType> dist;
00188 std::map<typename G::Vertex *, typename G::Edge *> pred;
00189
00190 for(typename VertexSet::const_iterator V = verts.begin(); V != verts.end(); ++V) {
00191 dist[*V] = W::LARGE;
00192 pred[*V] = 0;
00193 }
00194
00195 dist[start] = W::ZERO;
00196
00197 for(int i = 0; i < verts.size(); ++i) {
00198 for(typename EdgeSet::iterator E = edges.begin(); E != edges.end(); ++E) {
00199 Edge &e = **E;
00200
00201 typename W::WeightType testDist = dist[e.start] + weigher(e);
00202 if(testDist < dist[e.end]) {
00203 dist[e.end] = testDist;
00204 pred[e.end] = &e;
00205 }
00206 }
00207 }
00208
00209
00210 if(path) {
00211 path->clear();
00212 for(typename G::Edge *finger = pred[end]; finger != 0; finger = pred[finger->start]) {
00213 path->push_front(finger);
00214 }
00215 }
00216
00217 return dist[end];
00218 }
00219
00220 template<typename G>
00221 template<typename W>
00222 void ShGraph<G>::floydWarshall(W &weigher, VertexPairMap<typename W::WeightType> &dist, FirstStepMap *path)
00223 {
00224 typename VertexSet::const_iterator V, U, X;
00225 typename EdgeSet::iterator E;
00226
00227 dist.clear();
00228 if(path) path->clear();
00229
00230
00231 for(V = verts.begin(); V != verts.end(); ++V) for(U = verts.begin(); U != verts.end(); ++U) {
00232 if(V == U) dist(*V, *U) = W::ZERO;
00233 else dist(*V, *U) = W::LARGE;
00234 }
00235
00236
00237 for(E = edges.begin(); E != edges.end(); ++E) {
00238 Edge& e = **E;
00239 typename W::WeightType &testDist = dist(e.start, e.end);
00240 if(testDist > weigher(e)) {
00241 testDist = weigher(e);
00242 if(path) (*path)(e.start, e.end) = &e;
00243 }
00244 }
00245
00246
00247
00248
00249
00250
00251 for(V = verts.begin(); V != verts.end(); ++V) {
00252 for(U = verts.begin(); U != verts.end(); ++U) {
00253 for(X = verts.begin(); X != verts.end(); ++X) {
00254 typename W::WeightType &oldDist = dist(*U, *X);
00255 typename W::WeightType testDist = dist(*U, *V) + dist(*V, *X);
00256 if(oldDist > testDist && (dist(*U, *V) != W::LARGE &&
00257 dist(*V, *X) != W::LARGE)) {
00258 oldDist = testDist;
00259 if(path) (*path)(*U, *X) = (*path)(*U, *V);
00260 }
00261 }
00262 }
00263 }
00264 }
00265
00266
00267 template<typename G>
00268 void ShGraph<G>::transitiveClosure(TransitiveClosureMap &tcm)
00269 {
00270 typename VertexSet::const_iterator V, U, X;
00271 typename EdgeSet::iterator E;
00272 typedef VertexPairMap<bool> TCMap;
00273
00274
00275 tcm.clear();
00276 for(V = verts.begin(); V != verts.end(); ++V) tcm(*V, *V) = true;
00277
00278 for(E = edges.begin(); E != edges.end(); ++E) {
00279 Edge& e = **E;
00280 tcm(e.start, e.end) = true;
00281 }
00282
00283
00284 for(V = verts.begin(); V != verts.end(); ++V) {
00285 for(U = verts.begin(); U != verts.end(); ++U) {
00286 for(X = verts.begin(); X != verts.end(); ++X) {
00287 tcm(*U, *X) = tcm(*U, *X) || (tcm(*U, *V) && tcm(*V, *X));
00288 }
00289 }
00290 }
00291 }
00292
00293 template<typename G>
00294 void ShGraph<G>::rootSet(VertexSet &roots) {
00295 roots = verts;
00296 typename EdgeSet::const_iterator E;
00297 for(E = edges.begin(); E != edges.end(); ++E) {
00298 roots.erase((*E)->end);
00299 }
00300 }
00301
00302 template<typename G>
00303 struct NegativeWeigher {
00304 typedef int WeightType;
00305 static const int LARGE=2000000000;
00306 static const int ZERO=0;
00307 int operator()(const typename G::Edge &e) { return -1; }
00308 };
00309
00310 template<typename G>
00311 void ShGraph<G>::vertexHeight(const VertexSet &roots, HeightMap &heights) {
00312 heights.clear();
00313 VertexPairMap<int> dist;
00314 NegativeWeigher<G> weigher;
00315 typename VertexSet::const_iterator U, V;
00316
00317 floydWarshall(weigher, dist);
00318 for(U = verts.begin(); U != verts.end(); ++U) {
00319 for(V = roots.begin(); V != roots.end(); ++V) {
00320 heights[*U] = std::max(heights[*U], -dist(*V, *U));
00321 }
00322 }
00323 }
00324
00325
00326 template<typename G>
00327 void ShGraph<G>::leastCommonAncestor(LCAMap &ancestor)
00328 {
00329 typename VertexSet::const_iterator U, V, W;
00330 typename EdgeSet::const_iterator E;
00331
00332
00333
00334 VertexSet roots;
00335 rootSet(roots);
00336
00337
00338 HeightMap heights;
00339 vertexHeight(roots, heights);
00340
00341
00342 TransitiveClosureMap tcm;
00343 transitiveClosure(tcm);
00344
00345
00346
00347 ancestor.clear();
00348 for(U = verts.begin(); U != verts.end(); ++U) {
00349 for(V = verts.begin(); V != verts.end(); ++V) {
00350 int maxHeight = -1;
00351 for(W = verts.begin(); W != verts.end(); ++W) {
00352
00353 if(tcm(*W, *U) && tcm(*W, *V) && heights[*W] > maxHeight) {
00354 ancestor(*U, *V) = ancestor(*V, *U) = *W;
00355 maxHeight = heights[*W];
00356 }
00357 }
00358 }
00359 }
00360 }
00361
00362 template<typename G>
00363 std::ostream& ShGraphDefaultDumper<G>::operator()(std::ostream& out, const typename G::Vertex *v)
00364 {
00365 return v->graphvizDump(out);
00366 }
00367
00368 template<typename G>
00369 std::ostream& ShGraphDefaultDumper<G>::operator()(std::ostream& out, const typename G::Edge *e)
00370 {
00371 return e->graphvizDump(out);
00372 }
00373
00374 template<typename G>
00375 std::ostream& graphvizDump(std::ostream &out, const ShGraph<G> &g)
00376 {
00377 ShGraphDefaultDumper<G> dumper;
00378 return graphvizDump(out, g, dumper);
00379 }
00380
00381 template<typename G, typename D>
00382 std::ostream& graphvizDump(std::ostream &out, const ShGraph<G> &g, D &dumpFunctor)
00383 {
00384 out << "digraph {" << std::endl;
00385 typename ShGraph<G>::VertexSet::const_iterator V = g.verts.begin();
00386 for(; V != g.verts.end(); ++V) {
00387 out << "\"" << *V << "\" ";
00388 dumpFunctor(out, *V);
00389 out << ";" << std::endl;
00390 out << std::endl;
00391 }
00392
00393 typename ShGraph<G>::EdgeSet::const_iterator E = g.edges.begin();
00394 for(; E != g.edges.end(); ++E) {
00395 const typename G::Edge &e = **E;
00396 out << "\"" << e.start << "\" ";
00397 out << "-> ";
00398 out << "\"" << e.end << "\" ";
00399 dumpFunctor(out, *E);
00400 out << ";" << std::endl;
00401 out << std::endl;
00402 }
00403 out << "}" << std::endl;
00404
00405 return out;
00406 }
00407
00408 }
00409
00410 #endif