forked from hofmannol/AlgoDatSoSe25
Compare commits
6 Commits
f02669d601
...
1b0f9f8c50
Author | SHA1 | Date | |
---|---|---|---|
1b0f9f8c50 | |||
![]() |
4aeb01c003 | ||
![]() |
1af49ede8c | ||
![]() |
27a37037d1 | ||
![]() |
32190dc104 | ||
![]() |
7ced5ed336 |
41
praktika/02_merge_sort/merge_game.py
Normal file
41
praktika/02_merge_sort/merge_game.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import random
|
||||||
|
import pygame
|
||||||
|
from utils.game import Game
|
||||||
|
from utils.memory_array import MemoryArray
|
||||||
|
from merge_sorting import merge_sort_stepwise
|
||||||
|
|
||||||
|
WHITE = (255, 255, 255)
|
||||||
|
BLUE = (0, 0, 255)
|
||||||
|
|
||||||
|
class MergeGame(Game):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Merge Game", fps=10, size=(400, 400))
|
||||||
|
random.seed()
|
||||||
|
l =list(range(1, 101))
|
||||||
|
random.shuffle(l)
|
||||||
|
self.z = MemoryArray(l)
|
||||||
|
self.finished = False
|
||||||
|
self.sort_generator = merge_sort_stepwise(self.z)
|
||||||
|
|
||||||
|
def update_game(self):
|
||||||
|
if not self.finished:
|
||||||
|
try:
|
||||||
|
next(self.sort_generator)
|
||||||
|
except StopIteration:
|
||||||
|
self.finished = True
|
||||||
|
return True
|
||||||
|
|
||||||
|
def draw_game(self):
|
||||||
|
self.screen.fill(WHITE)
|
||||||
|
for i, cell in enumerate(self.z):
|
||||||
|
x = 50 + i*3
|
||||||
|
y = 350 - cell.value * 3
|
||||||
|
pygame.draw.rect(self.screen, BLUE, (x, y, 3, 3))
|
||||||
|
super().draw_game()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
s = MergeGame()
|
||||||
|
s.run()
|
||||||
|
|
87
praktika/02_merge_sort/merge_sorting.py
Normal file
87
praktika/02_merge_sort/merge_sorting.py
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
from utils.memory_array import MemoryArray
|
||||||
|
from utils.memory_cell import MemoryCell
|
||||||
|
from utils.memory_manager import MemoryManager
|
||||||
|
from utils.memory_range import mrange
|
||||||
|
from utils.literal import Literal
|
||||||
|
from time import perf_counter as pfc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def merge_sort_stepwise(z: MemoryArray, l: Literal = None, r: Literal = None, buffer: MemoryArray = None):
|
||||||
|
if l is None:
|
||||||
|
l = Literal(0)
|
||||||
|
if r is None:
|
||||||
|
r = z.length().pred()
|
||||||
|
if buffer is None:
|
||||||
|
buffer = MemoryArray(z.length())
|
||||||
|
if l < r:
|
||||||
|
m = Literal((int(l) + int(r)) // 2)
|
||||||
|
yield from merge_sort_stepwise(z, l, m, buffer)
|
||||||
|
yield from merge_sort_stepwise(z, m.succ(), r, buffer)
|
||||||
|
yield from merge(z, l, m, r, buffer)
|
||||||
|
|
||||||
|
def merge(z: MemoryArray, l: Literal, m: Literal, r: Literal, buffer: MemoryArray):
|
||||||
|
with MemoryCell(l) as i, MemoryCell(m.succ()) as j, MemoryCell(l) as k:
|
||||||
|
while i <= m and j <= r:
|
||||||
|
if z[i] <= z[j]:
|
||||||
|
buffer[k].set(z[i])
|
||||||
|
i = i.succ()
|
||||||
|
else:
|
||||||
|
buffer[k].set(z[j])
|
||||||
|
j = j.succ()
|
||||||
|
k = k.succ()
|
||||||
|
while i <= m:
|
||||||
|
buffer[k].set(z[i])
|
||||||
|
i = i.succ()
|
||||||
|
k = k.succ()
|
||||||
|
while j <= r:
|
||||||
|
buffer[k].set(z[j])
|
||||||
|
j = j.succ()
|
||||||
|
k = k.succ()
|
||||||
|
for k in mrange(l, r.succ()):
|
||||||
|
z[k].set(buffer[k])
|
||||||
|
yield z
|
||||||
|
|
||||||
|
def merge_sort(z: MemoryArray):
|
||||||
|
sort_generator = merge_sort_stepwise(z)
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
next(sort_generator)
|
||||||
|
except StopIteration:
|
||||||
|
break
|
||||||
|
|
||||||
|
def sort_file(filename, sort_func):
|
||||||
|
z = MemoryArray.create_array_from_file(filename)
|
||||||
|
sort_func(z)
|
||||||
|
return z
|
||||||
|
|
||||||
|
def analyze_complexity(sort_func, sizes, presorted=False):
|
||||||
|
"""
|
||||||
|
Analysiert die Komplexität einer Sortierfunktion.
|
||||||
|
|
||||||
|
:param sort_func: Die Funktion, die analysiert wird.
|
||||||
|
:param sizes: Eine Liste von Eingabegrößen für die Analyse.
|
||||||
|
"""
|
||||||
|
for size in sizes:
|
||||||
|
MemoryManager.purge() # Speicher zurücksetzen
|
||||||
|
if presorted:
|
||||||
|
random_array = MemoryArray.create_sorted_array(size)
|
||||||
|
else:
|
||||||
|
random_array = MemoryArray.create_random_array(size, -100, 100)
|
||||||
|
sort_func(random_array)
|
||||||
|
MemoryManager.save_stats(size)
|
||||||
|
|
||||||
|
MemoryManager.plot_stats(["cells", "compares", "writes"])
|
||||||
|
|
||||||
|
def swap(z: MemoryArray, i: int, j: int):
|
||||||
|
tmp = z[Literal(i)].value
|
||||||
|
z[Literal(i)] = z[Literal(j)]
|
||||||
|
z[Literal(j)].set(tmp)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
analyze_complexity(merge_sort, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
|
||||||
|
for filename in ["data/seq0.txt", "data/seq1.txt", "data/seq2.txt", "data/seq3.txt"]:
|
||||||
|
print(filename)
|
||||||
|
start = pfc()
|
||||||
|
print(sort_file(filename, merge_sort))
|
||||||
|
print(f"Dauer: {pfc() - start:.4f}s")
|
@ -58,6 +58,10 @@ class MemoryArray:
|
|||||||
"""Gibt die Größe des Speicherarrays zurück."""
|
"""Gibt die Größe des Speicherarrays zurück."""
|
||||||
return Literal(self.size)
|
return Literal(self.size)
|
||||||
|
|
||||||
|
def count_compares(self):
|
||||||
|
return sum([cell.compare_count for cell in self.cells])
|
||||||
|
|
||||||
|
|
||||||
def reset_counters(self):
|
def reset_counters(self):
|
||||||
"""Setzt alle Zähler auf 0 zurück."""
|
"""Setzt alle Zähler auf 0 zurück."""
|
||||||
for cell in self.cells:
|
for cell in self.cells:
|
||||||
|
@ -2,11 +2,24 @@ from utils.memory_manager import MemoryManager
|
|||||||
from utils.literal import Literal
|
from utils.literal import Literal
|
||||||
|
|
||||||
class MemoryCell (Literal):
|
class MemoryCell (Literal):
|
||||||
|
|
||||||
|
def __new__(cls, *args, **kwargs):
|
||||||
|
"""Erstellt eine neue Instanz von MemoryCell."""
|
||||||
|
instance = MemoryManager().acquire_cell()
|
||||||
|
if instance is None:
|
||||||
|
instance = super().__new__(cls)
|
||||||
|
MemoryManager().register_cell(instance)
|
||||||
|
return instance
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||||
|
MemoryManager().release_cell(self)
|
||||||
|
|
||||||
def __init__(self, value=None):
|
def __init__(self, value=None):
|
||||||
"""Initialisiert eine Speicherzelle mit optionalem Startwert."""
|
"""Initialisiert eine Speicherzelle mit optionalem Startwert."""
|
||||||
super().__init__(value)
|
super().__init__(value)
|
||||||
manager = MemoryManager.get_instance()
|
|
||||||
manager.add_cell(self)
|
|
||||||
self.write_count = 0
|
self.write_count = 0
|
||||||
self.add_count = 0
|
self.add_count = 0
|
||||||
self.sub_count = 0
|
self.sub_count = 0
|
||||||
@ -171,10 +184,6 @@ class MemoryCell (Literal):
|
|||||||
self.div(other)
|
self.div(other)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __imod__(self, other):
|
|
||||||
self.mod(other)
|
|
||||||
return self
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
a = MemoryCell(5)
|
a = MemoryCell(5)
|
||||||
|
@ -1,63 +1,72 @@
|
|||||||
import numpy as np
|
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
import queue
|
||||||
|
|
||||||
|
|
||||||
class MemoryManager:
|
class MemoryManager:
|
||||||
|
|
||||||
instance = None
|
_instance = None
|
||||||
stats = {}
|
stats = {}
|
||||||
|
|
||||||
@staticmethod
|
def __new__(cls, *args, **kwargs):
|
||||||
def get_instance():
|
"""Erstellt eine einzige Instanz von MemoryManager."""
|
||||||
if MemoryManager.instance is None:
|
if cls._instance is None:
|
||||||
MemoryManager.instance = MemoryManager()
|
cls._instance = super().__new__(cls)
|
||||||
return MemoryManager.instance
|
cls._instance._initialize() # Eigene Init-Methode, damit __init__ nicht mehrfach läuft
|
||||||
|
return cls._instance
|
||||||
|
|
||||||
|
def _initialize(self):
|
||||||
|
"""Initialisiert die Speicherverwaltung (einmalig)."""
|
||||||
|
self.cells = []
|
||||||
|
self._pool = queue.Queue()
|
||||||
|
self._finalizers = {}
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def count_cells():
|
def count_cells():
|
||||||
return len(MemoryManager.get_instance().cells)
|
return len(MemoryManager().cells)
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def count_reads():
|
def count_reads():
|
||||||
return sum([cell.read_count for cell in MemoryManager.get_instance().cells])
|
return sum([cell.read_count for cell in MemoryManager().cells])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def count_writes():
|
def count_writes():
|
||||||
return sum([cell.write_count for cell in MemoryManager.get_instance().cells])
|
return sum([cell.write_count for cell in MemoryManager().cells])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def count_compares():
|
def count_compares():
|
||||||
return sum([cell.compare_count for cell in MemoryManager.get_instance().cells])
|
return sum([cell.compare_count for cell in MemoryManager().cells])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def count_adds():
|
def count_adds():
|
||||||
return sum([cell.add_count for cell in MemoryManager.get_instance().cells])
|
return sum([cell.add_count for cell in MemoryManager().cells])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def count_subs():
|
def count_subs():
|
||||||
return sum([cell.sub_count for cell in MemoryManager.get_instance().cells])
|
return sum([cell.sub_count for cell in MemoryManager().cells])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def count_muls():
|
def count_muls():
|
||||||
return sum([cell.mul_count for cell in MemoryManager.get_instance().cells])
|
return sum([cell.mul_count for cell in MemoryManager().cells])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def count_divs():
|
def count_divs():
|
||||||
return sum([cell.div_count for cell in MemoryManager.get_instance().cells])
|
return sum([cell.div_count for cell in MemoryManager().cells])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def count_bitops():
|
def count_bitops():
|
||||||
return sum([cell.bitop_count for cell in MemoryManager.get_instance().cells])
|
return sum([cell.bitop_count for cell in MemoryManager().cells])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def reset():
|
def reset():
|
||||||
manager = MemoryManager.get_instance()
|
manager = MemoryManager()
|
||||||
for cell in manager.cells:
|
for cell in manager.cells:
|
||||||
cell.reset_counters()
|
cell.reset_counters()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def purge():
|
def purge():
|
||||||
MemoryManager.instance = None
|
MemoryManager._instance = None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def save_stats(count):
|
def save_stats(count):
|
||||||
@ -91,8 +100,49 @@ class MemoryManager:
|
|||||||
plt.xlabel("n")
|
plt.xlabel("n")
|
||||||
plt.show()
|
plt.show()
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.cells = []
|
|
||||||
|
|
||||||
def add_cell(self, cell):
|
def acquire_cell(self):
|
||||||
|
try:
|
||||||
|
return self._pool.get_nowait()
|
||||||
|
except queue.Empty:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def register_cell(self, cell):
|
||||||
self.cells.append(cell)
|
self.cells.append(cell)
|
||||||
|
|
||||||
|
def release_cell(self, cell):
|
||||||
|
self._pool.put(cell)
|
||||||
|
|
||||||
|
|
||||||
|
class Testcell:
|
||||||
|
|
||||||
|
def __new__(cls, *args, **kwargs):
|
||||||
|
instance = MemoryManager().acquire_cell()
|
||||||
|
if instance is None:
|
||||||
|
instance = super().__new__(cls)
|
||||||
|
MemoryManager().register_cell(instance)
|
||||||
|
return instance
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||||
|
MemoryManager().release_cell(self)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
# Einfaches Anlegen einer Zelle
|
||||||
|
a = Testcell()
|
||||||
|
print(MemoryManager.count_cells())
|
||||||
|
|
||||||
|
# Anlegen einer Zelle und Beenden des Scopes
|
||||||
|
with Testcell() as b:
|
||||||
|
print(MemoryManager.count_cells())
|
||||||
|
|
||||||
|
print(MemoryManager.count_cells())
|
||||||
|
|
||||||
|
# Reuse einer Zelle
|
||||||
|
c = Testcell()
|
||||||
|
print(MemoryManager.count_cells())
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from utils.memory_array import MemoryArray
|
from utils.memory_array import MemoryArray
|
||||||
from utils.memory_cell import MemoryCell
|
from utils.memory_cell import MemoryCell
|
||||||
from utils.constants import MIN_VALUE
|
|
||||||
from utils.memory_manager import MemoryManager
|
from utils.memory_manager import MemoryManager
|
||||||
from utils.memory_range import mrange
|
from utils.memory_range import mrange
|
||||||
from utils.literal import Literal
|
from utils.literal import Literal
|
||||||
|
@ -58,4 +58,4 @@ def swap(z: MemoryArray, i: int, j: int):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
analyze_complexity(insert_sort, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
|
analyze_complexity(insert_sort, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100])
|
||||||
analyze_complexity(insert_sort, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100], True)
|
#analyze_complexity(insert_sort, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100], True)
|
||||||
|
42
vorlesung/03_fortgeschrittenes_sortieren/heap_game.py
Normal file
42
vorlesung/03_fortgeschrittenes_sortieren/heap_game.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import random
|
||||||
|
import pygame
|
||||||
|
from utils.game import Game
|
||||||
|
from utils.memory_array import MemoryArray
|
||||||
|
from utils.literal import Literal
|
||||||
|
from heap_sorting import heap_sort_stepwise
|
||||||
|
|
||||||
|
WHITE = (255, 255, 255)
|
||||||
|
BLUE = (0, 0, 255)
|
||||||
|
|
||||||
|
class HeapGame(Game):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Heap Game", fps=20, size=(400, 400))
|
||||||
|
random.seed()
|
||||||
|
l =list(range(1, 101))
|
||||||
|
random.shuffle(l)
|
||||||
|
self.z = MemoryArray(l)
|
||||||
|
self.finished = False
|
||||||
|
self.sort_generator = heap_sort_stepwise(self.z)
|
||||||
|
|
||||||
|
def update_game(self):
|
||||||
|
if not self.finished:
|
||||||
|
try:
|
||||||
|
next(self.sort_generator)
|
||||||
|
except StopIteration:
|
||||||
|
self.finished = True
|
||||||
|
return True
|
||||||
|
|
||||||
|
def draw_game(self):
|
||||||
|
self.screen.fill(WHITE)
|
||||||
|
for i, cell in enumerate(self.z):
|
||||||
|
x = 50 + i*3
|
||||||
|
y = 350 - cell.value * 3
|
||||||
|
pygame.draw.rect(self.screen, BLUE, (x, y, 3, 3))
|
||||||
|
super().draw_game()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sort_game = HeapGame()
|
||||||
|
sort_game.run()
|
||||||
|
|
93
vorlesung/03_fortgeschrittenes_sortieren/heap_sorting.py
Normal file
93
vorlesung/03_fortgeschrittenes_sortieren/heap_sorting.py
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
from utils.memory_array import MemoryArray
|
||||||
|
from utils.memory_cell import MemoryCell
|
||||||
|
from utils.memory_manager import MemoryManager
|
||||||
|
from utils.memory_range import mrange
|
||||||
|
from utils.literal import Literal
|
||||||
|
|
||||||
|
def heap_sort_stepwise(z: MemoryArray):
|
||||||
|
n = z.length()
|
||||||
|
yield from make_max_heap(z)
|
||||||
|
with MemoryCell(n) as heapsize:
|
||||||
|
for i in mrange(n, 1, -1):
|
||||||
|
swap(z, 0, i.pred())
|
||||||
|
yield z
|
||||||
|
heapsize.set(heapsize.pred())
|
||||||
|
yield from max_heapyfy(z, Literal(1), heapsize)
|
||||||
|
|
||||||
|
|
||||||
|
def heap_sort(z: MemoryArray):
|
||||||
|
sort_generator = heap_sort_stepwise(z)
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
next(sort_generator)
|
||||||
|
except StopIteration:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
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 make_max_heap(z: MemoryArray):
|
||||||
|
n = z.length()
|
||||||
|
for i in mrange(int(n) // 2, 0, -1):
|
||||||
|
yield from max_heapyfy(z, i, n)
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
||||||
|
yield z
|
||||||
|
yield from max_heapyfy(z, max_value, heapsize)
|
||||||
|
|
||||||
|
|
||||||
|
def sort_file(filename, sort_func):
|
||||||
|
z = MemoryArray.create_array_from_file(filename)
|
||||||
|
sort_func(z)
|
||||||
|
return z
|
||||||
|
|
||||||
|
|
||||||
|
def analyze_complexity(sort_func, sizes, presorted=False):
|
||||||
|
"""
|
||||||
|
Analysiert die Komplexität einer Sortierfunktion.
|
||||||
|
|
||||||
|
:param sort_func: Die Funktion, die analysiert wird.
|
||||||
|
:param sizes: Eine Liste von Eingabegrößen für die Analyse.
|
||||||
|
"""
|
||||||
|
for size in sizes:
|
||||||
|
MemoryManager.purge() # Speicher zurücksetzen
|
||||||
|
if presorted:
|
||||||
|
random_array = MemoryArray.create_sorted_array(size)
|
||||||
|
else:
|
||||||
|
random_array = MemoryArray.create_random_array(size, -100, 100)
|
||||||
|
sort_func(random_array)
|
||||||
|
MemoryManager.save_stats(size)
|
||||||
|
|
||||||
|
MemoryManager.plot_stats(["cells", "compares", "writes"])
|
||||||
|
|
||||||
|
|
||||||
|
def swap(z: MemoryArray, i: int, j: int):
|
||||||
|
tmp = z[Literal(i)].value
|
||||||
|
z[Literal(i)] = z[Literal(j)]
|
||||||
|
z[Literal(j)].set(tmp)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sizes = range(10, 101, 10)
|
||||||
|
analyze_complexity(heap_sort, sizes)
|
||||||
|
# analyze_complexity(quick_sort, sizes, True)
|
42
vorlesung/03_fortgeschrittenes_sortieren/quick_game.py
Normal file
42
vorlesung/03_fortgeschrittenes_sortieren/quick_game.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import random
|
||||||
|
import pygame
|
||||||
|
from utils.game import Game
|
||||||
|
from utils.memory_array import MemoryArray
|
||||||
|
from utils.literal import Literal
|
||||||
|
from quick_sorting import quick_sort_stepwise
|
||||||
|
|
||||||
|
WHITE = (255, 255, 255)
|
||||||
|
BLUE = (0, 0, 255)
|
||||||
|
|
||||||
|
class QuickGame(Game):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("Quick Game", fps=10, size=(400, 400))
|
||||||
|
random.seed()
|
||||||
|
l =list(range(1, 101))
|
||||||
|
random.shuffle(l)
|
||||||
|
self.z = MemoryArray(l)
|
||||||
|
self.finished = False
|
||||||
|
self.sort_generator = quick_sort_stepwise(self.z, Literal(0), Literal(self.z.length().pred()))
|
||||||
|
|
||||||
|
def update_game(self):
|
||||||
|
if not self.finished:
|
||||||
|
try:
|
||||||
|
next(self.sort_generator)
|
||||||
|
except StopIteration:
|
||||||
|
self.finished = True
|
||||||
|
return True
|
||||||
|
|
||||||
|
def draw_game(self):
|
||||||
|
self.screen.fill(WHITE)
|
||||||
|
for i, cell in enumerate(self.z):
|
||||||
|
x = 50 + i*3
|
||||||
|
y = 350 - cell.value * 3
|
||||||
|
pygame.draw.rect(self.screen, BLUE, (x, y, 3, 3))
|
||||||
|
super().draw_game()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sort_game = QuickGame()
|
||||||
|
sort_game.run()
|
||||||
|
|
82
vorlesung/03_fortgeschrittenes_sortieren/quick_sorting.py
Normal file
82
vorlesung/03_fortgeschrittenes_sortieren/quick_sorting.py
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
from utils.memory_array import MemoryArray
|
||||||
|
from utils.memory_cell import MemoryCell
|
||||||
|
from utils.memory_manager import MemoryManager
|
||||||
|
from utils.memory_range import mrange
|
||||||
|
from utils.literal import Literal
|
||||||
|
|
||||||
|
def quick_sort_stepwise(z: MemoryArray, l: Literal, r: Literal):
|
||||||
|
n = z.length()
|
||||||
|
if l < r:
|
||||||
|
q = partition(z, l, r)
|
||||||
|
yield z
|
||||||
|
yield from quick_sort_stepwise(z, l, q.pred())
|
||||||
|
yield from quick_sort_stepwise(z, q.succ(), r)
|
||||||
|
yield z
|
||||||
|
|
||||||
|
|
||||||
|
def partition(z: MemoryArray, l: Literal, r: Literal):
|
||||||
|
with MemoryCell(z[r]) as pivot, MemoryCell(l) as i, MemoryCell(r.pred()) as j:
|
||||||
|
while i < j:
|
||||||
|
while z[i] < pivot:
|
||||||
|
i.set(i.succ())
|
||||||
|
while j > l and z[j] >= pivot:
|
||||||
|
j.set(j.pred())
|
||||||
|
if i < j:
|
||||||
|
swap(z, int(i), int(j))
|
||||||
|
i.set(i.succ())
|
||||||
|
j.set(j.pred())
|
||||||
|
if i == j and z[i] < pivot:
|
||||||
|
i.set(i.succ())
|
||||||
|
if z[i] != pivot:
|
||||||
|
swap(z, int(i), int(r))
|
||||||
|
return Literal(i)
|
||||||
|
|
||||||
|
|
||||||
|
def quick_sort(z: MemoryArray, l: Literal = None, r: Literal = None):
|
||||||
|
if l is None:
|
||||||
|
l = Literal(0)
|
||||||
|
if r is None:
|
||||||
|
r = z.length().pred()
|
||||||
|
sort_generator = quick_sort_stepwise(z, l, r)
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
next(sort_generator)
|
||||||
|
except StopIteration:
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def sort_file(filename, sort_func):
|
||||||
|
z = MemoryArray.create_array_from_file(filename)
|
||||||
|
sort_func(z)
|
||||||
|
return z
|
||||||
|
|
||||||
|
|
||||||
|
def analyze_complexity(sort_func, sizes, presorted=False):
|
||||||
|
"""
|
||||||
|
Analysiert die Komplexität einer Sortierfunktion.
|
||||||
|
|
||||||
|
:param sort_func: Die Funktion, die analysiert wird.
|
||||||
|
:param sizes: Eine Liste von Eingabegrößen für die Analyse.
|
||||||
|
"""
|
||||||
|
for size in sizes:
|
||||||
|
MemoryManager.purge() # Speicher zurücksetzen
|
||||||
|
if presorted:
|
||||||
|
random_array = MemoryArray.create_sorted_array(size)
|
||||||
|
else:
|
||||||
|
random_array = MemoryArray.create_random_array(size, -100, 100)
|
||||||
|
sort_func(random_array)
|
||||||
|
MemoryManager.save_stats(size)
|
||||||
|
|
||||||
|
MemoryManager.plot_stats(["cells", "compares", "writes"])
|
||||||
|
|
||||||
|
|
||||||
|
def swap(z: MemoryArray, i: int, j: int):
|
||||||
|
tmp = z[Literal(i)].value
|
||||||
|
z[Literal(i)] = z[Literal(j)]
|
||||||
|
z[Literal(j)].set(tmp)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
sizes = range(10, 101, 10)
|
||||||
|
analyze_complexity(quick_sort, sizes)
|
||||||
|
# analyze_complexity(quick_sort, sizes, True)
|
Loading…
x
Reference in New Issue
Block a user