Change project structure to a Maven Java project + Refactor (#2816)

This commit is contained in:
Aitor Fidalgo Sánchez
2021-11-12 07:59:36 +01:00
committed by GitHub
parent 8e533d2617
commit 9fb3364ccc
642 changed files with 26570 additions and 25488 deletions

View File

@ -0,0 +1,185 @@
/*
Time Complexity = O(E), where E is equal to the number of edges
*/
package com.thealgorithms.datastructures.graphs;
import java.util.*;
public class A_Star {
private static class Graph {
// Graph's structure can be changed only applying changes to this class.
private ArrayList<ArrayList<Edge>> graph;
// Initialise ArrayLists in Constructor
public Graph(int size) {
this.graph = new ArrayList<>();
for (int i = 0; i < size; i++) {
this.graph.set(i, new ArrayList<>());
}
}
private ArrayList<Edge> getNeighbours(int from) {
return this.graph.get(from);
}
// Graph is bidirectional, for just one direction remove second instruction of this method.
private void addEdge(Edge edge) {
this.graph.get(edge.getFrom()).add(new Edge(edge.getFrom(), edge.getTo(), edge.getWeight()));
this.graph.get(edge.getTo()).add(new Edge(edge.getTo(), edge.getFrom(), edge.getWeight()));
}
}
private static class Edge {
private int from;
private int to;
private int weight;
public Edge(int from, int to, int weight) {
this.from = from;
this.to = to;
this.weight = weight;
}
public int getFrom() {
return from;
}
public int getTo() {
return to;
}
public int getWeight() {
return weight;
}
}
// class to iterate during the algorithm execution, and also used to return the solution.
private static class PathAndDistance {
private int distance; // distance advanced so far.
private ArrayList<Integer> path; // list of visited nodes in this path.
private int estimated; // heuristic value associated to the last node od the path (current node).
public PathAndDistance(int distance, ArrayList<Integer> path, int estimated) {
this.distance = distance;
this.path = path;
this.estimated = estimated;
}
public int getDistance() {
return distance;
}
public ArrayList<Integer> getPath() {
return path;
}
public int getEstimated() {
return estimated;
}
private void printSolution() {
if (this.path != null) {
System.out.println(
"Optimal path: " + this.path + ", distance: " + this.distance);
} else {
System.out.println("There is no path available to connect the points");
}
}
}
private static void initializeGraph(Graph graph, ArrayList<Integer> data) {
for (int i = 0; i < data.size(); i += 4) {
graph.addEdge(new Edge(data.get(i), data.get(i + 1), data.get(i + 2)));
}
/*
.x. node
(y) cost
- or | or / bidirectional connection
( 98)- .7. -(86)- .4.
|
( 85)- .17. -(142)- .18. -(92)- .8. -(87)- .11.
|
. 1. -------------------- (160)
| \ |
(211) \ .6.
| \ |
. 5. (101)-.13. -(138) (115)
| | | /
( 99) ( 97) | /
| | | /
.12. -(151)- .15. -(80)- .14. | /
| | | | /
( 71) (140) (146)- .2. -(120)
| | |
.19. -( 75)- . 0. .10. -(75)- .3.
| |
(118) ( 70)
| |
.16. -(111)- .9.
*/
}
public static void main(String[] args) {
// heuristic function optimistic values
int[] heuristic = {
366, 0, 160, 242, 161, 178, 77, 151, 226, 244, 241, 234, 380, 98, 193, 253, 329, 80, 199, 374
};
Graph graph = new Graph(20);
ArrayList<Integer> graphData
= new ArrayList<>(
Arrays.asList(
0, 19, 75, null, 0, 15, 140, null, 0, 16, 118, null, 19, 12, 71, null, 12, 15, 151,
null, 16, 9, 111, null, 9, 10, 70, null, 10, 3, 75, null, 3, 2, 120, null, 2, 14,
146, null, 2, 13, 138, null, 2, 6, 115, null, 15, 14, 80, null, 15, 5, 99, null, 14,
13, 97, null, 5, 1, 211, null, 13, 1, 101, null, 6, 1, 160, null, 1, 17, 85, null,
17, 7, 98, null, 7, 4, 86, null, 17, 18, 142, null, 18, 8, 92, null, 8, 11, 87));
initializeGraph(graph, graphData);
PathAndDistance solution = aStar(3, 1, graph, heuristic);
solution.printSolution();
}
public static PathAndDistance aStar(int from, int to, Graph graph, int[] heuristic) {
// nodes are prioritised by the less value of the current distance of their paths, and the
// estimated value
// given by the heuristic function to reach the destination point from the current point.
PriorityQueue<PathAndDistance> queue
= new PriorityQueue<>(Comparator.comparingInt(a -> (a.getDistance() + a.getEstimated())));
// dummy data to start the algorithm from the beginning point
queue.add(new PathAndDistance(0, new ArrayList<>(List.of(from)), 0));
boolean solutionFound = false;
PathAndDistance currentData = new PathAndDistance(-1, null, -1);
while (!queue.isEmpty() && !solutionFound) {
currentData = queue.poll(); // first in the queue, best node so keep exploring.
int currentPosition
= currentData.getPath().get(currentData.getPath().size() - 1); // current node.
if (currentPosition == to) {
solutionFound = true;
} else {
for (Edge edge : graph.getNeighbours(currentPosition)) {
if (!currentData.getPath().contains(edge.getTo())) { // Avoid Cycles
ArrayList<Integer> updatedPath = new ArrayList<>(currentData.getPath());
updatedPath.add(edge.getTo()); // Add the new node to the path, update the distance,
// and the heuristic function value associated to that path.
queue.add(
new PathAndDistance(
currentData.getDistance() + edge.getWeight(),
updatedPath,
heuristic[edge.getTo()]));
}
}
}
}
return (solutionFound) ? currentData : new PathAndDistance(-1, null, -1);
// Out of while loop, if there is a solution, the current Data stores the optimal path, and its
// distance
}
}

View File

@ -0,0 +1,173 @@
package com.thealgorithms.datastructures.graphs;
import java.util.*;
class BellmanFord /*Implementation of Bellman ford to detect negative cycles. Graph accepts inputs in form of edges which have
start vertex, end vertex and weights. Vertices should be labelled with a number between 0 and total number of vertices-1,both inclusive*/ {
int vertex, edge;
private Edge edges[];
private int index = 0;
BellmanFord(int v, int e) {
vertex = v;
edge = e;
edges = new Edge[e];
}
class Edge {
int u, v;
int w;
/**
* @param u Source Vertex
* @param v End vertex
* @param c Weight
*/
public Edge(int a, int b, int c) {
u = a;
v = b;
w = c;
}
}
/**
* @param p[] Parent array which shows updates in edges
* @param i Current vertex under consideration
*/
void printPath(int p[], int i) {
if (p[i] == -1) // Found the path back to parent
{
return;
}
printPath(p, p[i]);
System.out.print(i + " ");
}
public static void main(String args[]) {
BellmanFord obj = new BellmanFord(0, 0); // Dummy object to call nonstatic variables
obj.go();
}
public void
go() // Interactive run for understanding the class first time. Assumes source vertex is 0 and
// shows distance to all vertices
{
Scanner sc = new Scanner(System.in); // Grab scanner object for user input
int i, v, e, u, ve, w, j, neg = 0;
System.out.println("Enter no. of vertices and edges please");
v = sc.nextInt();
e = sc.nextInt();
Edge arr[] = new Edge[e]; // Array of edges
System.out.println("Input edges");
for (i = 0; i < e; i++) {
u = sc.nextInt();
ve = sc.nextInt();
w = sc.nextInt();
arr[i] = new Edge(u, ve, w);
}
int dist[]
= new int[v]; // Distance array for holding the finalized shortest path distance between source
// and all vertices
int p[] = new int[v]; // Parent array for holding the paths
for (i = 0; i < v; i++) {
dist[i] = Integer.MAX_VALUE; // Initializing distance values
}
dist[0] = 0;
p[0] = -1;
for (i = 0; i < v - 1; i++) {
for (j = 0; j < e; j++) {
if ((int) dist[arr[j].u] != Integer.MAX_VALUE
&& dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
dist[arr[j].v] = dist[arr[j].u] + arr[j].w; // Update
p[arr[j].v] = arr[j].u;
}
}
}
// Final cycle for negative checking
for (j = 0; j < e; j++) {
if ((int) dist[arr[j].u] != Integer.MAX_VALUE && dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
neg = 1;
System.out.println("Negative cycle");
break;
}
}
if (neg == 0) // Go ahead and show results of computation
{
System.out.println("Distances are: ");
for (i = 0; i < v; i++) {
System.out.println(i + " " + dist[i]);
}
System.out.println("Path followed:");
for (i = 0; i < v; i++) {
System.out.print("0 ");
printPath(p, i);
System.out.println();
}
}
sc.close();
}
/**
* @param source Starting vertex
* @param end Ending vertex
* @param Edge Array of edges
*/
public void show(
int source,
int end,
Edge arr[]) // Just shows results of computation, if graph is passed to it. The graph should
// be created by using addEdge() method and passed by calling getEdgeArray() method
{
int i, j, v = vertex, e = edge, neg = 0;
double dist[]
= new double[v]; // Distance array for holding the finalized shortest path distance between source
// and all vertices
int p[] = new int[v]; // Parent array for holding the paths
for (i = 0; i < v; i++) {
dist[i] = Integer.MAX_VALUE; // Initializing distance values
}
dist[source] = 0;
p[source] = -1;
for (i = 0; i < v - 1; i++) {
for (j = 0; j < e; j++) {
if ((int) dist[arr[j].u] != Integer.MAX_VALUE
&& dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
dist[arr[j].v] = dist[arr[j].u] + arr[j].w; // Update
p[arr[j].v] = arr[j].u;
}
}
}
// Final cycle for negative checking
for (j = 0; j < e; j++) {
if ((int) dist[arr[j].u] != Integer.MAX_VALUE && dist[arr[j].v] > dist[arr[j].u] + arr[j].w) {
neg = 1;
System.out.println("Negative cycle");
break;
}
}
if (neg == 0) // Go ahead and show results of computaion
{
System.out.println("Distance is: " + dist[end]);
System.out.println("Path followed:");
System.out.print(source + " ");
printPath(p, end);
System.out.println();
}
}
/**
* @param x Source Vertex
* @param y End vertex
* @param z Weight
*/
public void addEdge(int x, int y, int z) // Adds unidirectional edge
{
edges[index++] = new Edge(x, y, z);
}
public Edge[] getEdgeArray() {
return edges;
}
}

View File

@ -0,0 +1,79 @@
package com.thealgorithms.datastructures.graphs;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
/**
* Given an adjacency list of a graph adj of V no. of vertices having 0 based
* index. Check whether the graph is bipartite or not.
*
* Input : {{0, 1, 0, 1}, {1, 0, 1, 0}, {0, 1, 0, 1}, {1, 0, 1, 0}}
*
* Output : YES
*/
public class BipartiteGrapfDFS {
private static boolean bipartite(int V, ArrayList<ArrayList<Integer>> adj, int[] color, int node) {
if (color[node] == -1) {
color[node] = 1;
}
for (Integer it : adj.get(node)) {
if (color[it] == -1) {
color[it] = 1 - color[node];
if (bipartite(V, adj, color, it) == false) {
return false;
}
} else if (color[it] == color[node]) {
return false;
}
}
return true;
}
public static boolean isBipartite(int V, ArrayList<ArrayList<Integer>> adj) {
// Code here
int[] color = new int[V + 1];
Arrays.fill(color, -1);
for (int i = 0; i < V; i++) {
if (color[i] == -1) {
if (!bipartite(V, adj, color, i)) {
return false;
}
}
}
return true;
}
public static void main(String[] args) throws IOException {
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(read.readLine().trim());
while (t-- > 0) {
String[] S = read.readLine().trim().split(" ");
int V = Integer.parseInt(S[0]);
int E = Integer.parseInt(S[1]);
ArrayList<ArrayList<Integer>> adj = new ArrayList<>();
for (int i = 0; i < V; i++) {
adj.add(new ArrayList<>());
}
for (int i = 0; i < E; i++) {
String[] s = read.readLine().trim().split(" ");
int u = Integer.parseInt(s[0]);
int v = Integer.parseInt(s[1]);
adj.get(u).add(v);
adj.get(v).add(u);
}
boolean ans = isBipartite(V, adj);
if (ans) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
}
}

View File

@ -0,0 +1,143 @@
package com.thealgorithms.datastructures.graphs;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
/**
* A class that counts the number of different connected components in a graph
*
* @author Lukas Keul, Florian Mercks
*/
class Graph<E extends Comparable<E>> {
class Node {
E name;
public Node(E name) {
this.name = name;
}
}
class Edge {
Node startNode, endNode;
public Edge(Node startNode, Node endNode) {
this.startNode = startNode;
this.endNode = endNode;
}
}
ArrayList<Edge> edgeList;
ArrayList<Node> nodeList;
public Graph() {
edgeList = new ArrayList<Edge>();
nodeList = new ArrayList<Node>();
}
/**
* Adds a new Edge to the graph. If the nodes aren't yet in nodeList, they
* will be added to it.
*
* @param startNode the starting Node from the edge
* @param endNode the ending Node from the edge
*/
public void addEdge(E startNode, E endNode) {
Node start = null, end = null;
for (Node node : nodeList) {
if (startNode.compareTo(node.name) == 0) {
start = node;
} else if (endNode.compareTo(node.name) == 0) {
end = node;
}
}
if (start == null) {
start = new Node(startNode);
nodeList.add(start);
}
if (end == null) {
end = new Node(endNode);
nodeList.add(end);
}
edgeList.add(new Edge(start, end));
}
/**
* Main method used for counting the connected components. Iterates through
* the array of nodes to do a depth first search to get all nodes of the
* graph from the actual node. These nodes are added to the array
* markedNodes and will be ignored if they are chosen in the nodeList.
*
* @return returns the amount of unconnected graphs
*/
public int countGraphs() {
int count = 0;
Set<Node> markedNodes = new HashSet<Node>();
for (Node n : nodeList) {
if (!markedNodes.contains(n)) {
markedNodes.add(n);
markedNodes.addAll(depthFirstSearch(n, new ArrayList<Node>()));
count++;
}
}
return count;
}
/**
* Implementation of depth first search.
*
* @param n the actual visiting node
* @param visited A list of already visited nodes in the depth first search
* @return returns a set of visited nodes
*/
public ArrayList<Node> depthFirstSearch(Node n, ArrayList<Node> visited) {
visited.add(n);
for (Edge e : edgeList) {
if (e.startNode.equals(n) && !visited.contains(e.endNode)) {
depthFirstSearch(e.endNode, visited);
}
}
return visited;
}
}
public class ConnectedComponent {
public static void main(String[] args) {
Graph<Character> graphChars = new Graph<>();
// Graph 1
graphChars.addEdge('a', 'b');
graphChars.addEdge('a', 'e');
graphChars.addEdge('b', 'e');
graphChars.addEdge('b', 'c');
graphChars.addEdge('c', 'd');
graphChars.addEdge('d', 'a');
graphChars.addEdge('x', 'y');
graphChars.addEdge('x', 'z');
graphChars.addEdge('w', 'w');
Graph<Integer> graphInts = new Graph<>();
// Graph 2
graphInts.addEdge(1, 2);
graphInts.addEdge(2, 3);
graphInts.addEdge(2, 4);
graphInts.addEdge(3, 5);
graphInts.addEdge(7, 8);
graphInts.addEdge(8, 10);
graphInts.addEdge(10, 8);
System.out.println("Amount of different char-graphs: " + graphChars.countGraphs());
System.out.println("Amount of different int-graphs: " + graphInts.countGraphs());
}
}

View File

@ -0,0 +1,88 @@
package com.thealgorithms.datastructures.graphs;
import java.util.ArrayList;
import java.util.Scanner;
class Cycle {
private int nodes, edges;
private int[][] adjacencyMatrix;
private boolean[] visited;
ArrayList<ArrayList<Integer>> cycles = new ArrayList<ArrayList<Integer>>();
public Cycle() {
Scanner in = new Scanner(System.in);
System.out.print("Enter the no. of nodes: ");
nodes = in.nextInt();
System.out.print("Enter the no. of Edges: ");
edges = in.nextInt();
adjacencyMatrix = new int[nodes][nodes];
visited = new boolean[nodes];
for (int i = 0; i < nodes; i++) {
visited[i] = false;
}
System.out.println("Enter the details of each edges <Start Node> <End Node>");
for (int i = 0; i < edges; i++) {
int start, end;
start = in.nextInt();
end = in.nextInt();
adjacencyMatrix[start][end] = 1;
}
in.close();
}
public void start() {
for (int i = 0; i < nodes; i++) {
ArrayList<Integer> temp = new ArrayList<>();
dfs(i, i, temp);
for (int j = 0; j < nodes; j++) {
adjacencyMatrix[i][j] = 0;
adjacencyMatrix[j][i] = 0;
}
}
}
private void dfs(Integer start, Integer curr, ArrayList<Integer> temp) {
temp.add(curr);
visited[curr] = true;
for (int i = 0; i < nodes; i++) {
if (adjacencyMatrix[curr][i] == 1) {
if (i == start) {
cycles.add(new ArrayList<Integer>(temp));
} else {
if (!visited[i]) {
dfs(start, i, temp);
}
}
}
}
if (temp.size() > 0) {
temp.remove(temp.size() - 1);
}
visited[curr] = false;
}
public void printAll() {
for (int i = 0; i < cycles.size(); i++) {
for (int j = 0; j < cycles.get(i).size(); j++) {
System.out.print(cycles.get(i).get(j) + " -> ");
}
System.out.println(cycles.get(i).get(0));
System.out.println();
}
}
}
public class Cycles {
public static void main(String[] args) {
Cycle c = new Cycle();
c.start();
c.printAll();
}
}

View File

@ -0,0 +1,86 @@
/*
Refer https://www.geeksforgeeks.org/dijkstras-shortest-path-algorithm-greedy-algo-7/
for better understanding
*/
package com.thealgorithms.datastructures.graphs;
class dijkstras {
int k = 9;
int minDist(int dist[], Boolean Set[]) {
int min = Integer.MAX_VALUE, min_index = -1;
for (int r = 0; r < k; r++) {
if (Set[r] == false && dist[r] <= min) {
min = dist[r];
min_index = r;
}
}
return min_index;
}
void print(int dist[]) {
System.out.println("Vertex \t\t Distance");
for (int i = 0; i < k; i++) {
System.out.println(i + " \t " + dist[i]);
}
}
void dijkstra(int graph[][], int src) {
int dist[] = new int[k];
Boolean Set[] = new Boolean[k];
for (int i = 0; i < k; i++) {
dist[i] = Integer.MAX_VALUE;
Set[i] = false;
}
dist[src] = 0;
for (int c = 0; c < k - 1; c++) {
int u = minDist(dist, Set);
Set[u] = true;
for (int v = 0; v < k; v++) {
if (!Set[v] && graph[u][v] != 0 && dist[u] != Integer.MAX_VALUE && dist[u] + graph[u][v] < dist[v]) {
dist[v] = dist[u] + graph[u][v];
}
}
}
print(dist);
}
public static void main(String[] args) {
int graph[][] = new int[][]{{0, 4, 0, 0, 0, 0, 0, 8, 0},
{4, 0, 8, 0, 0, 0, 0, 11, 0},
{0, 8, 0, 7, 0, 4, 0, 0, 2},
{0, 0, 7, 0, 9, 14, 0, 0, 0},
{0, 0, 0, 9, 0, 10, 0, 0, 0},
{0, 0, 4, 14, 10, 0, 2, 0, 0},
{0, 0, 0, 0, 0, 2, 0, 1, 6},
{8, 11, 0, 0, 0, 0, 1, 0, 7},
{0, 0, 2, 0, 0, 0, 6, 7, 0}};
dijkstras t = new dijkstras();
t.dijkstra(graph, 0);
}//main
}//djikstras
/*
OUTPUT :
Vertex Distance
0 0
1 4
2 12
3 19
4 21
5 11
6 9
7 8
8 14
*/

View File

@ -0,0 +1,77 @@
package com.thealgorithms.datastructures.graphs;
import java.util.Scanner;
public class FloydWarshall {
private int DistanceMatrix[][];
private int numberofvertices; // number of vertices in the graph
public static final int INFINITY = 999;
public FloydWarshall(int numberofvertices) {
DistanceMatrix
= new int[numberofvertices + 1][numberofvertices
+ 1]; // stores the value of distance from all the possible path form the source
// vertex to destination vertex
// The matrix is initialized with 0's by default
this.numberofvertices = numberofvertices;
}
public void floydwarshall(
int AdjacencyMatrix[][]) // calculates all the distances from source to destination vertex
{
for (int source = 1; source <= numberofvertices; source++) {
for (int destination = 1; destination <= numberofvertices; destination++) {
DistanceMatrix[source][destination] = AdjacencyMatrix[source][destination];
}
}
for (int intermediate = 1; intermediate <= numberofvertices; intermediate++) {
for (int source = 1; source <= numberofvertices; source++) {
for (int destination = 1; destination <= numberofvertices; destination++) {
if (DistanceMatrix[source][intermediate] + DistanceMatrix[intermediate][destination]
< DistanceMatrix[source][destination]) // if the new distance calculated is less then the earlier shortest
// calculated distance it get replaced as new shortest distance
{
DistanceMatrix[source][destination]
= DistanceMatrix[source][intermediate] + DistanceMatrix[intermediate][destination];
}
}
}
}
for (int source = 1; source <= numberofvertices; source++) {
System.out.print("\t" + source);
}
System.out.println();
for (int source = 1; source <= numberofvertices; source++) {
System.out.print(source + "\t");
for (int destination = 1; destination <= numberofvertices; destination++) {
System.out.print(DistanceMatrix[source][destination] + "\t");
}
System.out.println();
}
}
public static void main(String... arg) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter the number of vertices");
int numberOfVertices = scan.nextInt();
int[][] adjacencyMatrix = new int[numberOfVertices + 1][numberOfVertices + 1];
System.out.println("Enter the Weighted Matrix for the graph");
for (int source = 1; source <= numberOfVertices; source++) {
for (int destination = 1; destination <= numberOfVertices; destination++) {
adjacencyMatrix[source][destination] = scan.nextInt();
if (source == destination) {
adjacencyMatrix[source][destination] = 0;
continue;
}
if (adjacencyMatrix[source][destination] == 0) {
adjacencyMatrix[source][destination] = INFINITY;
}
}
}
System.out.println("The Transitive Closure of the Graph");
FloydWarshall floydwarshall = new FloydWarshall(numberOfVertices);
floydwarshall.floydwarshall(adjacencyMatrix);
scan.close();
}
}

View File

@ -0,0 +1,137 @@
package com.thealgorithms.datastructures.graphs;
import java.util.ArrayList;
class AdjacencyListGraph<E extends Comparable<E>> {
ArrayList<Vertex> verticies;
public AdjacencyListGraph() {
verticies = new ArrayList<>();
}
private class Vertex {
E data;
ArrayList<Vertex> adjacentVerticies;
public Vertex(E data) {
adjacentVerticies = new ArrayList<>();
this.data = data;
}
public boolean addAdjacentVertex(Vertex to) {
for (Vertex v : adjacentVerticies) {
if (v.data.compareTo(to.data) == 0) {
return false; // the edge already exists
}
}
return adjacentVerticies.add(to); // this will return true;
}
public boolean removeAdjacentVertex(E to) {
// use indexes here so it is possible to
// remove easily without implementing
// equals method that ArrayList.remove(Object o) uses
for (int i = 0; i < adjacentVerticies.size(); i++) {
if (adjacentVerticies.get(i).data.compareTo(to) == 0) {
adjacentVerticies.remove(i);
return true;
}
}
return false;
}
}
/**
* this method removes an edge from the graph between two specified
* verticies
*
* @param from the data of the vertex the edge is from
* @param to the data of the vertex the edge is going to
* @return returns false if the edge doesn't exist, returns true if the edge
* exists and is removed
*/
public boolean removeEdge(E from, E to) {
Vertex fromV = null;
for (Vertex v : verticies) {
if (from.compareTo(v.data) == 0) {
fromV = v;
break;
}
}
if (fromV == null) {
return false;
}
return fromV.removeAdjacentVertex(to);
}
/**
* this method adds an edge to the graph between two specified verticies
*
* @param from the data of the vertex the edge is from
* @param to the data of the vertex the edge is going to
* @return returns true if the edge did not exist, return false if it
* already did
*/
public boolean addEdge(E from, E to) {
Vertex fromV = null, toV = null;
for (Vertex v : verticies) {
if (from.compareTo(v.data) == 0) { // see if from vertex already exists
fromV = v;
} else if (to.compareTo(v.data) == 0) { // see if to vertex already exists
toV = v;
}
if (fromV != null && toV != null) {
break; // both nodes exist so stop searching
}
}
if (fromV == null) {
fromV = new Vertex(from);
verticies.add(fromV);
}
if (toV == null) {
toV = new Vertex(to);
verticies.add(toV);
}
return fromV.addAdjacentVertex(toV);
}
/**
* this gives a list of verticies in the graph and their adjacencies
*
* @return returns a string describing this graph
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (Vertex v : verticies) {
sb.append("Vertex: ");
sb.append(v.data);
sb.append("\n");
sb.append("Adjacent verticies: ");
for (Vertex v2 : v.adjacentVerticies) {
sb.append(v2.data);
sb.append(" ");
}
sb.append("\n");
}
return sb.toString();
}
}
public class Graphs {
public static void main(String args[]) {
AdjacencyListGraph<Integer> graph = new AdjacencyListGraph<>();
assert graph.addEdge(1, 2);
assert graph.addEdge(1, 5);
assert graph.addEdge(2, 5);
assert !graph.addEdge(1, 2);
assert graph.addEdge(2, 3);
assert graph.addEdge(3, 4);
assert graph.addEdge(4, 1);
assert !graph.addEdge(2, 3);
System.out.println(graph);
}
}

View File

@ -0,0 +1,154 @@
package com.thealgorithms.datastructures.graphs;
import java.util.ArrayList;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.HashMap;
import java.util.Set;
import java.util.Queue;
import java.util.LinkedList;
/**
* An algorithm that sorts a graph in toplogical order.
*/
/**
* A class that represents the adjaceny list of a graph
*/
class AdjacencyList<E extends Comparable<E>> {
Map<E, ArrayList<E>> adj;
AdjacencyList() {
adj = new LinkedHashMap<E, ArrayList<E>>();
}
/**
* This function adds an Edge to the adjaceny list
*
* @param from , the vertex the edge is from
* @param to, the vertex the edge is going to
*/
void addEdge(E from, E to) {
try {
adj.get(from).add(to);
} catch (Exception E) {
adj.put(from, new ArrayList<E>());
adj.get(from).add(to);
}
if (!adj.containsKey(to)) {
adj.put(to, new ArrayList<E>());
}
}
/**
* @param v, A vertex in a graph
* @return returns an ArrayList of all the adjacents of vertex v
*/
ArrayList<E> getAdjacents(E v) {
return adj.get(v);
}
/**
* @return returns a set of all vertices in the graph
*/
Set<E> getVertices() {
return adj.keySet();
}
/**
* Prints the adjacency list
*/
void printGraph() {
for (E vertex : adj.keySet()) {
System.out.print(vertex + " : ");
for (E adjacent : adj.get(vertex)) {
System.out.print(adjacent + " ");
}
System.out.println();
}
}
}
class TopologicalSort<E extends Comparable<E>> {
AdjacencyList<E> graph;
Map<E, Integer> inDegree;
TopologicalSort(AdjacencyList<E> graph) {
this.graph = graph;
}
/**
* Calculates the in degree of all vertices
*/
void calculateInDegree() {
inDegree = new HashMap<>();
for (E vertex : graph.getVertices()) {
if (!inDegree.containsKey(vertex)) {
inDegree.put(vertex, 0);
}
for (E adjacent : graph.getAdjacents(vertex)) {
try {
inDegree.put(adjacent, inDegree.get(adjacent) + 1);
} catch (Exception e) {
inDegree.put(adjacent, 1);
}
}
}
}
/**
* Returns an ArrayList with vertices arranged in topological order
*/
ArrayList<E> topSortOrder() {
calculateInDegree();
Queue<E> q = new LinkedList<E>();
for (E vertex : inDegree.keySet()) {
if (inDegree.get(vertex) == 0) {
q.add(vertex);
}
}
ArrayList<E> answer = new ArrayList<>();
while (!q.isEmpty()) {
E current = q.poll();
answer.add(current);
for (E adjacent : graph.getAdjacents(current)) {
inDegree.put(adjacent, inDegree.get(adjacent) - 1);
if (inDegree.get(adjacent) == 0) {
q.add(adjacent);
}
}
}
return answer;
}
}
/**
* A driver class that sorts a given graph in topological order.
*/
public class KahnsAlgorithm {
public static void main(String[] args) {
//Graph definition and initialization
AdjacencyList<String> graph = new AdjacencyList<>();
graph.addEdge("a", "b");
graph.addEdge("c", "a");
graph.addEdge("a", "d");
graph.addEdge("b", "d");
graph.addEdge("c", "u");
graph.addEdge("u", "b");
TopologicalSort<String> topSort = new TopologicalSort<>(graph);
//Printing the order
for (String s : topSort.topSortOrder()) {
System.out.print(s + " ");
}
}
}

View File

@ -0,0 +1,104 @@
package com.thealgorithms.datastructures.graphs;
// Problem -> Connect all the edges with the minimum cost.
// Possible Solution -> Kruskal Algorithm (KA), KA finds the minimum-spanning-tree, which means, the
// group of edges with the minimum sum of their weights that connect the whole graph.
// The graph needs to be connected, because if there are nodes impossible to reach, there are no
// edges that could connect every node in the graph.
// KA is a Greedy Algorithm, because edges are analysed based on their weights, that is why a
// Priority Queue is used, to take first those less weighted.
// This implementations below has some changes compared to conventional ones, but they are explained
// all along the code.
import java.util.Comparator;
import java.util.HashSet;
import java.util.PriorityQueue;
public class Kruskal {
// Complexity: O(E log V) time, where E is the number of edges in the graph and V is the number of
// vertices
private static class Edge {
private int from;
private int to;
private int weight;
public Edge(int from, int to, int weight) {
this.from = from;
this.to = to;
this.weight = weight;
}
}
private static void addEdge(HashSet<Edge>[] graph, int from, int to, int weight) {
graph[from].add(new Edge(from, to, weight));
}
public static void main(String[] args) {
HashSet<Edge>[] graph = new HashSet[7];
for (int i = 0; i < graph.length; i++) {
graph[i] = new HashSet<>();
}
addEdge(graph, 0, 1, 2);
addEdge(graph, 0, 2, 3);
addEdge(graph, 0, 3, 3);
addEdge(graph, 1, 2, 4);
addEdge(graph, 2, 3, 5);
addEdge(graph, 1, 4, 3);
addEdge(graph, 2, 4, 1);
addEdge(graph, 3, 5, 7);
addEdge(graph, 4, 5, 8);
addEdge(graph, 5, 6, 9);
System.out.println("Initial Graph: ");
for (int i = 0; i < graph.length; i++) {
for (Edge edge : graph[i]) {
System.out.println(i + " <-- weight " + edge.weight + " --> " + edge.to);
}
}
Kruskal k = new Kruskal();
HashSet<Edge>[] solGraph = k.kruskal(graph);
System.out.println("\nMinimal Graph: ");
for (int i = 0; i < solGraph.length; i++) {
for (Edge edge : solGraph[i]) {
System.out.println(i + " <-- weight " + edge.weight + " --> " + edge.to);
}
}
}
public HashSet<Edge>[] kruskal(HashSet<Edge>[] graph) {
int nodes = graph.length;
int[] captain = new int[nodes];
// captain of i, stores the set with all the connected nodes to i
HashSet<Integer>[] connectedGroups = new HashSet[nodes];
HashSet<Edge>[] minGraph = new HashSet[nodes];
PriorityQueue<Edge> edges = new PriorityQueue<>((Comparator.comparingInt(edge -> edge.weight)));
for (int i = 0; i < nodes; i++) {
minGraph[i] = new HashSet<>();
connectedGroups[i] = new HashSet<>();
connectedGroups[i].add(i);
captain[i] = i;
edges.addAll(graph[i]);
}
int connectedElements = 0;
// as soon as two sets merge all the elements, the algorithm must stop
while (connectedElements != nodes && !edges.isEmpty()) {
Edge edge = edges.poll();
// This if avoids cycles
if (!connectedGroups[captain[edge.from]].contains(edge.to)
&& !connectedGroups[captain[edge.to]].contains(edge.from)) {
// merge sets of the captains of each point connected by the edge
connectedGroups[captain[edge.from]].addAll(connectedGroups[captain[edge.to]]);
// update captains of the elements merged
connectedGroups[captain[edge.from]].forEach(i -> captain[i] = captain[edge.from]);
// add Edge to minimal graph
addEdge(minGraph, edge.from, edge.to, edge.weight);
// count how many elements have been merged
connectedElements = connectedGroups[captain[edge.from]].size();
}
}
return minGraph;
}
}

View File

@ -0,0 +1,349 @@
package com.thealgorithms.datastructures.graphs;
import java.util.List;
import java.util.Queue;
import java.util.ArrayList;
import java.util.LinkedList;
/**
* Implementation of a graph in a matrix form Also known as an adjacency matrix
* representation [Adjacency matrix -
* Wikipedia](https://en.wikipedia.org/wiki/Adjacency_matrix)
*
* @author Unknown
*/
public class MatrixGraphs {
public static void main(String args[]) {
AdjacencyMatrixGraph graph = new AdjacencyMatrixGraph(10);
graph.addEdge(1, 2);
graph.addEdge(1, 5);
graph.addEdge(2, 5);
graph.addEdge(1, 2);
graph.addEdge(2, 3);
graph.addEdge(3, 4);
graph.addEdge(4, 1);
graph.addEdge(2, 3);
graph.addEdge(3, 9);
graph.addEdge(9, 1);
graph.addEdge(9, 8);
graph.addEdge(1, 8);
graph.addEdge(5, 6);
System.out.println("The graph matrix:");
System.out.println(graph);
System.out.println("Depth first order beginning at node '1':");
System.out.println(graph.depthFirstOrder(1));
System.out.println("Breadth first order beginning at node '1':");
System.out.println(graph.breadthFirstOrder(1));
}
}
/**
* AdjacencyMatrixGraph Implementation
*/
class AdjacencyMatrixGraph {
/**
* The number of vertices in the graph
*/
private int _numberOfVertices;
/**
* The number of edges in the graph
*/
private int _numberOfEdges;
/**
* The adjacency matrix for the graph
*/
private int[][] _adjacency;
/**
* Static variables to define whether or not an edge exists in the adjacency
* matrix
*/
static final int EDGE_EXIST = 1;
static final int EDGE_NONE = 0;
/**
* Constructor
*/
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;
}
}
}
/**
* Updates the number of vertices in the graph
*
* @param newNumberOfVertices the new number of vertices
*/
private void setNumberOfVertices(int newNumberOfVertices) {
this._numberOfVertices = newNumberOfVertices;
}
/**
* Getter for `this._numberOfVertices`
*
* @return the number of vertices in the graph
*/
public int numberOfVertices() {
return this._numberOfVertices;
}
/**
* Updates the number of edges in the graph
*
* @param newNumberOfEdges
*
*/
private void setNumberOfEdges(int newNumberOfEdges) {
this._numberOfEdges = newNumberOfEdges;
}
/**
* Getter for `this._numberOfEdges`
*
* @return the number of edges
*/
public int numberOfEdges() {
return this._numberOfEdges;
}
/**
* Sets a new matrix as the adjacency matrix
*
* @param newAdjacency the new adjaceny matrix
*/
private void setAdjacency(int[][] newAdjacency) {
this._adjacency = newAdjacency;
}
/**
* Getter for the adjacency matrix
*
* @return the adjacency matrix
*/
private int[][] adjacency() {
return this._adjacency;
}
/**
* Checks if two vertices are connected by an edge
*
* @param from the parent vertex to check for adjacency
* @param to the child vertex to check for adjacency
* @return whether or not the vertices are adjancent
*/
private boolean adjacencyOfEdgeDoesExist(int from, int to) {
return (this.adjacency()[from][to] != AdjacencyMatrixGraph.EDGE_NONE);
}
/**
* Checks if a particular vertex exists in a graph
*
* @param aVertex the vertex to check for existence
* @return whether or not the vertex exists
*/
public boolean vertexDoesExist(int aVertex) {
if (aVertex >= 0 && aVertex < this.numberOfVertices()) {
return true;
} else {
return false;
}
}
/**
* Checks if two vertices are connected by an edge
*
* @param from the parent vertex to check for adjacency
* @param to the child vertex to check for adjacency
* @return whether or not the vertices are adjancent
*/
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 the data of the vertex the edge is from
* @param to the data of the vertex the edge is going to
* @return returns true if the edge did not exist, return false if it
* already did
*/
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.numberOfEdges() + 1);
return true;
}
}
return false;
}
/**
* this method removes an edge from the graph between two specified vertices
*
* @param from the data of the vertex the edge is from
* @param to the data of the vertex the edge is going to
* @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.numberOfEdges() - 1);
return true;
}
}
return false;
}
/**
* This method returns a list of the vertices in a depth first order
* beginning with the specified vertex
*
* @param startVertex the vertex to begin the traversal
* @return the list of the ordered vertices
*/
public List<Integer> depthFirstOrder(int startVertex) {
// If the startVertex is invalid, return an empty list
if (startVertex >= _numberOfVertices || startVertex < 0) {
return new ArrayList<Integer>();
}
// Create an array to track the visited vertices
boolean[] visited = new boolean[_numberOfVertices];
// Create a list to keep track of the order of our traversal
ArrayList<Integer> orderList = new ArrayList<Integer>();
// Perform our DFS algorithm
depthFirstOrder(startVertex, visited, orderList);
return orderList;
}
/**
* Helper method for public depthFirstOrder(int) that will perform a depth
* first traversal recursively on the graph
*
* @param currentVertex the currently exploring vertex
* @param visited the array of values denoting whether or not that vertex
* has been visited
* @param orderList the list to add vertices to as they are visited
*/
private void depthFirstOrder(int currentVertex, boolean[] visited, List<Integer> orderList) {
// If this vertex has already been visited, do nothing and return
if (visited[currentVertex]) {
return;
}
// Visit the currentVertex by marking it as visited and adding it
// to the orderList
visited[currentVertex] = true;
orderList.add(currentVertex);
// Get the adjacency array for this vertex
int[] adjacent = _adjacency[currentVertex];
for (int i = 0; i < adjacent.length; i++) // If an edge exists between the currentVertex and the vertex
// we are considering exploring, recurse on it
{
if (adjacent[i] == AdjacencyMatrixGraph.EDGE_EXIST) {
depthFirstOrder(i, visited, orderList);
}
}
}
/**
* This method returns a list of the vertices in a breadth first order
* beginning with the specified vertex
*
* @param startVertex the vertext to begin the traversal
* @return the list of the ordered vertices
*/
public List<Integer> breadthFirstOrder(int startVertex) {
// If the specified startVertex is invalid, return an empty list
if (startVertex >= _numberOfVertices || startVertex < 0) {
return new ArrayList<Integer>();
}
// Create an array to keep track of the visited vertices
boolean[] visited = new boolean[_numberOfVertices];
// Create a list to keep track of the ordered vertices
ArrayList<Integer> orderList = new ArrayList<Integer>();
// Create a queue for our BFS algorithm and add the startVertex
// to the queue
Queue<Integer> queue = new LinkedList<Integer>();
queue.add(startVertex);
// Continue until the queue is empty
while (!queue.isEmpty()) {
// Remove the first vertex in the queue
int currentVertex = queue.poll();
// If we've visited this vertex, skip it
if (visited[currentVertex]) {
continue;
}
// We now visit this vertex by adding it to the orderList and
// marking it as visited
orderList.add(currentVertex);
visited[currentVertex] = true;
// Get the adjacency array for the currentVertex and
// check each node
int[] adjacent = _adjacency[currentVertex];
for (int vertex = 0; vertex < adjacent.length; vertex++) // If an edge exists between the current vertex and the
// vertex we are considering exploring, we add it to the queue
{
if (adjacent[vertex] == AdjacencyMatrixGraph.EDGE_EXIST) {
queue.add(vertex);
}
}
}
return orderList;
}
/**
* this gives a list of vertices in the graph and their adjacencies
*
* @return returns a string describing this graph
*/
public String toString() {
String s = " ";
for (int i = 0; i < this.numberOfVertices(); i++) {
s = s + String.valueOf(i) + " ";
}
s = s + " \n";
for (int i = 0; i < this.numberOfVertices(); i++) {
s = s + String.valueOf(i) + " : ";
for (int j = 0; j < this.numberOfVertices(); j++) {
s = s + String.valueOf(this._adjacency[i][j]) + " ";
}
s = s + "\n";
}
return s;
}
}

