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