diff --git a/ConnectedComponents.java b/ConnectedComponents.java new file mode 100644 index 0000000..a6f623c --- /dev/null +++ b/ConnectedComponents.java @@ -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 vertices = new ArrayList(); + 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 edges = new ArrayList(); + 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)); + + } + +} diff --git a/Cycle.java b/Cycle.java new file mode 100644 index 0000000..209ba7a --- /dev/null +++ b/Cycle.java @@ -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 vertices = new ArrayList(); + 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 edges = new ArrayList(); + 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()); + } + +} diff --git a/DFSPaths.java b/DFSPaths.java new file mode 100644 index 0000000..be7d743 --- /dev/null +++ b/DFSPaths.java @@ -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 path = new Stack(); + + 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 vertices = new ArrayList(); + 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 edges = new ArrayList(); + 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); + + } + +} diff --git a/DegreeOfSeparation.java b/DegreeOfSeparation.java new file mode 100644 index 0000000..8d25f48 --- /dev/null +++ b/DegreeOfSeparation.java @@ -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 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 stack = new Stack(); + 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 vertices = new ArrayList(); + 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 edges = new ArrayList(); + 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); + } +} diff --git a/DiGraph.java b/DiGraph.java new file mode 100644 index 0000000..ae64502 --- /dev/null +++ b/DiGraph.java @@ -0,0 +1,288 @@ +package com.program.graph.algo; + +import java.util.ArrayList; +import java.util.List; + +public class DiGraph { + + private List vertices = new ArrayList(); + private List edges = new ArrayList(); + public int vertexCount; + + private Vertex [] edgeTo; + + public enum TYPE{ + DIRECTED, UNDIRECTED; + }; + + private TYPE type; + + public DiGraph(){ + this.type=TYPE.DIRECTED; + } + + public DiGraph(TYPE type){ + this.type=type; + } + + public DiGraph(TYPE type, List vertices, List edges){ + this(type); + this.vertices.addAll(vertices); + this.edges.addAll(edges); + this.vertexCount = vertices.size(); + + for (Edge e : edges){ + Vertex from = e.from; + Vertex to = e.to; + + if (!vertices.contains(from) || !vertices.contains(to)){ + continue; + } + + int index = vertices.indexOf(from); + from = vertices.get(index); + index = vertices.indexOf(to); + to = vertices.get(index); // only if u want reciprocal edge to be added + + from.addEdge(e); + + if (this.type == TYPE.UNDIRECTED) { + Edge reciprocal = new Edge(to, from); + to.addEdge(reciprocal); + this.edges.add(reciprocal); + } + + } + } + + public DiGraph(DiGraph g){ + /* + * Copy the vertices which copies edges + */ + for (Vertex v : g.vertices) { + this.vertices.add(new Vertex(v)); + } + /* + * update the object references i.e update edges + */ + for (Vertex v : this.vertices){ + for (Edge e : v.edges) { + Vertex from = e.from; + Vertex to = e.to; + int index = this.vertices.indexOf(from); + e.from = this.vertices.get(index); + index = this.vertices.indexOf(to); + e.to = this.vertices.get(index); + this.edges.add(e); + } + } + + } + + public int getIndexOf(Vertex v){ + return this.vertices.indexOf(v); + } + + /* + * Returns the reveres DiGraph of the current graph. + */ + public DiGraph reverse(){ + DiGraph R = new DiGraph(); + + for (Vertex v : vertices){ + R.vertices.add(new Vertex(v)); + } + + for (Vertex v : R.vertices) { + for (Edge e : v.edges) { + Vertex from = e.from; + Vertex to = e.to; + int index = R.vertices.indexOf(to); + e.from = R.vertices.get(index); + index = R.vertices.indexOf(from); + e.to = R.vertices.get(index); + R.edges.add(e); + } + } + return R; + } + + public void dfs(DiGraph g, Vertex v){ + v.visited=true; + System.out.println("-"+v); + for (Edge e : v.edges) { + Vertex w = e.to; + if (!w.visited) { + edgeTo[g.getIndexOf(w)] = v; + dfs(g, w); + } + } + } + + + public List getVertices() { + return vertices; + } + + public void setVertices(List vertices) { + this.vertices = vertices; + } + + public List getEdges() { + return edges; + } + + public void setEdges(List edges) { + this.edges = edges; + } + + public Vertex[] getEdgeTo() { + return edgeTo; + } + + public void setEdgeTo(Vertex[] edgeTo) { + this.edgeTo = edgeTo; + } + + public TYPE getType() { + return type; + } + + public void setType(TYPE type) { + this.type = type; + } + + + public static class Vertex{ + private String label; + private List edges = new ArrayList(); + private int weight; + private boolean visited; + + public Vertex(){ + weight = 0; + visited = false; + } + + public Vertex(String label){ + this(); + this.label=label; + } + + public Vertex(Vertex v){ + this(v.label); + for (Edge e : v.edges) { + edges.add(new Edge(e.from, e.to)); + } + + } + + public void addEdge(Edge e){ + this.edges.add(e); + } + + public boolean equals(Object obj){ + + if ( !(obj instanceof Vertex) && obj != null) { + return false; + } + + Vertex v = (Vertex)obj; + if (!this.label.equals(v.label)){ + return false; + } + + if (this.weight != v.weight){ + return false; + } + + return true; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public List getEdges() { + return edges; + } + + public void setEdges(List edges) { + this.edges = edges; + } + + public int getWeight() { + return weight; + } + + public void setWeight(int weight) { + this.weight = weight; + } + + public boolean isVisited() { + return visited; + } + + public void setVisited(boolean visited) { + this.visited = visited; + } + + public String toString(){ + return "Vertex["+this.label+"] -- Weight = "+this.weight; + } + + + } + + public static class Edge{ + + private Vertex from; + private Vertex to; + private int cost; + + public Edge(int cost){ + this.cost = 0; + } + + public Edge(Vertex from, Vertex to){ + this(0); + this.from=from; + this.to=to; + } + + public Edge(int cost, Vertex from, Vertex to){ + this(from, to); + this.cost=cost; + } + + public Vertex getFrom() { + return from; + } + + public void setFrom(Vertex from) { + this.from = from; + } + + public Vertex getTo() { + return to; + } + + public void setTo(Vertex to) { + this.to = to; + } + + public int getCost() { + return cost; + } + + public void setCost(int cost) { + this.cost = cost; + } + + } + +} diff --git a/Dijkstras.java b/Dijkstras.java new file mode 100644 index 0000000..87ce663 --- /dev/null +++ b/Dijkstras.java @@ -0,0 +1,138 @@ +package com.program.graph.algo; + +import java.util.ArrayList; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.ArrayBlockingQueue; + +public class Dijkstras { + + private int distance[]; + private DiGraph.Vertex [] path; + private final static int INT_MAX = 999999; + + public Dijkstras(DiGraph g){ + distance = new int[g.vertexCount]; + for (int i=0; i pq = new ArrayBlockingQueue(g.vertexCount); + pq.add(s); + distance[g.getIndexOf(s)] = 0; + + while (!pq.isEmpty()) { + v = pq.remove(); + + for (DiGraph.Edge e : v.getEdges()){ + w = e.getTo(); + wIndex = g.getIndexOf(w); + d = distance[g.getIndexOf(v)] + w.getWeight() + 1; + if (distance[wIndex] == -1) { + distance[wIndex] = d; + pq.add(w); + path[wIndex] = v; + } + if (distance[wIndex] > d) { + distance[wIndex] = d; + pq.add(w); + path[wIndex] = v; + } + } + } + } + + /* + * It will consider negative edges as well + * in this we intialise distance[] with INT_MAX value, so that we can only update in case + * distance[w] > distance[v] + w.weight; + */ + public void bellmanFordAlgo(DiGraph g, DiGraph.Vertex s){ + + for (int i=0; i q = new ArrayBlockingQueue(g.vertexCount); + q.add(s); + distance[g.getIndexOf(s)] = 0; + + while (!q.isEmpty()){ + v = q.remove(); + for (DiGraph.Edge e : v.getEdges()) { + w = e.getTo(); + wIndex = g.getIndexOf(w); + d = distance[g.getIndexOf(v)] + w.getWeight() + 1; + if (distance[wIndex] > d){ + distance[wIndex]=d; + path[wIndex] = v; + if (!q.contains(w)) { + q.add(w); + } + } + } + } + + + } + public static void main(String[] args) { + List vertices = new ArrayList(); + DiGraph.Vertex A = new DiGraph.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'); + * + */ + 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 edges = new ArrayList(); + 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.DIRECTED, vertices, edges); + Dijkstras dj = new Dijkstras(g); + dj.dijkstraAlgo(g, A); + int dist=0; + for (int i= g.getIndexOf(A); i<= g.getIndexOf(F); i++){ + dist += dj.distance[i]; + } + System.out.println("Distance between "+A+"---"+F+"---is --"+dist); + + dj.bellmanFordAlgo(g, C); + dist=0; + for (int i= g.getIndexOf(C); i<= g.getIndexOf(F); i++){ + dist += dj.distance[i]; + } + System.out.println("Distance BellMan ford between "+C+"---"+F+"---is --"+dist); + } +} diff --git a/DirectedCycle.java b/DirectedCycle.java new file mode 100644 index 0000000..00f1201 --- /dev/null +++ b/DirectedCycle.java @@ -0,0 +1,92 @@ +package com.program.graph.algo; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +public class DirectedCycle { + + private DiGraph.Vertex [] edgeTo; + private Stack cyclePath; + private boolean onStack[]; + + public DirectedCycle(DiGraph g){ + int size = g.getVertices().size(); + onStack = new boolean[size]; + edgeTo = new DiGraph.Vertex[size]; + + for (DiGraph.Vertex v : g.getVertices()) { + if (!v.isVisited()) { + dfs(g, v);//, v); + } + } + } + + public void dfs(DiGraph g, DiGraph.Vertex v) {//, DiGraph.Vertex prev){ + v.setVisited(true); + onStack[g.getIndexOf(v)] = true; + + for (DiGraph.Edge e : v.getEdges()) { + DiGraph.Vertex w = e.getTo(); + if (this.hashCycle()) { + return; + }else if (!w.isVisited()) { + edgeTo[g.getIndexOf(w)] = v; + dfs(g, w);//, v); + } else if ( onStack[g.getIndexOf(w)]) { // cycle has found + cyclePath = new Stack(); + //cycle path from source w to target v. + for (DiGraph.Vertex x = v; x != w; x = edgeTo[g.getIndexOf(x)]) { + cyclePath.push(x); + } + cyclePath.push(w); + cyclePath.push(v); // coz cycle will end again at v + } + onStack[g.getIndexOf(v)]=false; // once a vertex has visited completely it must be set to false, means its all edges has been visited; + } + } + + public boolean hashCycle() { + return cyclePath != null; + } + + public Stack getCyclePath(){ + return cyclePath; + } + public static void main(String[] args) { + List vertices = new ArrayList(); + 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 edges = new ArrayList(); + 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.DIRECTED, vertices, edges); + DirectedCycle dc = new DirectedCycle(g); + for (DiGraph.Vertex v : dc.getCyclePath()){ + System.out.println("-"+v); + } + } + +} diff --git a/Graph.java b/Graph.java index 8e885a8..1f6f4ea 100644 --- a/Graph.java +++ b/Graph.java @@ -1,251 +1,251 @@ -package com.test.graph.algo; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.CopyOnWriteArrayList; - -/* - * @author rrohit - */ -public class Graph { - - private List vertices = new CopyOnWriteArrayList(); - private List edges = new CopyOnWriteArrayList(); - private TYPE type = TYPE.UNDIRECTED; - - public enum TYPE { - DIRECTED, UNDIRECTED; - } - - public Graph(TYPE type){ - this.type = type; - } - - public Graph (List vertices, List edges) { - this(TYPE.UNDIRECTED, vertices, edges); - } - - public Graph(TYPE type, List vertices, List edges){ - this(type); - this.vertices.addAll(vertices); - this.edges.addAll(edges); - - /* - * Now construct graph with the help of the above vertices and edges - */ - - for (Edge e : edges) { - Vertex from = e.from; - Vertex to = e.to; - - if (!this.vertices.contains(from) || !this.vertices.contains(to)) { - continue; - } - - //get from and to vertex from list of Vertices using from and to in the respective edge - int index = vertices.indexOf(from); - Vertex fromVertex = this.vertices.get(index); - index = vertices.indexOf(to); - Vertex toVertex = this.vertices.get(index); - - fromVertex.edges.add(e); // fromVertex.addEdge(e); - - if (this.type == TYPE.UNDIRECTED) { - // add reciprocal edge also i.e A-->B and B-->A is reciprocal - Edge reciprocal = new Edge(e.cost, toVertex, fromVertex); - toVertex.edges.add(reciprocal); // toVertex.addEdge(reciprocal) - this.edges.add(reciprocal); - } - } - } - - /* - * return index of the given vertex from the list of vertex, vertices - */ - public int getIndexOf(Vertex v){ - return this.vertices.indexOf(v); - } - - /* - * Deep copy of a graph from another graph - */ - public Graph(Graph g){ - /* - * Copy the vertices which copies edges - */ - for (Vertex v : g.vertices) { - this.vertices.add(new Vertex(v)); - } - /* - * update the object references i.e update edges - */ - for (Vertex v : this.vertices){ - for (Edge e : v.edges) { - Vertex from = e.getFrom(); - Vertex to = e.getTo(); - int index = this.vertices.indexOf(from); - e.from = this.vertices.get(index); - index = this.vertices.indexOf(to); - e.to = this.vertices.get(index); - this.edges.add(e); - } - } - - } - - - public List getVertices() { - return vertices; - } - - public void setVertices(List vertices) { - this.vertices = vertices; - } - - public List getEdges() { - return edges; - } - - public void setEdges(List edges) { - this.edges = edges; - } - - public TYPE getType() { - return type; - } - - public void setType(TYPE type) { - this.type = type; - } - - - static class Vertex { - - private char label; - private int weight; - public boolean visited; - private List edges = new ArrayList(); - - public Vertex(char label){ - this.label = label; - weight=0; - visited=false; - } - - public Vertex(Vertex v){ - this(v.label); - for (Edge e : v.edges) { - this.edges.add(new Edge(e)); - } - } - - /* - * Find path from A to B, means fromVertex is A and toVertex is B - */ - private boolean pathTo(Vertex v){ - for (Edge e : edges) { - if (e.to.equals(v)) { - return true; - } - } - return false; - } - - public boolean equals(Object obj){ - if(!(obj instanceof Vertex)){ - return false; - } - - Vertex v = (Vertex) obj; - if (v.label != this.label){ - return false; - } - - if (v.weight != this.weight){ - return false; - } - return true; - } - - public String toString(){ - return "["+this.label+"]"; - } - - public char getLabel() { - return label; - } - - public void setLabel(char label) { - this.label = label; - } - - public int getWeight() { - return weight; - } - - public void setWeight(int weight) { - this.weight = weight; - } - - public List getEdges() { - return edges; - } - - public void setEdges(List edges) { - this.edges = edges; - } - - public boolean isVisited() { - return visited; - } - - public void setVisited(boolean visited) { - this.visited = visited; - } - - } - - - static class Edge{ - - private Vertex from; - private Vertex to; - private int cost; - - public Edge(int cost, Vertex from, Vertex to){ - this.from = from; - this.to = to; - this.cost=cost; - } - - public Edge(Edge e){ - this(e.cost, e.from, e.to); - } - - public Vertex getFrom() { - return from; - } - - public void setFrom(Vertex from) { - this.from = from; - } - - public Vertex getTo() { - return to; - } - - public void setTo(Vertex to) { - this.to = to; - } - - public int getCost() { - return cost; - } - - public void setCost(int cost) { - this.cost = cost; - } - - } - -} +package com.program.graph.algo; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +/* + * @author rrohit + */ +public class Graph { + + private List vertices = new CopyOnWriteArrayList(); + private List edges = new CopyOnWriteArrayList(); + private TYPE type = TYPE.UNDIRECTED; + + public enum TYPE { + DIRECTED, UNDIRECTED; + } + + public Graph(TYPE type){ + this.type = type; + } + + public Graph (List vertices, List edges) { + this(TYPE.UNDIRECTED, vertices, edges); + } + + public Graph(TYPE type, List vertices, List edges){ + this(type); + this.vertices.addAll(vertices); + this.edges.addAll(edges); + + /* + * Now construct graph with the help of the above vertices and edges + */ + + for (Edge e : edges) { + Vertex from = e.from; + Vertex to = e.to; + + if (!this.vertices.contains(from) || !this.vertices.contains(to)) { + continue; + } + + //get from and to vertex from list of Vertices using from and to in the respective edge + int index = vertices.indexOf(from); + Vertex fromVertex = this.vertices.get(index); + index = vertices.indexOf(to); + Vertex toVertex = this.vertices.get(index); + + fromVertex.edges.add(e); // fromVertex.addEdge(e); + + if (this.type == TYPE.UNDIRECTED) { + // add reciprocal edge also i.e A-->B and B-->A is reciprocal + Edge reciprocal = new Edge(e.cost, toVertex, fromVertex); + toVertex.edges.add(reciprocal); // toVertex.addEdge(reciprocal) + this.edges.add(reciprocal); + } + } + } + + /* + * return index of the given vertex from the list of vertex, vertices + */ + public int getIndexOf(Vertex v){ + return this.vertices.indexOf(v); + } + + /* + * Deep copy of a graph from another graph + */ + public Graph(Graph g){ + /* + * Copy the vertices which copies edges + */ + for (Vertex v : g.vertices) { + this.vertices.add(new Vertex(v)); + } + /* + * update the object references i.e update edges + */ + for (Vertex v : this.vertices){ + for (Edge e : v.edges) { + Vertex from = e.getFrom(); + Vertex to = e.getTo(); + int index = this.vertices.indexOf(from); + e.from = this.vertices.get(index); + index = this.vertices.indexOf(to); + e.to = this.vertices.get(index); + this.edges.add(e); + } + } + + } + + + public List getVertices() { + return vertices; + } + + public void setVertices(List vertices) { + this.vertices = vertices; + } + + public List getEdges() { + return edges; + } + + public void setEdges(List edges) { + this.edges = edges; + } + + public TYPE getType() { + return type; + } + + public void setType(TYPE type) { + this.type = type; + } + + + public static class Vertex { + + private char label; + private int weight; + public boolean visited; + private List edges = new ArrayList(); + + public Vertex(char label){ + this.label = label; + weight=0; + visited=false; + } + + public Vertex(Vertex v){ + this(v.label); + for (Edge e : v.edges) { + this.edges.add(new Edge(e)); + } + } + + /* + * Find path from A to B, means fromVertex is A and toVertex is B + */ + private boolean pathTo(Vertex v){ + for (Edge e : edges) { + if (e.to.equals(v)) { + return true; + } + } + return false; + } + + public boolean equals(Object obj){ + if(!(obj instanceof Vertex)){ + return false; + } + + Vertex v = (Vertex) obj; + if (v.label != this.label){ + return false; + } + + if (v.weight != this.weight){ + return false; + } + return true; + } + + public String toString(){ + return "["+this.label+"]"; + } + + public char getLabel() { + return label; + } + + public void setLabel(char label) { + this.label = label; + } + + public int getWeight() { + return weight; + } + + public void setWeight(int weight) { + this.weight = weight; + } + + public List getEdges() { + return edges; + } + + public void setEdges(List edges) { + this.edges = edges; + } + + public boolean isVisited() { + return visited; + } + + public void setVisited(boolean visited) { + this.visited = visited; + } + + } + + + public static class Edge { + + private Vertex from; + private Vertex to; + private int cost; + + public Edge(int cost, Vertex from, Vertex to){ + this.from = from; + this.to = to; + this.cost=cost; + } + + public Edge(Edge e){ + this(e.cost, e.from, e.to); + } + + public Vertex getFrom() { + return from; + } + + public void setFrom(Vertex from) { + this.from = from; + } + + public Vertex getTo() { + return to; + } + + public void setTo(Vertex to) { + this.to = to; + } + + public int getCost() { + return cost; + } + + public void setCost(int cost) { + this.cost = cost; + } + + } + +} diff --git a/SymbolGraph.java b/SymbolGraph.java new file mode 100644 index 0000000..79957e9 --- /dev/null +++ b/SymbolGraph.java @@ -0,0 +1,66 @@ +package com.program.graph.algo; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + +public class SymbolGraph { + Graph1 g; + public SymbolGraph(String fileName, String delim) throws FileNotFoundException { + + g = new Graph1(Graph1.TYPE.UNDIRECTED); + + /*FileInputStream fis = new FileInputStream(fileName); + InputStreamReader in = new InputStreamReader(fis);*/ + Scanner in = new Scanner(new File(fileName)); + //BufferedReader reader = new BufferedReader(new FileReader(fileName)); + List vertices = new ArrayList(); + List edges = new ArrayList(); + int index; + + while (in.hasNextLine()) { + + String [] input = in.nextLine().split(delim); + Graph1.Vertex fromVertex, toVertex; + fromVertex = new Graph1.Vertex(input[0]); + vertices.add(fromVertex); + + for (int i=1; i queue = new ArrayBlockingQueue(g.vertexCount); + int counter = 0; + // add all vertex with indegree 0 in queue + for (DiGraph.Vertex v : g.getVertices()) { + if (inDegree[g.getIndexOf(v)] == 0) { + queue.add(v); + } + } + + DiGraph.Vertex v,w; + while (!queue.isEmpty()) { + v = queue.remove(); + topologicalOrder[counter++] = v; + System.out.println("--"+v); + for (DiGraph.Edge e : v.getEdges()) { // for each w adjacent to v + w = e.getTo(); + if ( --inDegree[g.getIndexOf(w)] == 0) { + // decrease indegree of each vertex once visited by 1 and add to queue if indegree becomes 0 + queue.add(w); + } + } + } + if (counter != g.vertexCount) { + System.out.println("graph has cycle"); + } + } + + public static void main(String[] args) { + List vertices = new ArrayList(); + DiGraph.Vertex A = new DiGraph.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'); + * + */ + 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 edges = new ArrayList(); + edges.add(new DiGraph.Edge(0,A,B)); + edges.add(new DiGraph.Edge(0,B,C)); + edges.add(new DiGraph.Edge(0,B,H)); + 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.DIRECTED, vertices, edges); + TopologicalSort tp = new TopologicalSort(g); + for (DiGraph.Vertex v : tp.topologicalOrder) { + System.out.println("--"+v); + } + } + +} diff --git a/TwoColor.java b/TwoColor.java new file mode 100644 index 0000000..3fbe45d --- /dev/null +++ b/TwoColor.java @@ -0,0 +1,100 @@ +package com.program.graph.algo; + +import java.util.ArrayList; +import java.util.List; + +public class TwoColor { + private boolean[] color; + private boolean isTwoColorable = true; + + public TwoColor(Graph g){ + color = new boolean[g.getVertices().size()]; + for (Graph.Vertex v : g.getVertices()) { + if (!v.visited) { + dfs(g, v); + } + } + } + public void printColor(){ + + for (boolean val : color) { + System.out.print("--"+val); + } + } + + public void dfs(Graph g, Graph.Vertex v){ + v.visited = true; + Graph.Vertex w; + for (Graph.Edge e : v.getEdges()) { + w = e.getTo(); + if (!w.visited) { + color[g.getIndexOf(w)] = !color[g.getIndexOf(v)]; + dfs(g, w); + } else if (color[g.getIndexOf(w)] == color[g.getIndexOf(v)]) { + isTwoColorable = false; + } + } + } + + public boolean isBipartite(){ + return isTwoColorable; + } + + public static void main(String[] args) { + List vertices = new ArrayList(); + 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 edges = new ArrayList(); + 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); + TwoColor tc = new TwoColor(g); + System.out.println("Is graph Bipartite :: "+tc.isBipartite()); + System.out.println("---PRINT COLOR---"); + tc.printColor(); + } +}