Skip to content

Instantly share code, notes, and snippets.

@PandaWhoCodes
Forked from zaz/dijkstra.py
Created October 26, 2019 14:13
Show Gist options
  • Select an option

  • Save PandaWhoCodes/8e9fc8a0ae71d717b595c1384cc72b4e to your computer and use it in GitHub Desktop.

Select an option

Save PandaWhoCodes/8e9fc8a0ae71d717b595c1384cc72b4e to your computer and use it in GitHub Desktop.

Revisions

  1. @zaz zaz revised this gist Dec 15, 2015. 1 changed file with 59 additions and 1 deletion.
    60 changes: 59 additions & 1 deletion dijkstra.py
    Original file line number Diff line number Diff line change
    @@ -1,2 +1,60 @@
    # Zaz Brown
    # An efficient algorithm to find shortest paths between nodes in a graph.
    # 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]
  2. @zaz zaz created this gist Dec 15, 2015.
    2 changes: 2 additions & 0 deletions dijkstra.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,2 @@
    # Zaz Brown
    # An efficient algorithm to find shortest paths between nodes in a graph.