|
COT 5405 Advanced Algorithms Chris Lacher Notes 9: Graphs and Basic Graph Algorithms |
Graph in adjacency list representation (vertices indexed 0,1,...n-1) s = start vertex Vector < color_type > color // algorithm control Vector < vertex > parent // computed by algorithm Vector < int > distance // number of edges between start and v Queue < vertex > conQueue // algorithm control
// startup phase for(each vertex possibly excepting s) { color[v] = white; distance[v] = infinity; parent[v] = NIL; } color[s] = gray; distance[s] = 0; parent[s] = 0; conQueue.MakeEmpty(); conQueue.Push(s); // search phase while (!conQueue.Empty()) { u = conQueue.Pop(); for each v in ADJ[u] { if (color[v] = white) { color[v] = gray; distance[v] = distance[u] + 1; parent[v] = u; conQueue.Push(v); } } color[u] = black; }
class BFS { typedef unsigned int Vertex; private: // reference to structure being searched GraphBase& g_; // adjacency list representation (vertices indexed 0,1,...n-1) Vertex s_; // starting search here private: // control variables Vector < ColorType > color_; Queue < Vertex > conQueue_; public: // informational variables Vector < Vertex > parent_; // = parent in BFS tree Vector < int > distance_; // = distance from start public: // methods void Init(Vertex startHere) { s_ = startHere; for(each vertex v of g_ except possibly s_) { color_[v] = white; distance_[v] = infinity; parent_[v] = NIL; } color_[s_] = gray; distance_[s_] = 0; parent_[s_] = NIL; conQueue_.MakeEmpty(); conQueue_.Push(s_); } void Run() { while (!conQueue_.Empty()) { u = conQueue_.Pop(); for each v in g_.ADJ[u] { if (color_[v] = white) { color_[v] = gray; distance_[v] = distance_[u] + 1; parent_[v] = u; conQueue_.Push(v); } // if } // for color_[u] = black; } // while } };
class DFS { typedef unsigned int Vertex; private: GraphBase& g_; // adjacency list representation (vertices indexed 0,1,...n-1) Vertex start_; // starting search here Stack < Vertex > conStack_; Vector < ColorType > color_; unsigned int time_; // increments at each color change public: Vector < Vertex > parent_; // parent in DFS forrest Vector < int > d_; // discovery time - when color changes to gray Vector < int > f_; // finish time - when color color changes to black public: void Init(Vertex startHere) { start_ = startHere; for(each vertex v) { color_[v] = white; parent_[v] = NIL; } time_ = 0; conStack_.MakeEmpty(); } private: void Run(Vertex s) { color_[s] = gray; parent_[s] = NIL; ++time_; d_[s] = time_; conStack_.Push(s); while (!conStack_.Empty()) { u = conStack_.Top(); if (there exists v in ADJ[u] such that color_[v] == white) { color_[v] = gray; ++time_; d_[v] = time_; parent_[v] = u; conStack_.Push(v); } else { color_[u] = black; conStack_.Pop(); ++time_; f_[u] = time_; } } } // Run(s) public: // traditionally DFS is run until all vertices have been discovered void Run() { Run(start_); while (there is a white vertex s) Run(s); } // Run() };
class TopSort : public DFS { // DFS::Run() // then enque vertices in order of f_ value };
class TopSort2 { private: DiGraph& d_; Vector v_ of integers; // stores "unused" inDegree of each vertex (initialized to inDegree) Stack s_ of vertices; // stores vertices with no "unused" inDegree for processing public: Queue q_ of vertices; // stores topological ordering of vertices (initialized empty) void Init() { q_.Clear(); s_.Clear(); for (i = 0; i < d_.VrtxSize(); ++i) { v_[i] = d_.InDeg(i); if (v_[i] == 0) s_.Push(i); } } void Sort() { While (!s_.Empty()) { t = s_.Top(); s_.Pop(); for every neighbor n of t { --v_[n]; if (v_[n] == 0) s_.Push(n); } q_.Push (t); } if (q_.Size() == d_.VrtxSize()) q_ contains a topological ordering of d_; else d_ has a cycle; } // Replace stack with queue to preserve order of discovery // Replace stack with priority queue if vertices have "preferred" order };