Skip to content

Commit

Permalink
Adding Graph Algorithms
Browse files Browse the repository at this point in the history
  • Loading branch information
rrohitramsen authored Aug 9, 2017
1 parent 4af0597 commit d4a674a
Show file tree
Hide file tree
Showing 11 changed files with 1,429 additions and 251 deletions.
102 changes: 102 additions & 0 deletions ConnectedComponents.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.program.graph.algo;

import java.util.ArrayList;
import java.util.List;

public class ConnectedComponents {

private int [] connectedId;
private int processCount;

public ConnectedComponents(Graph g) {
this.connectedId = new int[g.getVertices().size()];
this.processCount = 0;
populateConnectedId(g);
}

public void populateConnectedId(Graph g){

for (Graph.Vertex v : g.getVertices()) {
if (!v.visited){
dfs(g, v);
processCount++;
}
}
}

public void dfs(Graph g, Graph.Vertex v){

v.visited = true;
connectedId[g.getIndexOf(v)] = processCount;
for (Graph.Edge e : v.getEdges()) {
if (!e.getTo().visited) {
dfs(g,e.getTo());
}
}
}


public boolean isConnected(Graph g, Graph.Vertex v, Graph.Vertex w){
return connectedId[g.getIndexOf(v)] == connectedId[g.getIndexOf(w)];
}

public static void main(String[] args) {
List<Graph.Vertex> vertices = new ArrayList<Graph.Vertex>();
Graph.Vertex A = new Graph.Vertex('A');
/*
* If Inner class graph and edge were not static then
* First we have to instantiate Graph and then vertex/edge
* eg :
* Grapg g1 = new Graph();
* Graph.vertex A = g1.new Vertex('A');
*
*/
Graph.Vertex B = new Graph.Vertex('B');
Graph.Vertex C = new Graph.Vertex('C');
Graph.Vertex D = new Graph.Vertex('D');
Graph.Vertex E = new Graph.Vertex('E');
Graph.Vertex F = new Graph.Vertex('F');
Graph.Vertex G = new Graph.Vertex('G');
Graph.Vertex H = new Graph.Vertex('H');
Graph.Vertex I = new Graph.Vertex('I');
Graph.Vertex J = new Graph.Vertex('J');
Graph.Vertex K = new Graph.Vertex('K');
Graph.Vertex L = new Graph.Vertex('L');
vertices.add(A);
vertices.add(B);
vertices.add(C);
vertices.add(D);
vertices.add(E);
vertices.add(F);
vertices.add(G);
vertices.add(H);
vertices.add(I);
vertices.add(J);
vertices.add(K);
vertices.add(L);

List<Graph.Edge> edges = new ArrayList<Graph.Edge>();
edges.add(new Graph.Edge(0,A,B));
edges.add(new Graph.Edge(0,B,C));
edges.add(new Graph.Edge(0,B,H));
edges.add(new Graph.Edge(0,C,D));
edges.add(new Graph.Edge(0,C,E));
edges.add(new Graph.Edge(0,E,H));
edges.add(new Graph.Edge(0,E,F));
edges.add(new Graph.Edge(0,E,G));

edges.add(new Graph.Edge(0,I,J));
edges.add(new Graph.Edge(0,J,K));
edges.add(new Graph.Edge(0,I,L));
edges.add(new Graph.Edge(0,I,K));


Graph g = new Graph(vertices, edges);
ConnectedComponents cc = new ConnectedComponents(g);
System.out.println("A is Connected to G ::: "+cc.isConnected(g, A, G));
System.out.println("I is Connected to A ::: "+cc.isConnected(g, I, A));
System.out.println("I is Connected to K ::: "+cc.isConnected(g, I, K));

}

}
87 changes: 87 additions & 0 deletions Cycle.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.program.graph.algo;

import java.util.ArrayList;
import java.util.List;

