Skip to content

Commit 8ce544b

Browse files
committed
Prims algorithm
1 parent 5994f00 commit 8ce544b

File tree

4 files changed

+127
-0
lines changed

4 files changed

+127
-0
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from vertex import Vertex
2+
from priorityqueue import PriorityQueue
3+
4+
5+
class Graph:
6+
def __init__(self):
7+
self._vertices: dict = {}
8+
self._adjacency_map: dict = {}
9+
self._prev: dict = {}
10+
11+
def add_vertex(self, label: str):
12+
v: Vertex = Vertex(label)
13+
self._vertices[label] = v
14+
self._adjacency_map[label]: list = []
15+
self._prev[label] = None
16+
17+
def add_edge(self, label1: str, label2: str, weight: int):
18+
self._adjacency_map[label1].append(Vertex(label2, weight))
19+
self._adjacency_map[label2].append(Vertex(label1, weight))
20+
21+
def prims(self, label: str):
22+
result: str = ""
23+
self._vertices[label].weight = 0
24+
pq: PriorityQueue = PriorityQueue()
25+
for label in self._vertices:
26+
pq.insert(self._vertices[label])
27+
while not pq.is_empty():
28+
current: Vertex = pq.delete_min()
29+
if self._prev[current.label] is not None:
30+
result += self._prev[current.label] + " -> " + current.label + ", "
31+
for neighbour in self._adjacency_map[current.label]:
32+
v: Vertex = self._vertices[neighbour.label]
33+
if neighbour.weight < v.weight:
34+
v.weight = neighbour.weight
35+
self._prev[v.label] = current.label
36+
pq.decrease_key(v.key)
37+
print(result)
38+
39+
40+
41+
42+
43+
44+
45+
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from graph import Graph
2+
3+
4+
graph: Graph = Graph()
5+
6+
graph.add_vertex("a")
7+
graph.add_vertex("b")
8+
graph.add_vertex("f")
9+
graph.add_vertex("c")
10+
graph.add_vertex("d")
11+
graph.add_vertex("e")
12+
13+
graph.add_edge("a", "b", 4)
14+
graph.add_edge("a", "f", 2)
15+
graph.add_edge("b", "c", 6)
16+
graph.add_edge("f", "b", 3)
17+
graph.add_edge("f", "c", 1)
18+
graph.add_edge("f", "e", 4)
19+
graph.add_edge("c", "d", 3)
20+
graph.add_edge("d", "e", 2)
21+
graph.prims("a") # a -> f, f -> c, f -> b, c -> d, d -> e,
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from vertex import Vertex
2+
3+
4+
class PriorityQueue:
5+
def __init__(self):
6+
self.pq: list = [None]
7+
self._pointer: int = 0
8+
9+
def is_empty(self) -> bool:
10+
return self._pointer == 0
11+
12+
def insert(self, vertex: Vertex):
13+
self.pq.append(vertex)
14+
self._pointer += 1
15+
vertex.key = self._pointer
16+
self._perc_up(self._pointer)
17+
18+
def _perc_up(self, pointer: int):
19+
while pointer // 2 > 0:
20+
if self.pq[pointer // 2].weight > self.pq[pointer].weight:
21+
self.pq[pointer // 2], self.pq[pointer] = self.pq[pointer], self.pq[pointer // 2]
22+
self.pq[pointer // 2].key = pointer // 2
23+
self.pq[pointer].key = pointer
24+
pointer = pointer // 2
25+
26+
def decrease_key(self, pointer: int):
27+
self._perc_up(pointer)
28+
29+
def delete_min(self) -> Vertex:
30+
if self.is_empty():
31+
raise Exception("Priority queue is empty")
32+
v: Vertex = self.pq[1]
33+
self.pq[1] = self.pq[self._pointer]
34+
self.pq[1].key = 1
35+
self.pq.pop()
36+
self._pointer -= 1
37+
self._perc_down(1)
38+
return v
39+
40+
def _perc_down(self, pointer: int):
41+
while pointer * 2 <= self._pointer:
42+
min_index: int = self._find_swap_index(pointer)
43+
if self.pq[pointer].weight > self.pq[min_index].weight:
44+
self.pq[pointer], self.pq[min_index] = self.pq[min_index], self.pq[pointer]
45+
self.pq[pointer].key = pointer
46+
self.pq[min_index].key = min_index
47+
pointer = min_index
48+
49+
def _find_swap_index(self, pointer: int) -> int:
50+
if pointer * 2 + 1 > self._pointer:
51+
return pointer * 2
52+
else:
53+
if self.pq[pointer * 2].weight <= self.pq[pointer * 2 + 1].weight:
54+
return pointer * 2
55+
else:
56+
return pointer * 2 + 1
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
class Vertex:
2+
def __init__(self, label: str = None, weight: int = float("inf"), key: int = None):
3+
self.label: str = label
4+
self.weight: int = weight
5+
self.key: int = key

0 commit comments

Comments
 (0)