forked from hofmannol/AlgoDatSoSe25
Compare commits
No commits in common. "b3d35519941bf5e44eea0041a75b660cd80223a6" and "38c099a94ec407cc6138f40439cb9cebddd693c3" have entirely different histories.
b3d3551994
...
38c099a94e
2
.idea/AlgoDatSoSe25.iml
generated
2
.idea/AlgoDatSoSe25.iml
generated
@ -5,7 +5,7 @@
|
|||||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||||
</content>
|
</content>
|
||||||
<orderEntry type="jdk" jdkName="Python 3.12 (AlgoDatSoSe25)" jdkType="Python SDK" />
|
<orderEntry type="jdk" jdkName="Python 3.12 (SoSe25)" jdkType="Python SDK" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
@ -1,150 +0,0 @@
|
|||||||
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"])
|
|
||||||
|
|
||||||
|
|
||||||
def analyze_complexity_pop(sizes, presorted=False):
|
|
||||||
"""
|
|
||||||
Analysiert die Komplexität der Pop-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:
|
|
||||||
pq.insert(MemoryCell(insert_value))
|
|
||||||
MemoryManager().reset()
|
|
||||||
pq.pop()
|
|
||||||
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)
|
|
||||||
analyze_complexity_pop(sizes, presorted=True)
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
|||||||
from utils.memory_array import MemoryArray
|
|
||||||
from utils.memory_cell import MemoryCell
|
|
||||||
from utils.memory_manager import MemoryManager
|
|
||||||
from utils.literal import Literal
|
|
||||||
|
|
||||||
def quick_sort_stepwise(z: MemoryArray, l: Literal, r: Literal):
|
|
||||||
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):
|
|
||||||
p = mid_index(z, l, r, Literal((int(l)+int(r))//2))
|
|
||||||
swap(z, p, r)
|
|
||||||
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 mid_index(z: MemoryArray, i1, i2, i3):
|
|
||||||
if z[i1] < z[i2] < z[i3]:
|
|
||||||
return i2
|
|
||||||
elif z[i3] < z[i2] < z[i1]:
|
|
||||||
return i2
|
|
||||||
elif z[i2] < z[i1] < z[i3]:
|
|
||||||
return i1
|
|
||||||
elif z[i3] < z[i1] < z[i2]:
|
|
||||||
return i1
|
|
||||||
else:
|
|
||||||
return i3
|
|
||||||
|
|
||||||
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, 5)
|
|
||||||
analyze_complexity(quick_sort, sizes)
|
|
||||||
analyze_complexity(quick_sort, sizes, True)
|
|
@ -1,15 +0,0 @@
|
|||||||
from utils.memory_cell import MemoryCell
|
|
||||||
|
|
||||||
class BinaryTreeNode(MemoryCell):
|
|
||||||
|
|
||||||
def __init__(self, value):
|
|
||||||
super().__init__(value)
|
|
||||||
self.left = None
|
|
||||||
self.right = None
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return f"BinaryTreeNode(value={self.value}, left={self.left}, right={self.right})"
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return str(self.value)
|
|
||||||
|
|
@ -102,13 +102,6 @@ class MemoryArray:
|
|||||||
a.reset_counters()
|
a.reset_counters()
|
||||||
return a
|
return a
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
result = "[ "
|
|
||||||
for cell in self.cells:
|
|
||||||
result += str(cell) + ", "
|
|
||||||
result += "]"
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import random
|
import random
|
||||||
|
@ -5,6 +5,7 @@ from utils.memory_range import mrange
|
|||||||
from utils.literal import Literal
|
from utils.literal import Literal
|
||||||
|
|
||||||
def quick_sort_stepwise(z: MemoryArray, l: Literal, r: Literal):
|
def quick_sort_stepwise(z: MemoryArray, l: Literal, r: Literal):
|
||||||
|
n = z.length()
|
||||||
if l < r:
|
if l < r:
|
||||||
q = partition(z, l, r)
|
q = partition(z, l, r)
|
||||||
yield z
|
yield z
|
||||||
@ -76,6 +77,6 @@ def swap(z: MemoryArray, i: int, j: int):
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
sizes = range(10, 101, 5)
|
sizes = range(10, 101, 10)
|
||||||
#analyze_complexity(quick_sort, sizes)
|
analyze_complexity(quick_sort, sizes)
|
||||||
analyze_complexity(quick_sort, sizes, True)
|
# analyze_complexity(quick_sort, sizes, True)
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
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 count_sort(a: MemoryArray, b: MemoryArray, k: int):
|
|
||||||
c = MemoryArray(Literal(k + 1))
|
|
||||||
for i in mrange(Literal(k + 1)):
|
|
||||||
c[i].set(Literal(0))
|
|
||||||
|
|
||||||
for j in mrange(a.length()):
|
|
||||||
c[a[j]].set(c[a[j]].succ())
|
|
||||||
|
|
||||||
for i in mrange(Literal(1), Literal(k + 1)):
|
|
||||||
c[i].set(int(c[i]) + int(c[i.pred()]))
|
|
||||||
|
|
||||||
for j in mrange(a.length().pred(), Literal(-1), Literal(-1)):
|
|
||||||
b[c[a[j]].pred()].set(a[j])
|
|
||||||
c[a[j]].set(c[a[j]].pred())
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def analyze_complexity(sizes, presorted=False):
|
|
||||||
"""
|
|
||||||
Analysiert die Komplexität einer Sortierfunktion.
|
|
||||||
|
|
||||||
: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, 0, 100)
|
|
||||||
else:
|
|
||||||
random_array = MemoryArray.create_random_array(size, 0, 100)
|
|
||||||
dest_array = MemoryArray(Literal(size))
|
|
||||||
count_sort(random_array, dest_array, 100)
|
|
||||||
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__':
|
|
||||||
|
|
||||||
# Test the count_sort function
|
|
||||||
a = MemoryArray([2, 5, 3, 0, 2, 3, 0, 3])
|
|
||||||
b = MemoryArray(Literal(len(a)))
|
|
||||||
count_sort(a, b, 5)
|
|
||||||
|
|
||||||
sizes = range(10, 101, 10)
|
|
||||||
analyze_complexity(sizes)
|
|
||||||
# analyze_complexity(sizes, True)
|
|
@ -1,61 +0,0 @@
|
|||||||
import random
|
|
||||||
|
|
||||||
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 binary_search(z: MemoryArray, s: MemoryCell, l: Literal = None, r: Literal = None):
|
|
||||||
"""
|
|
||||||
Perform a binary search on the sorted array z for the value x.
|
|
||||||
"""
|
|
||||||
if l is None:
|
|
||||||
l = Literal(0)
|
|
||||||
if r is None:
|
|
||||||
r = Literal(z.length().pred())
|
|
||||||
if l > r:
|
|
||||||
return None
|
|
||||||
with MemoryCell(l) as m:
|
|
||||||
m += r
|
|
||||||
m //= Literal(2)
|
|
||||||
if s < z[m]:
|
|
||||||
return binary_search(z, s, l, m.pred())
|
|
||||||
elif s > z[m]:
|
|
||||||
return binary_search(z, s, m.succ(), r)
|
|
||||||
else:
|
|
||||||
return m
|
|
||||||
|
|
||||||
|
|
||||||
def analyze_complexity(sizes):
|
|
||||||
"""
|
|
||||||
Analysiert die Komplexität
|
|
||||||
|
|
||||||
:param sizes: Eine Liste von Eingabegrößen für die Analyse.
|
|
||||||
"""
|
|
||||||
for size in sizes:
|
|
||||||
MemoryManager.purge() # Speicher zurücksetzen
|
|
||||||
random_array = MemoryArray.create_sorted_array(size)
|
|
||||||
search_value = random.randint(-100, 100)
|
|
||||||
binary_search(random_array, MemoryCell(search_value))
|
|
||||||
MemoryManager.save_stats(size)
|
|
||||||
|
|
||||||
MemoryManager.plot_stats(["cells", "compares", "adds"])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
# Example usage
|
|
||||||
arr = MemoryArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
|
||||||
search_value = MemoryCell(8)
|
|
||||||
result = binary_search(arr, search_value)
|
|
||||||
if result is not None:
|
|
||||||
print(f"Value {search_value} found at index {result}.")
|
|
||||||
else:
|
|
||||||
print(f"Value {search_value} not found in the array.")
|
|
||||||
|
|
||||||
|
|
||||||
sizes = range(1, 1001, 2)
|
|
||||||
analyze_complexity(sizes)
|
|
Loading…
x
Reference in New Issue
Block a user