#ifndef GRAPHALGORITHMS_H #define GRAPHALGORITHMS_H ///////////////////////////////////////////////////////////////// // GraphAlgorithms.h - Algorithms on graph structures // // ver 1.0 // // ----------------------------------------------------------- // // copyright © Jim Fawcett, 2012 // // All rights granted provided that this notice is retained // // ----------------------------------------------------------- // // Jim Fawcett, CST 4-187, Syracuse University, 315 443 3948 // // Summer Projects, 2012 // // Win7, Visual Studio 2010 // ///////////////////////////////////////////////////////////////// /* * Package Operations: * ------------------- * This package provides classes supporting algorithms on * directed graphs. It provides the classes: * - strongComp: * Find strong components of graph (mutual dependencies in * a dependency graph. * And the functions: * - vertsWithNoParents * Find all the top-level vertices, e.g., no parents, if they * exist. * Package Plans: * -------------- * - CondensedGraph: * Builds graph of strong components (which is always acyclic) * - TopoSort: * Executes topological sort on condensed graphs * - ExpandCondensedGraph * Expands sorted condensed graph to a quasi-sorted graph * of the original vertices * - Disconnected: * Find disconnected components */ #include #include #include #include "..\graph\Graph.h" #include "..\LibUtils\LibUtils.h" namespace DirectedGraph { //----------------------------------------------------------- // vertsWithNoParents - find top vertices if any template std::vector< Vertex > vertsWithNoParents(Graph& g) { typedef std::pair Edge; std::vector parentCount; Graph::iterator iter = g.begin(); while(iter != g.end()) { parentCount.push_back(0); ++iter; } iter = g.begin(); while(iter != g.end()) { Vertex v = *iter; for(size_t i=0; i> noParents; for(size_t j=0; j::strongComp(graph& g); class Components { public: typedef std::vector> Comps; Components() {} Components(Comps& comps) : comps_(comps) {} std::vector& operator[](size_t i) { return comps_[i]; } size_t size() { return comps_.size(); } size_t component(size_t index); void push_back(std::vector& vec) { comps_.push_back(vec); } private: Comps comps_; }; //----< find strong component of g[index] >------------------ size_t Components::component(size_t index) { for(size_t i=0; i class Algorithms { public: //typename typedef std::vector> Component; typedef Graph graph; typedef Vertex vertex; Components strongComp(const graph& g); Components createCondensedGraph(const graph& g, graph& condGraph); std::vector topoSort(graph& g); private: void Strong(const graph& g, size_t); void indexWalk(graph& g, size_t start); std::vector num; std::vector lowlink; LibUtils::SearchableStack stack_; size_t visitNum; Components comp; std::set targetVertices_; std::vector orderedVertices_; }; /* * A strong componet is a set of mutually dependent vertices where * you interpret a directed edge as a dependency relationship. * * The implemented here is based on an algorithm published by * D. Sleator, CMU which was based on an original by Tarjan. * http://www.cs.cmu.edu/afs/cs/academic/class/15451-s06/www/lectures/DFS-strong-components.pdf */ //----< helper function for strong components >-------------- template void Algorithms::Strong(const graph& g, size_t v) { ++visitNum; num[v-1] = visitNum; lowlink[v-1] = visitNum; stack_.push(v); for(size_t i=0; i compElem; size_t top = stack_.top(); size_t cmp = num[v-1]; while(stack_.size() > 0 && num[stack_.top()-1] >= num[v-1]) compElem.push_back(stack_.pop()-1); comp.push_back(compElem); } } //----< returns strong components of graph g >--------------- template Components Algorithms::strongComp(const graph& g) { std::vector compElem; visitNum = 0; for(size_t i=0; i Components Algorithms::createCondensedGraph(const graph& g, graph& condGraph) { Components comp = strongComp(g); //insert strong components as vertices for(size_t i=0; i v(id, value); condGraph.addVertex(v); } // to each vertex add an edge going to strong component of // every child of every vertex in strong component, eliminating // duplicates and edges that stay in strong component for(size_t i=0; i void Algorithms::indexWalk(Graph& g, size_t index) { g[index].visited() = true; for(size_t i=0; i std::vector Algorithms::topoSort(Graph& g) { g.resetVisited(); orderedVertices_.clear(); for(size_t i=0; i