Skip to content

Commit 061074a

Browse files
committed
Dijkstra adjacency matrix
1 parent 1e791e7 commit 061074a

13 files changed

+122
-104
lines changed

.idea/Problem-Solving-with-Algorithms-and-Data-Structures-using-Python.iml

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ but it also contains other data structures, algorithms and problems.
108108
- [Priority Queue implementation](https://github.com/ivanmmarkovic/Problem-Solving-with-Algorithms-and-Data-Structures-using-Python/tree/master/graphs/dijkstra/priority-queue-impl-adjacency-map)
109109
- [Matrix implementation](https://github.com/ivanmmarkovic/Problem-Solving-with-Algorithms-and-Data-Structures-using-Python/tree/master/graphs/dijkstra/matrix-impl)
110110
- [Minimum Spanning Tree](https://github.com/ivanmmarkovic/Problem-Solving-with-Algorithms-and-Data-Structures-using-Python/tree/master/graphs/minimum-spanning-tree)
111-
- [Prim's algorithm - Minimum Spanning Tree](https://github.com/ivanmmarkovic/Problem-Solving-with-Algorithms-and-Data-Structures-using-Python/tree/master/graphs/minimum-spanning-tree/prims-algorithm)
111+
- [Prim's algorithm - Minimum Spanning Tree in undirected weighted graph](https://github.com/ivanmmarkovic/Problem-Solving-with-Algorithms-and-Data-Structures-using-Python/tree/master/graphs/minimum-spanning-tree/prims-algorithm)
112112
- [Is graph bipartite](https://github.com/ivanmmarkovic/Problem-Solving-with-Algorithms-and-Data-Structures-using-Python/tree/master/graphs/is-graph-bipartite)
113113

114114
### [Trie](https://github.com/ivanmmarkovic/Problem-Solving-with-Algorithms-and-Data-Structures-using-Python/tree/master/trie)
Binary file not shown.
Binary file not shown.

graphs/dijkstra/matrix-impl/graph.py

+47-53
Original file line numberDiff line numberDiff line change
@@ -2,66 +2,60 @@
22

33

44
class Graph:
5-
def __init__(self, matrix_size: int = 10):
6-
self._matrix_size: int = matrix_size
7-
self._vertices: list = [None] * self._matrix_size
8-
self._pointer: int = 0
9-
self._adjacency_matrix: list = [[None for i in range(self._matrix_size)] for j in range(self._matrix_size)]
10-
self._prev: dict = {}
11-
self._visited: dict = {}
12-
13-
def add_vertex(self, label: str = None, weight: int = float("inf")):
14-
if self._pointer == self._matrix_size:
5+
def __init__(self, size: int = 10):
6+
self.size: int = size
7+
self.index: int = 0
8+
self.vertices_list: list = [None] * self.size
9+
self.vertices: dict = {}
10+
self.adjacency_matrix: list = [[None for i in range(self.size)] for j in range(self.size)]
11+
self.prev: dict = {}
12+
self.visited: dict = {}
13+
14+
def add_vertex(self, label: str):
15+
if self.index == self.size: # matrix is full
1516
return
16-
vertex: Vertex = Vertex(label, float("inf"), self._pointer)
17-
self._vertices[self._pointer] = vertex
18-
self._prev[label] = None
19-
self._pointer += 1
17+
vertex: Vertex = Vertex(label, float("inf"), self.index)
18+
self.vertices_list[self.index] = vertex
19+
self.vertices[vertex.label] = vertex
20+
self.index += 1
21+
self.prev[vertex.label] = None
22+
self.visited[vertex.label] = False
2023

2124
def add_edge(self, label1: str, label2: str, weight: int):
22-
vertex1: Vertex = self._find_vertex_by_label(label1)
23-
vertex2: Vertex = self._find_vertex_by_label(label2)
24-
self._adjacency_matrix[vertex1.get_index()][vertex2.get_index()] = weight
25+
index1: int = self.vertices[label1].index
26+
index2: int = self.vertices[label2].index
27+
self.adjacency_matrix[index1][index2] = weight
2528

2629
def dijkstra(self, label: str):
27-
vertex: Vertex = self._find_vertex_by_label(label)
28-
vertex.set_weight(0)
29-
while vertex is not None:
30-
index: int = vertex.get_index()
31-
for i in range(len(self._adjacency_matrix[index])):
32-
if self._adjacency_matrix[index][i] is not None:
33-
neighbour: Vertex = self._vertices[i]
34-
if neighbour.get_weight() > vertex.get_weight() + self._adjacency_matrix[index][i]:
35-
self._prev[neighbour.get_label()] = vertex.get_label()
36-
neighbour.set_weight(vertex.get_weight() + self._adjacency_matrix[index][i])
37-
self._visited[vertex.get_label()] = vertex
38-
vertex = self._find_minimum_weight_vertex()
39-
40-
def return_path(self, end_label: str = None) -> str:
41-
if self._prev[end_label] is None:
42-
return end_label
30+
current_vertex: Vertex = self.vertices[label]
31+
current_vertex.weight = 0
32+
while current_vertex is not None:
33+
self.visited[current_vertex.label] = True
34+
for i in range(self.index):
35+
if self.adjacency_matrix[current_vertex.index][i] is not None:
36+
weight: int = self.adjacency_matrix[current_vertex.index][i]
37+
neighbour: Vertex = self.vertices_list[i]
38+
if current_vertex.weight + weight < neighbour.weight:
39+
neighbour.weight = current_vertex.weight + weight
40+
self.prev[neighbour.label] = current_vertex.label
41+
current_vertex = self.find_minimum_weight_vertex()
42+
43+
def return_path(self, label: str) -> str:
44+
if self.prev[label] is None:
45+
return label
4346
else:
44-
return self.return_path(self._prev[end_label]) + " -> " + end_label
45-
46-
def _find_vertex_by_label(self, label: str) -> Vertex:
47-
vertex: Vertex = None
48-
i: int = 0
49-
found: bool = False
50-
while i <= self._pointer and not found:
51-
if self._vertices[i].get_label() == label:
52-
vertex = self._vertices[i]
53-
found = True
54-
else:
55-
i += 1
56-
return vertex
47+
return self.return_path(self.prev[label]) + " -> " + label
5748

58-
def _find_minimum_weight_vertex(self):
49+
def find_minimum_weight_vertex(self):
5950
vertex: Vertex = None
60-
for i in range(0, self._pointer, +1):
61-
v: Vertex = self._vertices[i]
62-
if v.get_label() not in self._visited:
51+
for label in self.vertices:
52+
if not self.visited[label]:
6353
if vertex is None:
64-
vertex = v
65-
elif vertex.get_weight() > v.get_weight():
66-
vertex = v
54+
vertex = self.vertices[label]
55+
else:
56+
if vertex.weight > self.vertices[label].weight:
57+
vertex = self.vertices[label]
6758
return vertex
59+
60+
61+

graphs/dijkstra/matrix-impl/main.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from graph import Graph
22

3-
graph: Graph = Graph(20)
3+
4+
graph: Graph = Graph()
45

56
graph.add_vertex("START")
67
graph.add_vertex("A")

graphs/dijkstra/matrix-impl/vertex.py

+4-18
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,6 @@
11
class Vertex:
2-
def __init__(self, label: str = None, weight: int = float("inf"), index: int = None):
3-
self._label: str = label
4-
self._weight: int = weight
5-
self._index: int = index
2+
def __init__(self, label: str = None, weight: int = float("inf"), index: int = None):
3+
self.label: str = label
4+
self.weight: int = weight
5+
self.index: int = index
66

7-
def get_index(self):
8-
return self._index
9-
10-
def get_label(self) -> str:
11-
return self._label
12-
13-
def set_label(self, label: str):
14-
self._label = label
15-
16-
def get_weight(self) -> int:
17-
return self._weight
18-
19-
def set_weight(self, weight: int = float("inf")):
20-
self._weight = weight

graphs/dijkstra/priority-queue-impl-adjacency-map/.idea/.gitignore

-3
This file was deleted.

graphs/dijkstra/priority-queue-impl-adjacency-map/.idea/inspectionProfiles/profiles_settings.xml

-6
This file was deleted.

graphs/dijkstra/priority-queue-impl-adjacency-map/.idea/misc.xml

-4
This file was deleted.

graphs/dijkstra/priority-queue-impl-adjacency-map/.idea/modules.xml

-8
This file was deleted.

graphs/dijkstra/priority-queue-impl-adjacency-map/.idea/priority-queue-impl-adjacency-map.iml

-10
This file was deleted.

graphs/dijkstra/priority-queue-impl-adjacency-map/.idea/workspace.xml

+67
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)