-
Notifications
You must be signed in to change notification settings - Fork 19.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added new, optimized version of DijkstraAlgorithm
- Loading branch information
Showing
2 changed files
with
130 additions
and
0 deletions.
There are no files selected for viewing
66 changes: 66 additions & 0 deletions
66
src/main/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithm.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package com.thealgorithms.datastructures.graphs; | ||
|
||
import java.util.Arrays; | ||
import java.util.Set; | ||
import java.util.TreeSet; | ||
import org.apache.commons.lang3.tuple.Pair; | ||
|
||
/** | ||
* Dijkstra's algorithm for finding the shortest path from a single source vertex to all other vertices in a graph. | ||
*/ | ||
public class DijkstraOptimizedAlgorithm { | ||
|
||
private final int vertexCount; | ||
|
||
/** | ||
* Constructs a Dijkstra object with the given number of vertices. | ||
* | ||
* @param vertexCount The number of vertices in the graph. | ||
*/ | ||
public DijkstraOptimizedAlgorithm(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]; | ||
Set<Pair<Integer, Integer>> unprocessed = new TreeSet<>(); | ||
|
||
Arrays.fill(distances, Integer.MAX_VALUE); | ||
Arrays.fill(processed, false); | ||
distances[source] = 0; | ||
unprocessed.add(Pair.of(0, source)); | ||
|
||
while (!unprocessed.isEmpty()) { | ||
Pair<Integer, Integer> distanceAndU = unprocessed.iterator().next(); | ||
unprocessed.remove(distanceAndU); | ||
int u = distanceAndU.getRight(); | ||
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]) { | ||
unprocessed.remove(Pair.of(distances[v], v)); | ||
distances[v] = distances[u] + graph[u][v]; | ||
unprocessed.add(Pair.of(distances[v], v)); | ||
} | ||
} | ||
} | ||
|
||
return distances; | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
src/test/java/com/thealgorithms/datastructures/graphs/DijkstraOptimizedAlgorithmTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package com.thealgorithms.datastructures.graphs; | ||
|
||
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 DijkstraOptimizedAlgorithmTest { | ||
|
||
private DijkstraOptimizedAlgorithm dijkstraOptimizedAlgorithm; | ||
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}, | ||
}; | ||
|
||
dijkstraOptimizedAlgorithm = new DijkstraOptimizedAlgorithm(graph.length); | ||
} | ||
|
||
@Test | ||
void testRunAlgorithm() { | ||
int[] expectedDistances = {0, 4, 12, 19, 21, 11, 9, 8, 14}; | ||
assertArrayEquals(expectedDistances, dijkstraOptimizedAlgorithm.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 | ||
}; | ||
|
||
DijkstraOptimizedAlgorithm dijkstraDisconnected = new DijkstraOptimizedAlgorithm(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}}; | ||
DijkstraOptimizedAlgorithm dijkstraSingleVertex = new DijkstraOptimizedAlgorithm(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, () -> dijkstraOptimizedAlgorithm.run(graph, -1)); | ||
assertThrows(IllegalArgumentException.class, () -> dijkstraOptimizedAlgorithm.run(graph, graph.length)); | ||
} | ||
} |