Intellipaat Back

Explore Courses Blog Tutorials Interview Questions
0 votes
2 views
in Python by (16.4k points)
recategorized by

I'm attempting to execute Dijikstra's algorithm in python with the help of arrays. Look at my implementation:

def extract(Q, w):

    m=0

    minimum=w[0]

    for i in range(len(w)):

        if w[i]<minimum:

            minimum=w[i]

            m=i

    return m, Q[m]

def dijkstra(G, s, t='B'):

    Q=[s]

    p={s:None}

    w=[0]

    d={}

    for i in G:

        d[i]=float('inf')

        Q.append(i)

        w.append(d[i])

    d[s]=0

    S=[]

    n=len(Q)

    while Q:

        u=extract(Q,w)[1]

        S.append(u)

        #w.remove(extract(Q, d, w)[0])

        Q.remove(u)

        for v in G[u]:

            if d[v]>=d[u]+G[u][v]:

                d[v]=d[u]+G[u][v]

                p[v]=u

    return d, p

B='B'

A='A'

D='D'

G='G'

E='E'

C='C'

F='F'

G={B:{A:5, D:1, G:2}, A:{B:5, D:3, E:12, F:5}, D:{B:1, G:1, E:1, A:3}, G:{B:2, D:1, C:2}, C:{G:2, E:1, F:16}, E:{A:12, D:1, C:1, F:2}, F:{A:5, E:2, C:16}}

print "Assuming the start vertex to be B:"

print "Shortest distances", dijkstra(G, B)[0]

print "Parents", dijkstra(G, B)[1]

I expect:

Assuming the start vertex to be B:

Shortest distances {'A': 4, 'C': 4, 'B': 0, 'E': 2, 'D': 1, 'G': 2, 'F': 4}

Parents {'A': 'D', 'C': 'G', 'B': None, 'E': 'D', 'D': 'B', 'G': 'D', 'F': 'E'}

But what I get:

Assuming the start vertex to be B:

Shortest distances {'A': 4, 'C': 4, 'B': 0, 'E': 2, 'D': 1, 'G': 2, 'F': 10}

Parents {'A': 'D', 'C': 'G', 'B': None, 'E': 'D', 'D': 'B', 'G': 'D', 'F': 'A'}.

It gives an incorrect answer for node F. Can anyone tell me why?

1 Answer

0 votes
by (26.4k points)

As others have brought up, because of not utilizing justifiable variable names, it is practically difficult to debug your code. 

Following the wiki article about Dijkstra's calculation, one can execute it thusly :

nodes = ('A', 'B', 'C', 'D', 'E', 'F', 'G')

distances = {

    'B': {'A': 5, 'D': 1, 'G': 2},

    'A': {'B': 5, 'D': 3, 'E': 12, 'F' :5},

    'D': {'B': 1, 'G': 1, 'E': 1, 'A': 3},

    'G': {'B': 2, 'D': 1, 'C': 2},

    'C': {'G': 2, 'E': 1, 'F': 16},

    'E': {'A': 12, 'D': 1, 'C': 1, 'F': 2},

    'F': {'A': 5, 'E': 2, 'C': 16}}

unvisited = {node: None for node in nodes} #using None as +inf

visited = {}

current = 'B'

currentDistance = 0

unvisited[current] = currentDistance

while True:

    for neighbour, distance in distances[current].items():

        if neighbour not in unvisited: continue

        newDistance = currentDistance + distance

        if unvisited[neighbour] is None or unvisited[neighbour] > newDistance:

            unvisited[neighbour] = newDistance

    visited[current] = currentDistance

    del unvisited[current]

    if not unvisited: break

    candidates = [node for node in unvisited.items() if node[1]]

    current, currentDistance = sorted(candidates, key = lambda x: x[1])[0]

print(visited)

This code is more verbous than needed and I trust contrasting your code and mine you may detect a few contrasts.

result:

{'E': 2, 'D': 1, 'G': 2, 'F': 4, 'A': 4, 'C': 3, 'B': 0}

Interested to learn the concepts of python in detail? Come and join the python course to gain more knowledge in python

Watch this video tutorial on how to become a professional in python

Related questions

31k questions

32.8k answers

501 comments

693 users

Browse Categories

...