mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-27 23:11:09 +00:00
9316e7c014
* flake8 --max-line-length=88 * fixup! Format Python code with psf/black push Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
103 lines
3.1 KiB
Python
103 lines
3.1 KiB
Python
# floyd_warshall.py
|
|
"""
|
|
The problem is to find the shortest distance between all pairs of vertices in a
|
|
weighted directed graph that can have negative edge weights.
|
|
"""
|
|
|
|
|
|
def _print_dist(dist, v):
|
|
print("\nThe shortest path matrix using Floyd Warshall algorithm\n")
|
|
for i in range(v):
|
|
for j in range(v):
|
|
if dist[i][j] != float("inf"):
|
|
print(int(dist[i][j]), end="\t")
|
|
else:
|
|
print("INF", end="\t")
|
|
print()
|
|
|
|
|
|
def floyd_warshall(graph, v):
|
|
"""
|
|
:param graph: 2D array calculated from weight[edge[i, j]]
|
|
:type graph: List[List[float]]
|
|
:param v: number of vertices
|
|
:type v: int
|
|
:return: shortest distance between all vertex pairs
|
|
distance[u][v] will contain the shortest distance from vertex u to v.
|
|
|
|
1. For all edges from v to n, distance[i][j] = weight(edge(i, j)).
|
|
3. The algorithm then performs distance[i][j] = min(distance[i][j], distance[i][k] +
|
|
distance[k][j]) for each possible pair i, j of vertices.
|
|
4. The above is repeated for each vertex k in the graph.
|
|
5. Whenever distance[i][j] is given a new minimum value, next vertex[i][j] is
|
|
updated to the next vertex[i][k].
|
|
"""
|
|
|
|
dist = [[float("inf") for _ in range(v)] for _ in range(v)]
|
|
|
|
for i in range(v):
|
|
for j in range(v):
|
|
dist[i][j] = graph[i][j]
|
|
|
|
# check vertex k against all other vertices (i, j)
|
|
for k in range(v):
|
|
# looping through rows of graph array
|
|
for i in range(v):
|
|
# looping through columns of graph array
|
|
for j in range(v):
|
|
if (
|
|
dist[i][k] != float("inf")
|
|
and dist[k][j] != float("inf")
|
|
and dist[i][k] + dist[k][j] < dist[i][j]
|
|
):
|
|
dist[i][j] = dist[i][k] + dist[k][j]
|
|
|
|
_print_dist(dist, v)
|
|
return dist, v
|
|
|
|
|
|
if __name__ == "__main__":
|
|
v = int(input("Enter number of vertices: "))
|
|
e = int(input("Enter number of edges: "))
|
|
|
|
graph = [[float("inf") for i in range(v)] for j in range(v)]
|
|
|
|
for i in range(v):
|
|
graph[i][i] = 0.0
|
|
|
|
# src and dst are indices that must be within the array size graph[e][v]
|
|
# failure to follow this will result in an error
|
|
for i in range(e):
|
|
print("\nEdge ", i + 1)
|
|
src = int(input("Enter source:"))
|
|
dst = int(input("Enter destination:"))
|
|
weight = float(input("Enter weight:"))
|
|
graph[src][dst] = weight
|
|
|
|
floyd_warshall(graph, v)
|
|
|
|
# Example Input
|
|
# Enter number of vertices: 3
|
|
# Enter number of edges: 2
|
|
|
|
# # generated graph from vertex and edge inputs
|
|
# [[inf, inf, inf], [inf, inf, inf], [inf, inf, inf]]
|
|
# [[0.0, inf, inf], [inf, 0.0, inf], [inf, inf, 0.0]]
|
|
|
|
# specify source, destination and weight for edge #1
|
|
# Edge 1
|
|
# Enter source:1
|
|
# Enter destination:2
|
|
# Enter weight:2
|
|
|
|
# specify source, destination and weight for edge #2
|
|
# Edge 2
|
|
# Enter source:2
|
|
# Enter destination:1
|
|
# Enter weight:1
|
|
|
|
# # Expected Output from the vertice, edge and src, dst, weight inputs!!
|
|
# 0 INF INF
|
|
# INF 0 2
|
|
# INF 1 0
|