|
|
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
};