0% found this document useful (0 votes)
12 views3 pages

Warshall's and Floyd's Algorithms Explained

The document outlines the implementation of Warshall's and Floyd's algorithms for computing the transitive closure and all pairs shortest paths in a directed graph. Both algorithms operate in O(n³) time complexity, with test cases confirming their correctness, including handling negative weights in Floyd's algorithm. The program execution results indicate 64 operations for both algorithms on a graph with 4 vertices.

Uploaded by

sithikbe
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views3 pages

Warshall's and Floyd's Algorithms Explained

The document outlines the implementation of Warshall's and Floyd's algorithms for computing the transitive closure and all pairs shortest paths in a directed graph. Both algorithms operate in O(n³) time complexity, with test cases confirming their correctness, including handling negative weights in Floyd's algorithm. The program execution results indicate 64 operations for both algorithms on a graph with 4 vertices.

Uploaded by

sithikbe
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Task 5: Dynamic Programming – Warshall’s & Floyd’s algorithm

Aim: Compute the transitive closure of a given directed graph using Warshall's algorithm
and for the same graph implement the all pairs shortest path problem using Floyd’s algorithm.

Algorithm:

1. Warshall's Algorithm (Transitive Closure)

Warshall’s algorithm is used to determine the transitive closure of a directed graph. It


answers whether there is a path between two vertices.

Steps:

 Given an adjacency matrix A, convert it into a reachability matrix.


 If there is a path from i → k and k → j, then there exists a path from i → j.
 The algorithm runs in O(n³) time.

2. Floyd's Algorithm (All Pairs Shortest Path)

Floyd’s algorithm computes the shortest paths between all pairs of vertices, even in the
presence of negative weights (but without negative cycles).

Steps:

 Given a weighted adjacency matrix D, initialize it.


 For each intermediate vertex kk, update D[i][j] as:

D[i][j]=min⁡(D[i][j],D[i][k]+D[k][j])D[i][j]=min(D[i][j],D[i][k]+D[k][j])

 The algorithm runs in O(n³) time.

Program Implementation for Warshall’s & Floyd’s algorithm


#include <stdio.h>
#include <limits.h>
#include <time.h>

#define V 4
int wcount=0,fcount=0;
void warshallAlgorithm(int graph[V][V]) {
int reach[V][V];
clock_t start, end;

// Initialize reachability matrix


for (int i = 0; i < V; i++)
for (int j = 0; j < V; j++)
reach[i][j] = graph[i][j] ? 1 : 0;

start = clock();
for (int k = 0; k < V; k++) {
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
reach[i][j] = reach[i][j] || (reach[i][k] && reach[k][j]);
wcount++;
}
}
}
end = clock();

printf("Transitive Closure Matrix:\n");


for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
printf("%d ", reach[i][j]);
}
printf("\n");
}
printf("Warshall's Algorithm No. of Operations: %d \n", wcount);
printf("Warshall's Algorithm Execution Time: %f seconds\n", (double)(end - start) / CLOCKS_PER_SEC);
}

void floydAlgorithm(int graph[V][V]) {


int dist[V][V];
clock_t start, end;

// Initialize distance matrix


for (int i = 0; i < V; i++)
for (int j = 0; j < V; j++)
dist[i][j] = graph[i][j];

start = clock();
for (int k = 0; k < V; k++) {
for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
if (dist[i][k] != INT_MAX && dist[k][j] != INT_MAX && dist[i][k] + dist[k][j] < dist[i][j]) {
dist[i][j] = dist[i][k] + dist[k][j];
}
fcount++;
}
}
}
end = clock();

printf("All-Pairs Shortest Path Matrix:\n");


for (int i = 0; i < V; i++) {
for (int j = 0; j < V; j++) {
if (dist[i][j] == INT_MAX)
printf("INF ");
else
printf("%d ", dist[i][j]);
}
printf("\n");
}
printf("Floyd's Algorithm No. of Operations: %d \n", fcount);
printf("Floyd's Algorithm Execution Time: %f seconds\n", (double)(end - start) / CLOCKS_PER_SEC);
}

int main() {
int graph[V][V] = {
{0, 3, INT_MAX, 7},
{8, 0, -2, INT_MAX},
{5, INT_MAX, 0, 1},
{2, INT_MAX, INT_MAX, 0}
};

printf("Running Warshall's Algorithm...\n");


warshallAlgorithm(graph);

printf("\nRunning Floyd's Algorithm...\n");


floydAlgorithm(graph);

return 0;
}

Output
Running Warshall's Algorithm...
Transitive Closure Matrix:
1111
1111
1111
1111
Warshall's Algorithm No. of Operations: 64
Warshall's Algorithm Execution Time: 0.000002 seconds

Running Floyd's Algorithm...


