forked from hofmannol/AlgoDatSoSe25
132 lines
3.9 KiB
Python
132 lines
3.9 KiB
Python
from utils.memory_array import MemoryArray
|
|
from utils.memory_cell import MemoryCell
|
|
from utils.memory_manager import MemoryManager
|
|
from utils.literal import Literal
|
|
import random
|
|
|
|
class PriorityQueue:
|
|
|
|
def __init__(self, size: Literal):
|
|
self.items = MemoryArray(size)
|
|
self.heapsize = MemoryCell(0)
|
|
|
|
def __len__(self):
|
|
return self.heapsize.value
|
|
|
|
def insert(self, item: MemoryCell):
|
|
if self.heapsize == self.items.length():
|
|
raise Exception("Queue is full")
|
|
self.heapsize.set(self.heapsize.succ())
|
|
self.items[adjust_index(self.heapsize)].set(item.value)
|
|
heapyfy_up(self.items, self.heapsize)
|
|
|
|
|
|
def pop(self) -> MemoryCell | None:
|
|
if self.is_empty():
|
|
return None
|
|
result = MemoryCell(self.items[Literal(0)])
|
|
self.heapsize.set(self.heapsize.pred())
|
|
if self.heapsize > Literal(1):
|
|
swap(self.items, 0, int(self.heapsize))
|
|
max_heapyfy(self.items, Literal(1), self.heapsize)
|
|
return result
|
|
|
|
def peek(self) -> MemoryCell | None:
|
|
if self.is_empty():
|
|
return None
|
|
return MemoryCell(self.items[Literal(0)])
|
|
|
|
def is_empty(self) -> bool:
|
|
return self.heapsize == Literal(0)
|
|
|
|
def __str__(self):
|
|
result = "[ "
|
|
for i, cell in enumerate(self.items.cells):
|
|
if i == int(self.heapsize):
|
|
result += "| "
|
|
result += str(cell) + " "
|
|
result += "]"
|
|
return result
|
|
|
|
def left_child(i: Literal):
|
|
return Literal(2 * int(i))
|
|
|
|
|
|
def right_child(i: Literal):
|
|
return Literal(2 * int(i) + 1)
|
|
|
|
|
|
def adjust_index(i: Literal):
|
|
return i.pred()
|
|
|
|
def heapyfy_up(z: MemoryArray, i: Literal):
|
|
if i == Literal(1):
|
|
return
|
|
parent = Literal(int(i) // 2)
|
|
if z[adjust_index(parent)] >= z[adjust_index(i)]:
|
|
return
|
|
swap(z, int(i)-1, int(parent)-1)
|
|
heapyfy_up(z, parent)
|
|
|
|
|
|
def max_heapyfy(z: MemoryArray, i: Literal, heapsize: Literal):
|
|
l = left_child(i)
|
|
r = right_child(i)
|
|
with MemoryCell(i) as max_value:
|
|
if l <= heapsize and z[adjust_index(l)] > z[adjust_index(i)]:
|
|
max_value.set(l)
|
|
if r <= heapsize and z[adjust_index(r)] > z[adjust_index(max_value)]:
|
|
max_value.set(r)
|
|
if max_value != i:
|
|
swap(z, int(i)-1, int(max_value)-1)
|
|
max_heapyfy(z, max_value, heapsize)
|
|
|
|
|
|
def swap(z: MemoryArray, i: int, j: int):
|
|
tmp = z[Literal(i)].value
|
|
z[Literal(i)] = z[Literal(j)]
|
|
z[Literal(j)].set(tmp)
|
|
|
|
|
|
def analyze_complexity_insert(sizes, presorted=False):
|
|
"""
|
|
Analysiert die Komplexität der Insert-Funktion.
|
|
"""
|
|
for size in sizes:
|
|
MemoryManager().purge() # Speicher zurücksetzen
|
|
pq = PriorityQueue(Literal(size))
|
|
insert_list = [random.randint(-100, 100) for _ in range(size)]
|
|
if presorted:
|
|
insert_list.sort()
|
|
for insert_value in insert_list[:-1]:
|
|
pq.insert(MemoryCell(insert_value))
|
|
MemoryManager().reset()
|
|
pq.insert(MemoryCell(insert_list[-1]))
|
|
MemoryManager.save_stats(size)
|
|
|
|
MemoryManager.plot_stats(["cells", "compares", "writes"])
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
length = Literal(10)
|
|
pq = PriorityQueue(length)
|
|
for i in range(10):
|
|
space_left = int(length) - len(pq)
|
|
if space_left > 0:
|
|
insert_count = random.randint(1, space_left)
|
|
insert_sequence = [random.randint(1, int(length)) for _ in range(insert_count)]
|
|
print(f"-> {insert_sequence}")
|
|
for j in insert_sequence:
|
|
pq.insert(MemoryCell(j))
|
|
print(f"{pq}")
|
|
if not pq.is_empty():
|
|
pop_count = random.randint(1, len(pq))
|
|
output_sequence = [int(pq.pop()) for _ in range(pop_count)]
|
|
print(f"<- {output_sequence}")
|
|
print(f"{pq}")
|
|
|
|
sizes = range(10, 501, 5)
|
|
analyze_complexity_insert(sizes, presorted=True)
|
|
|