-
-
Notifications
You must be signed in to change notification settings - Fork 46.8k
Add doctests for graphs_floyd_warshall.py #12436
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
base: master
Are you sure you want to change the base?
Changes from 8 commits
96f1505
e2cc729
f58a653
989d84e
d4bd7d7
2c3e58a
f3d6012
f48d6c8
f1e09cd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,112 @@ | ||
# 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. | ||
The problem is to find and return 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: list[list[float]], vertex: int) -> tuple: | ||
# 1. For all edges from v to n, distance[i][j] = weight(edge(i, j)). | ||
|
||
# 2. distance[i][j] = min(distance[i][j], distance[i][k] + distance[k][j]). | ||
|
||
# 3. Step 2 is true for each pair of vertices.Repeat for k vertex in the graph. | ||
|
||
# 4. Whenever distance[i][j] is given a new minimum value, | ||
# next vertex[i][j] = next vertex[i][k]. | ||
Comment on lines
+8
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This algorithm explanation should be moved into the docstring at the top of the file |
||
|
||
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]. | ||
# doctests: | ||
|
||
>>> graph = [[0, 3, float('inf')], [2, 0, float('inf')],[float('inf'), 7, 0]] | ||
>>> floyd_warshall(graph, 3)[0] | ||
[[0, 3, inf], [2, 0, inf], [9, 7, 0]] | ||
|
||
>>> graph = [[0, 1, 4],[float('inf'), 0, 2],[float('inf'), float('inf'), 0]] | ||
>>> floyd_warshall(graph, 3)[0] | ||
[[0, 1, 3], [inf, 0, 2], [inf, inf, 0]] | ||
|
||
>>> graph = [[0, 0, 0],[0, 0, 0],[0, 0, 0]] | ||
>>> floyd_warshall(graph, 3)[0] | ||
[[0, 0, 0], [0, 0, 0], [0, 0, 0]] | ||
|
||
#Graph with all edge weights = infinity | ||
|
||
>>> graph = [[float('inf'), float('inf'), float('inf')], | ||
... [float('inf'), float('inf'), float('inf')], | ||
... [float('inf'), float('inf'), float('inf')]] | ||
>>> floyd_warshall(graph, 3)[0] | ||
[[inf, inf, inf], [inf, inf, inf], [inf, inf, inf]] | ||
|
||
|
||
#Handling negetive weighted graph: | ||
|
||
>>> graph = [[0, -2, float('inf')],[float('inf'), 0, 3],[4, float('inf'), 0]] | ||
>>> floyd_warshall(graph, 3)[0] | ||
[[0, -2, 1], [7, 0, 3], [4, 2, 0]] | ||
|
||
|
||
#Handling negetive weighted cycle: | ||
|
||
>>> graph = [[0, -1, float('inf')],[float('inf'), 0, -2],[-3, float('inf'), 0]] | ||
>>> floyd_warshall(graph, 3)[0] | ||
[[-6, -7, -9], [-5, -6, -8], [-9, -10, -12]] | ||
|
||
|
||
#Number of vertex in function argument should match number of vertex in graph: | ||
|
||
>>> graph = [[0, -1, float('inf')],[float('inf'), 0, -2]] | ||
>>> floyd_warshall(graph, 3)[0] | ||
Traceback (most recent call last): | ||
... | ||
IndexError: list index out of range | ||
|
||
|
||
#Graph data type should be a 2D list: | ||
|
||
>>> graph = "strings not allowed" | ||
>>> floyd_warshall(graph, 3)[0] | ||
Traceback (most recent call last): | ||
... | ||
IndexError: string index out of range | ||
""" | ||
|
||
dist = [[float("inf") for _ in range(v)] for _ in range(v)] | ||
dist = [[float("inf") for _ in range(vertex)] for _ in range(vertex)] | ||
|
||
for i in range(v): | ||
for j in range(v): | ||
for i in range(vertex): | ||
for j in range(vertex): | ||
dist[i][j] = graph[i][j] | ||
|
||
# check vertex k against all other vertices (i, j) | ||
for k in range(v): | ||
|
||
for k in range(vertex): | ||
# looping through rows of graph array | ||
for i in range(v): | ||
|
||
for i in range(vertex): | ||
# looping through columns of graph array | ||
for j in range(v): | ||
|
||
for j in range(vertex): | ||
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 | ||
return dist, vertex | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is |
||
|
||
|
||
if __name__ == "__main__": | ||
import doctest | ||
|
||
doctest.testmod() | ||
|
||
v = int(input("Enter number of vertices: ")) | ||
asmitannu marked this conversation as resolved.
Show resolved
Hide resolved
|
||
e = int(input("Enter number of edges: ")) | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.