Skip to content

Commit 1a2aedd

Browse files
authored
Add optimized version of DijkstraAlgorithm (TheAlgorithms#6088)
1 parent 7ec5d24 commit 1a2aedd

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.thealgorithms.datastructures.graphs;
2+
3+
import java.util.Arrays;
4+
import java.util.Set;
5+
import java.util.TreeSet;
6+
import org.apache.commons.lang3.tuple.Pair;
7+
8+
/**
9+
* Dijkstra's algorithm for finding the shortest path from a single source vertex to all other vertices in a graph.
10+
*/
11+
public class DijkstraOptimizedAlgorithm {
12+
13+
private final int vertexCount;
14+
15+
/**
16+
* Constructs a Dijkstra object with the given number of vertices.
17+
*
18+
* @param vertexCount The number of vertices in the graph.
19+
*/
20+
public DijkstraOptimizedAlgorithm(int vertexCount) {
21+
this.vertexCount = vertexCount;
22+
}
23+
24+
/**
25+
* Executes Dijkstra's algorithm on the provided graph to find the shortest paths from the source vertex to all other vertices.
26+
*
27+
* The graph is represented as an adjacency matrix where {@code graph[i][j]} represents the weight of the edge from vertex {@code i}
28+
* to vertex {@code j}. A value of 0 indicates no edge exists between the vertices.
29+
*
30+
* @param graph The graph represented as an adjacency matrix.
31+
* @param source The source vertex.
32+
* @return An array where the value at each index {@code i} represents the shortest distance from the source vertex to vertex {@code i}.
33+
* @throws IllegalArgumentException if the source vertex is out of range.
34+
*/
35+
public int[] run(int[][] graph, int source) {
36+
if (source < 0 || source >= vertexCount) {
37+
throw new IllegalArgumentException("Incorrect source");
38+
}
39+
40+
int[] distances = new int[vertexCount];
41+
boolean[] processed = new boolean[vertexCount];
42+
Set<Pair<Integer, Integer>> unprocessed = new TreeSet<>();
43+
44+
Arrays.fill(distances, Integer.MAX_VALUE);
45+
Arrays.fill(processed, false);
46+
distances[source] = 0;
47+
unprocessed.add(Pair.of(0, source));
48+
49+
while (!unprocessed.isEmpty()) {
50+
Pair<Integer, Integer> distanceAndU = unprocessed.iterator().next();
51+
unprocessed.remove(distanceAndU);
52+
int u = distanceAndU.getRight();
53+
processed[u] = true;
54+
55+
for (int v = 0; v < vertexCount; v++) {
56+
if (!processed[v] && graph[u][v] != 0 && distances[u] != Integer.MAX_VALUE && distances[u] + graph[u][v] < distances[v]) {
57+
unprocessed.remove(Pair.of(distances[v], v));
58+
distances[v] = distances[u] + graph[u][v];
59+
unprocessed.add(Pair.of(distances[v], v));
60+
}
61+
}
62+
}
63+
64+
return distances;
65+
}
66+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.thealgorithms.datastructures.graphs;
2+
3+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
5+
6+
import org.junit.jupiter.api.BeforeEach;
7+
import org.junit.jupiter.api.Test;
8+
9+
public class DijkstraOptimizedAlgorithmTest {
10+
11+
private DijkstraOptimizedAlgorithm dijkstraOptimizedAlgorithm;
12+
private int[][] graph;
13+
14+
@BeforeEach
15+
void setUp() {
16+
graph = new int[][] {
17+
{0, 4, 0, 0, 0, 0, 0, 8, 0},
18+
{4, 0, 8, 0, 0, 0, 0, 11, 0},
19+
{0, 8, 0, 7, 0, 4, 0, 0, 2},
20+
{0, 0, 7, 0, 9, 14, 0, 0, 0},
21+
{0, 0, 0, 9, 0, 10, 0, 0, 0},
22+
{0, 0, 4, 14, 10, 0, 2, 0, 0},
23+
{0, 0, 0, 0, 0, 2, 0, 1, 6},
24+
{8, 11, 0, 0, 0, 0, 1, 0, 7},
25+
{0, 0, 2, 0, 0, 0, 6, 7, 0},
26+
};
27+
28+
dijkstraOptimizedAlgorithm = new DijkstraOptimizedAlgorithm(graph.length);
29+
}
30+
31+
@Test
32+
void testRunAlgorithm() {
33+
int[] expectedDistances = {0, 4, 12, 19, 21, 11, 9, 8, 14};
34+
assertArrayEquals(expectedDistances, dijkstraOptimizedAlgorithm.run(graph, 0));
35+
}
36+
37+
@Test
38+
void testGraphWithDisconnectedNodes() {
39+
int[][] disconnectedGraph = {
40+
{0, 3, 0, 0}, {3, 0, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0} // Node 3 is disconnected
41+
};
42+
43+
DijkstraOptimizedAlgorithm dijkstraDisconnected = new DijkstraOptimizedAlgorithm(disconnectedGraph.length);
44+
45+
// Testing from vertex 0
46+
int[] expectedDistances = {0, 3, 4, Integer.MAX_VALUE}; // Node 3 is unreachable
47+
assertArrayEquals(expectedDistances, dijkstraDisconnected.run(disconnectedGraph, 0));
48+
}
49+
50+
@Test
51+
void testSingleVertexGraph() {
52+
int[][] singleVertexGraph = {{0}};
53+
DijkstraOptimizedAlgorithm dijkstraSingleVertex = new DijkstraOptimizedAlgorithm(1);
54+
55+
int[] expectedDistances = {0}; // The only vertex's distance to itself is 0
56+
assertArrayEquals(expectedDistances, dijkstraSingleVertex.run(singleVertexGraph, 0));
57+
}
58+
59+
@Test
60+
void testInvalidSourceVertex() {
61+
assertThrows(IllegalArgumentException.class, () -> dijkstraOptimizedAlgorithm.run(graph, -1));
62+
assertThrows(IllegalArgumentException.class, () -> dijkstraOptimizedAlgorithm.run(graph, graph.length));
63+
}
64+
}

0 commit comments

Comments
 (0)