All-Pairs Shortest Path Matrix:
0312
1 0 -2 -1
3601
2530
Floyd's Algorithm No. of Operations: 64
Floyd's Algorithm Execution Time: 0.000001 seconds

Summary:
Test Case 1: Floyd’s algorithm yields the correct result even though included negative weigh value on the
directed graph.
Test Case 2: From the output of the above program we executed 64 operations for 4 vertices directed graph.
So total number of operations in Warshall’s & Floyd’s algorithm is n3 (Cubic) for n vertices.

Result:
Thus the program for Warshall’s & Floyd’s algorithm was executed its test cases were verified.

Common questions

Powered by AI

Warshall's and Floyd's algorithms are implemented using nested loops and conditional checks, which efficiently manage the iterative updates necessary to compute the reachability and distance matrices. The use of arrays to store matrices allows for direct index-based access and updates. Timer functions, as shown in the use of `clock()` within the C code, allow for performance measurement. These programming techniques ensure the algorithms execute correctly and efficiently, handling the necessary operations with precision while enabling performance evaluation .

Both Warshall’s and Floyd’s algorithms perform a similar operation count because they share the fundamental structure of using three nested loops for matrix updates corresponding to the number of vertices n. The operation count is calculated as n³ (cubic), as each pair of outer loops (for each vertex pair i and j) is processed once for each intermediate vertex (k), leading to n iterations for each loop level. This results in an overall multiplicative factor of n³ operations needed, defining the algorithm's computational complexity in terms of operations required to update respective matrices .

Warshall's algorithm determines the transitive closure of a directed graph by converting an adjacency matrix into a reachability matrix, where each entry at position (i, j) indicates if a path exists from vertex i to vertex j. It iteratively updates the reachability matrix by checking if a path exists through an intermediate vertex k, i.e., if a path exists from i to k and from k to j, then a path from i to j is established .

Warshall's algorithm uses the OR logical operator to update the reachability matrix, such that for any pair of vertices (i, j), if there is an existing direct connection (i.e., reach[i][j] is true) or an indirect path through intermediate vertex k (i.e., reach[i][k] && reach[k][j] is true), reach[i][j] is updated to true. This iterative application of the OR operator across all possible intermediate vertices ensures the final reachability matrix reflects the transitive closure of the graph .

Floyd's algorithm handles negative weights by iteratively updating the shortest paths using each vertex as an intermediate step, taking into account potential negative contributions, but does not provide a mechanism for detecting negative weight cycles. In contrast, Bellman-Ford's algorithm is specifically designed to handle graphs with negative weights and can detect negative weight cycles by checking for further reductions in path values after n-1 iterations (where n is the number of vertices). Therefore, Floyd's algorithm is efficient for general cases with negative weights, but Bellman-Ford is preferable when detecting or avoiding negative weight cycles is necessary .

The reachability matrix in Warshall’s algorithm is significant because it represents the transitive closure of the graph, indicating which vertices are reachable from others. It is constructed by initially setting it as a copy of the adjacency matrix, where direct connections are marked. Then, it is iteratively updated by considering paths through each intermediate vertex k, so if there is a path from i to k and k to j, the matrix is updated to indicate a path from i to j .

Floyd's algorithm is able to handle graphs with negative edge weights because it evaluates the minimum weights iteratively, allowing potential negative weights to contribute to shorter paths. However, it has the restriction that it cannot handle graphs with negative weight cycles, as such cycles would indefinitely reduce the path length, causing the algorithm to potentially enter an infinite loop trying to evaluate the shortest path .

Both Warshall's and Floyd's algorithms have a computational complexity of O(n³), where n is the number of vertices in the graph. This cubic complexity arises because both algorithms utilize three nested loops to respectively compute the transitive closure and all-pairs shortest paths. Their performance in practice is similar due to this shared complexity, although the specific operations and time may vary due to factors like specific graph structures or initial weight values; however, because they follow the same general approach of iterating through a possible intermediate vertex for every pair of vertices, their fundamental performance characteristics are parallel .

The use of adjacency matrices in Warshall’s and Floyd’s algorithms provides several benefits: it allows for straightforward representation of connectivity and weight information, enabling direct access and updates using matrix indices, which aligns well with the iterative nature of both algorithms. However, the main limitation is space complexity, as the matrix requires O(n²) space for n vertices, making it less efficient for very large or sparsely connected graphs. This representation is optimal for algorithms requiring frequent checking of edge presence or weight, as in the iterative execution loops used by both Warshall's and Floyd's algorithms .

In Floyd's algorithm, intermediate vertices play a crucial role in updating the shortest path between two vertices i and j. The algorithm iteratively checks each vertex k as an intermediate waypoint, and updates the distance D[i][j] if a shorter path can be formed through k, using the equation D[i][j]=min(D[i][j], D[i][k] + D[k][j]).

You might also like