1

I can use the following English algorithm to find shortest paths using Dijkstra's Algorithm on paper:

  • Step 1: Assign permanent label and order to starting node

  • Step 2: Assign temporary labels to all nodes directly reached by starting node

  • Step 3: Select the lowest temporary label and make it permanent

  • Step 4: Assign an order to the node

  • Step 5: Update and assign temporary labels for nodes directly reached from the new permanent node

  • Step 6: Repeat steps 3, 4 & 5 until the destination node is made permanent

I have searched for a Python implementation and many are quite complex or use data structures I'm not familiar with. Eventually I found the one below. I have spent quite some time tracing it's execution in a Python visualizer, and I can get a sense of how it works but it has not yet clicked for me.

Could someone please explain how the code relates to the English algorithm? For example, how does the notion of "predecessors" relate to the "permanent labels" in the English version?

from math import inf

graph = {'a':{'b':10,'c':3},'b':{'c':1,'d':2},'c':{'b':4,'d':8,'e':2},'d':{'e':7},'e':{'d':9}}


def dijkstra(graph,start,goal):
    shortest_distance = {}
    predecessor = {}
    unseenNodes = graph
    infinity = inf
    path = []
    for node in unseenNodes:
        shortest_distance[node] = infinity
    shortest_distance[start] = 0

    # Determine which is minimum node. What does that mean?
    while unseenNodes:
        minNode = None
        for node in unseenNodes:
            if minNode is None:
                minNode = node
            elif shortest_distance[node] < shortest_distance[minNode]:
                minNode = node

        for edge, weight in graph[minNode].items():
            if weight + shortest_distance[minNode] < shortest_distance[edge]:
                shortest_distance[edge] = weight + shortest_distance[minNode]
                predecessor[edge] = minNode
        unseenNodes.pop(minNode)

    currentNode = goal
    while currentNode != start:
        try:
            path.insert(0,currentNode)
            currentNode = predecessor[currentNode]
        except KeyError:
            print('Path not reachable')
            break
    path.insert(0,start)
    if shortest_distance[goal] != infinity:
        print('Shortest distance is ' + str(shortest_distance[goal]))
        print('And the path is ' + str(path))


dijkstra(graph, 'a', 'b')
2
  • 1
    Since your english algorithm is not the original wording, it is not surprising that there are differences to the implementation. „Labeling“ consists of three parts: 1. visited/unvisited (visited: permanent label, unvisited: temporary label) 2. shortest distance from origin as known so far 3. predecessor on the shortest way. While the predecessor is not necessary to FIND the shortest path, you need it to remember the path and to output it :-) Commented Sep 16, 2019 at 12:03
  • The algorithms are from completely different sources. I am hoping to be able to perceive how they are essentially expressions of the same algorithm. Commented Sep 16, 2019 at 12:12

1 Answer 1

1

Dijkstra’s algorithm same to prim’s algorithm for minimum spanning tree. Like Prim’s MST, we generate a shortest path tree with given source as root. We maintain two sets, one set contains vertices included in shortest path tree, other set includes vertices not yet included in shortest path tree. At every step of the algorithm, we find a vertex which is in the other set (set of not yet included) and has a minimum distance from the source.

import sys

class Graph():

    def __init__(self, vertices):
        self.V = vertices
        self.graph = [[0 for column in range(vertices)]
                  for row in range(vertices)]

    def printSolution(self, dist):
        print("Vertex tDistance from Source")
        for node in range(self.V):
            print(node, "t", dist[node])

    def minDistance(self, dist, sptSet):

        min = sys.maxint

        for v in range(self.V):
            if dist[v] < min and sptSet[v] == False:
                min = dist[v]
                min_index = v

        return min_index

    def dijkstra(self, src):

        dist = [sys.maxint] * self.V
        dist[src] = 0
        sptSet = [False] * self.V

        for cout in range(self.V):

            u = self.minDistance(dist, sptSet)

            sptSet[u] = True

            for v in range(self.V):
                if self.graph[u][v] > 0 and sptSet[v] == False and \
                    dist[v] > dist[u] + self.graph[u][v]:
                    dist[v] = dist[u] + self.graph[u][v]

        self.printSolution(dist)

g = Graph(9)
g.graph = [[0, 4, 0, 0, 0, 0, 0, 8, 0],
           [4, 0, 8, 0, 0, 0, 0, 11, 0],
           [0, 8, 0, 7, 0, 4, 0, 0, 2],
           [0, 0, 7, 0, 9, 14, 0, 0, 0],
           [0, 0, 0, 9, 0, 10, 0, 0, 0],
           [0, 0, 4, 14, 10, 0, 2, 0, 0],
           [0, 0, 0, 0, 0, 2, 0, 1, 6],
           [8, 11, 0, 0, 0, 0, 1, 0, 7],
           [0, 0, 2, 0, 0, 0, 6, 7, 0]]
g.dijkstra(0)
Sign up to request clarification or add additional context in comments.

1 Comment

Where are the parameters for source and destination?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.