View File

@ -0,0 +1,104 @@
package com.thealgorithms.datastructures.graphs;
/**
* A Java program for Prim's Minimum Spanning Tree (MST) algorithm. adjacency
* matrix representation of the graph
*/
class PrimMST {
// Number of vertices in the graph
private static final int V = 5;
// A utility function to find the vertex with minimum key
// value, from the set of vertices not yet included in MST
int minKey(int key[], Boolean mstSet[]) {
// Initialize min value
int min = Integer.MAX_VALUE, min_index = -1;
for (int v = 0; v < V; v++) {
if (mstSet[v] == false && key[v] < min) {
min = key[v];
min_index = v;
}
}
return min_index;
}
// A utility function to print the constructed MST stored in
// parent[]
void printMST(int parent[], int n, int graph[][]) {
System.out.println("Edge Weight");
for (int i = 1; i < V; i++) {
System.out.println(parent[i] + " - " + i + " " + graph[i][parent[i]]);
}
}
// Function to construct and print MST for a graph represented
// using adjacency matrix representation
void primMST(int graph[][]) {
// Array to store constructed MST
int parent[] = new int[V];
// Key values used to pick minimum weight edge in cut
int key[] = new int[V];
// To represent set of vertices not yet included in MST
Boolean mstSet[] = new Boolean[V];
// Initialize all keys as INFINITE
for (int i = 0; i < V; i++) {
key[i] = Integer.MAX_VALUE;
mstSet[i] = false;
}
// Always include first 1st vertex in MST.
key[0] = 0; // Make key 0 so that this vertex is
// picked as first vertex
parent[0] = -1; // First node is always root of MST
// The MST will have V vertices
for (int count = 0; count < V - 1; count++) {
// Pick thd minimum key vertex from the set of vertices
// not yet included in MST
int u = minKey(key, mstSet);
// Add the picked vertex to the MST Set
mstSet[u] = true;
// Update key value and parent index of the adjacent
// vertices of the picked vertex. Consider only those
// vertices which are not yet included in MST
for (int v = 0; v < V; v++) // graph[u][v] is non zero only for adjacent vertices of m
// mstSet[v] is false for vertices not yet included in MST
// Update the key only if graph[u][v] is smaller than key[v]
{
if (graph[u][v] != 0 && mstSet[v] == false && graph[u][v] < key[v]) {
parent[v] = u;
key[v] = graph[u][v];
}
}
}
// print the constructed MST
printMST(parent, V, graph);
}
public static void main(String[] args) {
/* Let us create the following graph
2 3
(0)--(1)--(2)
| / \ |
6| 8/ \5 |7
| / \ |
(3)-------(4)
9 */
PrimMST t = new PrimMST();
int graph[][]
= new int[][]{
{0, 2, 0, 6, 0}, {2, 0, 3, 8, 5}, {0, 3, 0, 0, 7}, {6, 8, 0, 0, 9}, {0, 5, 7, 9, 0},};
// Print the solution
t.primMST(graph);
}
}

