Skip to content

Commit de70da5

Browse files
committed
Prim impl - maps
1 parent d7d0168 commit de70da5

File tree

4 files changed

+103
-118
lines changed

4 files changed

+103
-118
lines changed
Lines changed: 30 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,41 @@
1-
from vertex import Vertex
21
from priorityqueue import PriorityQueue
2+
from vertex import Vertex
33

44
class Graph:
55
def __init__(self):
6-
self.vertices: list = []
7-
self.adjacencyList: dict = {}
8-
self.prev: dict = {}
9-
10-
def addVertex(self, label: str, weight:int = float("inf")):
11-
vertex: Vertex = Vertex(label, weight)
12-
vertex.index = len(self.vertices)
13-
self.vertices.append(vertex)
14-
self.prev[label] = None
15-
self.adjacencyList[label] = []
6+
self.__vertices__: dict = {}
7+
self.__prev__: dict = {}
8+
self.__adjacency_map__: dict = {}
169

17-
def addEdge(self, label1: str, label2: str, weight: int):
18-
vertex: Vertex = Vertex(label2, weight)
19-
index: int = self.findIndexByLabel(label2)
20-
vertex.index = index
21-
self.adjacencyList[label1].append(vertex)
10+
def add_vertex(self, label: str):
11+
self.__vertices__[label] = Vertex(label)
12+
self.__prev__[label] = None
13+
self.__adjacency_map__[label]: dict = {}
2214

23-
vertex = Vertex(label1, weight)
24-
index: int = self.findIndexByLabel(label1)
25-
vertex.index = index
26-
self.adjacencyList[label2].append(vertex)
15+
def add_edge(self, label1: str, label2: str, weight: int = float("inf")):
16+
self.__adjacency_map__[label1][label2] = Vertex(label2, weight)
2717

2818
def prims(self, label: str):
19+
self.__vertices__[label].weight = 0
20+
pq: PriorityQueue = PriorityQueue()
21+
for label in self.__vertices__:
22+
pq.insert(self.__vertices__[label])
23+
2924
result: str = ""
30-
index: int = self.findIndexByLabel(label)
31-
self.vertices[index].weight = 0
32-
pq = PriorityQueue()
33-
pq.buildHeap(self.vertices)
34-
current: Vertex
35-
while not pq.isEmpty():
36-
current = pq.deleteMin()
37-
print(current.label)
38-
if self.prev[current.label] is not None:
39-
result += self.prev[current.label] + " -> " + current.label + ", "
40-
for neighbour in self.adjacencyList[current.label]:
41-
if neighbour.weight < self.vertices[neighbour.index].weight:
42-
self.prev[self.vertices[neighbour.index].label] = current.label
43-
self.vertices[neighbour.index].weight = neighbour.weight
44-
pq.decreaseKey(self.vertices[neighbour.index].key)
25+
while not pq.is_empty():
26+
v: Vertex = pq.delete_min()
27+
if self.__prev__[v.label] is not None:
28+
result += self.__prev__[v.label] + " - " + v.label + ", "
29+
for neighbour_label in self.__adjacency_map__[v.label]:
30+
neighbour: Vertex = self.__adjacency_map__[v.label][neighbour_label]
31+
vertex: Vertex = self.__vertices__[neighbour_label]
32+
if neighbour.weight < vertex.weight:
33+
self.__prev__[neighbour_label] = v.label
34+
vertex.weight = neighbour.weight
35+
pq.decrease_key(vertex.key)
36+
4537
print(result)
38+
39+
4640

47-
def findIndexByLabel(self, label: str)->int:
48-
found: bool = False
49-
count: int = 0
50-
while count < len(self.vertices) and not found:
51-
if self.vertices[count].label == label:
52-
found = True
53-
else:
54-
count += 1
55-
if found:
56-
return count
57-
else:
58-
return None
59-
41+
Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
from graph import Graph
22

3-
graph = Graph()
3+
graph: Graph = Graph()
44

55
g = Graph()
6-
g.addVertex("A")
7-
g.addVertex("B")
8-
g.addVertex("C")
9-
g.addVertex("D")
10-
g.addVertex("E")
11-
g.addVertex("F")
6+
g.add_vertex("A")
7+
g.add_vertex("B")
8+
g.add_vertex("C")
9+
g.add_vertex("D")
10+
g.add_vertex("E")
11+
g.add_vertex("F")
1212

1313

14-
g.addEdge("A", "B", 4)
15-
g.addEdge("A", "F", 2)
16-
g.addEdge("B", "C", 6)
17-
g.addEdge("F", "B", 3)
18-
g.addEdge("F", "C", 1)
19-
g.addEdge("F", "E", 4)
20-
g.addEdge("C", "D", 3)
21-
g.addEdge("D", "E", 2)
14+
g.add_edge("A", "B", 4)
15+
g.add_edge("A", "F", 2)
16+
g.add_edge("B", "C", 6)
17+
g.add_edge("F", "B", 3)
18+
g.add_edge("F", "C", 1)
19+
g.add_edge("F", "E", 4)
20+
g.add_edge("C", "D", 3)
21+
g.add_edge("D", "E", 2)
2222

