Dijkstra's Algorithm
The algorithm finds the shortest paths between nodes in a weighted graph.
"""
Weighted graph vertex
"""
class City:
def __init__(self, name):
self.name = name
self.routes = {}
def add_route(self, city, price):
self.routes[city.name] = price
a = City('Atlanta')
b = City('Boston')
c = City('Chicago')
d = City('Denver')
e = City('El Paso')
a.add_route(b, 100); a.add_route(d, 160)
b.add_route(c, 120); b.add_route(d, 180)
c.add_route(e, 80)
d.add_route(c, 40); d.add_route(e, 140)
e.add_route(b, 100)
Cites = {'Atlanta': a, 'Boston': b, 'Chicago': c, 'Denver': d, 'El Paso': e}
for name, obj in Cites.items():
print(name, obj.routes)
"""
Atlanta {'Boston': 100, 'Denver': 160}
Boston {'Chicago': 120, 'Denver': 180}
Chicago {'El Paso': 80}
Denver {'Chicago': 40, 'El Paso': 140}
El Paso {'Boston': 100}
"""
"""
The CORE algorithm /
Get the cheapest table, containing all the cheapest prices
to get to each city from the STARTING point
"""
def dijkstra_shortest_path(starting_city, destination):
C = {} # Cheapest prices (table)
U = [] # Unvisited cities (list)
V = [] # Visited cities (list)
P = {} # Cheapest previous stopover city (table) - Look Here
current = starting_city
C[current.name] = 0 # The price to itself is 0
# Loop as long as we have unvisited cities
while current:
V.append(current.name)
if current.name in U:
U.remove(current.name)
# Loop adjacent cities
for name, price in current.routes.items():
if name not in V:
U.append(name)
# Price of getting from STARTING to ADJACENT city
# using CURRENT city as the second-to-last stop:
price_through_current_city = C[current.name] + price
# If the price is the cheapest one we've found so far:
if name not in C or price_through_current_city < C[name]:
C[name] = price_through_current_city
P[name] = current.name # Look Here
# Break the loop when there are no more unvisited cities
if len(U) == 0:
break
# Set next unvisited city, the cheapest one
current_name = min(U, key=lambda city: C[city])
current = Cites[current_name]
# We have completed the core algorithm.
# At this point, the cheapest table contains all the cheapest prices
# to get to each city from the STARTING point
# We build the shortest path using an array:
shortest_path = []
# Work backwords from final destination
current_name = destination.name
# Loop until we reach the starting city:
while current_name != starting_city.name:
# Add each current_name to shortest_path
shortest_path.append(current_name)
# Follow each city to its previous stopover city
current_name = P[current_name]
# Add the starting city to the path
shortest_path.append(starting_city.name)
# We reverse the path to see it from beginning to end
return list(reversed(shortest_path))
print(dijkstra_shortest_path(a, b))
print(dijkstra_shortest_path(a, c))
print(dijkstra_shortest_path(a, d))
print(dijkstra_shortest_path(a, e))
"""
['Atlanta', 'Boston']
['Atlanta', 'Denver', 'Chicago']
['Atlanta', 'Denver']
['Atlanta', 'Denver', 'Chicago', 'El Paso']
['Atlanta', 'Denver', 'Chicago', 'El Paso'] 280
['El Paso', 'Boston', 'Denver'] 280
"""
Last update: 490 days ago