From dee1c0a74cc7e31f3b738b8692f1271215331f75 Mon Sep 17 00:00:00 2001 From: Amit-Verma5262 Date: Tue, 29 Oct 2024 23:52:49 +0530 Subject: [PATCH 1/3] added Dijkstra Algorithm --- .../graph/DijkstraShortestPath.java | 50 ++++++++++++ .../graph/DijkstraShortestPathTest.java | 76 +++++++++++++++++++ 2 files changed, 126 insertions(+) create mode 100644 src/main/java/com/thealgorithms/graph/DijkstraShortestPath.java create mode 100644 src/test/java/com/thealgorithms/graph/DijkstraShortestPathTest.java diff --git a/src/main/java/com/thealgorithms/graph/DijkstraShortestPath.java b/src/main/java/com/thealgorithms/graph/DijkstraShortestPath.java new file mode 100644 index 000000000000..3cc1e4479f1f --- /dev/null +++ b/src/main/java/com/thealgorithms/graph/DijkstraShortestPath.java @@ -0,0 +1,50 @@ +import java.util.*; + +public class DijkstraShortestPath { + + /** + * Finds the shortest path distances from the startNode to all other nodes in a weighted graph. + * + * @param n The number of nodes in the graph. + * @param adjList The adjacency list where each entry contains pairs of neighboring nodes and edge weights. + * @param startNode The starting node for the shortest path calculation. + * @return An array where each index i contains the shortest distance from startNode to node i. + */ + public int[] shortestPath(int n, Map> adjList, int startNode) { + int[] distances = new int[n]; + Arrays.fill(distances, Integer.MAX_VALUE); + distances[startNode] = 0; + + PriorityQueue minHeap = new PriorityQueue<>(Comparator.comparingInt(a -> a[1])); + minHeap.offer(new int[]{startNode, 0}); + + while (!minHeap.isEmpty()) { + int[] current = minHeap.poll(); + int currentNode = current[0]; + int currentDistance = current[1]; + + // This condition prevents revisiting nodes with a longer distance + if (currentDistance > distances[currentNode]) { + continue; + } + + List neighbors = adjList.getOrDefault(currentNode, new ArrayList<>()); + for (int[] neighbor : neighbors) { + int nextNode = neighbor[0]; + int edgeWeight = neighbor[1]; + + int newDistance = distances[currentNode] + edgeWeight; + if (newDistance < distances[nextNode]) { + distances[nextNode] = newDistance; + minHeap.offer(new int[]{nextNode, newDistance}); + } + } + } + + return distances; + } +} + +//wikipedia link for algorithm + +//https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm#:~:text=Dijkstra's%20algorithm%20(/%CB%88da%C9%AA,and%20published%20three%20years%20later. \ No newline at end of file diff --git a/src/test/java/com/thealgorithms/graph/DijkstraShortestPathTest.java b/src/test/java/com/thealgorithms/graph/DijkstraShortestPathTest.java new file mode 100644 index 000000000000..25b611538139 --- /dev/null +++ b/src/test/java/com/thealgorithms/graph/DijkstraShortestPathTest.java @@ -0,0 +1,76 @@ +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import java.util.HashMap; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class DijkstraShortestPathTest { + + private DijkstraShortestPath dijkstra; + + @BeforeEach + public void setUp() { + dijkstra = new DijkstraShortestPath(); + } + + @Test + public void testSinglePath() { + Map> adjList = new HashMap<>(); + adjList.put(0, List.of(new int[]{1, 1})); + adjList.put(1, List.of(new int[]{2, 1})); + adjList.put(2, List.of(new int[]{3, 1})); + adjList.put(3, new ArrayList<>()); + + int[] result = dijkstra.shortestPath(4, adjList, 0); + + int[] expected = {0, 1, 2, 3}; + assertArrayEquals(expected, result, "Shortest path distances should match."); + } + + @Test + public void testDisconnectedGraph() { + Map> adjList = new HashMap<>(); + adjList.put(0, List.of(new int[]{1, 2})); + adjList.put(1, List.of(new int[]{2, 2})); + adjList.put(2, new ArrayList<>()); + adjList.put(3, new ArrayList<>()); + + int[] result = dijkstra.shortestPath(4, adjList, 0); + + int[] expected = {0, 2, 4, Integer.MAX_VALUE}; + assertArrayEquals(expected, result, "Shortest path should indicate unreachable nodes."); + } + + @Test + public void testComplexGraph() { + Map> adjList = new HashMap<>(); + adjList.put(0, List.of(new int[]{1, 4}, new int[]{2, 1})); + adjList.put(1, List.of(new int[]{3, 1})); + adjList.put(2, List.of(new int[]{1, 2}, new int[]{3, 5})); + adjList.put(3, new ArrayList<>()); + + int[] result = dijkstra.shortestPath(4, adjList, 0); + + int[] expected = {0, 3, 1, 4}; + assertArrayEquals(expected, result, "Distances should match expected shortest path distances."); + } + + @Test + public void testRevisitedNodeWithHigherDistance() { + // This graph is set up to test the condition where a node is revisited with a higher distance. + Map> adjList = new HashMap<>(); + adjList.put(0, List.of(new int[]{1, 5})); + adjList.put(1, List.of(new int[]{2, 1})); + adjList.put(2, List.of(new int[]{0, 3}, new int[]{3, 1})); + adjList.put(3, new ArrayList<>()); + + int[] result = dijkstra.shortestPath(4, adjList, 0); + + int[] expected = {0, 5, 6, 7}; + assertArrayEquals(expected, result, "Distances should match expected shortest path distances."); + } +} +//added test cases From 9f88de2d4088b8632eaabc39d414fb151f0a69a6 Mon Sep 17 00:00:00 2001 From: Amit-Verma5262 Date: Wed, 30 Oct 2024 00:14:31 +0530 Subject: [PATCH 2/3] added Dijkstra Algorithm in graph --- .../graph/DijkstraShortestPath.java | 31 +++++------------ .../graph/DijkstraShortestPathTest.java | 33 ++++++++----------- 2 files changed, 23 insertions(+), 41 deletions(-) diff --git a/src/main/java/com/thealgorithms/graph/DijkstraShortestPath.java b/src/main/java/com/thealgorithms/graph/DijkstraShortestPath.java index 3cc1e4479f1f..1b0f20f1f494 100644 --- a/src/main/java/com/thealgorithms/graph/DijkstraShortestPath.java +++ b/src/main/java/com/thealgorithms/graph/DijkstraShortestPath.java @@ -2,49 +2,36 @@ public class DijkstraShortestPath { - /** - * Finds the shortest path distances from the startNode to all other nodes in a weighted graph. - * - * @param n The number of nodes in the graph. - * @param adjList The adjacency list where each entry contains pairs of neighboring nodes and edge weights. - * @param startNode The starting node for the shortest path calculation. - * @return An array where each index i contains the shortest distance from startNode to node i. - */ - public int[] shortestPath(int n, Map> adjList, int startNode) { - int[] distances = new int[n]; + public int[] shortestPath(int numNodes, Map> adjList, int startNode) { + int[] distances = new int[numNodes]; Arrays.fill(distances, Integer.MAX_VALUE); distances[startNode] = 0; PriorityQueue minHeap = new PriorityQueue<>(Comparator.comparingInt(a -> a[1])); - minHeap.offer(new int[]{startNode, 0}); + minHeap.offer(new int[] {startNode, 0}); while (!minHeap.isEmpty()) { int[] current = minHeap.poll(); int currentNode = current[0]; int currentDistance = current[1]; - // This condition prevents revisiting nodes with a longer distance if (currentDistance > distances[currentNode]) { continue; } - List neighbors = adjList.getOrDefault(currentNode, new ArrayList<>()); - for (int[] neighbor : neighbors) { - int nextNode = neighbor[0]; - int edgeWeight = neighbor[1]; - + for (int[] edge : adjList.getOrDefault(currentNode, Collections.emptyList())) { + int nextNode = edge[0]; + int edgeWeight = edge[1]; int newDistance = distances[currentNode] + edgeWeight; if (newDistance < distances[nextNode]) { distances[nextNode] = newDistance; - minHeap.offer(new int[]{nextNode, newDistance}); + minHeap.offer(new int[] {nextNode, newDistance}); } } } - return distances; } } -//wikipedia link for algorithm - -//https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm#:~:text=Dijkstra's%20algorithm%20(/%CB%88da%C9%AA,and%20published%20three%20years%20later. \ No newline at end of file +// wikipedia link for algorithm +// https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm#:~:text=Dijkstra's%20algorithm%20(/%CB%88da%C9%AA,and%20published%20three%20years%20later. diff --git a/src/test/java/com/thealgorithms/graph/DijkstraShortestPathTest.java b/src/test/java/com/thealgorithms/graph/DijkstraShortestPathTest.java index 25b611538139..878b6c4b503f 100644 --- a/src/test/java/com/thealgorithms/graph/DijkstraShortestPathTest.java +++ b/src/test/java/com/thealgorithms/graph/DijkstraShortestPathTest.java @@ -1,8 +1,8 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; -import java.util.ArrayList; import java.util.Map; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -19,41 +19,38 @@ public void setUp() { @Test public void testSinglePath() { Map> adjList = new HashMap<>(); - adjList.put(0, List.of(new int[]{1, 1})); - adjList.put(1, List.of(new int[]{2, 1})); - adjList.put(2, List.of(new int[]{3, 1})); + adjList.put(0, List.of(new int[] {1, 1})); + adjList.put(1, List.of(new int[] {2, 1})); + adjList.put(2, List.of(new int[] {3, 1})); adjList.put(3, new ArrayList<>()); int[] result = dijkstra.shortestPath(4, adjList, 0); - int[] expected = {0, 1, 2, 3}; - assertArrayEquals(expected, result, "Shortest path distances should match."); + assertArrayEquals(expected, result, "Distances should match expected shortest path distances."); } @Test public void testDisconnectedGraph() { Map> adjList = new HashMap<>(); - adjList.put(0, List.of(new int[]{1, 2})); - adjList.put(1, List.of(new int[]{2, 2})); + adjList.put(0, List.of(new int[] {1, 2})); + adjList.put(1, List.of(new int[] {2, 2})); adjList.put(2, new ArrayList<>()); adjList.put(3, new ArrayList<>()); int[] result = dijkstra.shortestPath(4, adjList, 0); - int[] expected = {0, 2, 4, Integer.MAX_VALUE}; - assertArrayEquals(expected, result, "Shortest path should indicate unreachable nodes."); + assertArrayEquals(expected, result, "Distances should match expected shortest path distances."); } @Test public void testComplexGraph() { Map> adjList = new HashMap<>(); - adjList.put(0, List.of(new int[]{1, 4}, new int[]{2, 1})); - adjList.put(1, List.of(new int[]{3, 1})); - adjList.put(2, List.of(new int[]{1, 2}, new int[]{3, 5})); + adjList.put(0, List.of(new int[] {1, 4}, new int[] {2, 1})); + adjList.put(1, List.of(new int[] {3, 1})); + adjList.put(2, List.of(new int[] {1, 2}, new int[] {3, 5})); adjList.put(3, new ArrayList<>()); int[] result = dijkstra.shortestPath(4, adjList, 0); - int[] expected = {0, 3, 1, 4}; assertArrayEquals(expected, result, "Distances should match expected shortest path distances."); } @@ -62,15 +59,13 @@ public void testComplexGraph() { public void testRevisitedNodeWithHigherDistance() { // This graph is set up to test the condition where a node is revisited with a higher distance. Map> adjList = new HashMap<>(); - adjList.put(0, List.of(new int[]{1, 5})); - adjList.put(1, List.of(new int[]{2, 1})); - adjList.put(2, List.of(new int[]{0, 3}, new int[]{3, 1})); + adjList.put(0, List.of(new int[] {1, 5})); + adjList.put(1, List.of(new int[] {2, 1})); + adjList.put(2, List.of(new int[] {0, 3}, new int[] {3, 1})); adjList.put(3, new ArrayList<>()); int[] result = dijkstra.shortestPath(4, adjList, 0); - int[] expected = {0, 5, 6, 7}; assertArrayEquals(expected, result, "Distances should match expected shortest path distances."); } } -//added test cases From 76ca08887e115d4196aca054d65337b4b7f357eb Mon Sep 17 00:00:00 2001 From: Amit-Verma5262 Date: Wed, 30 Oct 2024 00:19:36 +0530 Subject: [PATCH 3/3] added Dijkstra --- src/main/java/com/thealgorithms/graph/DijkstraShortestPath.java | 2 +- .../java/com/thealgorithms/graph/DijkstraShortestPathTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/graph/DijkstraShortestPath.java b/src/main/java/com/thealgorithms/graph/DijkstraShortestPath.java index 1b0f20f1f494..1ac1830b9e48 100644 --- a/src/main/java/com/thealgorithms/graph/DijkstraShortestPath.java +++ b/src/main/java/com/thealgorithms/graph/DijkstraShortestPath.java @@ -33,5 +33,5 @@ public int[] shortestPath(int numNodes, Map> adjList, int s } } -// wikipedia link for algorithm +// wikipedia link // https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm#:~:text=Dijkstra's%20algorithm%20(/%CB%88da%C9%AA,and%20published%20three%20years%20later. diff --git a/src/test/java/com/thealgorithms/graph/DijkstraShortestPathTest.java b/src/test/java/com/thealgorithms/graph/DijkstraShortestPathTest.java index 878b6c4b503f..70057a0acb08 100644 --- a/src/test/java/com/thealgorithms/graph/DijkstraShortestPathTest.java +++ b/src/test/java/com/thealgorithms/graph/DijkstraShortestPathTest.java @@ -57,7 +57,7 @@ public void testComplexGraph() { @Test public void testRevisitedNodeWithHigherDistance() { - // This graph is set up to test the condition where a node is revisited with a higher distance. + // graph is set up to test the condition where a node is revisited with a higher distance. Map> adjList = new HashMap<>(); adjList.put(0, List.of(new int[] {1, 5})); adjList.put(1, List.of(new int[] {2, 1}));