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 library is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 //
00010 // This library is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with this library; if not, write to the Free Software
00017 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
00018 // MA  02110-1301, USA
00020 #ifndef SHGRAPH_HPP 
00021 #define SHGRAPH_HPP
00022 
00023 #include <list>
00024 #include <set>
00025 #include <map>
00026 #include <iostream>
00027 
00028 namespace SH {
00029 
00030 /* Framework for building directed graph classes and
00031  * algorithms on directed graph classes
00032  *
00033  * Built along the same lines as ShMesh.hpp, except
00034  * instead of a half-edge data structure this 
00035  * uses an ordered edge adjacency list.
00036  *
00037  */
00038 
00039 // This might be too weird, but
00040 // could make graph operations return other graphs
00041 // as an alternate operation mode
00042 //
00043 // e.g. shortest path would replace the edges with 
00044 // edges that hold an original edge for the first step in the
00045 // shortest path + a weight for total distance of the shortest
00046 // path...
00047 //
00048 // These new graphs would have predefined graphvizdump ops
00049 // so it would be easy to output the shortest-path
00050 // result through graphviz.
00051 // 
00052 
00053 
00054 // We do not impose any index scheme on vertices/edges 
00055 // (may want integer indexs on verts later to run faster)
00056 // so the user can choose an appropriate indexing scheme
00057 // or build a subclass that uses a specific indexing scheme
00058 
00059 template<typename VertexType, typename EdgeType>
00060 struct ShGraphType {
00061   typedef VertexType Vertex;
00062   typedef EdgeType Edge;
00063 
00064 };
00065 
00066 template<typename G>
00067 struct ShGraphVertex {
00068   typedef typename G::Edge Edge;
00069   typedef std::list<Edge*> EdgeList;
00070 
00072   ShGraphVertex();
00073 
00075   ShGraphVertex(const ShGraphVertex<G> &other);
00076 
00077   std::ostream& graphvizDump(std::ostream& out) const;
00078 
00079   EdgeList edges;
00080   bool marked;
00081 };
00082 
00083 template<typename G>
00084 struct ShGraphEdge {
00085   typedef typename G::Vertex Vertex;
00086 
00089   ShGraphEdge(); 
00090 
00092   ShGraphEdge(Vertex *start, Vertex *end);
00093 
00095   ShGraphEdge(const ShGraphEdge<G> &other);
00096 
00097   std::ostream& graphvizDump(std::ostream& out) const;
00098 
00099   Vertex *start;
00100   Vertex *end;
00101 };
00102 
00103 // TODO may want to not bother with memory management - use smart pointers for
00104 // verts/edges
00105 template<typename G>
00106 class ShGraph {
00107   public:
00108     // TODO maybe these typedefs should go somewhere else?
00109     typedef typename G::Vertex Vertex;
00110     typedef typename G::Edge Edge;
00111 
00112     typedef std::set<Vertex*> VertexSet;
00113     typedef std::set<Edge*> EdgeSet;
00114 
00115     typedef std::list<Vertex*> VertexList;
00116     typedef std::list<Edge*> EdgeList;
00117 
00118     typedef std::pair<Vertex*, Vertex*> VertexPair;
00119 
00120     template<typename T>
00121     struct VertexMap: public std::map<Vertex*, T> {};
00122 
00123     template<typename T>
00124     struct VertexPairMap: public std::map<VertexPair, T> {
00125       T& operator()(Vertex* u, Vertex *v) { return (*this)[VertexPair(u, v)]; }
00126       const T& operator()(Vertex* u, Vertex *v) const { return (*this)[VertexPair(u, v)]; }
00127     };
00128 
00129     ShGraph();
00130 
00132     ShGraph(const ShGraph<G> &other);
00133 
00135     ~ShGraph();
00136 
00138     void addVertex(Vertex *v);
00139 
00142     void addEdge(Edge *e);
00143 
00145     void removeVertex(Vertex *v);
00146 
00148     void removeEdge(Edge *e);
00149 
00151     void clear();
00152 
00154     void clearMarked();
00155 
00157     ShGraph<G>& operator=(const ShGraph<G> &other);
00158 
00165     template<typename F>
00166     void dfs(Vertex *start, F &functor);
00167 
00184     /*
00185     template<typename W>
00186     W::WeightType dijkstra(Vertex *start, Vertex *end, W &weigher); 
00187 
00188     template<typename W>
00189     W::WeightType dijkstra(Vertex *start, Vertex *end, W &weigher, EdgeList &path); 
00190     */
00191     // @}
00192 
00198     template<typename W>
00199     typename W::WeightType bellmanFord(Vertex *start, Vertex *end, W &weigher, EdgeList *path = 0); 
00200     // @}
00201 
00211     /* Describes a relationship between two vertices by the first step.
00212      * Mostly used in algorithms for backtracking one step at a time */
00213     typedef VertexPairMap<Edge*> FirstStepMap;
00214 
00215     template<typename W>
00216     void floydWarshall(W &weigher, VertexPairMap<typename W::WeightType> &dist, FirstStepMap *path = 0); 
00217     // @}
00218 
00219     // implemented like floyd warshall as described in CLRS 25.2
00220     typedef VertexPairMap<bool> TransitiveClosureMap;
00221     void transitiveClosure(TransitiveClosureMap &tcm);
00222 
00223     // functions on DAGs
00224    
00225     // Returns the set of root vertices (those with no incoming edges) 
00226     void rootSet(VertexSet &roots);
00227     
00228     // Finds the height of each node 
00229     // where height is the longest path from any root
00230     typedef VertexMap<int> HeightMap;
00231     void vertexHeight(const VertexSet &roots, HeightMap &heights);
00232 
00233 
00234     // Least Common Ancestor of a DAG 
00235     //
00236     // TODO implement DAG checking code - just a dfs cycle checker
00237     //
00238     // A least common ancestor of two verts x, y 
00239     // is a common ancestor of x and y, and not the ancestor
00240     // of any other common ancestor. (paraphrase of definition from 
00241     // Bender '01).
00242     //
00243     // Bender '01 has the fastest known asymptotic behaviour, but
00244     // it's easier to use the slower transitive closure...so 
00245     // that's what we use here.
00246     typedef VertexPairMap<Vertex *> LCAMap;
00247     void leastCommonAncestor(LCAMap &ancestor);
00248 
00249 
00250     VertexSet verts;
00251     EdgeSet edges;
00252 
00253 };
00254 
00255 // TODO
00256 // * extract a subgraph from a graph based on a bool functor on edges/verts
00257 
00276 template<typename G>
00277 struct ShGraphDefaultDumper {
00278   std::ostream& operator()(std::ostream& out, const typename G::Vertex *v);
00279   std::ostream& operator()(std::ostream& out, const typename G::Edge *e);
00280 };
00281 
00282 template<typename G>
00283 std::ostream& graphvizDump(std::ostream &out, const ShGraph<G> &g); 
00284 
00285 template<typename G, typename D>
00286 std::ostream& graphvizDump(std::ostream &out, const ShGraph<G> &g, D &dumpFunctor); 
00287 
00288 }
00289 
00290 #include "ShGraphImpl.hpp"
00291 
00292 #endif

Generated on Thu Jul 28 17:33:02 2005 for Sh by  doxygen 1.4.3-20050530