FAQ: Dijkstra's Algorithm: Python - Finishing the Algorithm!

This community-built FAQ covers the “Finishing the Algorithm!” exercise from the lesson “Dijkstra’s Algorithm: Python”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Computer Science

FAQs on the exercise Finishing the Algorithm!

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head here.

Looking for motivation to keep learning? Join our wider discussions.

Learn more about how to use this guide.

Found a bug? Report it!

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

Can anyone give some ideas/hints if we want to improve this exercise’s Dijkstra’s algorithm, which kind of data or data structure we should use another than the tuple?

Let’s say, if we change the graph to A -> B = 1, A -> C = 3, B -> C =1. Base on the solution code, each iteration, the vertices_to_explore (as the min heap or next unvisited/updated vertices) becomes:

# 1st iteration: 
[(0, "A")]
# 2nd iteration: 
[(1, "B"), (3, "C")]
# 3rd iteration: 
[(2, "C"), (3, "C"), (3, "D")]
# 4th iteration:
[(3, 'C'), (3, 'D')]
# 5th iteration: 
[(3, 'D')]
# Final iteration:
[(13, 'E')]

I think the “weight” (3) for vertex C coming from A should be replaced or deleted once we find its “weight” (1 + 1 = 2) is actually smaller while coming from B instead. There is no reason that we need to “pop” the “C” twice with two different weights (which means no need to push both into the heap). Same for vertex D, one is from vertex B, another one is from vertex C, even though they have the same weight.

Tried to improve it but realized that the tuple is immutable, and the dictionary is unordered which is harder to use it into the heap. I’d appreciate if anyone can give some thoughts. :grinning:

1 Like

Can anyone assist with this, I’m having a bit of trouble understanding the “verticies_to_explore” aspect,

for neighbor, edge_weight in graph[current_vertex]

should be referring to the neighbors for “A” which should only, B & C,
I’m a bit unsure how it goes where in the code it gets us to nodes D & E

Full cod eto the solution below:

raph = {
        'A': [('B', 10), ('C', 3)],
        'C': [('D', 2)],
        'D': [('E', 10)],
        'E': [('A', 7)],
        'B': [('C', 3), ('D', 2)]
    }


def dijkstras(graph, start):
  distances = {}
  
  for vertex in graph:
    distances[vertex] = inf
    
  distances[start] = 0
  vertices_to_explore = [(0, start)]
  
  while vertices_to_explore:
    current_distance, current_vertex = heappop(vertices_to_explore)
    
    for neighbor, edge_weight in graph[current_vertex]:
      new_distance = current_distance + edge_weight
      
      if new_distance < distances[neighbor]:
        distances[neighbor] = new_distance
        heappush(vertices_to_explore, (new_distance, neighbor))
        
  return distances
        
distances_from_d = dijkstras(graph, 'D')
print("\n\nShortest Distances: {0}".format(distances_from_d))

Hey,

for neighbor, edge_weight in graph[current_vertex]

let’s assume current_ vertex is “A”.
when we look at the graph dictionary we can see the connections: ‘A’: [(‘B’, 10), (‘C’, 3)],

therefor you can also read it like:

for neighbor, edge_weight in graph[current_vertex]

for “B” , 10 in graph ‘A’: [(‘B’, 10), (‘C’, 3)]
new_distance = 0 + 10

Personal I like to comment and print out a lot, to make sure I understand it correctly.
Here is my code with comments, maybe that’s also helpful.

#___________________Dijkstra Algorithm_______________________________________


def dijkstras(graph,start_vertex):
	#__Instantiating a distance dictionary that will eventually map vertecies
	# to their distanc from the start vertex
	distances = {}

	#__Loop through each vertex in graph and set its corresponding value within distances equal to inf
	for vertex in graph:
		distances[vertex] = inf

	#__settingt the start vertex to 0
	distances[start_vertex] = 0

	#__this tulpe represents the start vertex within the min - heap-list
	#______ HEAP LIST
	vertices_to_explore = [(0,start_vertex)]

	"""
	First, we’ll traverse the vertices_to_explore heap until it is empty, 
	popping off the vertex with the minimum distance from start. 
	Inside our while loop, we’ll iterate over the neighboring vertices of 
	current_vertex and add each neighbor (and its distance from start) 
	to the vertices_to_explore min-heap.

	"""

	#__as long theire is content in verticies to explore
	while vertices_to_explore:
		#__this will always be the vertex with the minimum distance from start
		current_distance,current_vertex = heappop(vertices_to_explore)
		print("\nThis is the current vertex: {0} with the distance: {1}".format(current_vertex,current_distance))
		#__Identify neighbor‘s distance from start
		for neighbor,edge_weight in graph[current_vertex]:
			new_distance = current_distance + edge_weight
			print("\nThis is the neighbor: {0} with the distance: {1}".format(neighbor,edge_weight))
			print("The distance from the start vertex \"{0}\" to its neighbor \"{1}\" is: {2}".format(start_vertex,neighbor,new_distance))
			#_____comparing the distances and replacing them in heap list
			if new_distance < distances[neighbor]:
				distances[neighbor] = new_distance
				heappush(vertices_to_explore, (new_distance, neighbor))
				print("Pushing the neigbor into the Heap List.....")

	# getting the minimum distance
	del distances[start_vertex]
	minimum_distance = min(distances.values())
	minimum_vertex = (list(distances.keys())[list(distances.values()).index(minimum_distance)])

	print("\nThe shortest distance is from \"{0}\" to \"{1}\". Weight: {2}".format(start_vertex,minimum_vertex,minimum_distance))
	#return distances



dijkstras(graph,"A")

output:

How can heappop be directly called on vertices_to_explore. Isn’t is supposed to he called only on heapq data type?