Last active
January 2, 2023 21:51
-
-
Save zaz/61cab8fbd02351d3047e to your computer and use it in GitHub Desktop.
Dijkstra's algorithm — Python. Deprecated: Find the updated version at https://github.com/zaz/dijkstra
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Zaz Brown | |
# github.com/zaz/dijkstra | |
"""An efficient algorithm to find shortest paths between nodes in a graph.""" | |
from collections import defaultdict | |
class Digraph(object): | |
def __init__(self, nodes=[]): | |
self.nodes = set() | |
self.neighbours = defaultdict(set) | |
self.dist = {} | |
def addNode(self, *nodes): | |
[self.nodes.add(n) for n in nodes] | |
def addEdge(self, frm, to, d=1e309): | |
self.addNode(frm, to) | |
self.neighbours[frm].add(to) | |
self.dist[ frm, to ] = d | |
def dijkstra(self, start, maxD=1e309): | |
"""Returns a map of nodes to distance from start and a map of nodes to | |
the neighbouring node that is closest to start.""" | |
# total distance from origin | |
tdist = defaultdict(lambda: 1e309) | |
tdist[start] = 0 | |
# neighbour that is nearest to the origin | |
preceding_node = {} | |
unvisited = self.nodes | |
while unvisited: | |
current = unvisited.intersection(tdist.keys()) | |
if not current: break | |
min_node = min(current, key=tdist.get) | |
unvisited.remove(min_node) | |
for neighbour in self.neighbours[min_node]: | |
d = tdist[min_node] + self.dist[min_node, neighbour] | |
if tdist[neighbour] > d and maxD >= d: | |
tdist[neighbour] = d | |
preceding_node[neighbour] = min_node | |
return tdist, preceding_node | |
def min_path(self, start, end, maxD=1e309): | |
"""Returns the minimum distance and path from start to end.""" | |
tdist, preceding_node = self.dijkstra(start, maxD) | |
dist = tdist[end] | |
backpath = [end] | |
try: | |
while end != start: | |
end = preceding_node[end] | |
backpath.append(end) | |
path = list(reversed(backpath)) | |
except KeyError: | |
path = None | |
return dist, path | |
def dist_to(self, *args): return self.min_path(*args)[0] | |
def path_to(self, *args): return self.min_path(*args)[1] |
Can u help how to take input from a file . like a/ b/ 8 is format from node a to b distance is 8
@christopher-abastar @PDelerm @ctriley @khairakiran6 Sorry for not being responsive on this.
The most up-to-date version is at zaz/dijkstra. Please create an issue there if there are still bugs.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I may be doing something wrong, but I believe this code will not work for multiple calls of dijkstra's algorithm. It seems to remove all of the nodes from the graph every time this algorithm is called.
unvisited = self.nodes
and thenunvisited.remove(min_node)
.To fix this I changed line 28 to
unvisited = copy.copy(self.nodes)