From 432656474d18fc0771b9c18e9d049c7de42a71bc Mon Sep 17 00:00:00 2001 From: Alex Klymenko Date: Thu, 15 Aug 2024 23:41:19 +0200 Subject: [PATCH 1/2] refactor: Dijkstra algorithm --- .../graphs/DIJSKSTRAS_ALGORITHM.java | 86 ------------------ .../graphs/DijkstraAlgorithm.java | 91 +++++++++++++++++++ .../graphs/DijkstraAlgorithmTest.java | 67 ++++++++++++++ 3 files changed, 158 insertions(+), 86 deletions(-) delete mode 100644 src/main/java/com/thealgorithms/datastructures/graphs/DIJSKSTRAS_ALGORITHM.java create mode 100644 src/main/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithm.java create mode 100644 src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/DIJSKSTRAS_ALGORITHM.java b/src/main/java/com/thealgorithms/datastructures/graphs/DIJSKSTRAS_ALGORITHM.java deleted file mode 100644 index 419da4a9be73..000000000000 --- a/src/main/java/com/thealgorithms/datastructures/graphs/DIJSKSTRAS_ALGORITHM.java +++ /dev/null @@ -1,86 +0,0 @@ -/* -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; - int minIndex = -1; - - for (int r = 0; r < k; r++) { - if (!set[r] && dist[r] <= min) { - min = dist[r]; - minIndex = r; - } - } - - return minIndex; - } - - 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] = Boolean.FALSE; - } - - dist[src] = 0; - - for (int c = 0; c < k - 1; c++) { - int u = minDist(dist, set); - - set[u] = Boolean.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 - */ diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithm.java b/src/main/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithm.java new file mode 100644 index 000000000000..70699a9461f7 --- /dev/null +++ b/src/main/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithm.java @@ -0,0 +1,91 @@ +package com.thealgorithms.datastructures.graphs; + +import java.util.Arrays; + +/** + * Dijkstra's algorithm for finding the shortest path from a single source vertex to all other vertices in a graph. + */ +public class DijkstraAlgorithm { + + private final int vertexCount; + + /** + * Constructs a Dijkstra object with the given number of vertices. + * + * @param vertexCount The number of vertices in the graph. + */ + public DijkstraAlgorithm(int vertexCount) { + this.vertexCount = vertexCount; + } + + /** + * Executes Dijkstra's algorithm on the provided graph to find the shortest paths from the source vertex to all other vertices. + * + * The graph is represented as an adjacency matrix where {@code graph[i][j]} represents the weight of the edge from vertex {@code i} + * to vertex {@code j}. A value of 0 indicates no edge exists between the vertices. + * + * @param graph The graph represented as an adjacency matrix. + * @param source The source vertex. + * @return An array where the value at each index {@code i} represents the shortest distance from the source vertex to vertex {@code i}. + * @throws IllegalArgumentException if the source vertex is out of range. + */ + public int[] run(int[][] graph, int source) { + if (source < 0 || source >= vertexCount) { + throw new IllegalArgumentException("Incorrect source"); + } + + int[] distances = new int[vertexCount]; + boolean[] processed = new boolean[vertexCount]; + + Arrays.fill(distances, Integer.MAX_VALUE); + Arrays.fill(processed, false); + distances[source] = 0; + + for (int count = 0; count < vertexCount - 1; count++) { + int u = getMinDistanceVertex(distances, processed); + processed[u] = true; + + for (int v = 0; v < vertexCount; v++) { + if (!processed[v] && graph[u][v] != 0 && distances[u] != Integer.MAX_VALUE && distances[u] + graph[u][v] < distances[v]) { + distances[v] = distances[u] + graph[u][v]; + } + } + } + + printDistances(distances); + return distances; + } + + /** + * Finds the vertex with the minimum distance value from the set of vertices that have not yet been processed. + * + * @param distances The array of current shortest distances from the source vertex. + * @param processed The array indicating whether each vertex has been processed. + * @return The index of the vertex with the minimum distance value. + */ + private int getMinDistanceVertex(int[] distances, boolean[] processed) { + int min = Integer.MAX_VALUE; + int minIndex = -1; + + for (int v = 0; v < vertexCount; v++) { + if (!processed[v] && distances[v] <= min) { + min = distances[v]; + minIndex = v; + } + } + + return minIndex; + } + + /** + * Prints the shortest distances from the source vertex to all other vertices. + * + * @param distances The array of shortest distances. + */ + private void printDistances(int[] distances) { + System.out.println("Vertex \t Distance"); + for (int i = 0; i < vertexCount; i++) { + System.out.println(i + " \t " + distances[i]); + } + } +} diff --git a/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java b/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java new file mode 100644 index 000000000000..e1d22e9cea52 --- /dev/null +++ b/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java @@ -0,0 +1,67 @@ +package com.thealgorithms.datastructures.graphs; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class DijkstraAlgorithmTest { + + private DijkstraAlgorithm dijkstraAlgorithm; + private int[][] graph; + + @BeforeEach + void setUp() { + 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}, + }; + + dijkstraAlgorithm = new DijkstraAlgorithm(graph.length); + } + + @Test + void testRunAlgorithm() { + int[] expectedDistances = {0, 4, 12, 19, 21, 11, 9, 8, 14}; + assertArrayEquals(expectedDistances, dijkstraAlgorithm.run(graph, 0)); + } + + @Test + void testGraphWithDisconnectedNodes() { + int[][] disconnectedGraph = { + {0, 3, 0, 0}, + {3, 0, 1, 0}, + {0, 1, 0, 0}, + {0, 0, 0, 0} // Node 3 is disconnected + }; + + DijkstraAlgorithm dijkstraDisconnected = new DijkstraAlgorithm(disconnectedGraph.length); + + // Testing from vertex 0 + int[] expectedDistances = {0, 3, 4, Integer.MAX_VALUE}; // Node 3 is unreachable + assertArrayEquals(expectedDistances, dijkstraDisconnected.run(disconnectedGraph, 0)); + } + + @Test + void testSingleVertexGraph() { + int[][] singleVertexGraph = {{0}}; + DijkstraAlgorithm dijkstraSingleVertex = new DijkstraAlgorithm(1); + + int[] expectedDistances = {0}; // The only vertex's distance to itself is 0 + assertArrayEquals(expectedDistances, dijkstraSingleVertex.run(singleVertexGraph, 0)); + } + + @Test + void testInvalidSourceVertex() { + assertThrows(IllegalArgumentException.class, () -> dijkstraAlgorithm.run(graph, -1)); + assertThrows(IllegalArgumentException.class, () -> dijkstraAlgorithm.run(graph, graph.length)); + } +} From b9da27172e1b4b894a2d6d83b7a2a07bfdc0ba75 Mon Sep 17 00:00:00 2001 From: Alex Klymenko Date: Thu, 15 Aug 2024 23:46:27 +0200 Subject: [PATCH 2/2] checkstyle: formatting --- .../graphs/DijkstraAlgorithmTest.java | 29 +++++++++---------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java b/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java index e1d22e9cea52..c5df9acdf33b 100644 --- a/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java +++ b/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java @@ -1,11 +1,11 @@ package com.thealgorithms.datastructures.graphs; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertThrows; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + public class DijkstraAlgorithmTest { private DijkstraAlgorithm dijkstraAlgorithm; @@ -14,15 +14,15 @@ public class DijkstraAlgorithmTest { @BeforeEach void setUp() { 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}, + {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}, }; dijkstraAlgorithm = new DijkstraAlgorithm(graph.length); @@ -37,10 +37,7 @@ void testRunAlgorithm() { @Test void testGraphWithDisconnectedNodes() { int[][] disconnectedGraph = { - {0, 3, 0, 0}, - {3, 0, 1, 0}, - {0, 1, 0, 0}, - {0, 0, 0, 0} // Node 3 is disconnected + {0, 3, 0, 0}, {3, 0, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0} // Node 3 is disconnected }; DijkstraAlgorithm dijkstraDisconnected = new DijkstraAlgorithm(disconnectedGraph.length);