refactor: Dijkstra algorithm
(#5329)
This commit is contained in:
parent
e32cab3189
commit
98bee26d51
@ -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
|
|
||||||
*/
|
|
@ -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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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 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));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user