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