Created
September 2, 2016 16:35
-
-
Save PythonJedi/6b26bbfc30674c37128a363271790fcb to your computer and use it in GitHub Desktop.
python version of max subarray solution
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/python3 | |
import random | |
# A quick test of a linear max subarray algorithm | |
class Partial: | |
"""Named collection corresponding to a partial sum of a sequence of deltas""" | |
def __init__(self, value, index): | |
self.value = value | |
self.index = index | |
class Subarray: | |
"""Named collection corresponding to a subarray and its sum. | |
Convenience to keep all the values straight.""" | |
def __init__(self, diff, start, end): | |
"""Usual python index semantics: start is inclusive, end exclusive.""" | |
self.diff = diff | |
self.start = start | |
self.end = end | |
def copy(self): | |
"""Avoid aliasing issues.""" | |
return Subarray(self.diff, self.start, self.end) | |
def __str__(self): | |
return "Difference of "+str(self.diff)+" from ["+str(self.start)+", "+str(self.end)+")" | |
def partials(deltas): | |
"""Return the running partial sums from a sequence of deltas. | |
Linear with respect to deltas.""" | |
running = 0 | |
index = 0 | |
for d in deltas: | |
running += d | |
yield Partial(running, index) | |
index += 1 | |
def max_subarray(deltas): | |
"""a linear maximal subarray algorithm for a finite sequence of deltas.""" | |
max = Subarray(0, 0, 0) | |
current = Subarray(0, 0, 0) | |
prev = None | |
for p in partials(deltas): | |
# inital element | |
if prev == None: | |
prev = p | |
continue # need to init prev | |
# Update eager current | |
current.diff += (p.value - prev.value) | |
current.end = p.index | |
prev = p | |
# Update lazy max if current has exceeded it | |
if current.diff > max.diff: | |
max = current.copy() | |
# Move eager current forward if it becomes negative or 0 | |
if current.diff <= 0: | |
current = Subarray(0, p.index, p.index) | |
return max | |
def n_rands(n, size): | |
for i in range(n): | |
yield random.randrange(-size, size) | |
if __name__ == "__main__": | |
data = list(n_rands(500, 100)) | |
print("Data: "+str(data)) | |
print("Max: "+str(max_subarray(data))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment