Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added graph algorithms with tests #1241

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 161 additions & 0 deletions src/main/java/com/dataStructures/graphs/AdjacencyMatrixGraph.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
package com.dataStructures.graphs;

/**
* Creates an adjacency matrix from a given graph
*/
public class AdjacencyMatrixGraph {
private int _numberOfVertices;
private int _numberOfEdges;
private int[][] _adjacency;

static final int EDGE_EXIST = 1;
static final int EDGE_NONE = 0;

/**
* This method sets the number of vertices
* @param numberOfVertices number of vertices in the graph
*/
private void setNumberOfVertices(int numberOfVertices) {
this._numberOfVertices = numberOfVertices;
}

/**
* This method returns the number of vertices
* @return the number of vertices
*/
public int getNumberOfVertices() {
return this._numberOfVertices;
}

/**
* This method sets the number of edges
* @param numberOfEdges the number of edges
*/
private void setNumberOfEdges(int numberOfEdges) {
this._numberOfEdges = numberOfEdges;
}

/**
* This method returns the number of edges
* @return the number of edges
*/
public int getNumberOfEdges() {
return this._numberOfEdges;
}

/**
* This method sets the adjacency matrix
* @param adjacency the adjacency matrix represented as a 2D array
*/
private void setAdjacency(int[][] adjacency) {
this._adjacency = adjacency;
}

/**
* This method returns the adjacency matrix
* @return adjacency matrix as 2D array
*/
private int[][] adjacency() {
return this._adjacency;
}

/**
* This methods checks if there is an edge between the two vertices
* @param from source vertex
* @param to target vertex
* @return true or false
*/
private boolean adjacencyOfEdgeDoesExist(int from, int to) {
return (this.adjacency()[from][to] != AdjacencyMatrixGraph.EDGE_NONE);
}

/**
* Constructor for the adjacency matrix
* @param givenNumberOfVertices number of vertices
*/
public AdjacencyMatrixGraph(int givenNumberOfVertices) {
this.setNumberOfVertices(givenNumberOfVertices);
this.setNumberOfEdges(0);
this.setAdjacency(new int[givenNumberOfVertices][givenNumberOfVertices]);
for (int i = 0; i < givenNumberOfVertices; i++) {
for (int j = 0; j < givenNumberOfVertices; j++) {
this.adjacency()[i][j] = AdjacencyMatrixGraph.EDGE_NONE;
}
}
}

/**
* This method checks if the given vertex exists
* @param vertex a vertex of the graph
* @return true or false
*/
public boolean vertexDoesExist(int vertex) {
if (vertex >= 0 && vertex < this.getNumberOfVertices()) {
return true;
}
return false;
}

/**
* This method checks if the edge between the source and target vertex exists
* @param from source vertex
* @param to target vertex
* @return true or false
*/
public boolean edgeDoesExist(int from, int to) {
if (this.vertexDoesExist(from) && this.vertexDoesExist(to)) {
return (this.adjacencyOfEdgeDoesExist(from, to));
}
return false;
}
/**
* This method adds an edge to the graph between two specified vertices
* @param from source vertex
* @param to target vertex
* @return returns true if the edge does not exist, return false if it already does
*/
public boolean addEdge(int from, int to) {
if (this.vertexDoesExist(from) && this.vertexDoesExist(to)) {
if (!this.adjacencyOfEdgeDoesExist(from, to)) {
this.adjacency()[from][to] = AdjacencyMatrixGraph.EDGE_EXIST;
this.adjacency()[to][from] = AdjacencyMatrixGraph.EDGE_EXIST;
this.setNumberOfEdges(this.getNumberOfEdges() + 1);
return true;
}
}
return false;
}

/**
* This method removes an edge from the graph between two specified vertices
* @param from source vertex
* @param to target vertex
* @return returns false if the edge doesn't exist, returns true if the edge exists and is removed
*/
public boolean removeEdge(int from, int to) {
if (this.vertexDoesExist(from) && this.vertexDoesExist(to)) {
if (this.adjacencyOfEdgeDoesExist(from, to)) {
this.adjacency()[from][to] = AdjacencyMatrixGraph.EDGE_NONE;
this.adjacency()[to][from] = AdjacencyMatrixGraph.EDGE_NONE;
this.setNumberOfEdges(this.getNumberOfEdges() - 1);
return true;
}
}
return false;
}

/**
* This method gives a list of vertices in the graph and their adjacencies
* @return returns a string describing this graph
*/
public String toString() {
StringBuilder text = new StringBuilder();
for (int i = 0; i < this.getNumberOfVertices(); i++) {
for (int j = 0; j < this.getNumberOfVertices(); j++) {
text.append(this._adjacency[i][j]).append(" ");
}
text.append("\n");
}
return text.toString();
}
}
97 changes: 97 additions & 0 deletions src/main/java/com/dataStructures/graphs/BellmanFord.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package com.dataStructures.graphs;

