Python Dijsktra's algorithm using adjacency matrix
parent
eac99813cc
commit
53267f12ed
|
@ -0,0 +1,111 @@
|
|||
# A Dijkstra's algorithm implementation in Python
|
||||
# using adjacency matrix
|
||||
# Time complexity: O(V+E)*O(logV)
|
||||
|
||||
from math import inf
|
||||
|
||||
wmat = [[0, 2, 0, 0, 0, 1, 0, 0],
|
||||
[2, 0, 2, 2, 4, 0, 0, 0],
|
||||
[0, 2, 0, 0, 3, 0, 0, 1],
|
||||
[0, 2, 0, 0, 4, 3, 0, 0],
|
||||
[0, 4, 3, 4, 0, 0, 7, 0],
|
||||
[1, 0, 0, 3, 0, 0, 5, 0],
|
||||
[0, 0, 0, 0, 7, 5, 0, 6],
|
||||
[0, 0, 1, 0, 0, 0, 6, 0]]
|
||||
|
||||
|
||||
def find_all(wmat, start, end=-1):
|
||||
"""
|
||||
Returns a tuple with a distances' list and paths' list of
|
||||
all remaining vertices with the same indexing.
|
||||
|
||||
(distances, paths)
|
||||
|
||||
For example, distances[x] are the shortest distances from x
|
||||
vertex which shortest path is paths[x]. x is an element of
|
||||
{0, 1, ..., n-1} where n is the number of vertices
|
||||
|
||||
Args:
|
||||
wmat -- weighted graph's adjacency matrix
|
||||
start -- paths' first vertex
|
||||
end -- (optional) path's end vertex. Return just the
|
||||
distance and its path
|
||||
|
||||
Exceptions:
|
||||
Index out of range, Be careful with start and end vertices
|
||||
"""
|
||||
n = len(wmat)
|
||||
|
||||
dist = [inf]*n
|
||||
dist[start] = wmat[start][start] # 0
|
||||
|
||||
spVertex = [False]*n
|
||||
parent = [-1]*n
|
||||
|
||||
path = [{}]*n
|
||||
|
||||
for count in range(n-1):
|
||||
minix = inf
|
||||
u = 0
|
||||
|
||||
for v in range(len(spVertex)):
|
||||
if spVertex[v] == False and dist[v] <= minix:
|
||||
minix = dist[v]
|
||||
u = v
|
||||
|
||||
spVertex[u] = True
|
||||
for v in range(n):
|
||||
if not(spVertex[v]) and wmat[u][v] != 0 and dist[u] + wmat[u][v] < dist[v]:
|
||||
parent[v] = u
|
||||
dist[v] = dist[u] + wmat[u][v]
|
||||
|
||||
for i in range(n):
|
||||
j = i
|
||||
s = []
|
||||
while parent[j] != -1:
|
||||
s.append(j)
|
||||
j = parent[j]
|
||||
s.append(start)
|
||||
path[i] = s[::-1]
|
||||
|
||||
return (dist[end], path[end]) if end >= 0 else (dist, path)
|
||||
|
||||
|
||||
def find_shortest_path(wmat, start, end=-1):
|
||||
"""
|
||||
Returns paths' list of all remaining vertices.
|
||||
|
||||
Args:
|
||||
wmat -- weigthted graph's adjacency matrix
|
||||
start -- paths' first vertex
|
||||
end -- (optional) path's end vertex. Return just
|
||||
the path
|
||||
|
||||
Exceptions:
|
||||
Index out of range, Be careful with start and end vertices.
|
||||
"""
|
||||
return find_all(wmat, start, end)[1]
|
||||
|
||||
|
||||
def find_shortest_distance(wmat, start, end=-1):
|
||||
"""
|
||||
Returns distances' list of all remaining vertices.
|
||||
|
||||
Args:
|
||||
wmat -- weigthted graph's adjacency matrix
|
||||
start -- paths' first vertex
|
||||
end -- (optional) path's end vertex. Return just
|
||||
the distance
|
||||
|
||||
Exceptions:
|
||||
Index out of range, Be careful with start and end vertices.
|
||||
"""
|
||||
return find_all(wmat, start, end)[0]
|
||||
|
||||
if __name__ == "__main__":
|
||||
i = 0
|
||||
for D, P in zip(*find_all(wmat, 0)):
|
||||
print("Target: {}, Distance: {}, Path: {}".format(i, D, P))
|
||||
i += 1
|
||||
print("\nshortest path to last node", find_shortest_path(wmat, 0, 7))
|
||||
print("shortest distance to last node", find_shortest_distance(wmat, 0, 7))
|
Loading…
Reference in New Issue