import logging logger = logging.getLogger(__name__) # logging.basicConfig(level=logging.DEBUG) import time def timeMS(func, *args, **kwargs): startTime = time.perf_counter() result = func(*args, **kwargs) endTime = time.perf_counter() elapsedMS = (endTime - startTime) * 1000 # Convert to milliseconds print(f"{func.__name__} took {elapsedMS:.2f} ms") return result from utils.memory_array import MemoryArray from utils.memory_cell import MemoryCell from utils.literal import Literal from utils.constants import MIN_VALUE from utils.memory_manager import MemoryManager from utils.memory_range import mrange def example(): initial = [6, 5, 3, 8, 1, 7, 2, 4] # initial = [-6, -5, -3, -8, 1, 7, 2, 4] toSort = MemoryArray(initial) # init_from_size not accessible? sorted = MemoryArray([-1] * len(initial)) mergeSort(toSort, sorted) logger.debug(f"sorted {sorted} vs initial {initial}") assert all(sorted[Literal(i)] == Literal(i+1) for i in range(len(initial))), "Array not sorted correctly" analyze_complexity(mergeSort, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]) def merge(left: MemoryArray, right: MemoryArray, sort: MemoryArray): pointerLeft = MemoryCell(0) pointerRight = MemoryCell(0) pointerSort = MemoryCell(0) compare = lambda x, y: x <= y logger.debug(f"Merging left {left} with right {right} in sort {sort}") while pointerLeft < left.length() and pointerRight < right.length(): if compare(left[pointerLeft], right[pointerRight]): sort[pointerSort] = left[pointerLeft] pointerLeft += Literal(1) else: sort[pointerSort] = right[pointerRight] pointerRight += Literal(1) logger.debug(f"Now are at sort {sort} with {pointerLeft} (l) and {pointerRight} (r)") pointerSort += Literal(1) # Consume remaining elements while pointerLeft < left.length(): logger.debug(f"Consuming left {left} from {pointerSort} at {pointerLeft}") sort[pointerSort] = left[pointerLeft] pointerLeft += Literal(1) pointerSort += Literal(1) while pointerRight < right.length(): logger.debug(f"Consuming right {right} from {pointerSort} at {pointerRight}") sort[pointerSort] = right[pointerRight] pointerRight += Literal(1) pointerSort += Literal(1) # Sort the array passed as "toSort" and place the result in array "sort" # Does not change the original Array def mergeSort(toSort: MemoryArray, sort: MemoryArray): logger.debug(toSort) toSortLength = MemoryCell(toSort.length()) # Splitting # Rec-Term -> Reached single Element. Single Element is already sorted so we place it! if toSortLength <= Literal(1): # still working for empty array if toSortLength == Literal(1): sort[Literal(0)] = toSort[Literal(0)] return # TODO - Use a global var or a reference to an array passed as argument for this # TODO - Tried non-temp-array approach with alternating Work-Arrays passed to the function, but made code really unreadable. Decided not worth it for now # Temporary Arrays to hold the split arrays mid : Literal = toSortLength // Literal(2) left : MemoryArray = MemoryArray([toSort[i] for i in mrange(mid)]) right : MemoryArray = MemoryArray([toSort[i] for i in mrange(mid, toSortLength)]) # Temporary arrays for sorted halves leftSort = MemoryArray([-1] * mid.get()) rightSort = MemoryArray([-1] * (toSortLength - mid).get()) # Split further mergeSort(left, leftSort) mergeSort(right, rightSort) # Recreate the array from the seperated parts merge(leftSort, rightSort, sort) def analyze_complexity(fn, sizes): """ Analysiert die Komplexität einer maximalen Teilfolgenfunktion. :param max_sequence_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 random_array = MemoryArray.create_random_array(size, -100, 100) other_array = MemoryArray([-1] * size) fn(random_array, other_array) MemoryManager.save_stats(size) MemoryManager.plot_stats(["cells", "adds", "compares"]) if __name__ == '__main__': # For debug, assert if working and complexity-analysis # example() for filename in ["data/seq0.txt", "data/seq1.txt", "data/seq2.txt", "data/seq3.txt"]: print(filename) toSort = MemoryArray.create_array_from_file(filename) sorted = MemoryArray([-1] * toSort.length().get()) timeMS(mergeSort, toSort, sorted) # print(sorted)