diff --git a/algorithm.py b/algorithm.py index cd44cad..91fb04d 100644 --- a/algorithm.py +++ b/algorithm.py @@ -10,15 +10,14 @@ import point class Algorithm(): - "The Sweep class is the base class for each individual sweep algorithm" - - # pylint: disable=too-many-instance-attributes + "The Algorithm class is the base class for each individual algorithm" def __init__(self): self._input = None # The input values - self._result = None # The result of the sweep + self._result = {} # The result of the sweep self._ready = False # If the sweep is reade to be executed self._running = False # If the sweep is currently running + self._section = "start" # A string that names the current section of the algorithm self._num_steps = {} # The number of steps that were needed to solve the problem def start(self): @@ -28,9 +27,30 @@ class Algorithm(): return False self._running = True return True - def get_result(self): + + def step(self): + """Perform a single step of the algorithm.""" + if self._section: + if self._section in self._num_steps: + self._num_steps[self._section] += 1 + else: + self._num_steps[self._section] = 1 + + def run(self): + """Execute the sweep. Returns the result dict.""" + if not self.start(): + return False + while self._running: + self.step() return self._result + def get_result(self): + """Return the result of the algorithm.""" + return self._result + + def draw(self): + """Dummy for draw method""" + class NearestNeighborsSweep(Algorithm): """Calculate the pair of points inside a set, that have the minimal distance between each @@ -46,35 +66,24 @@ class NearestNeighborsSweep(Algorithm): self._ready = True elif point_set is not None: raise Exception(self, "Wrong input type for point_set") - self._sss = [] + self._sss = {} self._es = [] - self._result = {"Success": False, \ - "MinDistSoFar": None, \ - "Startpoint": None, \ - "Endpoint": None} - - def exec(self): - """Execute the sweep. Returns True on success and False on failure.""" - if not self.start(): - return False - - while self._running: - self.step() - - return self._result + self._result = {"success": False, \ + "distance": None, \ + "points": [None, None]} def start(self): """Start the performing the algorithm. Return True if it was successful""" if not super().start(): return False - self._result["Success"] = False - self._sss = [] + self._result["success"] = False + self._sss = {"mindist": None, \ + "points": []} # Populate event structure self._es = copy.deepcopy(self._input) # Sort the input elements self._num_steps["sort"] = point.sort_point_set(self._es) - self._num_steps["sweep"] = 0 return True def step(self): @@ -82,28 +91,31 @@ class NearestNeighborsSweep(Algorithm): if not self._running: return + self._section = "sweep" + event = self._es.pop(0) - if self._result["MinDistSoFar"] is not None: - while len(self._sss) > 0 and \ - self._sss[0].get_x() <= (event.get_x() - self._result["MinDistSoFar"]): - del self._sss[0] - for pnt in self._sss: - if self._result["MinDistSoFar"] is None: - self._result["MinDistSoFar"] = linesegment.LineSegment(pnt, event).get_length() - elif (event.get_y() - self._result["MinDistSoFar"]) < \ - pnt.get_y() < (event.get_y() + self._result["MinDistSoFar"]): + if self._sss["mindist"] is not None: + while len(self._sss["points"]) > 0 and \ + self._sss["points"][0].get_x() <= (event.get_x() - self._sss["mindist"]): + del self._sss["points"][0] + for pnt in self._sss["points"]: + if self._sss["mindist"] is None: + self._sss["mindist"] = linesegment.LineSegment(pnt, event).get_length() + elif (event.get_y() - self._sss["mindist"]) < \ + pnt.get_y() < (event.get_y() + self._sss["mindist"]): distance = linesegment.LineSegment(pnt, event).get_length() - if self._result["MinDistSoFar"] > distance > 0: - self._result["MinDistSoFar"] = distance - self._result["Startpoint"] = pnt - self._result["Endpoint"] = event - self._num_steps["sweep"] += 1 + if self._sss["mindist"] > distance > 0: + self._sss["mindist"] = distance + self._result["points"][0] = pnt + self._result["points"][1] = event + super().step() - self._sss.append(event) + self._sss["points"].append(event) if len(self._es) == 0: - self._result["Success"] = True + self._result["success"] = True + self._result["distance"] = self._sss["mindist"] self._running = False def get_result_string(self, print_result=False): @@ -111,26 +123,30 @@ class NearestNeighborsSweep(Algorithm): result_string = "" if self._running: result_string = "Sweep is still running." - elif not self._result["Success"]: + elif not self._result["success"]: result_string = "Sweep was not successful." else: result_string = "Sweep successfully completed\n" result_string += " Summary:\n" result_string += " Number of Inputs:" + str(len(self._input)) + "\n" result_string += " Inputs: [" - for pnt in self._input: - result_string += pnt.str() + ", " + for i, pnt in enumerate(self._input): + if i: + result_string += "," + result_string += pnt.str() result_string += "]\n" result_string += " Nearest Neighbors: " - result_string += linesegment.LineSegment(self._result["Startpoint"], \ - self._result["Endpoint"]).str() + result_string += linesegment.LineSegment(self._result["points"][0], \ + self._result["points"][1]).str() result_string += "\n" - result_string += " Distance: " + str(self._result["MinDistSoFar"]) + "\n" + result_string += " Distance: " + str(self._result["distance"]) + "\n" result_string += " Number of steps:\n" result_string += " Sort:" + str(self._num_steps["sort"]) +"\n" result_string += " Sweep:" + str(self._num_steps["sweep"]) +"\n" - if print_result: print(result_string) return result_string + + def draw(self): + """TODO: Draw the algorithm state on a canvas"""