Count number of cycles in directed graph using DFS - algorithm

I want to count total number of directed cycles available in a directed graph (Only count is required).
You can assume graph is given as adjacency matrix.
I know DFS but could not make a working algorithm for this problem.
Please provide some pseudo code using DFS.

This algorithm based on DFS seems to work, but I don't have a proof.
This algorithm is modified from the dfs for topological sorting
(https://en.wikipedia.org/wiki/Topological_sorting#Depth-first_search).
class Solution {
vector<Edge> edges;
// graph[vertex_id] -> vector of index of outgoing edges from #vertex_id.
vector<vector<int>> graph;
vector<bool> mark;
vector<bool> pmark;
int cycles;
void dfs(int node) {
if (pmark[node]) {
return;
}
if (mark[node]) {
cycles++;
return;
}
mark[node] = true;
// Try all outgoing edges.
for (int edge_index : graph[node]) {
dfs(edges[edge_index].to);
}
pmark[node] = true;
mark[node] = false;
}
int CountCycles() {
// Build graph.
// ...
cycles = 0;
mark = vector<bool>(graph.size(), false);
pmark = vector<bool>(graph.size(), false);
for (int i = 0; i < (int) graph.size(); i++) {
dfs(i);
}
return cycles;
}
};

Let us consider that , we are coloring the nodes with three types of color . If the node is yet to be discovered then its color is white . If the node is discovered but any of its descendants is/are yet to be discovered then its color is grey. Otherwise its color is black . Now, while doing DFS if we face a situation when, there is an edge between two grey nodes then the graph has cycle. The total number of cycles will be total number of times we face the situation mentioned above i.e. we find an edge between two grey nodes .

Related

How to increase efficiency of Prim's algorithm used in finding minimum spanning tree from adjacency matrix of an undirected graph?

I have implemented an undirected graph using adjacency matrix. Now I want to find the edges in the minimum spanning tree that can be obtained by using Prim's Algorithm (along with priority queue). I did that using classic method, but it is highly inefficient (giving correct results). On larger data sets (of vertices and the vertices that they are connected to.).
This is the implementation of Prim's algorithm using priority queue as i used in my code. (This is the code from site geeksforgeeks, the code i wrote is an inspiration from this.)
void Graph::primMST()
{
// Create a priority queue to store vertices that
// are being primMST. This is weird syntax in C++.
// Refer below link for details of this syntax
// http://geeksquiz.com/implement-min-heap-using-stl/
priority_queue< iPair, vector <iPair> , greater<iPair> > pq;
int src = 0; // Taking vertex 0 as source
// Create a vector for keys and initialize all
// keys as infinite (INF)
vector<int> key(V, INF);
// To store parent array which in turn store MST
vector<int> parent(V, -1);
// To keep track of vertices included in MST
vector<bool> inMST(V, false);
// Insert source itself in priority queue and initialize
// its key as 0.
pq.push(make_pair(0, src));
key[src] = 0;
/* Looping till priority queue becomes empty */
while (!pq.empty())
{
// The first vertex in pair is the minimum key
// vertex, extract it from priority queue.
// vertex label is stored in second of pair (it
// has to be done this way to keep the vertices
// sorted key (key must be first item
// in pair)
int u = pq.top().second;
pq.pop();
//Different key values for same vertex may exist in the priority queue.
//The one with the least key value is always processed first.
//Therefore, ignore the rest.
if(inMST[u] == true){
continue;
}
inMST[u] = true; // Include vertex in MST
// 'i' is used to get all adjacent vertices of a vertex
list< pair<int, int> >::iterator i;
for (i = adj[u].begin(); i != adj[u].end(); ++i)
{
// Get vertex label and weight of current adjacent
// of u.
int v = (*i).first;
int weight = (*i).second;
// If v is not in MST and weight of (u,v) is smaller
// than current key of v
if (inMST[v] == false && key[v] > weight)
{
// Updating key of v
key[v] = weight;
pq.push(make_pair(key[v], v));
parent[v] = u;
}
}
}
// Print edges of MST using parent array
for (int i = 1; i < V; ++i)
printf("%d - %d\n", parent[i], i);
}
Thanks in advance.

How to reduce a strongly connected component to one vertex?

From https://algs4.cs.princeton.edu/42digraph/
Reachable vertex in a digraph. Design a linear-time algorithm to determine whether a digraph has a vertex that is reachable from
every other vertex.
Kosaraju-Sharir algorithm gives us the strongly connected components. Java code for that can be seen here. Reducing each SCC to a single vertex, a vertex that has outdegree zero is reachable from every other.
Problem is, everyone seems to be talking about reducing a SCC without providing details. What is an efficient algorithm to do so?
Following is a Java solution to my own question. For the graph representation, it uses edu.princeton.cs:algs4:1.0.3 from https://github.com/kevin-wayne/algs4. There appears to be general algorithms for graph contraction, as outlined in this paper; however, for my purposes, the following is sufficient.
/**
* 43. <b>Reachable vertex.</b>
* <p>
* DAG: Design a linear-time algorithm to determine whether a DAG has a vertex that is reachable from every other
* vertex, and if so, find one.
* Digraph: Design a linear-time algorithm to determine whether a digraph has a vertex that is reachable from every
* other vertex, and if so, find one.
* <p>
* Answer:
* DAG: Consider an edge (u, v) ∈ E. Since the graph is acyclic, u is not reachable from v.
* Thus u cannot be the solution to the problem. From this it follows that only a vertex of
* outdegree zero can be a solution. Furthermore, there has to be exactly one vertex with outdegree zero,
* or the problem has no solution. This is because if there were multiple vertices with outdegree zero,
* they wouldn't be reachable from each other.
* <p>
* Digraph: Reduce the graph to it's Kernel DAG, then find a vertex of outdegree zero.
*/
public class Scc {
private final Digraph g;
private final Stack<Integer> s = new Stack<>();
private final boolean marked[];
private final Digraph r;
private final int[] scc;
private final Digraph kernelDag;
public Scc(Digraph g) {
this.g = g;
this.r = g.reverse();
marked = new boolean[g.V()];
scc = new int[g.V()];
Arrays.fill(scc, -1);
for (int v = 0; v < r.V(); v++) {
if (!marked[v]) visit(v);
}
int i = 0;
while (!s.isEmpty()) {
int v = s.pop();
if (scc[v] == -1) visit(v, i++);
}
Set<Integer> vPrime = new HashSet<>();
Set<Map.Entry<Integer, Integer>> ePrime = new HashSet<>();
for (int v = 0; v < scc.length; v++) {
vPrime.add(scc[v]);
for (int w : g.adj(v)) {
// no self-loops, no parallel edges
if (scc[v] != scc[w]) {
ePrime.add(new SimpleImmutableEntry<>(scc[v], scc[w]));
}
}
}
kernelDag = new Digraph(vPrime.size());
for (Map.Entry<Integer, Integer> e : ePrime) kernelDag.addEdge(e.getKey(), e.getValue());
}
public int reachableFromAllOther() {
for (int v = 0; v < kernelDag.V(); v++) {
if (kernelDag.outdegree(v) == 0) return v;
}
return -1;
}
// reverse postorder
private void visit(int v) {
marked[v] = true;
for (int w : r.adj(v)) {
if (!marked[w]) visit(w);
}
s.push(v);
}
private void visit(int v, int i) {
scc[v] = i;
for (int w : g.adj(v)) {
if (scc[w] == -1) visit(w, i);
}
}
}
Running it on the graph below produces the strongly-connected components as shown. Vertex 0 in the reduced DAG is reachable from every other vertex.
What I couldn't find anywhere is the kind of detail that I presented above. Comments like "well, this is easy, you do that, then you do something else" are thrown around without concrete details.
Suppose you already have a method to compute SCCs and the usual graph, vertex and edge methods. Then it's just creating a new graph, adding a vertex representative for each SCC and then adding edge representatives.
For the edges you need to be able to map an original vertex (the edge destination) to its representative in the new graph. You can model that in the first pass using a Map<Vertex, SCC> which maps vertices to their SCCs and a Map<SCC, Vertex> which maps SCCs to their representative vertices in the new graph. Or you directly have a Map<Vertex, Vertex> mapping original vertices to their representatives.
Here is a Java solution:
public static Graph graphToSccGraph(Graph graph) {
Collection<SCC> sccs = SccComputation.computeSccs(graph);
Graph sccGraph = new Graph();
Map<Vertex, SCC> vertexToScc = new HashMap<>();
Map<SCC, Vertex> sccToRep = new HashMap<>();
// Add a representative for each SCC (O(|V|))
for (SCC scc : sccs) {
Vertex rep = new Vertex();
sccGraph.addVertex(rep);
sccToRep.put(scc, rep);
for (Vertex vertex : scc.getVertices()) {
vertexToScc.put(vertex, scc);
}
}
// Add edge representatives (O(|E|))
for (Vertex vertex : graph.getVertices()) {
Vertex sourceRep = sccToRep.get(vertexToScc.get(vertex));
for (Edge edge : vertex.getOutgoingEdges()) {
Vertex destRep = sccToRep.get(vertexToScc.get(edge.getDestination()));
Edge edgeRep = new Edge(sourceRep, destRep);
if (!sccGraph.contains(edgeRep)) {
sccGraph.addEdge(edgeRep);
}
}
}
return sccGraph;
}
Time complexity is linear in the size of the graph (amount of vertices and edges), so optimal. That is Theta(|V| + |E|).
Usually people use a Union-Find (see Wikipedia) data-structure to make this even simpler and get rid of the Maps.

Number of connected components after deleting k vertices

I am trying to solve the following graph problem:
We are given a general unweighted and undirected graph and k (k < |V| ) vertices that are
already known beforehand. The vertices are deleted sequentially. After
each deletion, how many connected components are there?
I thought of using tarjan's algorithm at each step to check if the current vertex to be deleted is a cut vertex so that when the deletion is performed, we can simply add the number of neighbours to the number of connected components. The complexity of this algorithm is O(V(V+E)).
I was told that there is a O(V+E) algorithm to perform this task. But I cannot figure it out. Research on Google also does not reveal much. Could anyone please advise me?
We can use the fact that the vertices are known beforehand.
Let's solve a "reverse" problem: given a graph and a list vertices that are ADDED to it sequentially, compute the number of connected components in the graph after each addition structure.
The solution is pretty straightforward: we can maintain a disjoint set union structure and add all edges incident to the vertex to the graph (it's easy to keep the number of components in this structure: initially, it is equal to the number of vertices and is decreased by one when a union actually happens).
The original problem is reduced to the "reverse" one in the following way:
Let's add all edges that are not incident to any of the deleted vertices to the disjoint set union.
Now we can reverse the list of deleted vertices and add them one by one as described above.
After that, we need to reverse the resulting list that contains the number of components.
Note: this solution is not actually O(V + E), its O(V + E * alpha(V)), where alpha(x) is the inverse Ackermann's function. It is very close to linear for all practical purposes.
here is my implementation of algorithm in c++ using disjoint set:
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
typedef pair<int, int> pii;
const int M=2e5+137;
class DisjointSet {
public:
int connected_comp;
int parent[100000];
void makeSet(int n){
for (int i=1;i<n+1; ++i)
parent[i] = i;
connected_comp = n;
}
int Find(int l) {
if (parent[l] == l)
return l;
return Find(parent[l]);
}
void Union(int m, int n) {
int x = Find(m);
int y = Find(n);
if(x==y) return;
if(x<y){
parent[y] = x;
connected_comp--;
}
else{
parent[x] = y;
connected_comp--;
}
}
};
set<pii> not_delete;
vector<pii> to_add;
int main(){
int node, edge;
cout<<"enter number of nodes and edges"<<"\n";
cin>>node>>edge;
DisjointSet dis;
dis.makeSet(node);
cout<<"enter two nodes to add edges"<<"\n";
for(int i=0;i<edge;i++){
int u,v;
cin>>u>>v;
if(u>v){
not_delete.insert({u,v});
}
else{
not_delete.insert({v,u});
}
}
int deletions;
cout<<"enter number of deletions"<<"\n";
cin>>deletions;
cout<<"enter two node to delete edge between them"<<"\n";
for(int i=0;i<deletions;i++){
int u,v;
cin>>u>>v;
if(u>v){
not_delete.erase({u,v});// edges that never delete from graph
to_add.pb({u,v}); // edges that gonna delete from graph
}
else{
not_delete.erase({v,u});
to_add.pb({v,u});
}
}
vector<int> res;
// first adding edges that never delete from graph
for(pii x: not_delete){
dis.Union(x.first, x.second);
}
res.pb(dis.connected_comp);
// then adding edges that will be deleted from graph backwards
reverse(to_add.begin(), to_add.end());
for(pii x: to_add){
dis.Union(x.first, x.second);
res.pb(dis.connected_comp);
}
cout<<"connected components after each deletion:"<<"\n";
for (auto it = ++res.rbegin(); it != res.rend(); ++it)
cout << *it << "\n";
return 0;
}

Writing a program to check if a graph is bipartite

I need to write a program that check if a graph is bipartite.
I have read through wikipedia articles about graph coloring and bipartite graph. These two article suggest methods to test bipartiteness like BFS search, but I cannot write a program implementing these methods.
Why can't you? Your question makes it hard for someone to even write the program for you since you don't even mention a specific language...
The idea is to start by placing a random node into a FIFO queue (also here). Color it blue. Then repeat this while there are nodes still left in the queue: dequeue an element. Color its neighbors with a different color than the extracted element and insert (enqueue) each neighbour into the FIFO queue. For example, if you dequeue (extract) an element (node) colored red, color its neighbours blue. If you extract a blue node, color its neighbours red. If there are no coloring conflicts, the graph is bipartite. If you end up coloring a node with two different colors, than it's not bipartite.
Like #Moron said, what I described will only work for connected graphs. However, you can apply the same algorithm on each connected component to make it work for any graph.
http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/GraphAlgor/breadthSearch.htm
Please read this web page, using breadth first search to check when you find a node has been visited, check the current cycle is odd or even.
A graph is bipartite if and only if it does not contain an odd cycle.
The detailed implementation is as follows (C++ version):
struct NODE
{
int color;
vector<int> neigh_list;
};
bool checkAllNodesVisited(NODE *graph, int numNodes, int & index);
bool checkBigraph(NODE * graph, int numNodes)
{
int start = 0;
do
{
queue<int> Myqueue;
Myqueue.push(start);
graph[start].color = 0;
while(!Myqueue.empty())
{
int gid = Myqueue.front();
for(int i=0; i<graph[gid].neigh_list.size(); i++)
{
int neighid = graph[gid].neigh_list[i];
if(graph[neighid].color == -1)
{
graph[neighid].color = (graph[gid].color+1)%2; // assign to another group
Myqueue.push(neighid);
}
else
{
if(graph[neighid].color == graph[gid].color) // touble pair in the same group
return false;
}
}
Myqueue.pop();
}
} while (!checkAllNodesVisited(graph, numNodes, start)); // make sure all nodes visited
// to be able to handle several separated graphs, IMPORTANT!!!
return true;
}
bool checkAllNodesVisited(NODE *graph, int numNodes, int & index)
{
for (int i=0; i<numNodes; i++)
{
if (graph[i].color == -1)
{
index = i;
return false;
}
}
return true;
}

algorithm to use to return a specific range of nodes in a directed graph

I have a class Graph with two lists types namely nodes and edges
I have a function
List<int> GetNodesInRange(Graph graph, int Range)
when I get these parameters I need an algorithm that will go through the graph and return the list of nodes only as deep (the level) as the range.
The algorithm should be able to accommodate large number of nodes and large ranges.
Atop this, should I use a similar function
List<int> GetNodesInRange(Graph graph, int Range, int selected)
I want to be able to search outwards from it, to the number of nodes outwards (range) specified.
alt text http://www.freeimagehosting.net/uploads/b110ccba58.png
So in the first function, should I pass the nodes and require a range of say 2, I expect the results to return the nodes shown in the blue box.
The other function, if I pass the nodes as in the graph with a range of 1 and it starts at node 5, I want it to return the list of nodes that satisfy this criteria (placed in the orange box)
What you need seems to be simply a depth-limited breadth-first search or depth-first search, with an option of ignoring edge directionality.
Here's a recursive definition that may help you:
I'm the only one of range 1 from myself.
I know who my immediate neighbors are.
If N > 1, then those of range N from myself are
The union of all that is of range N-1 from my neighbors
It should be a recursive function, that finds neighbours of the selected, then finds neighbours of each neighbour until range is 0. DFS search something like that:
List<int> GetNodesInRange(Graph graph, int Range, int selected){
var result = new List<int>();
result.Add( selected );
if (Range > 0){
foreach ( int neighbour in GetNeighbours( graph, selected ) ){
result.AddRange( GetNodesInRange(graph, Range-1, neighbour) );
}
}
return result;
}
You should also check for cycles, if they are possible. This code is for tree structure.
// get all the nodes that are within Range distance of the root node of graph
Set<int> GetNodesInRange(Graph graph, int Range)
{
Set<int> out = new Set<int>();
GetNodesInRange(graph.root, int Range, out);
return out;
}
// get all the nodes that are within Range successor distance of node
// accepted nodes are placed in out
void GetNodesInRange(Node node, int Range, Set<int> out)
{
boolean alreadyVisited = out.add(node.value);
if (alreadyVisited) return;
if (Range == 0) return;
// for each successor node
{
GetNodesInRange(successor, Range-1, out);
}
}
// get all the nodes that are within Range distance of selected node in graph
Set<int> GetNodesInRange(Graph graph, int Range, int selected)
{
Set<int> out = new Set<int>();
GetNodesInRange(graph, Range, selected, out);
return out;
}
// get all the nodes that are successors of node and within Range distance
// of selected node
// accepted nodes are placed in out
// returns distance to selected node
int GetNodesInRange(Node node, int Range, int selected, Set<int> out)
{
if (node.value == selected)
{
GetNodesInRange(node, Range-1, out);
return 1;
}
else
{
int shortestDistance = Range + 1;
// for each successor node
{
int distance = GetNodesInRange(successor, Range, selected, out);
if (distance < shortestDistance) shortestDistance = distance;
}
if (shortestDistance <= Range)
{
out.add(node.value);
}
return shortestDistance + 1;
}
}
I modified your requirements somewhat to return a Set rather than a List.
The GetNodesInRange(Graph, int, int) method will not handle graphs that contain cycles. This can be overcome by maintaining a collection of nodes that have already been visited. The GetNodesInRange(Graph, int) method makes use of the fact that the out set is a collection of visited nodes to overcome cycles.
Note: This has not been tested in any way.

Resources