Thursday, July 13th
Courses with pre-requisites. Given prerequisite requirements, can all courses be taken? We are given a directed edgelist where a node from u to v means to take course u, you must first take node u.
A collection of courses cannot be completed when there's cyclic dependencies. This problem is the same as yesterday's. We will use topological sort to find cycles.
First we reverse the graph. For topological sort, we want to start with nodes that have no incoming edges. This means we reverse the graph so an edge v to u means v must be taken before u. We will create an adjacency list to represent the reversed graph
vector<vector<int> > adjlist(numCourses);
int u,v;
for(int i=0; i<prerequisites.size(); i++) {
u=prerequisites[i][0];
v=prerequisites[i][1];
adjlist[v].push_back(u);
}
Next we calculate the indegree for each vertex. This is accomplished by iterating over the adjacency list, and incrementing a node's indegree whenever the node appears in the adjacency list
vector<int> indegree(numCourses, 0);
vector<int> adj;
for(int i=0; i<numCourses; i++) {
adj=adjlist[i];
for(int j=0; j<adj.size(); j++) {
v=adj[j];
indegree[v]+=1;
}
}
We want to begin topological sort using nodes with indegree of zero, so iterate through the indegree vector and push nodes with 0 indegree
queue<int> q;
for(int i=0; i<numCourses; i++) {
if(indegree[i]==0) {
q.push(i);
}
}
Finally, we perform breadth first search using the queue of nodes with 0 indegree. We count each time a node is popped from the queue. Every time a node is popped, we iterate over its neighbors and decrement each neighbor's indegree by 1. If the new indegree is 0, it's added to the back of the queue. Like breadth-first search, this process continues until the queue is empty.
int node, numdone=0, qsize, neighbor;
vector<int> neighbors;
while(!q.empty()) {
qsize=q.size();
for(int i=0; i<qsize; i++) {
node = q.front();
q.pop();
numdone++;
neighbors = adjlist[node];
for(int j=0; j<neighbors.size(); j++) {
neighbor=neighbors[j];
indegree[neighbor]-=1;
if(indegree[neighbor]==0) {
q.push(neighbor);
}
}
}
}
Counting the number of processed ("popped") nodes, if the number processed equals the total number of nodes in the original graph, then we can finish all the courses. If the number of processed nodes is less than the total number of nodes, then we have a cycle, and the courses cannot be finished
return numdone == numCourses ? true : false;
Comments
Post a Comment