public class Cycle {

private boolean hasCycle;

public Cycle(Graph g){

for (Graph.Vertex v: g.getVertices()) {
if (!v.visited) {
dfs(g, v, v);
}
}
}

/*
* For each vertex we have three option
* 1> Either next vertex will be unvisited, then simply call dfs(q, w, prev)
* 2> Or next vertex is visited. then we go to else part
* 3> if (w != prev), here if w == prev means w next vertex is same vertex we are coming from
* and if its visited and its not equal to prev then we have encountered loop in graph.
* coz this vertex w is already visited and its not equal to prev vertex.
*/
public void dfs(Graph g, Graph.Vertex v, Graph.Vertex prevVertex ){

v.visited = true;
Graph.Vertex w;
for (Graph.Edge e : v.getEdges()) {
w = e.getTo();
if (!w.visited) {
dfs(g, w, v); // here v is previous visited vertex
}else if (w != prevVertex){
hasCycle = true;
}
}
}

public boolean hasCycle(){
return hasCycle;
}

public static void main(String[] args) {
List<Graph.Vertex> vertices = new ArrayList<Graph.Vertex>();
Graph.Vertex A = new Graph.Vertex('A');
/*
* If Inner class graph and edge were not static then
* First we have to instantiate Graph and then vertex/edge
* eg :
* Grapg g1 = new Graph();
* Graph.vertex A = g1.new Vertex('A');
*
*/
Graph.Vertex B = new Graph.Vertex('B');
Graph.Vertex C = new Graph.Vertex('C');
Graph.Vertex D = new Graph.Vertex('D');
Graph.Vertex E = new Graph.Vertex('E');
Graph.Vertex F = new Graph.Vertex('F');
Graph.Vertex G = new Graph.Vertex('G');
Graph.Vertex H = new Graph.Vertex('H');
vertices.add(A);
vertices.add(B);
vertices.add(C);
vertices.add(D);
vertices.add(E);
vertices.add(F);
vertices.add(G);
vertices.add(H);

List<Graph.Edge> edges = new ArrayList<Graph.Edge>();
edges.add(new Graph.Edge(0,A,B));
edges.add(new Graph.Edge(0,B,C));
edges.add(new Graph.Edge(0,B,H));
edges.add(new Graph.Edge(0,C,D));
edges.add(new Graph.Edge(0,C,E));
edges.add(new Graph.Edge(0,E,H));
edges.add(new Graph.Edge(0,E,F));
edges.add(new Graph.Edge(0,E,G));

Graph g = new Graph(vertices, edges);
Cycle cyc = new Cycle(g);
System.out.println("Graph has cycle ::: "+cyc.hasCycle());
}

}
96 changes: 96 additions & 0 deletions DFSPaths.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.program.graph.algo;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class DFSPaths {
private Graph.Vertex [] edgeTo;
private boolean visited[];

/*
* its a recursive approach no need of method getAdjUnvisitedVertex()
*/
public void dfs(Graph g, Graph.Vertex v){

//visited[g.getIndexOf(v)] = true;
v.visited = true;
for (Graph.Edge e : v.getEdges()) {
Graph.Vertex w = e.getTo();
if (!w.visited) {
edgeTo[g.getIndexOf(w)] = v; // edge path, it says how can w access from v, like edgTo[B] = A;, if we are starting from A,
dfs(g, w);
}
}

}


/*
* Used stack coz want to print path in source to target order else
* we can print it in target to source order without using stack
*/
public void printPath(Graph g, Graph.Vertex source, Graph.Vertex target){
Stack<Graph.Vertex> path = new Stack<Graph.Vertex>();

for(Graph.Vertex v = target; v != source; v = edgeTo[g.getIndexOf(v)]){
path.add(v);
}
path.add(source);
//print paths
while (!path.isEmpty()) {
System.out.println(path.pop());
}
}


public DFSPaths(int size) {
edgeTo = new Graph.Vertex[size];
visited = new boolean[size];
}

public static void main(String[] args) {
List<Graph.Vertex> vertices = new ArrayList<Graph.Vertex>();
Graph.Vertex A = new Graph.Vertex('A');
/*
* If Inner class graph and edge were not static then
* First we have to instantiate Graph and then vertex/edge
* eg :
* Grapg g1 = new Graph();
* Graph.vertex A = g1.new Vertex('A');
*
*/
Graph.Vertex B = new Graph.Vertex('B');
Graph.Vertex C = new Graph.Vertex('C');
Graph.Vertex D = new Graph.Vertex('D');
Graph.Vertex E = new Graph.Vertex('E');
Graph.Vertex F = new Graph.Vertex('F');
Graph.Vertex G = new Graph.Vertex('G');
Graph.Vertex H = new Graph.Vertex('H');
vertices.add(A);
vertices.add(B);
vertices.add(C);
vertices.add(D);
vertices.add(E);
vertices.add(F);
vertices.add(G);
vertices.add(H);

List<Graph.Edge> edges = new ArrayList<Graph.Edge>();
edges.add(new Graph.Edge(0,A,B));
edges.add(new Graph.Edge(0,B,C));
edges.add(new Graph.Edge(0,B,H));
edges.add(new Graph.Edge(0,C,D));
edges.add(new Graph.Edge(0,C,E));
edges.add(new Graph.Edge(0,E,H));
edges.add(new Graph.Edge(0,E,F));
edges.add(new Graph.Edge(0,E,G));

Graph g = new Graph(vertices, edges);
DFSPaths dfs = new DFSPaths(g.getVertices().size());
dfs.dfs(g, A);
dfs.printPath(g, A, F);

}

}
111 changes: 111 additions & 0 deletions DegreeOfSeparation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package com.program.graph.algo;

