Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ShGraph.hpp

00001 // Sh: A GPU metaprogramming language.
00002 //
00003 // Copyright 2003-2005 Serious Hack Inc.
00004 // 
00005 // This software is provided 'as-is', without any express or implied
00006 // warranty. In no event will the authors be held liable for any damages
00007 // arising from the use of this software.
00008 // 
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it
00011 // freely, subject to the following restrictions:
00012 // 
00013 // 1. The origin of this software must not be misrepresented; you must
00014 // not claim that you wrote the original software. If you use this
00015 // software in a product, an acknowledgment in the product documentation
00016 // would be appreciated but is not required.
00017 // 
00018 // 2. Altered source versions must be plainly marked as such, and must
00019 // not be misrepresented as being the original software.
00020 // 
00021 // 3. This notice may not be removed or altered from any source
00022 // distribution.
00024 #ifndef SHGRAPH_HPP 
00025 #define SHGRAPH_HPP
00026 
00027 #include <list>
00028 #include <set>
00029 #include <map>
00030 #include <iostream>
00031 
00032 namespace SH {
00033 
00034 /* Framework for building directed graph classes and
00035  * algorithms on directed graph classes
00036  *
00037  * Built along the same lines as ShMesh.hpp, except
00038  * instead of a half-edge data structure this 
00039  * uses an ordered edge adjacency list.
00040  *
00041  */
00042 
00043 // This might be too weird, but
00044 // could make graph operations return other graphs
00045 // as an alternate operation mode
00046 //
00047 // e.g. shortest path would replace the edges with 
00048 // edges that hold an original edge for the first step in the
00049 // shortest path + a weight for total distance of the shortest
00050 // path...
00051 //
00052 // These new graphs would have predefined graphvizdump ops
00053 // so it would be easy to output the shortest-path
00054 // result through graphviz.
00055 // 
00056 
00057 
00058 // We do not impose any index scheme on vertices/edges 
00059 // (may want integer indexs on verts later to run faster)
00060 // so the user can choose an appropriate indexing scheme
00061 // or build a subclass that uses a specific indexing scheme
00062 
00063 template<typename VertexType, typename EdgeType>
00064 struct ShGraphType {
00065   typedef VertexType Vertex;
00066   typedef EdgeType Edge;
00067 
00068 };
00069 
00070 template<typename G>
00071 struct ShGraphVertex {
00072   typedef typename G::Edge Edge;
00073   typedef std::list<Edge*> EdgeList;
00074 
00076   ShGraphVertex();
00077 
00079   ShGraphVertex(const ShGraphVertex<G> &other);
00080 
00081   std::ostream& graphvizDump(std::ostream& out) const;
00082 
00083   EdgeList edges;
00084   bool marked;
00085 };
00086 
00087 template<typename G>
00088 struct ShGraphEdge {
00089   typedef typename G::Vertex Vertex;
00090 
00093   ShGraphEdge(); 
00094 
00096   ShGraphEdge(Vertex *start, Vertex *end);
00097 
00099   ShGraphEdge(const ShGraphEdge<G> &other);
00100 
00101   std::ostream& graphvizDump(std::ostream& out) const;
00102 
00103   Vertex *start;
00104   Vertex *end;
00105 };
00106 
00107 // TODO may want to not bother with memory management - use smart pointers for
00108 // verts/edges
00109 template<typename G>
00110 class ShGraph {
00111   public:
00112     // TODO maybe these typedefs should go somewhere else?
00113     typedef typename G::Vertex Vertex;
00114     typedef typename G::Edge Edge;
00115 
00116     typedef std::set<Vertex*> VertexSet;
00117     typedef std::set<Edge*> EdgeSet;
00118 
00119     typedef std::list<Vertex*> VertexList;
00120     typedef std::list<Edge*> EdgeList;
00121 
00122     typedef std::pair<Vertex*, Vertex*> VertexPair;
00123 
00124     template<typename T>
00125     struct VertexMap: public std::map<Vertex*, T> {};
00126 
00127     template<typename T>
00128     struct VertexPairMap: public std::map<VertexPair, T> {
00129       T& operator()(Vertex* u, Vertex *v) { return (*this)[VertexPair(u, v)]; }
00130       const T& operator()(Vertex* u, Vertex *v) const { return (*this)[VertexPair(u, v)]; }
00131     };
00132 
00133     ShGraph();
00134 
00136     ShGraph(const ShGraph<G> &other);
00137 
00139     ~ShGraph();
00140 
00142     void addVertex(Vertex *v);
00143 
00146     void addEdge(Edge *e);
00147 
00149     void removeVertex(Vertex *v);
00150 
00152     void removeEdge(Edge *e);
00153 
00155     void clear();
00156 
00158     void clearMarked();
00159 
00161     ShGraph<G>& operator=(const ShGraph<G> &other);
00162 
00169     template<typename F>
00170     void dfs(Vertex *start, F &functor);
00171 
00188     /*
00189     template<typename W>
00190     W::WeightType dijkstra(Vertex *start, Vertex *end, W &weigher); 
00191 
00192     template<typename W>
00193     W::WeightType dijkstra(Vertex *start, Vertex *end, W &weigher, EdgeList &path); 
00194     */
00195     // @}
00196 
00202     template<typename W>
00203     typename W::WeightType bellmanFord(Vertex *start, Vertex *end, W &weigher, EdgeList *path = 0); 
00204     // @}
00205 
00215     /* Describes a relationship between two vertices by the first step.
00216      * Mostly used in algorithms for backtracking one step at a time */
00217     typedef VertexPairMap<Edge*> FirstStepMap;
00218 
00219     template<typename W>
00220     void floydWarshall(W &weigher, VertexPairMap<typename W::WeightType> &dist, FirstStepMap *path = 0); 
00221     // @}
00222 
00223     // implemented like floyd warshall as described in CLRS 25.2
00224     typedef VertexPairMap<bool> TransitiveClosureMap;
00225     void transitiveClosure(TransitiveClosureMap &tcm);
00226 
00227     // functions on DAGs
00228    
00229     // Returns the set of root vertices (those with no incoming edges) 
00230     void rootSet(VertexSet &roots);
00231     
00232     // Finds the height of each node 
00233     // where height is the longest path from any root
00234     typedef VertexMap<int> HeightMap;
00235     void vertexHeight(const VertexSet &roots, HeightMap &heights);
00236 
00237 
00238     // Least Common Ancestor of a DAG 
00239     //
00240     // TODO implement DAG checking code - just a dfs cycle checker
00241     //
00242     // A least common ancestor of two verts x, y 
00243     // is a common ancestor of x and y, and not the ancestor
00244     // of any other common ancestor. (paraphrase of definition from 
00245     // Bender '01).
00246     //
00247     // Bender '01 has the fastest known asymptotic behaviour, but
00248     // it's easier to use the slower transitive closure...so 
00249     // that's what we use here.
00250     typedef VertexPairMap<Vertex *> LCAMap;
00251     void leastCommonAncestor(LCAMap &ancestor);
00252 
00253 
00254     VertexSet verts;
00255     EdgeSet edges;
00256 
00257 };
00258 
00259 // TODO
00260 // * extract a subgraph from a graph based on a bool functor on edges/verts
00261 
00280 template<typename G>
00281 struct ShGraphDefaultDumper {
00282   std::ostream& operator()(std::ostream& out, const typename G::Vertex *v);
00283   std::ostream& operator()(std::ostream& out, const typename G::Edge *e);
00284 };
00285 
00286 template<typename G>
00287 std::ostream& graphvizDump(std::ostream &out, const ShGraph<G> &g); 
00288 
00289 template<typename G, typename D>
00290 std::ostream& graphvizDump(std::ostream &out, const ShGraph<G> &g, D &dumpFunctor); 
00291 
00292 }
00293 
00294 #include "ShGraphImpl.hpp"
00295 
00296 #endif

Generated on Wed Jun 15 18:12:39 2005 for Sh by  doxygen 1.4.3-20050530