Skip to content

Remove print & main methods, improve comments, add tests in `Floy… #5584

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
1 change: 1 addition & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,7 @@
* [BoruvkaAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithmTest.java)
* [DijkstraAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/DijkstraAlgorithmTest.java)
* [EdmondsBlossomAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/EdmondsBlossomAlgorithmTest.java)
* [FloydWarshallTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/FloydWarshallTest.java)
* [FordFulkersonTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/FordFulkersonTest.java)
* [HamiltonianCycleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/HamiltonianCycleTest.java)
* [KosarajuTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/KosarajuTest.java)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,46 @@
package com.thealgorithms.datastructures.graphs;

import java.util.Scanner;

/**
* The {@code FloydWarshall} class provides an implementation of the Floyd-Warshall algorithm
* to compute the shortest paths between all pairs of vertices in a weighted graph.
* It handles both positive and negative edge weights but does not support negative cycles.
* The algorithm is based on dynamic programming and runs in O(V^3) time complexity,
* where V is the number of vertices in the graph.
*
* <p>
* The distance matrix is updated iteratively to find the shortest distance between any two vertices
* by considering each vertex as an intermediate step.
* </p>
*
* Reference: <a href="https://en.wikipedia.org/wiki/Floyd%E2%80%93Warshall_algorithm">Floyd-Warshall Algorithm</a>
*/
public class FloydWarshall {

private int[][] distanceMatrix;
private int numberofvertices; // number of vertices in the graph
private int numberofvertices;
public static final int INFINITY = 999;

/**
* Constructs a Floyd-Warshall instance for a graph with the given number of vertices.
* Initializes the distance matrix for the graph.
*
* @param numberofvertices The number of vertices in the graph.
*/
public FloydWarshall(int numberofvertices) {
distanceMatrix = new int[numberofvertices + 1][numberofvertices + 1]; // stores the value of distance from all the possible path form the source
// vertex to destination vertex
distanceMatrix = new int[numberofvertices + 1][numberofvertices + 1];
// The matrix is initialized with 0's by default
this.numberofvertices = numberofvertices;
}

public void floydwarshall(int[][] adjacencyMatrix) { // calculates all the distances from source to destination vertex
/**
* Executes the Floyd-Warshall algorithm to compute the shortest path between all pairs of vertices.
* It uses an adjacency matrix to calculate the distance matrix by considering each vertex as an intermediate point.
*
* @param adjacencyMatrix The weighted adjacency matrix representing the graph.
* A value of 0 means no direct edge between the vertices, except for diagonal elements which are 0 (distance to self).
*/
public void floydwarshall(int[][] adjacencyMatrix) {
// Initialize the distance matrix with the adjacency matrix.
for (int source = 1; source <= numberofvertices; source++) {
for (int destination = 1; destination <= numberofvertices; destination++) {
distanceMatrix[source][destination] = adjacencyMatrix[source][destination];
Expand All @@ -24,19 +49,29 @@ public void floydwarshall(int[][] adjacencyMatrix) { // calculates all the dista
for (int intermediate = 1; intermediate <= numberofvertices; intermediate++) {
for (int source = 1; source <= numberofvertices; source++) {
for (int destination = 1; destination <= numberofvertices; destination++) {
if (distanceMatrix[source][intermediate] + distanceMatrix[intermediate][destination] < distanceMatrix[source][destination]) { // calculated distance it get replaced as
// new shortest distance // if the new
// distance calculated is less then the
// earlier shortest
// Update distance if a shorter path through the intermediate vertex exists.
if (distanceMatrix[source][intermediate] + distanceMatrix[intermediate][destination] < distanceMatrix[source][destination]) {
distanceMatrix[source][destination] = distanceMatrix[source][intermediate] + distanceMatrix[intermediate][destination];
}
}
}
}

printDistanceMatrix();
}

/**
* Prints the distance matrix representing the shortest paths between all pairs of vertices.
* The rows and columns correspond to the source and destination vertices.
*/
private void printDistanceMatrix() {
// Print header for vertices
for (int source = 1; source <= numberofvertices; source++) {
System.out.print("\t" + source);
}
System.out.println();

// Print the distance matrix
for (int source = 1; source <= numberofvertices; source++) {
System.out.print(source + "\t");
for (int destination = 1; destination <= numberofvertices; destination++) {
Expand All @@ -46,27 +81,7 @@ public void floydwarshall(int[][] adjacencyMatrix) { // calculates all the dista
}
}

public static void main(String... arg) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter the number of vertices");
int numberOfVertices = scan.nextInt();
int[][] adjacencyMatrix = new int[numberOfVertices + 1][numberOfVertices + 1];
System.out.println("Enter the Weighted Matrix for the graph");
for (int source = 1; source <= numberOfVertices; source++) {
for (int destination = 1; destination <= numberOfVertices; destination++) {
adjacencyMatrix[source][destination] = scan.nextInt();
if (source == destination) {
adjacencyMatrix[source][destination] = 0;
continue;
}
if (adjacencyMatrix[source][destination] == 0) {
adjacencyMatrix[source][destination] = INFINITY;
}
}
}
System.out.println("The Transitive Closure of the Graph");
FloydWarshall floydwarshall = new FloydWarshall(numberOfVertices);
floydwarshall.floydwarshall(adjacencyMatrix);
scan.close();
public Object[] getDistanceMatrix() {
return distanceMatrix;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.thealgorithms.datastructures.graphs;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;

import org.junit.jupiter.api.Test;

class FloydWarshallTest {

@Test
void testSmallGraph() {
int[][] adjacencyMatrix = {{0, 0, 0, 0}, // Ignored row (0 index)
{0, 0, 3, FloydWarshall.INFINITY}, {0, FloydWarshall.INFINITY, 0, 1}, {0, FloydWarshall.INFINITY, FloydWarshall.INFINITY, 0}};

FloydWarshall fw = new FloydWarshall(3);
fw.floydwarshall(adjacencyMatrix);

int[][] expectedDistanceMatrix = {{0, 0, 0, 0}, {0, 0, 3, 4}, {0, FloydWarshall.INFINITY, 0, 1}, {0, FloydWarshall.INFINITY, FloydWarshall.INFINITY, 0}};

assertArrayEquals(expectedDistanceMatrix, fw.getDistanceMatrix());
}

@Test
void testLargerGraph() {
int[][] adjacencyMatrix = {{0, 0, 0, 0, 0}, {0, 0, 1, FloydWarshall.INFINITY, 2}, {0, FloydWarshall.INFINITY, 0, 4, FloydWarshall.INFINITY}, {0, FloydWarshall.INFINITY, FloydWarshall.INFINITY, 0, 3}, {0, FloydWarshall.INFINITY, FloydWarshall.INFINITY, FloydWarshall.INFINITY, 0}};

FloydWarshall fw = new FloydWarshall(4);
fw.floydwarshall(adjacencyMatrix);

int[][] expectedDistanceMatrix = {{0, 0, 0, 0, 0}, {0, 0, 1, 5, 2}, {0, FloydWarshall.INFINITY, 0, 4, 7}, {0, FloydWarshall.INFINITY, FloydWarshall.INFINITY, 0, 3}, {0, FloydWarshall.INFINITY, FloydWarshall.INFINITY, FloydWarshall.INFINITY, 0}};

assertArrayEquals(expectedDistanceMatrix, fw.getDistanceMatrix());
}
}