import java.util.*;

/*
* Expedia----
* I rephrase the original question as the following: Let say in Facebook,
* given two person A and B. Write a function to find out whether A is a friend or a friend
* of a friend of ... of B.
*/

/*
* Consider any social networking website like facebook etc.
* Design an algorithm / function that calculates minimum degree of connection
* between given two users. Assume that you are have already written function that
* returns a list of friends of given user :
* getFriends(username/id) : its similar to getting no of edges for the given vertex.
*/


public class DegreeOfSeparation {

DiGraph.Vertex [] pathTo;

public DegreeOfSeparation(int size){
pathTo = new DiGraph.Vertex[size];
}

/*
* Traverse till target vertex t is not visited,once t is visited hence we have found
* the shortest path between given friend A and B.
*/
public void bfs(DiGraph g, DiGraph.Vertex v, DiGraph.Vertex t){
Queue<DiGraph.Vertex> queue = new ArrayDeque<>(g.getVertices().size());
queue.add(v);
v.setVisited(true);
DiGraph.Vertex w;
boolean found = false;
while (!queue.isEmpty() && !found) {
v = queue.remove();
for (DiGraph.Edge e : v.getEdges()) {
w = e.getTo();
if (!w.isVisited()) {
queue.add(w);
w.setVisited(true);
pathTo[g.getIndexOf(w)] = v;
}
if (t.isVisited()) {
found = true; // traverse till t is not visited
break;
}
}
}
}

public void printPath(DiGraph g, DiGraph.Vertex s, DiGraph.Vertex t){
//call bfs to prepare the path
bfs(g, s, t);
Stack<DiGraph.Vertex> stack = new Stack<DiGraph.Vertex>();
for (DiGraph.Vertex x = t; x != s; x = pathTo[g.getIndexOf(x)]) {
stack.add(x);
}
stack.add(s);

System.out.println("Shortest Path Between Source and Target");
while (!stack.isEmpty()) {
System.out.println(stack.pop());
}

//or if we want to print in format A is friend of a Friend of B
System.out.println("["+s+"] is friend");
for (DiGraph.Vertex x = t; x != s; x = pathTo[g.getIndexOf(x)]) {
System.out.println("of a friend");
}
System.out.println(" of ["+t+"] ");
}

public static void main(String[] args) {
List<DiGraph.Vertex> vertices = new ArrayList<DiGraph.Vertex>();
DiGraph.Vertex A = new DiGraph.Vertex("A");
DiGraph.Vertex B = new DiGraph.Vertex("B");
DiGraph.Vertex C = new DiGraph.Vertex("C");
DiGraph.Vertex D = new DiGraph.Vertex("D");
DiGraph.Vertex E = new DiGraph.Vertex("E");
DiGraph.Vertex F = new DiGraph.Vertex("F");
DiGraph.Vertex G = new DiGraph.Vertex("G");
DiGraph.Vertex H = new DiGraph.Vertex("H");
vertices.add(A);
vertices.add(B);
vertices.add(C);
vertices.add(D);
vertices.add(E);
vertices.add(F);
vertices.add(G);
vertices.add(H);

List<DiGraph.Edge> edges = new ArrayList<DiGraph.Edge>();
edges.add(new DiGraph.Edge(0,A,B));
edges.add(new DiGraph.Edge(0,B,C));
edges.add(new DiGraph.Edge(0,H,B));
edges.add(new DiGraph.Edge(0,C,D));
edges.add(new DiGraph.Edge(0,C,E));
edges.add(new DiGraph.Edge(0,E,H));
edges.add(new DiGraph.Edge(0,E,F));
edges.add(new DiGraph.Edge(0,E,G));

DiGraph g = new DiGraph(DiGraph.TYPE.UNDIRECTED, vertices, edges);
DegreeOfSeparation dgs = new DegreeOfSeparation(g.getVertices().size());
dgs.printPath(g, A, G);
}
}
Loading

0 comments on commit d4a674a

Please sign in to comment.