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 max_sequence_1(z: MemoryArray): n = z.length() m = MemoryCell(MIN_VALUE) s = MemoryCell() l = MemoryCell() r = MemoryCell() for i in mrange(n): for j in mrange(i, n): s.set(0) for k in mrange(i, j): s += z[k] if s > m: m.set(s) l.set(i) r.set(j) return m, l, r def max_sequence_2(z: MemoryArray): n = z.length() m = MemoryCell(MIN_VALUE) s = MemoryCell() l = MemoryCell() r = MemoryCell() for i in mrange(n): s.set(0) for j in mrange(i, n): s += z[j] if s > m: m.set(s) l.set(i) r.set(j) return m, l, r def _max_sequence_3_sub(z: MemoryArray, l: Literal, m: Literal, r: Literal): # find max-sum from Middle to left (including on elem from right) linksMax = MemoryCell(MIN_VALUE) sum = MemoryCell(0) links = MemoryCell(l) rechts = MemoryCell(l) for i in mrange(m, MemoryCell(l)-Literal(1), -1): sum += z[i] if sum > linksMax : linksMax.set(sum) links.set(i) # find max-sum from Middle to right (inluding one elem from left) rechtsMax = MemoryCell(MIN_VALUE) sum.set(0); startRight = MemoryCell(1) + m for i in mrange(startRight, r): sum += z[i] if sum > rechtsMax: rechtsMax.set(sum) rechts.set(i) return (linksMax + rechtsMax), links, rechts def _max_sequence_3(z: MemoryArray, l: Literal, r: Literal): # Calc-Vars -> illegal to use Literal(0) here? Probably linksMax = MemoryCell() linksL = MemoryCell() linksR = MemoryCell() rechtsMax = MemoryCell() rechtsL = MemoryCell() rechtsR = MemoryCell() zwiMax = MemoryCell() zwiL = MemoryCell() zwiR = MemoryCell() # Middle m = MemoryCell() # Rec-Term - Reached subarray of size 1 if l == r: return (z[l], l, r) # calc middle m.set(MemoryCell(l) + r) m /= Literal(2); # get maxLeft, then maxRight and then cross them (rec) (linksMax, linksL, linksR) = _max_sequence_3(z, l, m) startRight = MemoryCell(1) + m (rechtsMax, rechtsL, rechtsR) = _max_sequence_3(z, startRight, r) (zwiMax, zwiL, zwiR) = _max_sequence_3_sub(z, l, m, r) if linksMax >= rechtsMax and linksMax >= zwiMax: return (linksMax, linksL, linksR) if rechtsMax >= linksMax and rechtsMax >= zwiMax: return (rechtsMax, rechtsL, rechtsR) return (zwiMax, zwiL, zwiR) # Wrapper for Seq DivAndConquer to keep call/teststructure possible def max_sequence_3(z: MemoryArray): # Start with full range lstart = Literal(0) rend = Literal(len(z) - 1) return _max_sequence_3(z, lstart, rend) def example(max_sequence_func): l = [-59, 52, 46, 14, -50, 58, -87, -77, 34, 15] print(l) z = MemoryArray(l) m, l, r = max_sequence_func(z) print(m, l, r) assert(m == Literal(120)) def seq(filename, max_sequence_func): z = MemoryArray.create_array_from_file(filename) m, l, r = max_sequence_func(z) print(m, l, r) def analyze_complexity(max_sequence_func, 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) max_sequence_func(random_array) MemoryManager.save_stats(size) MemoryManager.plot_stats(["cells", "adds"]) if __name__ == '__main__': fn = max_sequence_3 example(fn) for filename in ["data/seq0.txt", "data/seq1.txt", "data/seq2.txt"]: print(filename) seq(filename, fn) analyze_complexity(fn, [10, 20, 30, 40, 50, 60, 70, 80, 90, 100])