Skip to content

Commit a87fcf9

Browse files
committed
Adding Dijkstra's Algorithm
1 parent b511072 commit a87fcf9

File tree

2 files changed

+162
-0
lines changed

2 files changed

+162
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ This is my study repository.
2525
* Graph with Breadth-First Search (BFS).
2626
* Greedy Search Graph.
2727
* A* Search Graph.
28+
* Dijkstra's Algorithm.
2829

2930

3031
## Link

src/dijkstra.py

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
#!/usr/bin/env python3
2+
3+
##
4+
# Dijkstra's Algorithm
5+
#
6+
# Shortest path using Dijkstra's algorithm
7+
##
8+
9+
import numpy as np
10+
import sys
11+
12+
# Graph structure - adjacency matrix
13+
vertices = {'arad': 0, 'zerind': 1, 'oradea': 2, 'sibiu': 3, 'timisoara': 4,
14+
'lugoj': 5, 'mehadia': 6, 'dobreta': 7, 'craiova': 8, 'rimnicu': 9,
15+
'fagaras': 10, 'pitesti': 11, 'bucharest': 12, 'giurgiu': 13}
16+
17+
# Reverse lookup for cities
18+
cities = {0: 'arad', 1: 'zerind', 2: 'oradea', 3: 'sibiu', 4: 'timisoara',
19+
5: 'lugoj', 6: 'mehadia', 7: 'dobreta', 8: 'craiova', 9: 'rimnicu',
20+
10: 'fagaras', 11: 'pitesti', 12: 'bucharest', 13: 'giurgiu'}
21+
22+
# Initialize adjacency matrix for the graph
23+
edges = np.zeros([len(cities), len(cities)], dtype=int)
24+
25+
# Set edge weights for the graph
26+
edges[vertices['arad'], [vertices['zerind']]] = 75
27+
edges[vertices['arad'], [vertices['sibiu']]] = 140
28+
edges[vertices['arad'], [vertices['timisoara']]] = 118
29+
30+
edges[vertices['zerind'], [vertices['arad']]] = 75
31+
edges[vertices['zerind'], [vertices['oradea']]] = 71
32+
33+
edges[vertices['oradea'], [vertices['zerind']]] = 71
34+
edges[vertices['oradea'], [vertices['sibiu']]] = 151
35+
36+
edges[vertices['sibiu'], [vertices['oradea']]] = 151
37+
edges[vertices['sibiu'], [vertices['arad']]] = 140
38+
edges[vertices['sibiu'], [vertices['fagaras']]] = 99
39+
edges[vertices['sibiu'], [vertices['rimnicu']]] = 80
40+
41+
edges[vertices['timisoara'], [vertices['arad']]] = 118
42+
edges[vertices['timisoara'], [vertices['lugoj']]] = 111
43+
44+
edges[vertices['lugoj'], [vertices['timisoara']]] = 111
45+
edges[vertices['lugoj'], [vertices['mehadia']]] = 70
46+
47+
edges[vertices['mehadia'], [vertices['lugoj']]] = 70
48+
edges[vertices['mehadia'], [vertices['dobreta']]] = 75
49+
50+
edges[vertices['dobreta'], [vertices['mehadia']]] = 75
51+
edges[vertices['dobreta'], [vertices['craiova']]] = 120
52+
53+
edges[vertices['craiova'], [vertices['dobreta']]] = 120
54+
edges[vertices['craiova'], [vertices['pitesti']]] = 138
55+
edges[vertices['craiova'], [vertices['rimnicu']]] = 146
56+
57+
edges[vertices['rimnicu'], [vertices['craiova']]] = 146
58+
edges[vertices['rimnicu'], [vertices['sibiu']]] = 80
59+
edges[vertices['rimnicu'], [vertices['pitesti']]] = 97
60+
61+
edges[vertices['fagaras'], [vertices['sibiu']]] = 99
62+
edges[vertices['fagaras'], [vertices['bucharest']]] = 211
63+
64+
edges[vertices['pitesti'], [vertices['rimnicu']]] = 97
65+
edges[vertices['pitesti'], [vertices['craiova']]] = 138
66+
edges[vertices['pitesti'], [vertices['bucharest']]] = 101
67+
68+
edges[vertices['bucharest'], [vertices['fagaras']]] = 211
69+
edges[vertices['bucharest'], [vertices['pitesti']]] = 101
70+
edges[vertices['bucharest'], [vertices['giurgiu']]] = 90
71+
72+
73+
# Dijkstra's Algorithm class
74+
class Dijkstra:
75+
"""
76+
Dijkstra's algorithm to find the shortest path in a graph.
77+
78+
Attributes:
79+
- vertices: List of graph vertices
80+
- edges: Adjacency matrix representing the graph
81+
- start: Starting vertex for the algorithm
82+
"""
83+
84+
def __init__(self, vertices, edges, start):
85+
"""
86+
Initializes the Dijkstra object with the graph and starting vertex.
87+
88+
:param vertices: List of vertices in the graph
89+
:param edges: Adjacency matrix representing the edges of the graph
90+
:param start: The starting vertex for the algorithm
91+
"""
92+
self.size = len(vertices)
93+
self.vertices = vertices
94+
self.graph = edges
95+
self.start = start
96+
97+
def display_solution(self, distances):
98+
"""
99+
Displays the shortest distances from the start vertex to all other vertices.
100+
101+
:param distances: List of shortest distances
102+
"""
103+
print(f'Shortest distances from {self.vertices[self.start]} to all other vertices:')
104+
for vertex in range(self.size):
105+
print(f'{self.vertices[vertex]}: {distances[vertex]}')
106+
107+
def find_min_distance(self, distance, visited):
108+
"""
109+
Finds the vertex with the minimum distance that has not been visited.
110+
111+
:param distance: List of current distances
112+
:param visited: List of visited vertices
113+
:return: Index of the vertex with the minimum distance
114+
"""
115+
min_distance = sys.maxsize
116+
for vertex in range(self.size):
117+
if distance[vertex] < min_distance and not visited[vertex]:
118+
min_distance = distance[vertex]
119+
min_index = vertex
120+
return min_index
121+
122+
def run_dijkstra(self):
123+
"""
124+
Runs Dijkstra's algorithm to find the shortest path from the start vertex.
125+
"""
126+
distance = [sys.maxsize] * self.size
127+
distance[self.start] = 0
128+
visited = [False] * self.size
129+
130+
for _ in range(self.size):
131+
min_index = self.find_min_distance(distance, visited)
132+
visited[min_index] = True
133+
134+
for vertex in range(self.size):
135+
if self.graph[min_index][vertex] > 0 and not visited[vertex] \
136+
and distance[vertex] > distance[min_index] + self.graph[min_index][vertex]:
137+
distance[vertex] = distance[min_index] + self.graph[min_index][vertex]
138+
139+
self.display_solution(distance)
140+
141+
142+
# Example with the first graph
143+
dijkstra = Dijkstra(cities, edges, vertices['arad'])
144+
dijkstra.run_dijkstra()
145+
146+
# Test with another graph
147+
vertices2 = {'A': 0, 'B': 1, 'C': 2, 'D': 3, 'E': 4, 'F': 5}
148+
vertices2_inv = {0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E', 5: 'F'}
149+
150+
edges2 = np.zeros([len(vertices2), len(vertices2)], dtype=int)
151+
edges2[vertices2['A'], [vertices2['B']]] = 2
152+
edges2[vertices2['A'], [vertices2['C']]] = 1
153+
edges2[vertices2['B'], [vertices2['D']]] = 1
154+
edges2[vertices2['C'], [vertices2['D']]] = 3
155+
edges2[vertices2['C'], [vertices2['E']]] = 4
156+
edges2[vertices2['D'], [vertices2['F']]] = 2
157+
edges2[vertices2['E'], [vertices2['F']]] = 2
158+
159+
# Running Dijkstra on the second graph
160+
dijkstra = Dijkstra(vertices2_inv, edges2, vertices2['A'])
161+
dijkstra.run_dijkstra()

0 commit comments

Comments
 (0)