View File

@ -0,0 +1,42 @@
## Graph
Graph is a useful data structure for representing most of the real world problems involving a set of users/candidates/nodes and their relations. A Graph consists of two parameters :
```
V = a set of vertices
E = a set of edges
```
Each edge in `E` connects any two vertices from `V`. Based on the type of edge, graphs can be of two types:
1. **Directed**: The edges are directed in nature which means that when there is an edge from node `A` to `B`, it does not imply that there is an edge from `B` to `A`.
An example of directed edge graph the **follow** feature of social media. If you follow a celebrity, it doesn't imply that s/he follows you.
2. **Undirected**: The edges don't have any direction. So if `A` and `B` are connected, we can assume that there is edge from both `A` to `B` and `B` to `A`.
Example: Social media graph, where if two persons are friend, it implies that both are friend with each other.
### Representation
1. **Adjacency Lists**: Each node is represented as an entry and all the edges are represented as a list emerging from the corresponding node. So if vertex `1` has eadges to 2,3, and 6, the list corresponding to 1 will have 2,3 and 6 as entries. Consider the following graph.
```
0: 1-->2-->3
1: 0-->2
2: 0-->1
3: 0-->4
4: 3
```
It means there are edges from 0 to 1, 2 and 3; from 1 to 0 and 2 and so on.
2. **Adjacency Matrix**: The graph is represented as a matrix of size `|V| x |V|` and an entry 1 in cell `(i,j)` implies that there is an edge from i to j. 0 represents no edge.
The mtrix for the above graph:
```
0 1 2 3 4
0 0 1 1 1 0
1 1 0 1 0 0
2 1 1 0 0 0
3 1 0 0 0 1
4 0 0 0 1 0
```