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