/**
* This algorithm find shortest paths from src to all vertices in the given graph. The graph may contain negative weight edges.
*/
public class BellmanFord {
private int[] _dist;
private boolean _negativeWeightCycle;

static class Edge {
int start, end, weight;

public Edge(int start, int end, int weight) {
this.start = start;
this.end = end;
this.weight = weight;
}
}

static class Graph {
int numberOfVertices;
int numberOfEdges;
Edge[] edge;

public Graph(int vertices, int edges, Edge[] edge) {
this.numberOfEdges = edges;
this.numberOfVertices = vertices;
this.edge = edge;
}
}

/**
* This method sets the distance matrix
*
* @param dist distance array
*/
private void setDist(int[] dist) {
this._dist = dist;
}

/**
* Constructor for Bellman-Ford algorithm
*
* @param graph input graph
* @param source source vertex
*/
public BellmanFord(Graph graph, int source) {
int totalVertices = graph.numberOfVertices;
int totalEdges = graph.numberOfEdges;

this.setDist(new int[totalVertices]);

for (int i = 0; i < totalVertices; i++) {
this._dist[i] = Integer.MAX_VALUE;
}
this._dist[source] = 0;

for (int i = 1; i < totalVertices; i++) {
for (int j = 0; j < totalEdges; j++) {
int u = graph.edge[j].start;
int v = graph.edge[j].end;
int w = graph.edge[j].weight;

if (this._dist[u] != Integer.MAX_VALUE && this._dist[v] > this._dist[u] + w) {
this._dist[v] = this._dist[u] + w;
}
}
}

for (int i = 0; i < totalEdges; i++) {
int u = graph.edge[i].start;
int v = graph.edge[i].end;
int w = graph.edge[i].weight;
if (this._dist[u] != Integer.MAX_VALUE && this._dist[v] > this._dist[u] + w) {
this._negativeWeightCycle = true;
return;
}
}

}

/**
* This method returns the vertices and their distance from the source vertex
*
* @return result as a String
*/
public String toString() {
StringBuilder text = new StringBuilder();
for (int i = 0; i < this._dist.length; i++) {
text.append("Vertex: ").append(i).append(" distance: ").append(this._dist[i]).append("\n");
}
if (this._negativeWeightCycle) {
text.append("Negative weight cycle detected.");
}
return text.toString();
}
}
98 changes: 98 additions & 0 deletions src/main/java/com/dataStructures/graphs/BreadthFirstSearch.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package com.dataStructures.graphs;

import java.util.LinkedList;

/**
* It is an algorithm for traversing or searching tree or graph data structures.
* It starts at the tree root in a breadthward motion.
*/

public class BreadthFirstSearch {
private int _numberOfVertices;
private LinkedList<Integer>[] _adjacencyList;
private int _source;

/**
* This method returns the source vertex
*
* @return source vertex
*/
public int getSource() {
return this._source;
}

/**
* This method sets the source
*
* @param source source vertex
*/
private void setSource(int source) {
this._source = source;
}

/**
* This method sets the number of vertices
*
* @param numberOfVertices number of vertices in the graph
*/
private void setNumberOfVertices(int numberOfVertices) {
this._numberOfVertices = numberOfVertices;
}

/**
* This method sets the adjacency list
*
* @param adjacencyList given adjacency list
*/
private void setAdjacencyList(LinkedList<Integer>[] adjacencyList) {
this._adjacencyList = adjacencyList;
}

/**
* Constructor for breadth first search
*
* @param givenNumberOfVertices number of vertices
*/
public BreadthFirstSearch(int givenNumberOfVertices, int source) {
this.setSource(source);
this.setNumberOfVertices(givenNumberOfVertices);
this.setAdjacencyList(new LinkedList[givenNumberOfVertices]);
for (int i = 0; i < givenNumberOfVertices; ++i) {
this._adjacencyList[i] = new LinkedList();
}
}

/**
* This method adds an edge between source vertex and target vertex
*
* @param source source vertex
* @param target target vertex
*/
public void addEdge(int source, int target) {
this._adjacencyList[source].add(target);
}

/**
* This method prints BFS traversal from a given source vertex
*
* @return BFS traversal
*/
public String toString() {
StringBuilder text = new StringBuilder();
boolean[] visited = new boolean[_numberOfVertices];
LinkedList<Integer> queue = new LinkedList<>();
visited[this.getSource()] = true;
queue.add(this.getSource());
while (queue.size() != 0) {
this.setSource(queue.poll());
text.append(this.getSource() + " ");
for (int n : _adjacencyList[this.getSource()]) {
if (!visited[n]) {
visited[n] = true;
queue.add(n);
}
}
}
return text.toString();
}
}
Loading