Modify algorithm module to be more common to use

Method exec() is now in base class algorithm and called run().
The algorithm class should now be better to use for various algorithms.
This commit is contained in:
2020-03-09 18:18:52 +01:00
parent 7210a94995
commit f19dcee20b

View File

@@ -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"""