Guide to Floyd-Warshall Algorithm

Abhinandan Sharma
5 min readJul 13, 2023

--

Introduction

In the world of computer science, the Floyd Warshall Algorithm is a strong performer. It’s named after its creators, mathematicians Robert W. Floyd and Stephen Warshall. The algorithm’s claim to fame is its knack for figuring out the shortest paths between all pairs of vertices in a weighted graph.

An interesting fact about this algorithm is its ability to handle negative weights, unlike the similar Dijkstra’s algorithm. The only caveat to this, however, is the non-existence of any negative cycles in the graph. Given the intricate and intertwined structure of data these days, having an algorithm that can identify the best possible path is really valuable, and that’s where Floyd Warshall comes into the picture.

The Floyd Warshall Algorithm is a classic example of dynamic programming at work. It tackles a problem by chopping it up into bite-sized pieces, then goes about solving them step by step. Even though the algorithm seems straightforward on the surface, it has the ability to untangle some really complicated scenarios, such as finding the shortest distances in a graph.

In this article, we will journey through the many aspects of the Floyd Warshall Algorithm. We’ll be looking at its time complexity, comparing it with other graph algorithms, discussing where it can be applied, and doing a hands-on implementation. This article should give you a well-rounded understanding of this algorithm.

Understanding the mechanics

The Floyd-Warshall algorithm functions by progressively refining an approximation of the shortest path between any two nodes, until the accurate shortest path is eventually determined. This is achieved by continuously assessing all feasible routes between all pairs of nodes and adjusting the corresponding path distances when a shorter route is identified.

  1. Start by setting up a two-dimensional matrix, dist[][]. The value of dist[i][j] corresponds to the weight of the connection from node i to node j, assuming such a connection is present. If there's no direct link from i to j, assign it a value of infinity. In cases where i is identical to j, the value will be 0.
  2. For each node, denoted as k, execute the following actions for every pair of nodes i and j:
  • If the sum of dist[i][k] and dist[k][j] is less than dist[i][j], this indicates a shorter path has been found. Consequently, update dist[i][j] to be equal to dist[i][k] + dist[k][j].

The beauty of this algorithm is that it meticulously inspects whether any given node can act as a stepping stone to a shorter route connecting two other nodes.

import numpy as np

def floyd_warshall(graph):

n = len(graph)

dist = np.array(graph)


for k in range(n):
for i in range(n):
for j in range(n):
# If the distance through k is less than the current distance
if dist[i][k] + dist[k][j] < dist[i][j]:
# Update the distance
dist[i][j] = dist[i][k] + dist[k][j]

return dist

graph = [[0, 5, np.inf, 10],
[np.inf, 0, 3, np.inf],
[np.inf, np.inf, 0, 1],
[np.inf, np.inf, np.inf, 0]]

distances = floyd_warshall(graph)
print(distances)

Assessing Time Complexity

In the realm of algorithms, understanding time complexity is crucial. This essentially equates to knowing how much computational time an algorithm consumes in relation to the size of the input data.

For our subject of interest, the Floyd Warshall Algorithm, its time complexity is somewhat uncomplicated — it stands at O(n³). If this figure appears a little high, let’s break it down. In this context, ’n’ corresponds to the quantity of vertices in the graph.

The reasoning behind the cubic time complexity is relatively simple. The algorithm operates by taking into account each vertex as a possible midway point in the path connecting every pair of vertices. Following this, it determines the shortest path for each vertex pair utilising this midway vertex. Due to this requirement, the algorithm needs to run these operations n³ times, resulting in a time complexity of O(n³).

It might sound considerably high compared to other algorithms, but remember, the Floyd Warshall Algorithm is performing an extensive task — it’s calculating the shortest path between every pair of vertices. So, in light of its job, O(n³) might not seem practical but it has some very important use cases.

A valuable aspect of this algorithm is the predictability of its time complexity. Regardless of the nature of the graph — be it densely or sparsely populated — the time complexity remains O(n³). In a situation where consistency can be scarce, this predictability is a noteworthy attribute.

Comparison

There are a variety of algorithms, each equipped with its own set of capabilities, for finding the shortest path. Let’s compare it with two other notable algorithms — the Dijkstra’s Algorithm and the Bellman-Ford Algorithm.

Dijkstra’s Algorithm is a frequently used algorithm for shortest path detection. Nevertheless, it mainly serves to identify the shortest path from a singular source to all other vertices within the graph. Contrarily, the Floyd Warshall Algorithm calculates the shortest paths between each pair of vertices, thus providing a more comprehensive solution.

The time complexity of Dijkstra’s Algorithm may vary from O(n²) to O((E + n)log n), depending on the specific implementation. While this might appear superior to the O(n³) time complexity of the Floyd Warshall Algorithm, it’s essential to recall that Dijkstra’s Algorithm is constrained by its incapacity to deal with negative weights. The Floyd Warshall Algorithm is devoid of such constraints, which gives it an advantage in more intricate graphs.

Now, let’s examine the Bellman-Ford Algorithm. Much like the Floyd Warshall Algorithm, Bellman-Ford can manage negative weights. However, its common application is for resolving single-source shortest path issues. The time complexity for Bellman-Ford is O(nE), where ’n’ signifies the number of vertices and ‘E’ stands for the number of edges. In dense graphs, this can potentially be less efficient than the O(n³) time complexity of the Floyd Warshall Algorithm.

So, the takeaway from this comparative analysis is that each algorithm has its own specialty. Dijkstra’s Algorithm excels in single-source shortest path problems, provided there are no negative weights. Bellman-Ford is similarly adept at resolving single-source shortest path issues and has the additional ability to handle negative weights. However, when dealing with problems involving the shortest path between all pairs of vertices, especially in dense graphs and those with negative weights, the Floyd Warshall Algorithm often takes the lead.

Use Cases of the Floyd Warshall Algorithm

1. Navigation Systems

2. Internet Routing

3. Google Maps

4. Telecommunication Networks

5. Social Networking Applications

6. Game Development

7. Supply Chain Management

Conclusion

The Floyd Warshall Algorithm emerges as a notable solution in regards to graph algorithms, offering a robust strategy for determining the shortest paths connecting all pairs of vertices in a graph. Even though it possesses an O(n³) time complexity, this algorithm demonstrates its strengths when dealing with intricate graphs containing negative weights, thereby comparable to other algorithms such as Dijkstra’s and Bellman-Ford.

Its practical applications are manifold and influential, ranging from fueling efficient navigation on our GPS systems to boosting network optimization for internet data routing. Whether it’s guiding us to our destinations via the quickest path, supporting game development, or promoting effective planning in city infrastructure, the influence of the Floyd Warshall Algorithm is widely felt.

With a solid grasp of its working, its comparison with similar algorithms, and its wide-ranging uses, we now have a holistic understanding of the Floyd Warshall Algorithm.

--

--