2323
g.prims("A")
Lines changed: 53 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,63 @@
11
from vertex import Vertex
22

33
class PriorityQueue:
4-
def __init__(self, size: int = 0):
5-
self.heap: list = [None]
6-
self.size = size
4+
def __init__(self):
5+
self.__queue__: list = [None]
6+
self.__pointer__: int = 0
77

8-
def isEmpty(self)->bool:
9-
return self.size == 0
8+
def is_empty(self) -> bool:
9+
return self.__pointer__ == 0
1010

1111
def insert(self, vertex: Vertex):
12-
self.size += 1
13-
vertex.key = self.size
14-
self.heap.append(vertex)
15-
self.percUp(self.size)
16-
17-
def percUp(self, index: int):
18-
while index // 2 > 0:
19-
if self.heap[index].weight < self.heap[index//2].weight:
20-
self.heap[index], self.heap[index//2] = self.heap[index//2], self.heap[index]
21-
self.heap[index].key = index
22-
self.heap[index//2].key = index // 2
23-
index = index // 2
24-
25-
def decreaseKey(self, index):
26-
self.percUp(index)
27-
28-
def deleteMin(self)->Vertex:
29-
if self.isEmpty():
30-
return None
31-
else:
32-
tmp: Vertex = self.heap[1]
33-
self.heap[1] = self.heap[self.size]
34-
self.heap[1].key = 1
35-
self.heap.pop()
36-
self.size -= 1
37-
self.percDown(1)
38-
return tmp
39-
40-
def percDown(self, index: int):
41-
while index * 2 <= self.size:
42-
minIndex: int = self.getMinIndex(index)
43-
if self.heap[index].weight > self.heap[minIndex].weight:
44-
self.heap[index], self.heap[minIndex] = self.heap[minIndex], self.heap[index]
45-
self.heap[index].key = index
46-
self.heap[minIndex].key = minIndex
47-
index = minIndex
48-
49-
def getMinIndex(self, index: int):
50-
if index * 2 + 1 > self.size:
12+
self.__pointer__ += 1
13+
self.__queue__.append(vertex)
14+
vertex.key = self.__pointer__
15+
self.__perc_up__(self.__pointer__)
16+
17+
def __perc_up__(self, pointer: int):
18+
while pointer // 2 > 0:
19+
if self.__queue__[pointer].weight < self.__queue__[pointer // 2].weight:
20+
self.__queue__[pointer], self.__queue__[pointer // 2] = self.__queue__[pointer // 2], self.__queue__[pointer]
21+
self.__queue__[pointer].key = pointer
22+
self.__queue__[pointer // 2].key = pointer // 2
23+
pointer = pointer // 2
24+
25+
def decrease_key(self, key: int):
26+
self.__perc_up__(key)
27+
28+
def get_min(self) -> Vertex:
29+
if self.is_empty():
30+
raise Exception("Priority Queue is empty")
31+
return self.__queue__[1]
32+
33+
def delete_min(self) -> Vertex:
34+
if self.is_empty():
35+
raise Exception("Priority Queue is empty")
36+
min_vertex: Vertex = self.__queue__[1]
37+
self.__queue__[1] = self.__queue__[self.__pointer__]
38+
self.__queue__[1].key = 1
39+
self.__pointer__ -= 1
40+
self.__queue__.pop()
41+
self.__perc_down__(1)
42+
return min_vertex
43+
44+
def __perc_down__(self, index: int):
45+
while index * 2 <= self.__pointer__:
46+
min_index: int = self.__min_index__(index)
47+
if self.__queue__[index].weight > self.__queue__[min_index].weight:
48+
self.__queue__[index], self.__queue__[min_index] = self.__queue__[min_index], self.__queue__[index]
49+
self.__queue__[index].key = index
50+
self.__queue__[min_index].key = min_index
51+
index = min_index
52+
53+
def __min_index__(self, index: int) -> int:
54+
if index * 2 + 1 > self.__pointer__:
5155
return index * 2
5256
else:
53-
if self.heap[index * 2].weight <= self.heap[index * 2 + 1].weight:
54-
return index * 2
57+
if self.__queue__[index * 2].weight <= self.__queue__[index * 2 + 1].weight:
58+
return index * 2
5559
else:
5660
return index * 2 + 1
57-
58-
def buildHeap(self, vertices: list):
59-
for vertex in vertices:
60-
self.insert(vertex)
61+
62+
63+
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
class Vertex:
3-
def __init__(self, label: str = None, weight: int = None, index: int = None, key: int = None):
4-
self.label = label
5-
self.weight = weight
6-
self.index = index
7-
self.key = key
3+
def __init__(self, label: str = None, weight: int = float("inf"), key: int = None):
4+
self.label: str = label
5+
self.weight: int = weight
6+
self.key: int = key
7+

0 commit comments

Comments
 (0)