From d14a5c9241183e60cf166434a29c8d4e354fade8 Mon Sep 17 00:00:00 2001 From: ajnebro Date: Thu, 28 Sep 2017 16:55:59 +0200 Subject: [PATCH 01/90] Minor changes --- jmetal/core/algorithm.py | 1 - 1 file changed, 1 deletion(-) diff --git a/jmetal/core/algorithm.py b/jmetal/core/algorithm.py index 0f0dc86d..d8d1ff11 100644 --- a/jmetal/core/algorithm.py +++ b/jmetal/core/algorithm.py @@ -39,7 +39,6 @@ def __init__(self, evaluator: Evaluator[S] = SequentialEvaluator[S]()): def create_initial_population(self) -> List[S]: pass - def evaluate_population(self, population: List[S]) -> List[S]: pass From 87d8b7ee7e2dd457d737ae6abb7c84b02785833a Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 24 Apr 2018 11:58:43 +0200 Subject: [PATCH 02/90] Delete class Objective and refactor problems --- jmetal/core/objective.py | 13 -- jmetal/core/problem.py | 6 +- jmetal/problem/multiobjective/constrained.py | 56 ++---- jmetal/problem/multiobjective/dtlz.py | 9 - .../multiobjective/test/test_constrained.py | 1 + .../multiobjective/test/test_unconstrained.py | 7 +- .../problem/multiobjective/test/test_zdt.py | 1 + .../problem/multiobjective/unconstrained.py | 94 +++------- jmetal/problem/multiobjective/zdt.py | 176 +++++++----------- 9 files changed, 129 insertions(+), 234 deletions(-) delete mode 100644 jmetal/core/objective.py diff --git a/jmetal/core/objective.py b/jmetal/core/objective.py deleted file mode 100644 index 5682eb5d..00000000 --- a/jmetal/core/objective.py +++ /dev/null @@ -1,13 +0,0 @@ - -from jmetal.core.problem import Problem -from jmetal.core.solution import Solution - -__author__ = "Antonio J. Nebro" - - -class Objective: - def compute(self, solution: Solution, problem: Problem) -> float: - pass - - def is_a_minimization_objective(self) -> bool: - return True diff --git a/jmetal/core/problem.py b/jmetal/core/problem.py index 056ea7a9..3ca0e4a4 100644 --- a/jmetal/core/problem.py +++ b/jmetal/core/problem.py @@ -19,11 +19,7 @@ def __init__(self): self.number_of_constraints: int = None def evaluate(self, solution: S) -> None: - for i in range(self.number_of_objectives): - if self.objectives[i].is_a_minimization_objective(): - solution.objectives[i] = self.objectives[i].compute(solution, self) - else: - solution.objectives[i] = -1.0 * self.objectives[i].compute(solution, self) + pass def evaluate_constraints(self, solution: S): pass diff --git a/jmetal/problem/multiobjective/constrained.py b/jmetal/problem/multiobjective/constrained.py index 683cd0b4..9b869bf2 100644 --- a/jmetal/problem/multiobjective/constrained.py +++ b/jmetal/problem/multiobjective/constrained.py @@ -1,7 +1,6 @@ from math import pi, cos, atan """ Unconstrained Test problems for multi-objective optimization """ -from jmetal.core.objective import Objective from jmetal.core.solution import FloatSolution from jmetal.core.problem import FloatProblem @@ -10,37 +9,28 @@ class Srinivas(FloatProblem): """ Class representing problem Srinivas """ def __init__(self): - self.objectives = [self.Objective1(), self.Objective2()] - - self.number_of_objectives = len(self.objectives) + self.number_of_objectives = 2 self.number_of_variables = 2 self.number_of_constraints = 2 - self.lower_bound = [-20.0 for i in range(self.number_of_variables)] - self.upper_bound = [20.0 for i in range(self.number_of_variables)] + self.lower_bound = [-20.0 for _ in range(self.number_of_variables)] + self.upper_bound = [20.0 for _ in range(self.number_of_variables)] FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def get_name(self): - return "Srinivas" - - class Objective1(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - x1 = solution.variables[0] - x2 = solution.variables[1] - - return 2.0 + (x1 - 2.0) * (x1 - 2.0) + (x2 - 1.0) * (x2 - 1.0) + def evaluate(self, solution: FloatSolution): + x1 = solution.variables[0] + x2 = solution.variables[1] - class Objective2(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - x1 = solution.variables[0] - x2 = solution.variables[1] + solution.objectives[0] = 2.0 + (x1 - 2.0) * (x1 - 2.0) + (x2 - 1.0) * (x2 - 1.0) + solution.objectives[1] = 9.0 * x1 - (x2 - 1.0) * (x2 - 1.0) - return 9.0 * x1 - (x2 - 1.0) * (x2 - 1.0) + def get_name(self): + return "Srinivas" def evaluate_constraints(self, solution: FloatSolution) -> None: - constraints : [float] = [0.0 for x in range(self.number_of_constraints)] + constraints : [float] = [0.0 for _ in range(self.number_of_constraints)] x1 = solution.variables[0] x2 = solution.variables[1] @@ -63,28 +53,19 @@ def evaluate_constraints(self, solution: FloatSolution) -> None: class Tanaka(FloatProblem): """ Class representing problem Tanaka """ def __init__(self): - self.objectives = [self.Objective1(), self.Objective2()] - - self.number_of_objectives = len(self.objectives) + self.number_of_objectives = 2 self.number_of_variables = 2 self.number_of_constraints = 2 - self.lower_bound = [10e-5 for i in range(self.number_of_variables)] - self.upper_bound = [pi for i in range(self.number_of_variables)] + self.lower_bound = [10e-5 for _ in range(self.number_of_variables)] + self.upper_bound = [pi for _ in range(self.number_of_variables)] FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def get_name(self): - return "Tanaka" - - class Objective1(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - return solution.variables[0] - - class Objective2(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - return solution.variables[1] + def evaluate(self, solution: FloatSolution): + solution.objectives[0] = solution.variables[0] + solution.objectives[1] = solution.variables[1] def evaluate_constraints(self, solution: FloatSolution) -> None: constraints : [float] = [0.0 for x in range(self.number_of_constraints)] @@ -106,3 +87,6 @@ def evaluate_constraints(self, solution: FloatSolution) -> None: solution.attributes["overall_constraint_violation"] = overall_constraint_violation solution.attributes["number_of_violated_constraints"] = number_of_violated_constraints + def get_name(self): + return "Tanaka" + diff --git a/jmetal/problem/multiobjective/dtlz.py b/jmetal/problem/multiobjective/dtlz.py index d4944f9e..bfb6f6bd 100644 --- a/jmetal/problem/multiobjective/dtlz.py +++ b/jmetal/problem/multiobjective/dtlz.py @@ -25,7 +25,6 @@ from math import pi, cos -from jmetal.core.objective import Objective from jmetal.core.problem import FloatProblem from jmetal.core.solution import FloatSolution @@ -46,8 +45,6 @@ def __init__(self, number_of_variables: int = 30, number_of_objectives = 3): :param number_of_variables: number of decision variables of the problem """ - self.objectives = [self.Dtlz1Objective() for i in range(number_of_objectives)] - self.number_of_variables = number_of_variables self.number_of_objectives = number_of_objectives self.number_of_constraints = 0 @@ -58,10 +55,6 @@ def __init__(self, number_of_variables: int = 30, number_of_objectives = 3): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - class Dtlz1Objective(Objective): - def is_a_minimization_objective(self): - return True - def evaluate(self, solution: FloatSolution): g = 0.0 k = self.number_of_variables - self.number_of_objectives + 1 @@ -83,5 +76,3 @@ def evaluate(self, solution: FloatSolution): def get_name(self): return "DTLZ1" - - diff --git a/jmetal/problem/multiobjective/test/test_constrained.py b/jmetal/problem/multiobjective/test/test_constrained.py index 1117beee..55af5e3d 100644 --- a/jmetal/problem/multiobjective/test/test_constrained.py +++ b/jmetal/problem/multiobjective/test/test_constrained.py @@ -71,5 +71,6 @@ def test_should_get_name_return_the_right_name(self): problem = Tanaka() self.assertEqual("Tanaka", problem.get_name()) + if __name__ == '__main__': unittest.main() diff --git a/jmetal/problem/multiobjective/test/test_unconstrained.py b/jmetal/problem/multiobjective/test/test_unconstrained.py index 8427b36f..e8deda63 100644 --- a/jmetal/problem/multiobjective/test/test_unconstrained.py +++ b/jmetal/problem/multiobjective/test/test_unconstrained.py @@ -198,13 +198,14 @@ def test_should_create_solution_return_right_evaluation_values(self): problem.evaluate(solution2) - self.assertAlmostEqual(solution2.objectives[0], 14.0607692307); - self.assertAlmostEqual(solution2.objectives[1], -11.8818055555); - self.assertAlmostEqual(solution2.objectives[2], -11.1532369747); + self.assertAlmostEqual(solution2.objectives[0], 14.0607692307) + self.assertAlmostEqual(solution2.objectives[1], -11.8818055555) + self.assertAlmostEqual(solution2.objectives[2], -11.1532369747) def test_should_get_name_return_the_right_name(self): problem = Viennet2() self.assertEqual("Viennet2", problem.get_name()) + if __name__ == '__main__': unittest.main() diff --git a/jmetal/problem/multiobjective/test/test_zdt.py b/jmetal/problem/multiobjective/test/test_zdt.py index 98f07919..929bc542 100644 --- a/jmetal/problem/multiobjective/test/test_zdt.py +++ b/jmetal/problem/multiobjective/test/test_zdt.py @@ -232,5 +232,6 @@ def test_should_get_name_return_the_right_name(self): problem = ZDT6() self.assertEqual("ZDT6", problem.get_name()) + if __name__ == '__main__': unittest.main() diff --git a/jmetal/problem/multiobjective/unconstrained.py b/jmetal/problem/multiobjective/unconstrained.py index 0c83441d..8b5843e8 100644 --- a/jmetal/problem/multiobjective/unconstrained.py +++ b/jmetal/problem/multiobjective/unconstrained.py @@ -1,22 +1,20 @@ from math import sqrt, exp, pow, sin -from jmetal.core.objective import Objective from jmetal.core.problem import FloatProblem from jmetal.core.solution import FloatSolution """ Unconstrained Test problems for multi-objective optimization """ + class Kursawe(FloatProblem): """ Class representing problem Kursawe """ def __init__(self, number_of_variables: int = 3): - self.objectives = [self.Objective1(), self.Objective2()] - - self.number_of_objectives = len(self.objectives) + self.number_of_objectives = 2 self.number_of_variables = number_of_variables self.number_of_constraints = 0 - self.lower_bound = [-5.0 for i in range(number_of_variables)] - self.upper_bound = [5.0 for i in range(number_of_variables)] + self.lower_bound = [-5.0 for _ in range(number_of_variables)] + self.upper_bound = [5.0 for _ in range(number_of_variables)] FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound @@ -24,30 +22,21 @@ def __init__(self, number_of_variables: int = 3): def get_name(self): return "Kursawe" - class Objective1(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - fx = 0.0 - for i in range(problem.number_of_variables - 1): - xi = solution.variables[i] * solution.variables[i] - xj = solution.variables[i + 1] * solution.variables[i + 1] - aux = -0.2 * sqrt(xi + xj) - fx += -10 * exp(aux) - - return fx + def evaluate(self, solution: FloatSolution): + fx = [0.0 for _ in range(self.number_of_objectives)] + for i in range(self.number_of_variables): + xi = solution.variables[i] * solution.variables[i] + xj = solution.variables[i + 1] * solution.variables[i + 1] + aux = -0.2 * sqrt(xi + xj) + fx[0] += -10 * exp(aux) + fx[1] += pow(abs(solution.variables[i]), 0.8) + 5.0 * sin(pow(solution.variables[i], 3.0)) - class Objective2(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - fx = 0.0 - for i in range(problem.number_of_variables): - fx += pow(abs(solution.variables[i]), 0.8) + 5.0 * sin(pow(solution.variables[i], 3.0)) - - return fx + solution.objectives[0] = fx[0] + solution.objectives[1] = fx[1] class Fonseca(FloatProblem): def __init__(self): - self.objectives = [self.Objective1(), self.Objective2()] - self.number_of_variables = 3 self.number_of_objectives = 2 self.number_of_constraints = 0 @@ -61,22 +50,14 @@ def __init__(self): def get_name(self): return "Fonseca" - class Objective1(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - n = problem.number_of_variables - - return 1 - exp(-sum([(x - 1.0 / n ** 0.5) ** 2 for x in solution.variables])) + def evaluate(self, solution: FloatSolution): + n = self.number_of_variables + solution.objectives[0] = 1 - exp(-sum([(x - 1.0 / n ** 0.5) ** 2 for x in solution.variables])) + solution.objectives[1] = 1 - exp(-sum([(x + 1.0 / n ** 0.5) ** 2 for x in solution.variables])) - class Objective2(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - n = problem.number_of_variables - - return 1 - exp(-sum([(x + 1.0 / n ** 0.5) ** 2 for x in solution.variables])) class Schaffer(FloatProblem): def __init__(self): - self.objectives = [self.Objective1(), self.Objective2()] - self.number_of_variables = 1 self.number_of_objectives = 2 self.number_of_constraints = 0 @@ -90,19 +71,15 @@ def __init__(self): def get_name(self): return "Schaffer" - class Objective1(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - return solution.variables[0] ** 2 + def evaluate(self, solution: FloatSolution): + value = solution.variables[0] - class Objective2(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - return (solution.variables[0] - 2.0) ** 2 + solution.objectives[0] = value ** 2 + solution.objectives[1] = (value - 2) ** 2 class Viennet2(FloatProblem): def __init__(self): - self.objectives = [self.Objective1(), self.Objective2(), self.Objective3()] - self.number_of_variables = 2 self.number_of_objectives = 3 self.number_of_constraints = 0 @@ -116,23 +93,14 @@ def __init__(self): def get_name(self): return "Viennet2" - class Objective1(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - x0 = solution.variables[0] - x1 = solution.variables[1] - - return (x0 - 2) * (x0 - 2) / 2.0 + (x1 + 1) * (x1 + 1) / 13.0 + 3.0 - - class Objective2(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - x0 = solution.variables[0] - x1 = solution.variables[1] - - return (x0 + x1 - 3.0) * (x0 + x1 - 3.0) / 36.0 + (-x0 + x1 + 2.0) * (-x0 + x1 + 2.0) / 8.0 - 17.0 + def evaluate(self, solution: FloatSolution): + x0 = solution.variables[0] + x1 = solution.variables[1] - class Objective3(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - x0 = solution.variables[0] - x1 = solution.variables[1] + f1 = (x0 - 2) * (x0 - 2) / 2.0 + (x1 + 1) * (x1 + 1) / 13.0 + 3.0 + f2 = (x0 + x1 - 3.0) * (x0 + x1 - 3.0) / 36.0 + (-x0 + x1 + 2.0) * (-x0 + x1 + 2.0) / 8.0 - 17.0 + f3 = (x0 + 2 * x1 - 1) * (x0 + 2 * x1 - 1) / 175.0 + (2 * x1 - x0) * (2 * x1 - x0) / 17.0 - 13.0 - return (x0 + 2 * x1 - 1) * (x0 + 2 * x1 - 1) / 175.0 + (2 * x1 - x0) * (2 * x1 - x0) / 17.0 - 13.0 + solution.objectives[0] = f1 + solution.objectives[1] = f2 + solution.objectives[2] = f3 \ No newline at end of file diff --git a/jmetal/problem/multiobjective/zdt.py b/jmetal/problem/multiobjective/zdt.py index 7e0ded61..1b29532c 100644 --- a/jmetal/problem/multiobjective/zdt.py +++ b/jmetal/problem/multiobjective/zdt.py @@ -27,7 +27,6 @@ from math import sqrt, exp, pow, sin, pi, cos -from jmetal.core.objective import Objective from jmetal.core.problem import FloatProblem from jmetal.core.solution import FloatSolution @@ -47,10 +46,8 @@ def __init__(self, number_of_variables: int = 30): :param number_of_variables: number of decision variables of the problem """ - self.objectives = [self.Objective1(), self.Objective2()] - self.number_of_variables = number_of_variables - self.number_of_objectives = len(self.objectives) + self.number_of_objectives = 2 self.number_of_constraints = 0 self.lower_bound = self.number_of_variables * [0.0] @@ -59,29 +56,23 @@ def __init__(self, number_of_variables: int = 30): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - class Objective1(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - return solution.variables[0] - - class Objective2(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - g = self.__eval_g(solution) - h = self.__eval_h(solution.variables[0], g) + def evaluate(self, solution: FloatSolution): + g = self.__eval_g(solution) + h = self.__eval_h(solution.variables[0], g) - return h * g + solution.objectives[0] = solution.variables[0] + solution.objectives[1] = h * g - @staticmethod - def __eval_g(solution: FloatSolution): - g = sum(solution.variables) - solution.variables[0] + def __eval_g(self, solution: FloatSolution): + g = sum(solution.variables) - solution.variables[0] - constant = 9.0 / (solution.number_of_variables - 1) - g = constant * g - g = g + 1.0 - return g + constant = 9.0 / (solution.number_of_variables - 1) + g = constant * g + g = g + 1.0 + return g - @staticmethod - def __eval_h(f: float, g: float) -> float: - return 1.0 - sqrt(f/g) + def __eval_h(self, f: float, g: float) -> float: + return 1.0 - sqrt(f / g) def get_name(self): return "ZDT1" @@ -96,10 +87,8 @@ class ZDT2(FloatProblem): """ def __init__(self, number_of_variables: int = 30): - self.objectives = [self.Objective1(), self.Objective2()] - self.number_of_variables = number_of_variables - self.number_of_objectives = len(self.objectives) + self.number_of_objectives = 2 self.number_of_constraints = 0 self.lower_bound = self.number_of_variables * [0.0] @@ -108,27 +97,23 @@ def __init__(self, number_of_variables: int = 30): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - class Objective1(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - return solution.variables[0] + def evaluate(self, solution: FloatSolution): + g = self.__eval_g(solution) + h = self.__eval_h(solution.variables[0], g) - class Objective2(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - g = self.__eval_g(solution) - h = self.__eval_h(solution.variables[0], g) + solution.objectives[0] = solution.variables[0] + solution.objectives[1] = h * g - return h * g + def __eval_g(self, solution: FloatSolution): + g = sum(solution.variables) - solution.variables[0] - def __eval_g(self, solution: FloatSolution): - g = sum(solution.variables) - solution.variables[0] + constant = 9.0 / (solution.number_of_variables - 1) + g = constant * g + g = g + 1.0 + return g - constant = 9.0 / (solution.number_of_variables - 1) - g = constant * g - g = g + 1.0 - return g - - def __eval_h(self, f: float, g: float) -> float: - return 1.0 - pow(f / g, 2.0) + def __eval_h(self, f: float, g: float) -> float: + return 1.0 - pow(f / g, 2.0) def get_name(self): return "ZDT2" @@ -143,10 +128,8 @@ class ZDT3(FloatProblem): """ def __init__(self, number_of_variables: int = 30): - self.objectives = [self.Objective1(), self.Objective2()] - self.number_of_variables = number_of_variables - self.number_of_objectives = len(self.objectives) + self.number_of_objectives = 2 self.number_of_constraints = 0 self.lower_bound = self.number_of_variables * [0.0] @@ -155,27 +138,23 @@ def __init__(self, number_of_variables: int = 30): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - class Objective1(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - return solution.variables[0] + def evaluate(self, solution: FloatSolution): + g = self.__eval_g(solution) + h = self.__eval_h(solution.variables[0], g) - class Objective2(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - g = self.__eval_g(solution) - h = self.__eval_h(solution.variables[0], g) + solution.objectives[0] = solution.variables[0] + solution.objectives[1] = h * g - return h * g + def __eval_g(self, solution: FloatSolution): + g = sum(solution.variables) - solution.variables[0] - def __eval_g(self, solution: FloatSolution): - g = sum(solution.variables) - solution.variables[0] + constant = 9.0 / (solution.number_of_variables - 1) + g = constant * g + g = g + 1.0 + return g - constant = 9.0 / (solution.number_of_variables - 1) - g = constant * g - g = g + 1.0 - return g - - def __eval_h(self, f: float, g: float) -> float: - return 1.0 - sqrt(f / g) - (f / g) * sin(10.0 * f * pi) + def __eval_h(self, f: float, g: float) -> float: + return 1.0 - sqrt(f / g) - (f / g) * sin(10.0 * f * pi) def get_name(self): return "ZDT3" @@ -190,10 +169,8 @@ class ZDT4(FloatProblem): """ def __init__(self, number_of_variables: int = 10): - self.objectives = [self.Objective1(), self.Objective2()] - self.number_of_variables = number_of_variables - self.number_of_objectives = len(self.objectives) + self.number_of_objectives = 2 self.number_of_constraints = 0 self.lower_bound = self.number_of_variables * [-5.0] @@ -204,29 +181,25 @@ def __init__(self, number_of_variables: int = 10): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - class Objective1(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - return solution.variables[0] - - class Objective2(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - g = self.__eval_g(solution) - h = self.__eval_h(solution.variables[0], g) + def evaluate(self, solution: FloatSolution): + g = self.__eval_g(solution) + h = self.__eval_h(solution.variables[0], g) - return h * g + solution.objectives[0] = solution.variables[0] + solution.objectives[1] = h * g - def __eval_g(self, solution: FloatSolution): - g = 0.0 + def __eval_g(self, solution: FloatSolution): + g = 0.0 - for i in range(1, solution.number_of_variables): - g += pow(solution.variables[i], 2.0) - 10.0 * cos(4.0 * pi * solution.variables[i]) + for i in range(1, solution.number_of_variables): + g += pow(solution.variables[i], 2.0) - 10.0 * cos(4.0 * pi * solution.variables[i]) - g += 1.0 + 10.0 * (solution.number_of_variables - 1) + g += 1.0 + 10.0 * (solution.number_of_variables - 1) - return g + return g - def __eval_h(self, f: float, g: float) -> float: - return 1.0 - sqrt(f / g) + def __eval_h(self, f: float, g: float) -> float: + return 1.0 - sqrt(f / g) def get_name(self): return "ZDT4" @@ -241,10 +214,8 @@ class ZDT6(FloatProblem): """ def __init__(self, number_of_variables: int = 10): - self.objectives = [self.Objective1(), self.Objective2()] - self.number_of_variables = number_of_variables - self.number_of_objectives = len(self.objectives) + self.number_of_objectives = 2 self.number_of_constraints = 0 self.lower_bound = self.number_of_variables * [0.0] @@ -253,29 +224,24 @@ def __init__(self, number_of_variables: int = 10): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - class Objective1(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - return 1.0 - exp((-4.0) * solution.variables[0]) \ - * pow(sin(6.0 * pi * solution.variables[0]), 6.0) - - class Objective2(Objective): - def compute(self, solution: FloatSolution, problem: FloatProblem): - g = self.__eval_g(solution) - h = self.__eval_h(solution.objectives[0], g) + def evaluate(self, solution: FloatSolution): + g = self.__eval_g(solution) + h = self.__eval_h(solution.variables[0], g) - return h * g + solution.objectives[0] = solution.variables[0] + solution.objectives[1] = h * g - def __eval_g(self, solution: FloatSolution): - g = sum(solution.variables) - solution.variables[0] - g = g / (solution.number_of_variables - 1) - g = pow(g, 0.25) - g = 9.0 * g - g = 1.0 + g + def __eval_g(self, solution: FloatSolution): + g = sum(solution.variables) - solution.variables[0] + g = g / (solution.number_of_variables - 1) + g = pow(g, 0.25) + g = 9.0 * g + g = 1.0 + g - return g + return g - def __eval_h(self, f: float, g: float) -> float: - return 1.0 - pow(f / g, 2.0) + def __eval_h(self, f: float, g: float) -> float: + return 1.0 - pow(f / g, 2.0) def get_name(self): return "ZDT6" From 0963baf56216f099c04bf3386152156a4ab7fce8 Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 24 Apr 2018 12:40:30 +0200 Subject: [PATCH 03/90] Fixed index error --- jmetal/problem/multiobjective/unconstrained.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/jmetal/problem/multiobjective/unconstrained.py b/jmetal/problem/multiobjective/unconstrained.py index 8b5843e8..0bbce645 100644 --- a/jmetal/problem/multiobjective/unconstrained.py +++ b/jmetal/problem/multiobjective/unconstrained.py @@ -24,7 +24,7 @@ def get_name(self): def evaluate(self, solution: FloatSolution): fx = [0.0 for _ in range(self.number_of_objectives)] - for i in range(self.number_of_variables): + for i in range(self.number_of_variables - 1): xi = solution.variables[i] * solution.variables[i] xj = solution.variables[i + 1] * solution.variables[i + 1] aux = -0.2 * sqrt(xi + xj) @@ -103,4 +103,4 @@ def evaluate(self, solution: FloatSolution): solution.objectives[0] = f1 solution.objectives[1] = f2 - solution.objectives[2] = f3 \ No newline at end of file + solution.objectives[2] = f3 From d78ae88f1a5f043ebb31d206e5e5827e22fee114 Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 24 Apr 2018 13:00:08 +0200 Subject: [PATCH 04/90] Added SMPSO algorithm --- jmetal/algorithm/multiobjective/smpso.py | 107 +++++++++--------- .../multiobjective/smpso_standard_settings.py | 13 ++- 2 files changed, 63 insertions(+), 57 deletions(-) diff --git a/jmetal/algorithm/multiobjective/smpso.py b/jmetal/algorithm/multiobjective/smpso.py index 3bbccc0b..05560d39 100644 --- a/jmetal/algorithm/multiobjective/smpso.py +++ b/jmetal/algorithm/multiobjective/smpso.py @@ -1,5 +1,6 @@ from copy import copy -from random import Random +import random +from math import sqrt from typing import TypeVar, List import numpy @@ -29,7 +30,7 @@ def __init__(self, self.problem = problem self.swarm_size = swarm_size self.max_evaluations = max_evaluations - self.mutation : Mutation[FloatSolution] = mutation + self.mutation: Mutation[FloatSolution] = mutation self.leaders = leaders self.observable = observable self.evaluator = evaluator @@ -40,7 +41,10 @@ def __init__(self, self.c1_max = 2.5 self.c2_min = 1.5 self.c2_max = 2.5 - + self.r1_min = 0.0 + self.r1_max = 1.0 + self.r2_min = 0.0 + self.r2_max = 1.0 self.min_weight = 0.1 self.max_weight = 0.1 @@ -50,24 +54,25 @@ def __init__(self, self.dominance_comparator = DominanceComparator() self.speed = numpy.zeros((self.swarm_size, self.problem.number_of_variables), dtype=float) - self.delta_max = numpy.empty(problem.number_of_variables) - self.delta_min = numpy.empty(problem.number_of_variables) + self.delta_max, self.delta_min = numpy.empty(problem.number_of_variables),\ + numpy.empty(problem.number_of_variables) for i in range(problem.number_of_variables): self.delta_max[i] = (self.problem.upper_bound[i] - self.problem.lower_bound[i]) / 2.0 self.delta_min = -1.0 * self.delta_max - def init_progress(self) -> None : + def init_progress(self) -> None: self.evaluations = self.swarm_size self.leaders.compute_density_estimator() - def update_progress(self) -> None : + def update_progress(self) -> None: self.evaluations += self.swarm_size self.leaders.compute_density_estimator() observable_data = {'evaluations': self.evaluations, - 'population': self.swarm, + 'population': self.leaders.solution_list, 'computing time': self.get_current_computing_time()} + self.observable.notify_all(**observable_data) def is_stopping_condition_reached(self) -> bool: @@ -75,54 +80,52 @@ def is_stopping_condition_reached(self) -> bool: def create_initial_swarm(self) -> List[FloatSolution]: swarm = [] - - for i in range(self.swarm_size): + for _ in range(self.swarm_size): swarm.append(self.problem.create_solution()) - return swarm def evaluate_swarm(self, swarm: List[FloatSolution]) -> List[FloatSolution]: return self.evaluator.evaluate(swarm, self.problem) def initialize_global_best(self, swarm: List[FloatSolution]) -> None: - for particle in self.swarm: + for particle in swarm: self.leaders.add(particle) def initialize_particle_best(self, swarm: List[FloatSolution]) -> None: - for particle in self.swarm: + for particle in swarm: particle.attributes["local_best"] = copy(particle) def initialize_velocity(self, swarm: List[FloatSolution]) -> None: - pass # Velocity initialized in the constructor + pass # Velocity initialized in the constructor def update_velocity(self, swarm: List[FloatSolution]) -> None: for i in range(self.swarm_size): - particle = copy(self.swarm[i]) - best_particle = copy(self.swarm[i].attributes["local_best"]) + best_particle = copy(swarm[i].attributes["local_best"]) best_global = self.__select_global_best() - r1 = Random.random() - r2 = Random.random() - - c1 = Random.uniform(self.c1_min, self.c1_max) - c2 = Random.uniform(self.c2_min, self.c2_max) - - wmin = self.min_weight + r1 = round(random.uniform(self.r1_min, self.r1_max), 1) + r2 = round(random.uniform(self.r2_min, self.r2_max), 1) + c1 = round(random.uniform(self.c1_min, self.c1_max), 1) + c2 = round(random.uniform(self.c2_min, self.c2_max), 1) wmax = self.max_weight + wmin = self.min_weight - for var in range(self.problem.number_of_variables): + for var in range(swarm[i].number_of_variables): self.speed[i][var] = \ - self.__velocity_constriction(self.__constriction_coefficient(c1, c2) * \ - (wmax * self.speed[i][var] + - c1 * r1 * (best_particle.variables[var] - particle.variables[var]) + - c2 * r2 * (best_global.variables[var] - particle.variables[var])), - var) + self.__velocity_constriction( + self.__constriction_coefficient(c1, c2) * + ((self.__inertia_weight(self.evaluations, self.max_evaluations, wmax, wmin) + * self.speed[i][var]) + + (c1 * r1 * (best_particle.variables[var] - swarm[i].variables[var])) + + (c2 * r2 * (best_global.variables[var] - swarm[i].variables[var])) + ), + self.delta_max, self.delta_min, var) def update_position(self, swarm: List[FloatSolution]) -> None: for i in range(self.swarm_size): - particle = self.swarm[i] + particle = swarm[i] - for j in particle.variables: + for j in range(particle.number_of_variables): particle.variables[j] += self.speed[i][j] if particle.variables[j] < self.problem.lower_bound[j]: @@ -134,30 +137,27 @@ def update_position(self, swarm: List[FloatSolution]) -> None: self.speed[i][j] *= self.change_velocity2 def perturbation(self, swarm: List[FloatSolution]) -> None: - for particle in self.swarm: - self.mutation.execute(particle) + for i in range(self.swarm_size): + if (i % 6) == 0: + self.mutation.execute(swarm[i]) def update_global_best(self, swarm: List[FloatSolution]) -> None: - for particle in self.swarm: + for particle in swarm: self.leaders.add(copy(particle)) def update_particle_best(self, swarm: List[FloatSolution]) -> None: for i in range(self.swarm_size): flag = self.dominance_comparator.compare( - self.swarm[i], - self.swarm[i].attribute["local_best"]) - - if flag is not 1: - swarm[i].attributes["local_best"] = copy(self.swarm[i]) + swarm[i], + swarm[i].attributes["local_best"]) + if flag != 1: + swarm[i].attributes["local_best"] = copy(swarm[i]) def get_result(self) -> List[FloatSolution]: - self.leaders.solution_list + return self.leaders.solution_list def __select_global_best(self) -> FloatSolution: - #pos1 = Random.randint(0, len(self.leaders.solution_list) - 1) - #pos2 = Random.randint(0, len(self.leaders.solution_list) - 1) - best_global = None - particles = Random.sample(self.leaders.solution_list, 2) + particles = random.sample(self.leaders.solution_list, 2) if self.leaders.get_comparator().compare(particles[0], particles[1]) < 1: best_global = copy(particles[0]) else: @@ -165,22 +165,23 @@ def __select_global_best(self) -> FloatSolution: return best_global - def __velocity_constriction(self, value: float, variable_index: int) -> float: - result = None - if value > self.delta_max[variable_index]: - result = self.delta_max[variable_index] - - if value < self.delta_min[variable_index]: - result = self.delta_min[variable_index] + def __velocity_constriction(self, value: float, delta_max: [], delta_min: [], variable_index: int) -> float: + result = value + if value > delta_max[variable_index]: + result = delta_max[variable_index] + if value < delta_min[variable_index]: + result = delta_min[variable_index] return result + def __inertia_weight(self, evaluations: int, max_evaluations: int, wmax: float, wmin: float): + return wmax + def __constriction_coefficient(self, c1: float, c2: float) -> float: - result = 0.0 rho = c1 + c2 if rho <= 4: result = 1.0 else: - result = 2.0 / (2.0 - rho - numpy.sqrt(pow(rho, 2.0) - 4.0 * rho)) + result = 2.0 / (2.0 - rho - sqrt(pow(rho, 2.0) - 4.0 * rho)) return result diff --git a/jmetal/runner/multiobjective/smpso_standard_settings.py b/jmetal/runner/multiobjective/smpso_standard_settings.py index 799053f1..14749592 100644 --- a/jmetal/runner/multiobjective/smpso_standard_settings.py +++ b/jmetal/runner/multiobjective/smpso_standard_settings.py @@ -2,9 +2,10 @@ from jmetal.algorithm.multiobjective.smpso import SMPSO from jmetal.component.archive import CrowdingDistanceArchive +from jmetal.component.observer import AlgorithmObserver from jmetal.core.solution import FloatSolution from jmetal.operator.mutation import Polynomial -from jmetal.problem.multiobjective.unconstrained import Kursawe +from jmetal.problem.multiobjective.zdt import ZDT1 from jmetal.util.solution_list_output import SolutionListOutput logging.basicConfig(level=logging.INFO) @@ -12,21 +13,25 @@ def main() -> None: - problem = Kursawe() + problem = ZDT1() algorithm = SMPSO( problem=problem, swarm_size=100, max_evaluations=25000, - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), + mutation=Polynomial(probability=1.0/problem.number_of_variables, distribution_index=20), leaders=CrowdingDistanceArchive(100)) + observer = AlgorithmObserver(animation_speed=1*10e-8) + algorithm.observable.register(observer=observer) + algorithm.run() result = algorithm.get_result() - SolutionListOutput[FloatSolution].print_function_values_to_file("FUN."+problem.get_name(), result) + SolutionListOutput[FloatSolution].plot_scatter_to_screen(result) logger.info("Algorithm (continuous problem): " + algorithm.get_name()) logger.info("Problem: " + problem.get_name()) + if __name__ == '__main__': main() From 4db5014b7d9d0a3e8200b0aff75455f35e04bcc2 Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 26 Apr 2018 19:01:11 +0200 Subject: [PATCH 05/90] Add python files --- .gitignore | 127 ++++++++++++++---- {auto-docs => docs/auto-docs}/Makefile | 0 {auto-docs => docs/auto-docs}/source/conf.py | 0 .../auto-docs}/source/index.rst | 0 jmetal/util/test/conftest.py | 12 -- 5 files changed, 99 insertions(+), 40 deletions(-) rename {auto-docs => docs/auto-docs}/Makefile (100%) rename {auto-docs => docs/auto-docs}/source/conf.py (100%) rename {auto-docs => docs/auto-docs}/source/index.rst (100%) delete mode 100644 jmetal/util/test/conftest.py diff --git a/.gitignore b/.gitignore index 19a78003..c6065b07 100644 --- a/.gitignore +++ b/.gitignore @@ -1,36 +1,107 @@ -*.class +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so -# Mobile Tools for Java (J2ME) -.mtj.tmp/ +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg -# Package Files # -*.jar -*.war -*.ear +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml -hs_err_pid* +# Installer logs +pip-log.txt +pip-delete-this-directory.txt -venv -env -.idea -*.pyc +# Unit test / coverage reports +htmlcov/ +.tox/ .coverage -__pycache__/ -build -dist -*.spec -coverage.xml -*.egg-info +.coverage.* .cache -pytest-env -*.zip +nosetests.xml +coverage.xml +*.cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook .ipynb_checkpoints -# Avoid documentation -auto-docs/build -auto-docs/source/*.rst -!auto-docs/source/index.rst -.RData -.Rhistory -_pycache__ +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# dotenv +.env + +# virtualenv +.venv +venv/ +ENV/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ + +# idea +.idea + +# pypi +.pypirc \ No newline at end of file diff --git a/auto-docs/Makefile b/docs/auto-docs/Makefile similarity index 100% rename from auto-docs/Makefile rename to docs/auto-docs/Makefile diff --git a/auto-docs/source/conf.py b/docs/auto-docs/source/conf.py similarity index 100% rename from auto-docs/source/conf.py rename to docs/auto-docs/source/conf.py diff --git a/auto-docs/source/index.rst b/docs/auto-docs/source/index.rst similarity index 100% rename from auto-docs/source/index.rst rename to docs/auto-docs/source/index.rst diff --git a/jmetal/util/test/conftest.py b/jmetal/util/test/conftest.py deleted file mode 100644 index d93458ce..00000000 --- a/jmetal/util/test/conftest.py +++ /dev/null @@ -1,12 +0,0 @@ -#from jmetal.util.test.test_ranking import DominanceRankingTestCases - - -def pytest_addoption(parser): - parser.addoption('--self', default=1, help="run many tests") - - -def pytest_generate_tests(metafunc): - self = metafunc.config.getoption('--self') - if 'self' in metafunc.fixturenames: - for x in range(1, self): - metafunc.parametrize("self", self) \ No newline at end of file From c5704c3ae8a7bf271460013a698e74079621c326 Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 26 Apr 2018 19:01:53 +0200 Subject: [PATCH 06/90] Add python files --- docs/auto-docs/Makefile | 20 ---- docs/auto-docs/source/conf.py | 158 -------------------------------- docs/auto-docs/source/index.rst | 20 ---- 3 files changed, 198 deletions(-) delete mode 100644 docs/auto-docs/Makefile delete mode 100644 docs/auto-docs/source/conf.py delete mode 100644 docs/auto-docs/source/index.rst diff --git a/docs/auto-docs/Makefile b/docs/auto-docs/Makefile deleted file mode 100644 index 15c772b2..00000000 --- a/docs/auto-docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = python -msphinx -SPHINXPROJ = jMetalPy -SOURCEDIR = source -BUILDDIR = build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/auto-docs/source/conf.py b/docs/auto-docs/source/conf.py deleted file mode 100644 index d5694d89..00000000 --- a/docs/auto-docs/source/conf.py +++ /dev/null @@ -1,158 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# jMetalPy documentation build configuration file, created by -# sphinx-quickstart on Mon Jun 12 15:06:53 2017. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os -import sys -sys.path.insert(0, os.path.abspath('../..')) - - - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = ['sphinx.ext.autodoc'] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -# source_suffix = ['.rst', '.md'] -source_suffix = '.rst' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = 'jMetalPy' -copyright = '2017, Antonio J. Nebro' -author = 'Antonio J. Nebro' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '1.0.0' -# The full version, including alpha/beta/rc tags. -release = '1.0.0' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path -exclude_patterns = [] - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'classic' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -# html_theme_options = {} - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - - -# -- Options for HTMLHelp output ------------------------------------------ - -# Output file base name for HTML help builder. -htmlhelp_basename = 'jMetalPydoc' - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'jMetalPy.tex', 'jMetalPy Documentation', - 'Antonio J. Nebro', 'manual'), -] - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'jmetalpy', 'jMetalPy Documentation', - [author], 1) -] - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'jMetalPy', 'jMetalPy Documentation', - author, 'jMetalPy', 'One line description of project.', - 'Miscellaneous'), -] - - - diff --git a/docs/auto-docs/source/index.rst b/docs/auto-docs/source/index.rst deleted file mode 100644 index 6fffa070..00000000 --- a/docs/auto-docs/source/index.rst +++ /dev/null @@ -1,20 +0,0 @@ -.. jMetalPy documentation master file, created by - sphinx-quickstart on Mon Jun 12 15:06:53 2017. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to jMetalPy's documentation! -==================================== - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` From 9997421a6fa0820e291ea6b6cd3c2019a9aa7ae8 Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 26 Apr 2018 19:02:42 +0200 Subject: [PATCH 07/90] Fix minor error --- jmetal/algorithm/multiobjective/smpso.py | 2 +- jmetal/algorithm/multiobjective/test/test_smpo.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jmetal/algorithm/multiobjective/smpso.py b/jmetal/algorithm/multiobjective/smpso.py index 05560d39..e22f7672 100644 --- a/jmetal/algorithm/multiobjective/smpso.py +++ b/jmetal/algorithm/multiobjective/smpso.py @@ -30,7 +30,7 @@ def __init__(self, self.problem = problem self.swarm_size = swarm_size self.max_evaluations = max_evaluations - self.mutation: Mutation[FloatSolution] = mutation + self.mutation = mutation self.leaders = leaders self.observable = observable self.evaluator = evaluator diff --git a/jmetal/algorithm/multiobjective/test/test_smpo.py b/jmetal/algorithm/multiobjective/test/test_smpo.py index e62a3ae0..fde77ddb 100644 --- a/jmetal/algorithm/multiobjective/test/test_smpo.py +++ b/jmetal/algorithm/multiobjective/test/test_smpo.py @@ -10,7 +10,6 @@ class SMPSOTestCases(unittest.TestCase): - def setUp(self): pass @@ -40,6 +39,7 @@ def test_should_constructor_create_a_valid_object(self): class __DummyFloatProblem(Problem[FloatSolution]): def __init__(self): + super().__init__() self.number_of_variables = 2 self.number_of_objectives = 2 self.number_of_constraints = 0 From c5e9fab0e87972890a3180199d4f22cec2ae6b7f Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 26 Apr 2018 19:03:08 +0200 Subject: [PATCH 08/90] Minor syntax changes --- jmetal/component/test/test_archive.py | 1 - jmetal/core/algorithm.py | 2 - jmetal/core/operator.py | 3 -- jmetal/core/problem.py | 5 ++- jmetal/operator/mutation.py | 2 +- jmetal/problem/multiobjective/constrained.py | 11 +++-- .../multiobjective/smpso_standard_settings.py | 3 +- jmetal/util/comparator.py | 20 +-------- jmetal/util/graphic.py | 1 - jmetal/util/ranking.py | 9 ++-- jmetal/util/test/test_comparator.py | 43 ++++++------------- jmetal/util/test/test_graphic.py | 6 ++- jmetal/util/test/test_observable.py | 7 +-- 13 files changed, 40 insertions(+), 73 deletions(-) diff --git a/jmetal/component/test/test_archive.py b/jmetal/component/test/test_archive.py index e7d2f3a3..ff5ab136 100644 --- a/jmetal/component/test/test_archive.py +++ b/jmetal/component/test/test_archive.py @@ -27,7 +27,6 @@ def test_should_constructor_set_the_max_size(self): class NonDominatedSolutionListArchiveTestCases(unittest.TestCase): - def setUp(self): self.archive = NonDominatedSolutionListArchive[Solution]() diff --git a/jmetal/core/algorithm.py b/jmetal/core/algorithm.py index fd92053f..54f36c58 100644 --- a/jmetal/core/algorithm.py +++ b/jmetal/core/algorithm.py @@ -139,8 +139,6 @@ def get_result(self) -> R: pass def run(self): - """ - """ self.start_computing_time = time.time() self.swarm = self.create_initial_swarm() diff --git a/jmetal/core/operator.py b/jmetal/core/operator.py index 3f47b9f3..e80fc945 100644 --- a/jmetal/core/operator.py +++ b/jmetal/core/operator.py @@ -48,8 +48,5 @@ def get_number_of_parents(self) -> int: class Selection(Operator[Source, Result]): - def __init__(self): - super(Selection, self).__init__() - def execute(self, source: Source) -> Result: pass diff --git a/jmetal/core/problem.py b/jmetal/core/problem.py index 3ca0e4a4..f1d6a63a 100644 --- a/jmetal/core/problem.py +++ b/jmetal/core/problem.py @@ -1,7 +1,6 @@ import random from typing import Generic, TypeVar -import jmetal from jmetal.core.solution import BinarySolution, FloatSolution, IntegerSolution __author__ = "Antonio J. Nebro" @@ -13,7 +12,6 @@ class Problem(Generic[S]): """ Class representing problems """ def __init__(self): - self.objectives = [jmetal.core.objective.Objective] self.number_of_variables: int = None self.number_of_objectives: int = None self.number_of_constraints: int = None @@ -45,6 +43,7 @@ class FloatProblem(Problem[FloatSolution]): """ Class representing float problems """ def __init__(self): + super().__init__() self.lower_bound : [] = None self.upper_bound : [] = None @@ -59,7 +58,9 @@ def create_solution(self) -> FloatSolution: class IntegerProblem(Problem[IntegerSolution]): """ Class representing integer problems """ + def __init__(self): + super().__init__() self.lower_bound : [] = None self.upper_bound : [] = None diff --git a/jmetal/operator/mutation.py b/jmetal/operator/mutation.py index 38338603..54a8b83c 100644 --- a/jmetal/operator/mutation.py +++ b/jmetal/operator/mutation.py @@ -154,4 +154,4 @@ def execute(self, solution: FloatSolution) -> FloatSolution: solution.variables[i] = tmp - return solution \ No newline at end of file + return solution diff --git a/jmetal/problem/multiobjective/constrained.py b/jmetal/problem/multiobjective/constrained.py index 9b869bf2..c7865f8c 100644 --- a/jmetal/problem/multiobjective/constrained.py +++ b/jmetal/problem/multiobjective/constrained.py @@ -1,14 +1,16 @@ from math import pi, cos, atan -""" Unconstrained Test problems for multi-objective optimization """ from jmetal.core.solution import FloatSolution - from jmetal.core.problem import FloatProblem +""" Unconstrained Test problems for multi-objective optimization """ + class Srinivas(FloatProblem): """ Class representing problem Srinivas """ + def __init__(self): + super().__init__() self.number_of_objectives = 2 self.number_of_variables = 2 self.number_of_constraints = 2 @@ -52,7 +54,9 @@ def evaluate_constraints(self, solution: FloatSolution) -> None: class Tanaka(FloatProblem): """ Class representing problem Tanaka """ + def __init__(self): + super().__init__() self.number_of_objectives = 2 self.number_of_variables = 2 self.number_of_constraints = 2 @@ -68,7 +72,7 @@ def evaluate(self, solution: FloatSolution): solution.objectives[1] = solution.variables[1] def evaluate_constraints(self, solution: FloatSolution) -> None: - constraints : [float] = [0.0 for x in range(self.number_of_constraints)] + constraints : [float] = [0.0 for _ in range(self.number_of_constraints)] x1 = solution.variables[0] x2 = solution.variables[1] @@ -89,4 +93,3 @@ def evaluate_constraints(self, solution: FloatSolution) -> None: def get_name(self): return "Tanaka" - diff --git a/jmetal/runner/multiobjective/smpso_standard_settings.py b/jmetal/runner/multiobjective/smpso_standard_settings.py index 14749592..60b87672 100644 --- a/jmetal/runner/multiobjective/smpso_standard_settings.py +++ b/jmetal/runner/multiobjective/smpso_standard_settings.py @@ -19,7 +19,8 @@ def main() -> None: swarm_size=100, max_evaluations=25000, mutation=Polynomial(probability=1.0/problem.number_of_variables, distribution_index=20), - leaders=CrowdingDistanceArchive(100)) + leaders=CrowdingDistanceArchive(100) + ) observer = AlgorithmObserver(animation_speed=1*10e-8) algorithm.observable.register(observer=observer) diff --git a/jmetal/util/comparator.py b/jmetal/util/comparator.py index 966930cf..e02a5a54 100644 --- a/jmetal/util/comparator.py +++ b/jmetal/util/comparator.py @@ -43,24 +43,6 @@ def compare(self, solution1: Solution, solution2: Solution) -> int: elif dominate2 == 1: return 1 -""" -class DominanceRankingComparator(Comparator): - def compare(self, solution1: Solution, solution2: Solution) -> int: - rank1 = solution1.attributes.get("dominance_ranking") - rank2 = solution1.attributes.get("dominance_ranking") - - result = 0 - if rank1 is not None or rank2 is not None: - if rank1 < rank2: - result = -1 - elif rank1 > rank2: - result = 1 - else: - result = 0 - - return result -""" - class SolutionAttributeComparator(): def __init__(self, key: str, lowest_is_best: bool = True): @@ -142,4 +124,4 @@ def __dominance_test(self, solution1, solution2) -> float: else: result = 0 - return result \ No newline at end of file + return result diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index 9c29174a..26ff0ca4 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -20,7 +20,6 @@ class ScatterPlot(): - def __init__(self, plot_title: str, animation_speed: float = 1*10e-10): """ Creates a new :class:`ScatterPlot` instance. Args: diff --git a/jmetal/util/ranking.py b/jmetal/util/ranking.py index af25dd49..fd478420 100644 --- a/jmetal/util/ranking.py +++ b/jmetal/util/ranking.py @@ -26,7 +26,8 @@ def get_number_of_comparions(self) -> int: class FastNonDominatedRanking(Ranking[List[S]]): - """ Class implementing the non-dominated ranking of NSGA-II""" + """ Class implementing the non-dominated ranking of NSGA-II """ + def __init__(self): super(FastNonDominatedRanking, self).__init__() @@ -80,10 +81,10 @@ def compute_ranking(self, solution_list: List[S]): class EfficientNonDominatedRanking(Ranking[List[S]]): """ Class implementing the EDS (efficient non-dominated sorting) algorithm """ + def __init__(self): super(EfficientNonDominatedRanking, self).__init__() def compute_ranking(self, solution_list: List[S]): - #todo - - return self.ranked_sublists \ No newline at end of file + #todo + return self.ranked_sublists diff --git a/jmetal/util/test/test_comparator.py b/jmetal/util/test/test_comparator.py index f9317767..ee13a269 100644 --- a/jmetal/util/test/test_comparator.py +++ b/jmetal/util/test/test_comparator.py @@ -6,7 +6,6 @@ class DominanceComparatorTestCases(unittest.TestCase): - def setUp(self): self.comparator = DominanceComparator() @@ -28,6 +27,7 @@ def test_should_dominance_comparator_raise_an_exception_if_the_solutions_have_no with self.assertRaises(Exception): self.comparator.compare(solution, solution2) """ + def test_should_dominance_comparator_return_zero_if_the_two_solutions_have_one_objective_with_the_same_value(self): solution = FloatSolution(3, 1, 0, [], []) solution2 = FloatSolution(3, 1, 0, [], []) @@ -56,9 +56,9 @@ def test_should_dominance_comparator_return_minus_one_if_the_two_solutions_have_ self.assertEqual(-1, self.comparator.compare(solution, solution2)) def test_should_dominance_comparator_work_properly_case_a(self): - ''' + """ Case A: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [2.0, 6.0, 15.0] - ''' + """ solution = FloatSolution(3, 3, 0, [], []) solution2 = FloatSolution(3, 3, 0, [], []) @@ -68,9 +68,9 @@ def test_should_dominance_comparator_work_properly_case_a(self): self.assertEqual(-1, self.comparator.compare(solution, solution2)) def test_should_dominance_comparator_work_properly_case_b(self): - ''' + """ Case b: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-1.0, 5.0, 10.0] - ''' + """ solution = FloatSolution(3, 3, 0, [], []) solution2 = FloatSolution(3, 3, 0, [], []) @@ -80,9 +80,9 @@ def test_should_dominance_comparator_work_properly_case_b(self): self.assertEqual(-1, self.comparator.compare(solution, solution2)) def test_should_dominance_comparator_work_properly_case_c(self): - ''' + """ Case c: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-2.0, 5.0, 9.0] - ''' + """ solution = FloatSolution(3, 3, 0, [], []) solution2 = FloatSolution(3, 3, 0, [], []) @@ -92,9 +92,9 @@ def test_should_dominance_comparator_work_properly_case_c(self): self.assertEqual(1, self.comparator.compare(solution, solution2)) def test_should_dominance_comparator_work_properly_case_d(self): - ''' + """ Case d: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-1.0, 5.0, 8.0] - ''' + """ solution = FloatSolution(3, 3, 0, [], []) solution2 = FloatSolution(3, 3, 0 , [], []) @@ -102,24 +102,11 @@ def test_should_dominance_comparator_work_properly_case_d(self): solution2.objectives = [-1.0, 5.0, 8.0] self.assertEqual(1, self.comparator.compare(solution, solution2)) - """ - def test_should_dominance_comparator_work_properly_case_3(self): - ''' - Case d: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-2.0, 5.0, 10.0] - ''' - solution = FloatSolution(3, 3, 0, [], []) - solution2 = FloatSolution(3, 3, 0, [], []) - solution.objectives = [-1.0, 5.0, 9.0] - solution2.objectives = [-2.0, 5.0, 10.0] - - self.assertEqual(0, self.comparator.compare(solution, solution2)) - - """ def test_should_dominance_comparator_work_properly_with_constrains_case_1(self): - ''' + """ Case 1: solution1 has a higher degree of constraint violation than solution 2 - ''' + """ solution1 = FloatSolution(3, 3, 0, [], []) solution2 = FloatSolution(3, 3, 0, [], []) solution1.attributes["overall_constraint_violation"] = -0.1 @@ -131,9 +118,9 @@ def test_should_dominance_comparator_work_properly_with_constrains_case_1(self): self.assertEqual(-1, self.comparator.compare(solution1, solution2)) def test_should_dominance_comparator_work_properly_with_constrains_case_2(self): - ''' + """ Case 2: solution1 has a lower degree of constraint violation than solution 2 - ''' + """ solution1 = FloatSolution(3, 3, 0, [], []) solution2 = FloatSolution(3, 3, 0, [], []) solution1.attributes["overall_constraint_violation"] = -0.3 @@ -145,9 +132,7 @@ def test_should_dominance_comparator_work_properly_with_constrains_case_2(self): self.assertEqual(1, self.comparator.compare(solution1, solution2)) - class SolutionAttributeComparatorTestCases(unittest.TestCase): - def setUp(self): self.comparator = SolutionAttributeComparator("attribute") @@ -227,7 +212,6 @@ def test_should_compare_works_properly_case4(self): class RankingAndCrowdingComparatorTestCases(unittest.TestCase): - def setUp(self): self.comparator = RankingAndCrowdingDistanceComparator() @@ -298,4 +282,3 @@ def test_should_compare_work_properly_case_5(self): if __name__ == '__main__': unittest.main() - diff --git a/jmetal/util/test/test_graphic.py b/jmetal/util/test/test_graphic.py index 3da614f4..15829b8c 100644 --- a/jmetal/util/test/test_graphic.py +++ b/jmetal/util/test/test_graphic.py @@ -9,14 +9,15 @@ class GraphicTestCases(unittest.TestCase): def setUp(self): pass + """ def tearDown(self): if os.path.exists("test.png"): os.remove("test.png") def test_should_print_solution_points_correctly(self): solution1, solution2 = FloatSolution(1, 2, 0, [], []), FloatSolution(1, 2, 0, [], []) - solution1.objectives[0], solution2.objectives[0] = 5.0, 1.0 # x values - solution1.objectives[1], solution2.objectives[1] = 3.0, 6.0 # y values + solution1.objectives[0], solution2.objectives[0] = 5.0, 1.0 # x values + solution1.objectives[1], solution2.objectives[1] = 3.0, 6.0 # y values solution_list = [solution1, solution2] plot = ScatterPlot(plot_title="title", animation_speed=1*10e-10) @@ -39,6 +40,7 @@ def test_should_raise_an_exception_when_format_is_not_supported(self): with self.assertRaises(Exception): plot.simple_plot(solution_list=solution_list, file_name="file", fmt="null", save=True) + """ def test_should_raise_an_exception_when_updating_a_plot_that_doesnt_exist(self): plot = ScatterPlot(plot_title="title", animation_speed=1*10e-10) diff --git a/jmetal/util/test/test_observable.py b/jmetal/util/test/test_observable.py index dad01cab..71774e85 100644 --- a/jmetal/util/test/test_observable.py +++ b/jmetal/util/test/test_observable.py @@ -52,13 +52,14 @@ def test_should_deregister_all_remove_all_the_observers(self): self.assertEqual(0, len(self.observable.observers)) -""" + """ def test_should_notify_all_update_an_observer(self): observer = mock(Observer) self.observable.register(observer) self.observable.notify_all("color", "blue") -""" + """ + if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() From bf7511f546a4810cad4f0a4ecd427cde3cdde7cc Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 26 Apr 2018 19:03:35 +0200 Subject: [PATCH 09/90] README updated --- CHANGELOG.md | 3 +++ README.md | 52 ++++++++++++++++++++++------------------- TODO.md | 10 ++++---- resources/jmetalpy.png | Bin 0 -> 5831 bytes 4 files changed, 36 insertions(+), 29 deletions(-) create mode 100644 resources/jmetalpy.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ac0b975..66125f47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,7 @@ # History +## Last changes (April 26th 2018) +* Added [SMPSO](jmetal/algorithm/multiobjective/smpso.py). + ## Last changes (July 21th 2017) * Added guide for using [cProfile](resources/pages/profiling.md). * Starting to implement [SMPSO](jmetal/algorithm/multiobjective/smpso.py). diff --git a/README.md b/README.md index 5e39cc10..ccb05066 100644 --- a/README.md +++ b/README.md @@ -1,45 +1,49 @@ +

+
+ jMetalPy +
+

+ # jMetalPy: Python version of the jMetal framework -[![Build Status](https://travis-ci.org/jMetal/jMetalPy.svg?branch=master)](https://travis-ci.org/jMetal/jMetalPy) -[![PyPI](https://img.shields.io/pypi/l/jMetalPy.svg)]() -[![PyPI](https://img.shields.io/pypi/v/jMetalPy.svg)]() +[![Build Status](https://img.shields.io/travis/jMetal/jMetalPy.svg?style=flat-square)](https://travis-ci.org/jMetal/jMetalPy) +[![PyPI Version](https://img.shields.io/pypi/v/jMetalPy.svg?style=flat-square)]() +[![PyPI License](https://img.shields.io/pypi/l/jMetalPy.svg?style=flat-square)]() +[![PyPI Python version](https://img.shields.io/pypi/pyversions/jMetalPy.svg?style=flat-square)]() > jMetalPy is currently under heavy development! - -I started a new project called jMetalPy in February 2017. The initial idea was not to write the whole jMetal proyect in Python but to use it as a practical study to learn that programming language, although due to the interest of some researchers the goal of an usable jMetal version in Python is an ongoing work. - -Any ideas about how the structure the project, coding style, useful tools (I'm using PyCharm), or links to related projects are welcome (see [CONTRIBUTING](https://github.com/jMetal/jMetalPy/blob/master/CONTRIBUTING.md)). The starting point is the jMetal architecture: - -![jMetal architecture](resources/jMetal5UML.png) - ---- +> Any ideas about how the structure the project, coding style, useful tools or links to related projects are welcome (see [CONTRIBUTING](https://github.com/jMetal/jMetalPy/blob/master/CONTRIBUTING.md)). The starting point is the jMetal architecture: +> ![jMetal architecture](resources/jMetal5UML.png) # Table of Contents -- [Usage](#usage) +- [Installation](#installation) - [Dependencies](#dependencies) -- [History](#history) - - [Last changes (July 17th 2017)](#last-changes-july-17th-2017) +- [Usage](#usage) - [Contributing](#contributing) - [License](#license) +# Installation +To download jMetalPy just clone the Git repository hosted in GitHub: +```bash +$ git clone https://github.com/jMetal/jMetalPy.git +$ python setup.py install +``` -# Usage -Examples of configuring and running all the included algorithms are located in the [jmetal.runner](https://github.com/jMetal/jMetalPy/tree/master/jmetal/runner) folder. +Alternatively, you can install with `pip`: +```bash +$ pip install jmetalpy +``` ## Dependencies With Python 3.6 installed, run: -```Bash -$ git clone https://github.com/jMetal/jMetalPy.git +```bash $ pip install -r requirements.txt ``` -# History -See [CHANGELOG](CHANGELOG.md) for full version history. - -## Last changes (July 27th 2017) -* (Fix) Search solution in `ScatterPlot()` now return only one solution object (as intended). +# Usage +Examples of configuring and running all the included algorithms are located in the [jmetalpy.runner](jmetal/runner) folder. # Contributing Please read [CONTRIBUTING](CONTRIBUTING.md) for details on how to contribute to the project. # License -This project is licensed under the terms of the MIT - see the [LICENSE](LICENSE) file for details. +This project is licensed under the terms of the MIT - see the [LICENSE](LICENSE) file for details. \ No newline at end of file diff --git a/TODO.md b/TODO.md index eba0d856..a8c22c90 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,6 @@ -# TODO list +# ToDo list -- [ ] The documentation of the code is not complete. -- [ ] Inclusion of integration tests for the algorithm implementations. -- [ ] Full coverage with unit tests. -- [ ] Add MSA problem. \ No newline at end of file +- [ ] Add _experiment_ class with options to export results in LaTeX. +- [ ] Support parallelism (see: [Dask](https://dask.pydata.org/en/latest/)). +- [ ] Auto-generate documentation (also: the documentation of the code is not complete!) +- [ ] Add _state-of-the-art_ visualization methods. \ No newline at end of file diff --git a/resources/jmetalpy.png b/resources/jmetalpy.png new file mode 100644 index 0000000000000000000000000000000000000000..a41ad1e1540faa39e0d44ce99e430a3e86121480 GIT binary patch literal 5831 zcmX|F2Q<~;`@bSH2}QD31J@pzQ3xSryTo;`eZQ`ZYwuC^D0??9GP3U14hh+cxO|Ol z;Ucn2fBpWy^Lx*E_j^8{^StkQKF@RBXaoKG^t9J#VK5lIwwC(ivz~NTZ&Fj9wM>qI z&tWjK2Tn$2o@RQw3MecfibP{=?L>V5x3hg1OzDn~8xrMW=gDJh=iub3%(vCl%E#k` zR^~I6(G%BmyJzRF4aa(8m`bi%sw{KG`rV!b?-`S`^C zk%;}5<;*;>|Jipo`QHuMxt?8%`ME(hr?mH`K4y?*y zn=mHoNhTVaHO)_s&B5)`G-P+3#mMg7wT(}@#7D%5kui}CokXbm_4x1!Ff|9mEQYvY zLvY5VIU1f^+_o96`+y_NAN#G`eM0mgkuCA|Yelb8OJh=F1vYT#V9EpAW4(P}sXF(Z zVFAO1kS6%aKuB!;7IE$p$9d%lu7t2Kt^}@xhpU~9Jhv%&Ee`LS_tix`EC%ywbty#8 zcU2{X`$Sb=IR6C1+?bt3Qpa@MRA+pYbM-veiuB8mhPONA6W7b14!*Y>VxV1NtypQ^DCRH>qn8J>C+_1)1X+h*?ojJfmfV&N-kEED&SjF!vS~G>Eagt*O+M` zX$SY_i63E4?s9*yc}Ct@Yt)uVdl-36C4T8eB}c&HZPJbNr4Hv`KcvME%{vTL@9gGp zo}RY;Odl_bM9oJCGd}sdZYoFay(K*3YWV%U8`nA@`}`z_Y`m?F`fu%T>o4`vV~5oj zE%Lg0gQay&we4ijRfI5q?{>nLa|a@~tL;vrB7v~ZFdBQtt}55H;WF1{{r;xR%#P*` z-Rt(7N@Ehj23|;OxVYD$o279x-AM+yuqsM|HJxc~j69HKpN92mq~uI}alizwkc6ZC z?SbiAX{+B&CgI4M<5sfoY+L%1CjWHYtbJy1g*AON`0)6ct@qpH;l3hjGc}g*(W1Tk z6;ghO)@9)nyI9N9Ir=QS{7eax1)x0X_Onc5jPOOqXJ(9>FbOx6 zsps?S7-8CF)~nu*&6i#~C;WSYY+2{Be1nF*ZY=Hdh;<{fTYSs<0x`JWG^y>9T zb?;phC~IN-9r!RfIYb-fQVHBlX%`N?ZvBk@(#7_?XCNysw6b&gsCW5D&{b+Q;x1nZ zJSe!PElJcPIhRt-;yhz}|8xn92cyOSuX9E{Z0$M}qroF=f01x58rDq_!038gcwVgB zW~gl@)F}WxGFUlHrpTk@m@PYxA_IN|n*EjlEWc*nB4+K(rRkV)^Io`w$Ig`%ZMUc* z`~5V7fvGE$8nC5G@gNgNA5ovV*t;3N$S3NF0olGNkuGx@vxR+!U@xgCocoah?yl#H zIu}G@qU#RXTgyg;6VbPM`~=rNWTWKjs)I=kuO)FToLj;H+qt2p`eVJt zg#hc5hUiJzAH)(leQ&2p>!TOz54fjotsA;JejQ1KvV3nqrZ*AFU-?`d2AOr@(d-B7 zftY*{PL`vZ^$Xxiipc`Mf?=91jSnC{_%Ytq)uLJ4WA_s%1FTDJTYLqF_}uK8@<@2# zB!b7b+O$mwF-y6+P%UYe&gD$y0x8Dz)m0v=&H0DJCvh9`kS>&0BB?(KI<@}l9xtLC zp|tt?YxeIkJ`T@K=eWxq$Taa(7&6&w!6?F-dR5Hd26Fd;11HBeAOQy&zsSY7tR36C zGbJj^Sr2Cdebq~^97UjZMNC;D&9rxqsIQso+Mf&>1~fuE?Pg6JFf=BSHT7J8p{2T) zxE~AXvS%Ku6DUaQe-E>>wLc71h2V0&4P9XWHi4`0L_~#9iW5~+d-RtTLJkhk_H_l+AJ|h-1mwR zSlN#a_6cUBIP<9(PqPU2h#5&&var z$S~Pk`9DzBFT0f`po=Bm-MS0zWK;G~;;e?OuLx*$NyY^You&mr(WWX0cDb3W*R8V4 z4#U?!)DhvA&CODO?qIQL1Mh=G3L?800OA{VD5`}W15s(3v$yi1!fRI^RhMHO5TrKH z1cf-bj8W`g!xlGn%0qdKeEr=nG?fevkf6yvbR7gF0b2C|W42QFxzxIMB7av7DyU%B zj-NhENibf@{(GuD4cEu%7FfZo9oC2F*=Jq=MNzqE?^%PYrU8x;6VU4FlqOHmsT-IY z2TTWn@fw6daCtfuv(A+bh*4)g?7_!B$bX!ucR}7>iYpd4aZ*Mhz)HA8ic$>5Z#jPA zpfy-|ziT%RiI|>8cT-qUPlCVa_@O+mVnD3NRWuxn;fGg*Vd~e25a6lO9Y%8$RT#?6X|QcNArho6ebd+psse>x1becxW(vTGC~-dVe9952!WO5 zG7}~`+a_%<%NXi%fk3Xx9Sz@#`}R;0jnRbgBo&o(Xh8EM7+|BE0f_DH5vn%Yz}H^X zlE5OL|H8MSU_U8npD=f*N~d-sRqa+sMH^+)1c(`sAZk#v z-I*`A?!Blc36jW)@$eF=%g-1bzZMa4?6!u$qMPaF0=|1J%bc~OT%mhFhH?>3@0frA}TB<1yeZ*-cgTsnXsHypko~ zv+-FwuOP>6U8=TUd)Y9O5RtMZuy8N4oOAZ}f<~{#epjX3^d`#~Eks>;n^@As&W2t)Ia7X}`*P{0@} zGaNXsVVjHC@K5t=>QxqRsy*N=rYXpl@2LXfL~a~iM#gOO^=UuhjY}>7YI4wi$;dNW z15*~E=IwKlZAE{5q_%dxC4N!Xm%Z*O46`8;D^=b~mODYouU4+z;a4wYO{KGJWj_;t zp130A*&?K(GsK)Urve}vT0WWpE}85(@kP_4V2Ts;QZTg^7<*RQ(tl;D5Qs;1H42w8 z!-~xRoG+x?tk>-!vWT~&JGAZC`RE;7Z~L` z-413|0q(K<&~e)bAyE{9rlR_Im5cR+2qwCvDks}(6;0g2tBc*5e2${i$&4MhtR~g5 zK{J#L9h(OD+fB|$D1c&E_@%ZA-zp4*TP;`MHVSf?A1~R4HMWRjcvh9@Awy5TRqeCD za*@;Blx)bNz0nHNF^`ok-muW zKhDXQAH4xRf|$A?9EidtzKDMwSoftQ*S_Ls+c0Y;7znJE{h(aAgz-QL%PIIOP}P2C z>ErLAsYT-Gitncw*51a8EhjH7o`RYwrJK3V;%bvD=^qqK**N!ZsixwKerSL|yueC9 zV0_i>0w=urpTnKxc->Z4^%T<#cBE@egYg4_Bl<4Ajn}#0{;b7{NQr)p*&=R3mu{{^ znKFpOgw$VIRls}?f9BP8he$N!?p}vZWwx9k!$8E=GY5?`Mk_1}q+{5xrlwf&LutC% zHRXLolbSQtA&!xd2yU!uxeF8nh%pXU7fsb-vRpBW{GS8{=Z}+6*Ld=$7GeObB$!)R z{XBV*?4unTlIMHy3GUtR`V|CwSdmNE_wH>1`Scpg7S61;*4a9<(+qPe@W2-a{DSGDVTVvv8g2s0eJ|Y*;i)X z!`EpX7FnyFBE{OYtVsoyH~FS~b4gxQ>Dt|Rg=c5|Rw0!o3zQ`uaQ*xs;+-hR-;-Jz z&?-`*09n*&xtl&H;B@~z644(`PWvt)heD4Nw9}CZouKS$Y+(R|_cGZLnx~GVB{Vr+ z0DB$jD`*lST95;H0Hyu}V6fW89QKYBT|2!=eJimi!676-uNC_ZoZ^45HZuv9?oo#X zYE$oDSiPg{;DPs^Ore@71iS0{K&&x?+L()VGUb>LeH z41kOM1o}o9l>j3JApy8<%(j|`xSAehLQbo5Fepa=urK3be)m2Xkxq&E)Al=zH>D)zET;Z%R5n&=d(IT0&!*e~r{`4$Ry%NGR7UGk1mp zUOv2_^R|w0anj@k2w$57Im`?~8t6uI(7>5!A!yATIzzvtV>Ki%!bGsGR%`_I&qC3Cx=p`J>?#Mebdr(#`Pnu9~ z{k=8c7@PE=6(mi{Hw-j7Bl;unC({Zsc{$&M-gWW@Tx`7$Me!IVlPO|KYs<-n^&d6$ z){=yEw%Y=%tKlLlNnp!5TR1`DkQ6+j zysccv6>5wviF!rfaK~|Xg5K2^%lQMq2(u@nPl}1MRU1Jdd_o3=kYNooP^l{4L_)U2 z=K>GO`;I?18p+vQ9Gk{uBeJR_rXBcIcpQ0Q>Gz^LL%hoVZr`-#_vOunPn(WlAdgMf zq&35Q-_w@(Ld=i4ftaB+h7qud!qRlT0x0DfH3708Dvk_;#-i2ezy^)C0Q@X08q8^) z>2!FbuS|~Ecp&_(|44wPlq^>XA(UnFfC7{Ey5aPbNqcFQl+d?v^J$BOce9aAd_BOy zMqx5~V9<;#;~Hcemb%s81?L%j-9Hf|c=Ih+{o`k1Ql&9#MDekGCJ%=*@wJR^h}S@f zIwQg{b!^>Nla4=&gzhJZ8>&}ZiAA{9+}isg)4Hs@lCfzIHFJCf)BgA?f#s)Te~4gO zZ+$yh{Q?M7gf5oS%*I@?=zllbrL>exdW#r&gN{WX!H(pO_l;Hx`v2bVvm1}V;HmEp z+YD}s<^)aMU=VMf3t!4GX$#~4rhwJB^w~x&o1+a+>Z)t!i|~FX?=0 z*NlWKx1OLHsb91?Q9MN>qLa~qrdz#^u>xCLlv$7StDdUXui!^p!24BVd#+K5 zfinztzyUGr`~C;#BTROno|fJ^Em84Z$R|<-Cj-GU6m*2%7M8C5o;gPkxR_Z=AJ#6b5fkaq7pZENkO= zCwjpLC}o2wv*9@w(5h=oHZ%p0V-n+P0||9Er^11BysY>Ql$2cUB3E|G5I-RiFcv{S zHkXj7`B0LbSzn^HQ55J0k_?rbH;bQi?_93fSS_7dhE`NePVT68C$jzYeR=rr|5;l@ LU%le4P1yedxE53B literal 0 HcmV?d00001 From 243f52877330c3be421e597332099bd3aa845259 Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 4 May 2018 12:14:16 +0200 Subject: [PATCH 10/90] Added documentation --- CONTRIBUTING.md | 18 +- docs/Makefile | 20 +++ docs/make.bat | 36 ++++ docs/source/conf.py | 160 ++++++++++++++++++ docs/source/index.rst | 20 +++ .../jmetal.algorithm.multiobjective.rst | 45 +++++ .../jmetal.algorithm.multiobjective.test.rst | 22 +++ docs/source/jmetal.algorithm.rst | 18 ++ .../jmetal.algorithm.singleobjective.rst | 22 +++ docs/source/jmetal.component.rst | 53 ++++++ docs/source/jmetal.component.test.rst | 30 ++++ docs/source/jmetal.core.rst | 53 ++++++ docs/source/jmetal.core.test.rst | 46 +++++ docs/source/jmetal.operator.rst | 45 +++++ docs/source/jmetal.operator.test.rst | 38 +++++ docs/source/jmetal.problem.multiobjective.rst | 53 ++++++ .../jmetal.problem.multiobjective.test.rst | 38 +++++ docs/source/jmetal.problem.rst | 18 ++ .../source/jmetal.problem.singleobjective.rst | 29 ++++ .../jmetal.problem.singleobjective.test.rst | 22 +++ docs/source/jmetal.rst | 23 +++ docs/source/jmetal.runner.multiobjective.rst | 70 ++++++++ docs/source/jmetal.runner.rst | 18 ++ ...ner.singleobjective.evolution_strategy.rst | 62 +++++++ ...nner.singleobjective.genetic_algorithm.rst | 54 ++++++ docs/source/jmetal.runner.singleobjective.rst | 18 ++ docs/source/jmetal.util.rst | 69 ++++++++ docs/source/jmetal.util.test.rst | 46 +++++ docs/source/modules.rst | 7 + jmetal/algorithm/multiobjective/nsgaii.py | 30 ++++ .../algorithm/multiobjective/randomSearch.py | 9 +- jmetal/algorithm/multiobjective/smpso.py | 24 +++ .../singleobjective/evolutionaryalgorithm.py | 8 + jmetal/core/algorithm.py | 32 ++-- ...ational_genetic_algorithm_with_observer.py | 4 +- 35 files changed, 1244 insertions(+), 16 deletions(-) create mode 100644 docs/Makefile create mode 100644 docs/make.bat create mode 100644 docs/source/conf.py create mode 100644 docs/source/index.rst create mode 100644 docs/source/jmetal.algorithm.multiobjective.rst create mode 100644 docs/source/jmetal.algorithm.multiobjective.test.rst create mode 100644 docs/source/jmetal.algorithm.rst create mode 100644 docs/source/jmetal.algorithm.singleobjective.rst create mode 100644 docs/source/jmetal.component.rst create mode 100644 docs/source/jmetal.component.test.rst create mode 100644 docs/source/jmetal.core.rst create mode 100644 docs/source/jmetal.core.test.rst create mode 100644 docs/source/jmetal.operator.rst create mode 100644 docs/source/jmetal.operator.test.rst create mode 100644 docs/source/jmetal.problem.multiobjective.rst create mode 100644 docs/source/jmetal.problem.multiobjective.test.rst create mode 100644 docs/source/jmetal.problem.rst create mode 100644 docs/source/jmetal.problem.singleobjective.rst create mode 100644 docs/source/jmetal.problem.singleobjective.test.rst create mode 100644 docs/source/jmetal.rst create mode 100644 docs/source/jmetal.runner.multiobjective.rst create mode 100644 docs/source/jmetal.runner.rst create mode 100644 docs/source/jmetal.runner.singleobjective.evolution_strategy.rst create mode 100644 docs/source/jmetal.runner.singleobjective.genetic_algorithm.rst create mode 100644 docs/source/jmetal.runner.singleobjective.rst create mode 100644 docs/source/jmetal.util.rst create mode 100644 docs/source/jmetal.util.test.rst create mode 100644 docs/source/modules.rst diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b2e2fb41..6afbb71f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,4 +8,20 @@ Contributions to the jMetalPy project are welcome. Please, take into account the - [Incorporate the new features of Python 3.5](resources/pages/features_python3.md) - [Respect the initial structure](resources/pages/project_structure.md) - [How to create auto documentation using compatible code](resources/pages/auto_doc.md) -- [Performance analysis of Python](resources/pages/profiling.md) \ No newline at end of file +- [Performance analysis of Python](resources/pages/profiling.md) + +# Documentation + +To generate the documentation, install [Sphinx](http://www.sphinx-doc.org/en/master/) by running: + +```bash +$ pip install sphinx +$ pip install sphinx_rtd_theme +``` + +And then `cd` to `/docs` and run: + +```bash +$ sphinx-apidoc -f -o source/ ../jmetal/ +$ make html +``` \ No newline at end of file diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 00000000..c3ba2e24 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = jMetalPy +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 00000000..5205888d --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build +set SPHINXPROJ=jMetalPy + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 00000000..bbb61108 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,160 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/master/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys +sys.path.insert(0, os.path.abspath('../..')) + + +# -- Project information ----------------------------------------------------- + +project = 'jMetalPy' +copyright = '2018, Antonio J. Nebro' +author = 'Antonio J. Nebro' + +# The short X.Y version +version = '' +# The full version, including alpha/beta/rc tags +release = '' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path . +exclude_patterns = [] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'jMetalPydoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'jMetalPy.tex', 'jMetalPy Documentation', + 'Antonio J. Nebro', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'jmetalpy', 'jMetalPy Documentation', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'jMetalPy', 'jMetalPy Documentation', + author, 'jMetalPy', 'One line description of project.', + 'Miscellaneous'), +] + + +# -- Extension configuration ------------------------------------------------- +autoclass_content = 'both' \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 00000000..a30fffa9 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,20 @@ +.. jMetalPy documentation master file, created by + sphinx-quickstart on Fri May 4 10:10:17 2018. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to jMetalPy's documentation! +==================================== + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/source/jmetal.algorithm.multiobjective.rst b/docs/source/jmetal.algorithm.multiobjective.rst new file mode 100644 index 00000000..77baa1d6 --- /dev/null +++ b/docs/source/jmetal.algorithm.multiobjective.rst @@ -0,0 +1,45 @@ +jmetal.algorithm.multiobjective package +======================================= + +Subpackages +----------- + +.. toctree:: + + jmetal.algorithm.multiobjective.test + +Submodules +---------- + +jmetal.algorithm.multiobjective.nsgaii module +--------------------------------------------- + +.. automodule:: jmetal.algorithm.multiobjective.nsgaii + :members: + :undoc-members: + :show-inheritance: + +jmetal.algorithm.multiobjective.randomSearch module +--------------------------------------------------- + +.. automodule:: jmetal.algorithm.multiobjective.randomSearch + :members: + :undoc-members: + :show-inheritance: + +jmetal.algorithm.multiobjective.smpso module +-------------------------------------------- + +.. automodule:: jmetal.algorithm.multiobjective.smpso + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.algorithm.multiobjective + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.algorithm.multiobjective.test.rst b/docs/source/jmetal.algorithm.multiobjective.test.rst new file mode 100644 index 00000000..c657a3f9 --- /dev/null +++ b/docs/source/jmetal.algorithm.multiobjective.test.rst @@ -0,0 +1,22 @@ +jmetal.algorithm.multiobjective.test package +============================================ + +Submodules +---------- + +jmetal.algorithm.multiobjective.test.test\_smpo module +------------------------------------------------------ + +.. automodule:: jmetal.algorithm.multiobjective.test.test_smpo + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.algorithm.multiobjective.test + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.algorithm.rst b/docs/source/jmetal.algorithm.rst new file mode 100644 index 00000000..e0fd2a03 --- /dev/null +++ b/docs/source/jmetal.algorithm.rst @@ -0,0 +1,18 @@ +jmetal.algorithm package +======================== + +Subpackages +----------- + +.. toctree:: + + jmetal.algorithm.multiobjective + jmetal.algorithm.singleobjective + +Module contents +--------------- + +.. automodule:: jmetal.algorithm + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.algorithm.singleobjective.rst b/docs/source/jmetal.algorithm.singleobjective.rst new file mode 100644 index 00000000..70e0d327 --- /dev/null +++ b/docs/source/jmetal.algorithm.singleobjective.rst @@ -0,0 +1,22 @@ +jmetal.algorithm.singleobjective package +======================================== + +Submodules +---------- + +jmetal.algorithm.singleobjective.evolutionaryalgorithm module +------------------------------------------------------------- + +.. automodule:: jmetal.algorithm.singleobjective.evolutionaryalgorithm + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.algorithm.singleobjective + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.component.rst b/docs/source/jmetal.component.rst new file mode 100644 index 00000000..207cea0b --- /dev/null +++ b/docs/source/jmetal.component.rst @@ -0,0 +1,53 @@ +jmetal.component package +======================== + +Subpackages +----------- + +.. toctree:: + + jmetal.component.test + +Submodules +---------- + +jmetal.component.archive module +------------------------------- + +.. automodule:: jmetal.component.archive + :members: + :undoc-members: + :show-inheritance: + +jmetal.component.density\_estimator module +------------------------------------------ + +.. automodule:: jmetal.component.density_estimator + :members: + :undoc-members: + :show-inheritance: + +jmetal.component.evaluator module +--------------------------------- + +.. automodule:: jmetal.component.evaluator + :members: + :undoc-members: + :show-inheritance: + +jmetal.component.observer module +-------------------------------- + +.. automodule:: jmetal.component.observer + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.component + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.component.test.rst b/docs/source/jmetal.component.test.rst new file mode 100644 index 00000000..94a0efc4 --- /dev/null +++ b/docs/source/jmetal.component.test.rst @@ -0,0 +1,30 @@ +jmetal.component.test package +============================= + +Submodules +---------- + +jmetal.component.test.test\_archive module +------------------------------------------ + +.. automodule:: jmetal.component.test.test_archive + :members: + :undoc-members: + :show-inheritance: + +jmetal.component.test.test\_density\_estimator module +----------------------------------------------------- + +.. automodule:: jmetal.component.test.test_density_estimator + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.component.test + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.core.rst b/docs/source/jmetal.core.rst new file mode 100644 index 00000000..8e2c9d1b --- /dev/null +++ b/docs/source/jmetal.core.rst @@ -0,0 +1,53 @@ +jmetal.core package +=================== + +Subpackages +----------- + +.. toctree:: + + jmetal.core.test + +Submodules +---------- + +jmetal.core.algorithm module +---------------------------- + +.. automodule:: jmetal.core.algorithm + :members: + :undoc-members: + :show-inheritance: + +jmetal.core.operator module +--------------------------- + +.. automodule:: jmetal.core.operator + :members: + :undoc-members: + :show-inheritance: + +jmetal.core.problem module +-------------------------- + +.. automodule:: jmetal.core.problem + :members: + :undoc-members: + :show-inheritance: + +jmetal.core.solution module +--------------------------- + +.. automodule:: jmetal.core.solution + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.core + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.core.test.rst b/docs/source/jmetal.core.test.rst new file mode 100644 index 00000000..0ddd8cc9 --- /dev/null +++ b/docs/source/jmetal.core.test.rst @@ -0,0 +1,46 @@ +jmetal.core.test package +======================== + +Submodules +---------- + +jmetal.core.test.test\_algorithm module +--------------------------------------- + +.. automodule:: jmetal.core.test.test_algorithm + :members: + :undoc-members: + :show-inheritance: + +jmetal.core.test.test\_operator module +-------------------------------------- + +.. automodule:: jmetal.core.test.test_operator + :members: + :undoc-members: + :show-inheritance: + +jmetal.core.test.test\_problem module +------------------------------------- + +.. automodule:: jmetal.core.test.test_problem + :members: + :undoc-members: + :show-inheritance: + +jmetal.core.test.test\_solution module +-------------------------------------- + +.. automodule:: jmetal.core.test.test_solution + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.core.test + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.operator.rst b/docs/source/jmetal.operator.rst new file mode 100644 index 00000000..443da83b --- /dev/null +++ b/docs/source/jmetal.operator.rst @@ -0,0 +1,45 @@ +jmetal.operator package +======================= + +Subpackages +----------- + +.. toctree:: + + jmetal.operator.test + +Submodules +---------- + +jmetal.operator.crossover module +-------------------------------- + +.. automodule:: jmetal.operator.crossover + :members: + :undoc-members: + :show-inheritance: + +jmetal.operator.mutation module +------------------------------- + +.. automodule:: jmetal.operator.mutation + :members: + :undoc-members: + :show-inheritance: + +jmetal.operator.selection module +-------------------------------- + +.. automodule:: jmetal.operator.selection + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.operator + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.operator.test.rst b/docs/source/jmetal.operator.test.rst new file mode 100644 index 00000000..f9ed52ff --- /dev/null +++ b/docs/source/jmetal.operator.test.rst @@ -0,0 +1,38 @@ +jmetal.operator.test package +============================ + +Submodules +---------- + +jmetal.operator.test.test\_crossover module +------------------------------------------- + +.. automodule:: jmetal.operator.test.test_crossover + :members: + :undoc-members: + :show-inheritance: + +jmetal.operator.test.test\_mutation module +------------------------------------------ + +.. automodule:: jmetal.operator.test.test_mutation + :members: + :undoc-members: + :show-inheritance: + +jmetal.operator.test.test\_selection module +------------------------------------------- + +.. automodule:: jmetal.operator.test.test_selection + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.operator.test + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.problem.multiobjective.rst b/docs/source/jmetal.problem.multiobjective.rst new file mode 100644 index 00000000..925a5f9b --- /dev/null +++ b/docs/source/jmetal.problem.multiobjective.rst @@ -0,0 +1,53 @@ +jmetal.problem.multiobjective package +===================================== + +Subpackages +----------- + +.. toctree:: + + jmetal.problem.multiobjective.test + +Submodules +---------- + +jmetal.problem.multiobjective.constrained module +------------------------------------------------ + +.. automodule:: jmetal.problem.multiobjective.constrained + :members: + :undoc-members: + :show-inheritance: + +jmetal.problem.multiobjective.dtlz module +----------------------------------------- + +.. automodule:: jmetal.problem.multiobjective.dtlz + :members: + :undoc-members: + :show-inheritance: + +jmetal.problem.multiobjective.unconstrained module +-------------------------------------------------- + +.. automodule:: jmetal.problem.multiobjective.unconstrained + :members: + :undoc-members: + :show-inheritance: + +jmetal.problem.multiobjective.zdt module +---------------------------------------- + +.. automodule:: jmetal.problem.multiobjective.zdt + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.problem.multiobjective + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.problem.multiobjective.test.rst b/docs/source/jmetal.problem.multiobjective.test.rst new file mode 100644 index 00000000..03126d46 --- /dev/null +++ b/docs/source/jmetal.problem.multiobjective.test.rst @@ -0,0 +1,38 @@ +jmetal.problem.multiobjective.test package +========================================== + +Submodules +---------- + +jmetal.problem.multiobjective.test.test\_constrained module +----------------------------------------------------------- + +.. automodule:: jmetal.problem.multiobjective.test.test_constrained + :members: + :undoc-members: + :show-inheritance: + +jmetal.problem.multiobjective.test.test\_unconstrained module +------------------------------------------------------------- + +.. automodule:: jmetal.problem.multiobjective.test.test_unconstrained + :members: + :undoc-members: + :show-inheritance: + +jmetal.problem.multiobjective.test.test\_zdt module +--------------------------------------------------- + +.. automodule:: jmetal.problem.multiobjective.test.test_zdt + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.problem.multiobjective.test + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.problem.rst b/docs/source/jmetal.problem.rst new file mode 100644 index 00000000..c2f8aac9 --- /dev/null +++ b/docs/source/jmetal.problem.rst @@ -0,0 +1,18 @@ +jmetal.problem package +====================== + +Subpackages +----------- + +.. toctree:: + + jmetal.problem.multiobjective + jmetal.problem.singleobjective + +Module contents +--------------- + +.. automodule:: jmetal.problem + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.problem.singleobjective.rst b/docs/source/jmetal.problem.singleobjective.rst new file mode 100644 index 00000000..cad885c1 --- /dev/null +++ b/docs/source/jmetal.problem.singleobjective.rst @@ -0,0 +1,29 @@ +jmetal.problem.singleobjective package +====================================== + +Subpackages +----------- + +.. toctree:: + + jmetal.problem.singleobjective.test + +Submodules +---------- + +jmetal.problem.singleobjective.unconstrained module +--------------------------------------------------- + +.. automodule:: jmetal.problem.singleobjective.unconstrained + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.problem.singleobjective + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.problem.singleobjective.test.rst b/docs/source/jmetal.problem.singleobjective.test.rst new file mode 100644 index 00000000..46d52079 --- /dev/null +++ b/docs/source/jmetal.problem.singleobjective.test.rst @@ -0,0 +1,22 @@ +jmetal.problem.singleobjective.test package +=========================================== + +Submodules +---------- + +jmetal.problem.singleobjective.test.test\_unconstrained module +-------------------------------------------------------------- + +.. automodule:: jmetal.problem.singleobjective.test.test_unconstrained + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.problem.singleobjective.test + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.rst b/docs/source/jmetal.rst new file mode 100644 index 00000000..f9243e1e --- /dev/null +++ b/docs/source/jmetal.rst @@ -0,0 +1,23 @@ +jmetal package +============== + +Subpackages +----------- + +.. toctree:: + + jmetal.algorithm + jmetal.component + jmetal.core + jmetal.operator + jmetal.problem + jmetal.runner + jmetal.util + +Module contents +--------------- + +.. automodule:: jmetal + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.runner.multiobjective.rst b/docs/source/jmetal.runner.multiobjective.rst new file mode 100644 index 00000000..1e54ee58 --- /dev/null +++ b/docs/source/jmetal.runner.multiobjective.rst @@ -0,0 +1,70 @@ +jmetal.runner.multiobjective package +==================================== + +Submodules +---------- + +jmetal.runner.multiobjective.nsgaII\_standard\_settings\_plot\_interactive module +--------------------------------------------------------------------------------- + +.. automodule:: jmetal.runner.multiobjective.nsgaII_standard_settings_plot_interactive + :members: + :undoc-members: + :show-inheritance: + +jmetal.runner.multiobjective.nsgaII\_standard\_settings\_with\_observer\_basic module +------------------------------------------------------------------------------------- + +.. automodule:: jmetal.runner.multiobjective.nsgaII_standard_settings_with_observer_basic + :members: + :undoc-members: + :show-inheritance: + +jmetal.runner.multiobjective.nsgaii\_standard\_settings module +-------------------------------------------------------------- + +.. automodule:: jmetal.runner.multiobjective.nsgaii_standard_settings + :members: + :undoc-members: + :show-inheritance: + +jmetal.runner.multiobjective.nsgaii\_standard\_settings\_with\_observer module +------------------------------------------------------------------------------ + +.. automodule:: jmetal.runner.multiobjective.nsgaii_standard_settings_with_observer + :members: + :undoc-members: + :show-inheritance: + +jmetal.runner.multiobjective.nsgaii\_standard\_settings\_with\_observer\_plot\_realtime module +---------------------------------------------------------------------------------------------- + +.. automodule:: jmetal.runner.multiobjective.nsgaii_standard_settings_with_observer_plot_realtime + :members: + :undoc-members: + :show-inheritance: + +jmetal.runner.multiobjective.nsgaii\_stopping\_by\_time module +-------------------------------------------------------------- + +.. automodule:: jmetal.runner.multiobjective.nsgaii_stopping_by_time + :members: + :undoc-members: + :show-inheritance: + +jmetal.runner.multiobjective.smpso\_standard\_settings module +------------------------------------------------------------- + +.. automodule:: jmetal.runner.multiobjective.smpso_standard_settings + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.runner.multiobjective + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.runner.rst b/docs/source/jmetal.runner.rst new file mode 100644 index 00000000..c3388b49 --- /dev/null +++ b/docs/source/jmetal.runner.rst @@ -0,0 +1,18 @@ +jmetal.runner package +===================== + +Subpackages +----------- + +.. toctree:: + + jmetal.runner.multiobjective + jmetal.runner.singleobjective + +Module contents +--------------- + +.. automodule:: jmetal.runner + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.runner.singleobjective.evolution_strategy.rst b/docs/source/jmetal.runner.singleobjective.evolution_strategy.rst new file mode 100644 index 00000000..a7e6847d --- /dev/null +++ b/docs/source/jmetal.runner.singleobjective.evolution_strategy.rst @@ -0,0 +1,62 @@ +jmetal.runner.singleobjective.evolution\_strategy package +========================================================= + +Submodules +---------- + +jmetal.runner.singleobjective.evolution\_strategy.elitist\_evolution\_strategy\_binary module +--------------------------------------------------------------------------------------------- + +.. automodule:: jmetal.runner.singleobjective.evolution_strategy.elitist_evolution_strategy_binary + :members: + :undoc-members: + :show-inheritance: + +jmetal.runner.singleobjective.evolution\_strategy.elitist\_evolution\_strategy\_float module +-------------------------------------------------------------------------------------------- + +.. automodule:: jmetal.runner.singleobjective.evolution_strategy.elitist_evolution_strategy_float + :members: + :undoc-members: + :show-inheritance: + +jmetal.runner.singleobjective.evolution\_strategy.elitist\_evolution\_strategy\_running\_as\_a\_thread module +------------------------------------------------------------------------------------------------------------- + +.. automodule:: jmetal.runner.singleobjective.evolution_strategy.elitist_evolution_strategy_running_as_a_thread + :members: + :undoc-members: + :show-inheritance: + +jmetal.runner.singleobjective.evolution\_strategy.non\_elitist\_evolution\_strategy\_binary module +-------------------------------------------------------------------------------------------------- + +.. automodule:: jmetal.runner.singleobjective.evolution_strategy.non_elitist_evolution_strategy_binary + :members: + :undoc-members: + :show-inheritance: + +jmetal.runner.singleobjective.evolution\_strategy.non\_elitist\_evolution\_strategy\_float module +------------------------------------------------------------------------------------------------- + +.. automodule:: jmetal.runner.singleobjective.evolution_strategy.non_elitist_evolution_strategy_float + :members: + :undoc-members: + :show-inheritance: + +jmetal.runner.singleobjective.evolution\_strategy.non\_elitist\_evolution\_strategy\_running\_as\_a\_thread module +------------------------------------------------------------------------------------------------------------------ + +.. automodule:: jmetal.runner.singleobjective.evolution_strategy.non_elitist_evolution_strategy_running_as_a_thread + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.runner.singleobjective.evolution_strategy + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.runner.singleobjective.genetic_algorithm.rst b/docs/source/jmetal.runner.singleobjective.genetic_algorithm.rst new file mode 100644 index 00000000..7154d610 --- /dev/null +++ b/docs/source/jmetal.runner.singleobjective.genetic_algorithm.rst @@ -0,0 +1,54 @@ +jmetal.runner.singleobjective.genetic\_algorithm package +======================================================== + +Submodules +---------- + +jmetal.runner.singleobjective.genetic\_algorithm.generational\_genetic\_algorithm\_binary module +------------------------------------------------------------------------------------------------ + +.. automodule:: jmetal.runner.singleobjective.genetic_algorithm.generational_genetic_algorithm_binary + :members: + :undoc-members: + :show-inheritance: + +jmetal.runner.singleobjective.genetic\_algorithm.generational\_genetic\_algorithm\_float module +----------------------------------------------------------------------------------------------- + +.. automodule:: jmetal.runner.singleobjective.genetic_algorithm.generational_genetic_algorithm_float + :members: + :undoc-members: + :show-inheritance: + +jmetal.runner.singleobjective.genetic\_algorithm.generational\_genetic\_algorithm\_running\_as\_a\_thread module +---------------------------------------------------------------------------------------------------------------- + +.. automodule:: jmetal.runner.singleobjective.genetic_algorithm.generational_genetic_algorithm_running_as_a_thread + :members: + :undoc-members: + :show-inheritance: + +jmetal.runner.singleobjective.genetic\_algorithm.generational\_genetic\_algorithm\_stopping\_by\_time module +------------------------------------------------------------------------------------------------------------ + +.. automodule:: jmetal.runner.singleobjective.genetic_algorithm.generational_genetic_algorithm_stopping_by_time + :members: + :undoc-members: + :show-inheritance: + +jmetal.runner.singleobjective.genetic\_algorithm.generational\_genetic\_algorithm\_with\_observer module +-------------------------------------------------------------------------------------------------------- + +.. automodule:: jmetal.runner.singleobjective.genetic_algorithm.generational_genetic_algorithm_with_observer + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.runner.singleobjective.genetic_algorithm + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.runner.singleobjective.rst b/docs/source/jmetal.runner.singleobjective.rst new file mode 100644 index 00000000..ccee8355 --- /dev/null +++ b/docs/source/jmetal.runner.singleobjective.rst @@ -0,0 +1,18 @@ +jmetal.runner.singleobjective package +===================================== + +Subpackages +----------- + +.. toctree:: + + jmetal.runner.singleobjective.evolution_strategy + jmetal.runner.singleobjective.genetic_algorithm + +Module contents +--------------- + +.. automodule:: jmetal.runner.singleobjective + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.util.rst b/docs/source/jmetal.util.rst new file mode 100644 index 00000000..c3147aa3 --- /dev/null +++ b/docs/source/jmetal.util.rst @@ -0,0 +1,69 @@ +jmetal.util package +=================== + +Subpackages +----------- + +.. toctree:: + + jmetal.util.test + +Submodules +---------- + +jmetal.util.comparator module +----------------------------- + +.. automodule:: jmetal.util.comparator + :members: + :undoc-members: + :show-inheritance: + +jmetal.util.graphic module +-------------------------- + +.. automodule:: jmetal.util.graphic + :members: + :undoc-members: + :show-inheritance: + +jmetal.util.observable module +----------------------------- + +.. automodule:: jmetal.util.observable + :members: + :undoc-members: + :show-inheritance: + +jmetal.util.ranking module +-------------------------- + +.. automodule:: jmetal.util.ranking + :members: + :undoc-members: + :show-inheritance: + +jmetal.util.solution\_list\_output module +----------------------------------------- + +.. automodule:: jmetal.util.solution_list_output + :members: + :undoc-members: + :show-inheritance: + +jmetal.util.time module +----------------------- + +.. automodule:: jmetal.util.time + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.util + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/jmetal.util.test.rst b/docs/source/jmetal.util.test.rst new file mode 100644 index 00000000..6607bb62 --- /dev/null +++ b/docs/source/jmetal.util.test.rst @@ -0,0 +1,46 @@ +jmetal.util.test package +======================== + +Submodules +---------- + +jmetal.util.test.test\_comparator module +---------------------------------------- + +.. automodule:: jmetal.util.test.test_comparator + :members: + :undoc-members: + :show-inheritance: + +jmetal.util.test.test\_graphic module +------------------------------------- + +.. automodule:: jmetal.util.test.test_graphic + :members: + :undoc-members: + :show-inheritance: + +jmetal.util.test.test\_observable module +---------------------------------------- + +.. automodule:: jmetal.util.test.test_observable + :members: + :undoc-members: + :show-inheritance: + +jmetal.util.test.test\_ranking module +------------------------------------- + +.. automodule:: jmetal.util.test.test_ranking + :members: + :undoc-members: + :show-inheritance: + + +Module contents +--------------- + +.. automodule:: jmetal.util.test + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/modules.rst b/docs/source/modules.rst new file mode 100644 index 00000000..f4e2b81d --- /dev/null +++ b/docs/source/modules.rst @@ -0,0 +1,7 @@ +jmetal +====== + +.. toctree:: + :maxdepth: 4 + + jmetal diff --git a/jmetal/algorithm/multiobjective/nsgaii.py b/jmetal/algorithm/multiobjective/nsgaii.py index 386f46b3..924eb460 100644 --- a/jmetal/algorithm/multiobjective/nsgaii.py +++ b/jmetal/algorithm/multiobjective/nsgaii.py @@ -10,6 +10,14 @@ S = TypeVar('S') R = TypeVar(List[S]) +""" +.. module:: NSGA-II + :platform: Unix, Windows + :synopsis: Implementation of NSGA-II. + +.. moduleauthor:: Antonio J. Nebro +""" + class NSGAII(GenerationalGeneticAlgorithm[S, R]): def __init__(self, @@ -21,6 +29,19 @@ def __init__(self, selection: Selection[List[S], S], observable: Observable = DefaultObservable(), evaluator: Evaluator[S] = SequentialEvaluator[S]()): + """ NSGA-II is a genetic algorithm (GA), i.e. it belongs to the evolutionary algorithms (EAs) + family. The implementation of NSGA-II provided in jMetalPy follows the evolutionary + algorithm template described in the algorithm templates section (:mod:`algorithm`) of the documentation. + + :param problem: The problem to solve. + :param population_size: + :param max_evaluations: + :param mutation: + :param crossover: + :param selection: + :param observable: + :param evaluator: An evaluator object to evaluate the solutions in the population. + """ super(NSGAII, self).__init__( problem, population_size, @@ -32,6 +53,13 @@ def __init__(self, evaluator) def replacement(self, population: List[S], offspring_population: List[S]) -> List[List[TypeVar('S')]]: + """ This method joins the current and offspring populations to produce the population of the next generation + by applying the ranking and crowding distance selection. + + :param population: + :param offspring_population: + :return: New population. + """ join_population = population + offspring_population return RankingAndCrowdingDistanceSelection(self.population_size).execute(join_population) @@ -39,6 +67,8 @@ def get_name(self) -> str: return "NSGA-II" def get_result(self) -> R: + """:return: Population. + """ return self.population diff --git a/jmetal/algorithm/multiobjective/randomSearch.py b/jmetal/algorithm/multiobjective/randomSearch.py index 3f6f9303..16f44535 100644 --- a/jmetal/algorithm/multiobjective/randomSearch.py +++ b/jmetal/algorithm/multiobjective/randomSearch.py @@ -3,10 +3,15 @@ from jmetal.component.archive import NonDominatedSolutionListArchive from jmetal.core.problem import Problem -""" Class representing simple random search algorithms """ +S = TypeVar('S') +""" +.. module:: RamdomSearch + :platform: Unix, Windows + :synopsis: Simple random search algorithms. -S = TypeVar('S') +.. moduleauthor:: Antonio J. Nebro +""" class RandomSearch(Generic[S]): diff --git a/jmetal/algorithm/multiobjective/smpso.py b/jmetal/algorithm/multiobjective/smpso.py index e22f7672..35990b41 100644 --- a/jmetal/algorithm/multiobjective/smpso.py +++ b/jmetal/algorithm/multiobjective/smpso.py @@ -16,6 +16,14 @@ R = TypeVar('R') +""" +.. module:: SMPSO + :platform: Unix, Windows + :synopsis: Implementation of SMPSO. + +.. moduleauthor:: Antonio Benítez-Hidalgo +""" + class SMPSO(ParticleSwarmOptimization): def __init__(self, @@ -26,6 +34,22 @@ def __init__(self, leaders: BoundedArchive[FloatSolution], observable: Observable = DefaultObservable(), evaluator: Evaluator[FloatSolution] = SequentialEvaluator[FloatSolution]()): + """ This class implements the SMPSO algorithm described in + + * SMPSO: A new PSO-based metaheuristic for multi-objective optimization + * MCDM 2009. DOI: ``_. + + The implementation of SMPSO provided in jMetalPy follows the + algorithm template described in the algorithm templates section (:mod:`algorithm`) of the documentation. + + :param problem: The problem to solve. + :param swarm_size: + :param max_evaluations: + :param mutation: + :param leaders: + :param observable: + :param evaluator: An evaluator object to evaluate the solutions in the population. + """ super(SMPSO, self).__init__() self.problem = problem self.swarm_size = swarm_size diff --git a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py index 14a91977..aa429bf1 100644 --- a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py +++ b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py @@ -10,6 +10,14 @@ S = TypeVar('S') R = TypeVar('R') +""" +.. module:: evolutionaryalgorithm + :platform: Unix, Windows + :synopsis: Implementation of Evolutionary Algorithms. + +.. moduleauthor:: Antonio J. Nebro +""" + class ElitistEvolutionStrategy(EvolutionaryAlgorithm[S, R]): def __init__(self, diff --git a/jmetal/core/algorithm.py b/jmetal/core/algorithm.py index 54f36c58..5f939e66 100644 --- a/jmetal/core/algorithm.py +++ b/jmetal/core/algorithm.py @@ -12,6 +12,14 @@ S = TypeVar('S') R = TypeVar('R') +""" +.. module:: algorithm + :platform: Unix, Windows + :synopsis: Templates for algorithms. + +.. moduleauthor:: Antonio J. Nebro +""" + class Algorithm(Generic[S, R], threading.Thread): def __init__(self): @@ -65,27 +73,29 @@ def get_result(self) -> R: pass def run(self): - """ - Step One: Generate the initial population of individuals randomly. (First generation) - Step Two: Evaluate the fitness of each individual in that population (time limit, sufficient fitness achieved, etc.) - Step Three: Repeat the following regenerational steps until termination: + """* Step One: Generate the initial population of individuals randomly. (First generation) + * Step Two: Evaluate the fitness of each individual in that population (time limit, sufficient fitness achieved, etc.) + * Step Three: Repeat the following regenerational steps until termination: 1. Select the best-fit individuals for reproduction. (Parents) 2. Breed new individuals through crossover and mutation operations to give birth to offspring. 3. Evaluate the individual fitness of new individuals. 4. Replace least-fit population with new individuals. + + .. note:: + To develop an EA, all the abstract the methods used in the run() method must be implemented. """ self.start_computing_time = time.time() - self.population = self.create_initial_population() # Step One - self.population = self.evaluate_population(self.population) # Step Two + self.population = self.create_initial_population() + self.population = self.evaluate_population(self.population) self.init_progress() - while not self.is_stopping_condition_reached(): # Step Three - mating_population = self.selection(self.population) # Step Three.1 - offspring_population = self.reproduction(mating_population) # Step Three.2 - offspring_population = self.evaluate_population(offspring_population) # Step Three.3 - self.population = self.replacement(self.population, offspring_population) # Step Three.4 + while not self.is_stopping_condition_reached(): + mating_population = self.selection(self.population) + offspring_population = self.reproduction(mating_population) + offspring_population = self.evaluate_population(offspring_population) + self.population = self.replacement(self.population, offspring_population) self.update_progress() self.total_computing_time = self.get_current_computing_time() diff --git a/jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_with_observer.py b/jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_with_observer.py index 95ded0a1..53fd2243 100644 --- a/jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_with_observer.py +++ b/jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_with_observer.py @@ -1,7 +1,7 @@ import logging from jmetal.algorithm.singleobjective.evolutionaryalgorithm import GenerationalGeneticAlgorithm -from jmetal.component.observer import BasicAlgorithmConsumer +from jmetal.component.observer import BasicAlgorithmObserver from jmetal.core.solution import FloatSolution from jmetal.operator.crossover import SBX from jmetal.operator.mutation import Polynomial @@ -23,7 +23,7 @@ def main() -> None: crossover=SBX(1.0, distribution_index=20), selection=BinaryTournamentSelection()) - observer = BasicAlgorithmConsumer(2000) + observer = BasicAlgorithmObserver(2000) algorithm.observable.register(observer=observer) From 2d22390a10ac67b8ca7c1557080bde136481c6b8 Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 4 May 2018 13:05:31 +0200 Subject: [PATCH 11/90] Updated doc configuration file --- docs/source/conf.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/docs/source/conf.py b/docs/source/conf.py index bbb61108..14bf909a 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -16,6 +16,31 @@ import sys sys.path.insert(0, os.path.abspath('../..')) +# http://read-the-docs.readthedocs.org/en/latest/faq.html#i-get-import-errors-on-libraries-that-depend-on-c-modules +try: + from unittest.mock import MagicMock +except ImportError: + from mock import Mock as MagicMock + + +class Mock(MagicMock): + @classmethod + def __getattr__(cls, name): + return Mock() + + +MOCK_MODULES = [ + 'numpy', + 'scipy', + 'matplotlib', + 'scipy.ndimage', + 'scipy.ndimage.filters', + 'skimage', + 'skimage.morphology', + 'skimage.io', + 'skimage.exposure', +] +sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES) # -- Project information ----------------------------------------------------- From 049a37b27b4ebca2a4188ea6967b7ed84b80689f Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 4 May 2018 13:09:36 +0200 Subject: [PATCH 12/90] Undo changes --- docs/source/conf.py | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 14bf909a..bbb61108 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -16,31 +16,6 @@ import sys sys.path.insert(0, os.path.abspath('../..')) -# http://read-the-docs.readthedocs.org/en/latest/faq.html#i-get-import-errors-on-libraries-that-depend-on-c-modules -try: - from unittest.mock import MagicMock -except ImportError: - from mock import Mock as MagicMock - - -class Mock(MagicMock): - @classmethod - def __getattr__(cls, name): - return Mock() - - -MOCK_MODULES = [ - 'numpy', - 'scipy', - 'matplotlib', - 'scipy.ndimage', - 'scipy.ndimage.filters', - 'skimage', - 'skimage.morphology', - 'skimage.io', - 'skimage.exposure', -] -sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES) # -- Project information ----------------------------------------------------- From 34a7df51fd452dd4f8456cf8b50fb9bd2cdf5e7c Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 4 May 2018 13:19:48 +0200 Subject: [PATCH 13/90] Updated doc configuration file --- docs/source/conf.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/source/conf.py b/docs/source/conf.py index bbb61108..45425164 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -16,6 +16,12 @@ import sys sys.path.insert(0, os.path.abspath('../..')) +# http://blog.rtwilson.com/how-to-make-your-sphinx-documentation-compile-with-readthedocs-when-youre-using-numpy-and-scipy/ +import mock + +MOCK_MODULES = ['numpy', 'matplotlib'] +for mod_name in MOCK_MODULES: + sys.modules[mod_name] = mock.Mock() # -- Project information ----------------------------------------------------- From a6db29efdb9f57f9851222c8918cad369651ec50 Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 4 May 2018 13:32:09 +0200 Subject: [PATCH 14/90] WIP auto-doc build --- docs/requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/requirements.txt diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..8e052c08 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1 @@ +sphinx==1.5.6 \ No newline at end of file From fa23977c75e576e16d4277efe47997f2e75d061d Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 4 May 2018 13:42:56 +0200 Subject: [PATCH 15/90] Updated module version --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 8e052c08..5a154449 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1 @@ -sphinx==1.5.6 \ No newline at end of file +sphinx==1.6.3 \ No newline at end of file From e38677d20c6f70c8a2cfcd581083e4db1d599a30 Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 7 May 2018 11:43:24 +0200 Subject: [PATCH 16/90] WIP documentation --- jmetal/component/archive.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/jmetal/component/archive.py b/jmetal/component/archive.py index 77c8c552..4a2a670d 100644 --- a/jmetal/component/archive.py +++ b/jmetal/component/archive.py @@ -5,6 +5,14 @@ S = TypeVar('S') +""" +.. module:: archive + :platform: Unix, Windows + :synopsis: Archive implementation. + +.. moduleauthor:: Antonio J. Nebro +""" + class Archive(Generic[S]): def __init__(self): From a0641563825862ff67bdec16399a9c3768cb9763 Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 7 May 2018 12:06:58 +0200 Subject: [PATCH 17/90] Added readthedocs configuration file --- .readthedocs.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .readthedocs.yml diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 00000000..60ede3de --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,9 @@ +build: + image: latest + +python: + version: 3.6 + pip_install: true + pip_install: true + +requirements_file: docs/requirements.txt \ No newline at end of file From 0a2ae4d7f2930708183774c0924b2a3154497324 Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 7 May 2018 12:18:08 +0200 Subject: [PATCH 18/90] Populate docs index --- docs/source/conf.py | 2 +- docs/source/index.rst | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 45425164..1694ee45 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -19,7 +19,7 @@ # http://blog.rtwilson.com/how-to-make-your-sphinx-documentation-compile-with-readthedocs-when-youre-using-numpy-and-scipy/ import mock -MOCK_MODULES = ['numpy', 'matplotlib'] +MOCK_MODULES = ['numpy', 'matplotlib', 'matplotlib.pyplot'] for mod_name in MOCK_MODULES: sys.modules[mod_name] = mock.Mock() diff --git a/docs/source/index.rst b/docs/source/index.rst index a30fffa9..a204fb01 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -10,11 +10,44 @@ Welcome to jMetalPy's documentation! :maxdepth: 2 :caption: Contents: + changelog +Installation +------------ + +Via pip: + +.. code-block:: console + + $ pip install jmetalpy + +Via Github: + +.. code-block:: console + + $ git clone https://github.com/jMetal/jMetalPy.git + $ pip install -r requirements.txt + + +Basic Usage +----------- + +.. code-block:: python + + problem = ZDT1() + algorithm = NSGAII[FloatSolution, List[FloatSolution]]( + problem=problem, + population_size=100, + max_evaluations=25000, + mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), + crossover=SBX(1.0, distribution_index=20), + selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) + + algorithm.run() + result = algorithm.get_result() Indices and tables ================== * :ref:`genindex` * :ref:`modindex` -* :ref:`search` From 199ed4a6b4478db0f8a92ed9675dff17f891b379 Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 7 May 2018 12:31:24 +0200 Subject: [PATCH 19/90] WIP documentation --- .readthedocs.yml | 1 - docs/source/about.rst | 0 .../{ => api}/jmetal.algorithm.multiobjective.rst | 0 .../jmetal.algorithm.multiobjective.test.rst | 0 docs/source/{ => api}/jmetal.algorithm.rst | 0 .../{ => api}/jmetal.algorithm.singleobjective.rst | 0 docs/source/{ => api}/jmetal.component.rst | 0 docs/source/{ => api}/jmetal.component.test.rst | 0 docs/source/{ => api}/jmetal.core.rst | 0 docs/source/{ => api}/jmetal.core.test.rst | 0 docs/source/{ => api}/jmetal.operator.rst | 0 docs/source/{ => api}/jmetal.operator.test.rst | 0 .../{ => api}/jmetal.problem.multiobjective.rst | 0 .../{ => api}/jmetal.problem.multiobjective.test.rst | 0 docs/source/{ => api}/jmetal.problem.rst | 0 .../{ => api}/jmetal.problem.singleobjective.rst | 0 .../jmetal.problem.singleobjective.test.rst | 0 docs/source/{ => api}/jmetal.rst | 0 .../{ => api}/jmetal.runner.multiobjective.rst | 0 docs/source/{ => api}/jmetal.runner.rst | 0 ...tal.runner.singleobjective.evolution_strategy.rst | 0 ...etal.runner.singleobjective.genetic_algorithm.rst | 0 .../{ => api}/jmetal.runner.singleobjective.rst | 0 docs/source/{ => api}/jmetal.util.rst | 0 docs/source/{ => api}/jmetal.util.test.rst | 0 docs/source/index.rst | 12 ++++++++++-- docs/source/runner.rst | 0 27 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 docs/source/about.rst rename docs/source/{ => api}/jmetal.algorithm.multiobjective.rst (100%) rename docs/source/{ => api}/jmetal.algorithm.multiobjective.test.rst (100%) rename docs/source/{ => api}/jmetal.algorithm.rst (100%) rename docs/source/{ => api}/jmetal.algorithm.singleobjective.rst (100%) rename docs/source/{ => api}/jmetal.component.rst (100%) rename docs/source/{ => api}/jmetal.component.test.rst (100%) rename docs/source/{ => api}/jmetal.core.rst (100%) rename docs/source/{ => api}/jmetal.core.test.rst (100%) rename docs/source/{ => api}/jmetal.operator.rst (100%) rename docs/source/{ => api}/jmetal.operator.test.rst (100%) rename docs/source/{ => api}/jmetal.problem.multiobjective.rst (100%) rename docs/source/{ => api}/jmetal.problem.multiobjective.test.rst (100%) rename docs/source/{ => api}/jmetal.problem.rst (100%) rename docs/source/{ => api}/jmetal.problem.singleobjective.rst (100%) rename docs/source/{ => api}/jmetal.problem.singleobjective.test.rst (100%) rename docs/source/{ => api}/jmetal.rst (100%) rename docs/source/{ => api}/jmetal.runner.multiobjective.rst (100%) rename docs/source/{ => api}/jmetal.runner.rst (100%) rename docs/source/{ => api}/jmetal.runner.singleobjective.evolution_strategy.rst (100%) rename docs/source/{ => api}/jmetal.runner.singleobjective.genetic_algorithm.rst (100%) rename docs/source/{ => api}/jmetal.runner.singleobjective.rst (100%) rename docs/source/{ => api}/jmetal.util.rst (100%) rename docs/source/{ => api}/jmetal.util.test.rst (100%) create mode 100644 docs/source/runner.rst diff --git a/.readthedocs.yml b/.readthedocs.yml index 60ede3de..4c99b882 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -4,6 +4,5 @@ build: python: version: 3.6 pip_install: true - pip_install: true requirements_file: docs/requirements.txt \ No newline at end of file diff --git a/docs/source/about.rst b/docs/source/about.rst new file mode 100644 index 00000000..e69de29b diff --git a/docs/source/jmetal.algorithm.multiobjective.rst b/docs/source/api/jmetal.algorithm.multiobjective.rst similarity index 100% rename from docs/source/jmetal.algorithm.multiobjective.rst rename to docs/source/api/jmetal.algorithm.multiobjective.rst diff --git a/docs/source/jmetal.algorithm.multiobjective.test.rst b/docs/source/api/jmetal.algorithm.multiobjective.test.rst similarity index 100% rename from docs/source/jmetal.algorithm.multiobjective.test.rst rename to docs/source/api/jmetal.algorithm.multiobjective.test.rst diff --git a/docs/source/jmetal.algorithm.rst b/docs/source/api/jmetal.algorithm.rst similarity index 100% rename from docs/source/jmetal.algorithm.rst rename to docs/source/api/jmetal.algorithm.rst diff --git a/docs/source/jmetal.algorithm.singleobjective.rst b/docs/source/api/jmetal.algorithm.singleobjective.rst similarity index 100% rename from docs/source/jmetal.algorithm.singleobjective.rst rename to docs/source/api/jmetal.algorithm.singleobjective.rst diff --git a/docs/source/jmetal.component.rst b/docs/source/api/jmetal.component.rst similarity index 100% rename from docs/source/jmetal.component.rst rename to docs/source/api/jmetal.component.rst diff --git a/docs/source/jmetal.component.test.rst b/docs/source/api/jmetal.component.test.rst similarity index 100% rename from docs/source/jmetal.component.test.rst rename to docs/source/api/jmetal.component.test.rst diff --git a/docs/source/jmetal.core.rst b/docs/source/api/jmetal.core.rst similarity index 100% rename from docs/source/jmetal.core.rst rename to docs/source/api/jmetal.core.rst diff --git a/docs/source/jmetal.core.test.rst b/docs/source/api/jmetal.core.test.rst similarity index 100% rename from docs/source/jmetal.core.test.rst rename to docs/source/api/jmetal.core.test.rst diff --git a/docs/source/jmetal.operator.rst b/docs/source/api/jmetal.operator.rst similarity index 100% rename from docs/source/jmetal.operator.rst rename to docs/source/api/jmetal.operator.rst diff --git a/docs/source/jmetal.operator.test.rst b/docs/source/api/jmetal.operator.test.rst similarity index 100% rename from docs/source/jmetal.operator.test.rst rename to docs/source/api/jmetal.operator.test.rst diff --git a/docs/source/jmetal.problem.multiobjective.rst b/docs/source/api/jmetal.problem.multiobjective.rst similarity index 100% rename from docs/source/jmetal.problem.multiobjective.rst rename to docs/source/api/jmetal.problem.multiobjective.rst diff --git a/docs/source/jmetal.problem.multiobjective.test.rst b/docs/source/api/jmetal.problem.multiobjective.test.rst similarity index 100% rename from docs/source/jmetal.problem.multiobjective.test.rst rename to docs/source/api/jmetal.problem.multiobjective.test.rst diff --git a/docs/source/jmetal.problem.rst b/docs/source/api/jmetal.problem.rst similarity index 100% rename from docs/source/jmetal.problem.rst rename to docs/source/api/jmetal.problem.rst diff --git a/docs/source/jmetal.problem.singleobjective.rst b/docs/source/api/jmetal.problem.singleobjective.rst similarity index 100% rename from docs/source/jmetal.problem.singleobjective.rst rename to docs/source/api/jmetal.problem.singleobjective.rst diff --git a/docs/source/jmetal.problem.singleobjective.test.rst b/docs/source/api/jmetal.problem.singleobjective.test.rst similarity index 100% rename from docs/source/jmetal.problem.singleobjective.test.rst rename to docs/source/api/jmetal.problem.singleobjective.test.rst diff --git a/docs/source/jmetal.rst b/docs/source/api/jmetal.rst similarity index 100% rename from docs/source/jmetal.rst rename to docs/source/api/jmetal.rst diff --git a/docs/source/jmetal.runner.multiobjective.rst b/docs/source/api/jmetal.runner.multiobjective.rst similarity index 100% rename from docs/source/jmetal.runner.multiobjective.rst rename to docs/source/api/jmetal.runner.multiobjective.rst diff --git a/docs/source/jmetal.runner.rst b/docs/source/api/jmetal.runner.rst similarity index 100% rename from docs/source/jmetal.runner.rst rename to docs/source/api/jmetal.runner.rst diff --git a/docs/source/jmetal.runner.singleobjective.evolution_strategy.rst b/docs/source/api/jmetal.runner.singleobjective.evolution_strategy.rst similarity index 100% rename from docs/source/jmetal.runner.singleobjective.evolution_strategy.rst rename to docs/source/api/jmetal.runner.singleobjective.evolution_strategy.rst diff --git a/docs/source/jmetal.runner.singleobjective.genetic_algorithm.rst b/docs/source/api/jmetal.runner.singleobjective.genetic_algorithm.rst similarity index 100% rename from docs/source/jmetal.runner.singleobjective.genetic_algorithm.rst rename to docs/source/api/jmetal.runner.singleobjective.genetic_algorithm.rst diff --git a/docs/source/jmetal.runner.singleobjective.rst b/docs/source/api/jmetal.runner.singleobjective.rst similarity index 100% rename from docs/source/jmetal.runner.singleobjective.rst rename to docs/source/api/jmetal.runner.singleobjective.rst diff --git a/docs/source/jmetal.util.rst b/docs/source/api/jmetal.util.rst similarity index 100% rename from docs/source/jmetal.util.rst rename to docs/source/api/jmetal.util.rst diff --git a/docs/source/jmetal.util.test.rst b/docs/source/api/jmetal.util.test.rst similarity index 100% rename from docs/source/jmetal.util.test.rst rename to docs/source/api/jmetal.util.test.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index a204fb01..f6846f90 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -3,7 +3,7 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Welcome to jMetalPy's documentation! +jMetalPy ==================================== .. toctree:: @@ -11,6 +11,8 @@ Welcome to jMetalPy's documentation! :caption: Contents: changelog + runner + about Installation ------------ @@ -28,7 +30,6 @@ Via Github: $ git clone https://github.com/jMetal/jMetalPy.git $ pip install -r requirements.txt - Basic Usage ----------- @@ -46,6 +47,13 @@ Basic Usage algorithm.run() result = algorithm.get_result() +API documentation +----------------- + +.. toctree:: + + api/jmetal + Indices and tables ================== diff --git a/docs/source/runner.rst b/docs/source/runner.rst new file mode 100644 index 00000000..e69de29b From 6e4fd339d5ec1a88bf0451f936f92006e9da8395 Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 7 May 2018 12:40:43 +0200 Subject: [PATCH 20/90] WIP documentation structure --- docs/source/about.rst | 2 + .../api/jmetal.algorithm.multiobjective.rst | 16 ----- .../jmetal.algorithm.multiobjective.test.rst | 22 ------ docs/source/api/jmetal.algorithm.rst | 8 --- .../api/jmetal.algorithm.singleobjective.rst | 9 --- docs/source/api/jmetal.component.rst | 18 +---- docs/source/api/jmetal.component.test.rst | 30 -------- docs/source/api/jmetal.core.rst | 18 +---- docs/source/api/jmetal.core.test.rst | 46 ------------ docs/source/api/jmetal.operator.rst | 16 ----- docs/source/api/jmetal.operator.test.rst | 38 ---------- .../api/jmetal.problem.multiobjective.rst | 18 +---- .../jmetal.problem.multiobjective.test.rst | 38 ---------- docs/source/api/jmetal.problem.rst | 10 +-- .../api/jmetal.problem.singleobjective.rst | 18 +---- .../jmetal.problem.singleobjective.test.rst | 22 ------ docs/source/api/jmetal.rst | 12 +--- .../api/jmetal.runner.multiobjective.rst | 70 ------------------- docs/source/api/jmetal.runner.rst | 18 ----- ...ner.singleobjective.evolution_strategy.rst | 62 ---------------- ...nner.singleobjective.genetic_algorithm.rst | 54 -------------- .../api/jmetal.runner.singleobjective.rst | 18 ----- docs/source/api/jmetal.util.rst | 18 +---- docs/source/api/jmetal.util.test.rst | 46 ------------ docs/source/runner.rst | 2 + 25 files changed, 12 insertions(+), 617 deletions(-) delete mode 100644 docs/source/api/jmetal.algorithm.multiobjective.test.rst delete mode 100644 docs/source/api/jmetal.component.test.rst delete mode 100644 docs/source/api/jmetal.core.test.rst delete mode 100644 docs/source/api/jmetal.operator.test.rst delete mode 100644 docs/source/api/jmetal.problem.multiobjective.test.rst delete mode 100644 docs/source/api/jmetal.problem.singleobjective.test.rst delete mode 100644 docs/source/api/jmetal.runner.multiobjective.rst delete mode 100644 docs/source/api/jmetal.runner.rst delete mode 100644 docs/source/api/jmetal.runner.singleobjective.evolution_strategy.rst delete mode 100644 docs/source/api/jmetal.runner.singleobjective.genetic_algorithm.rst delete mode 100644 docs/source/api/jmetal.runner.singleobjective.rst delete mode 100644 docs/source/api/jmetal.util.test.rst diff --git a/docs/source/about.rst b/docs/source/about.rst index e69de29b..f0142046 100644 --- a/docs/source/about.rst +++ b/docs/source/about.rst @@ -0,0 +1,2 @@ +About +============== \ No newline at end of file diff --git a/docs/source/api/jmetal.algorithm.multiobjective.rst b/docs/source/api/jmetal.algorithm.multiobjective.rst index 77baa1d6..d2d309b9 100644 --- a/docs/source/api/jmetal.algorithm.multiobjective.rst +++ b/docs/source/api/jmetal.algorithm.multiobjective.rst @@ -1,13 +1,6 @@ jmetal.algorithm.multiobjective package ======================================= -Subpackages ------------ - -.. toctree:: - - jmetal.algorithm.multiobjective.test - Submodules ---------- @@ -34,12 +27,3 @@ jmetal.algorithm.multiobjective.smpso module :members: :undoc-members: :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.algorithm.multiobjective - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/jmetal.algorithm.multiobjective.test.rst b/docs/source/api/jmetal.algorithm.multiobjective.test.rst deleted file mode 100644 index c657a3f9..00000000 --- a/docs/source/api/jmetal.algorithm.multiobjective.test.rst +++ /dev/null @@ -1,22 +0,0 @@ -jmetal.algorithm.multiobjective.test package -============================================ - -Submodules ----------- - -jmetal.algorithm.multiobjective.test.test\_smpo module ------------------------------------------------------- - -.. automodule:: jmetal.algorithm.multiobjective.test.test_smpo - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.algorithm.multiobjective.test - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/jmetal.algorithm.rst b/docs/source/api/jmetal.algorithm.rst index e0fd2a03..1b59a800 100644 --- a/docs/source/api/jmetal.algorithm.rst +++ b/docs/source/api/jmetal.algorithm.rst @@ -8,11 +8,3 @@ Subpackages jmetal.algorithm.multiobjective jmetal.algorithm.singleobjective - -Module contents ---------------- - -.. automodule:: jmetal.algorithm - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/jmetal.algorithm.singleobjective.rst b/docs/source/api/jmetal.algorithm.singleobjective.rst index 70e0d327..216438aa 100644 --- a/docs/source/api/jmetal.algorithm.singleobjective.rst +++ b/docs/source/api/jmetal.algorithm.singleobjective.rst @@ -11,12 +11,3 @@ jmetal.algorithm.singleobjective.evolutionaryalgorithm module :members: :undoc-members: :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.algorithm.singleobjective - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/jmetal.component.rst b/docs/source/api/jmetal.component.rst index 207cea0b..1ef57f82 100644 --- a/docs/source/api/jmetal.component.rst +++ b/docs/source/api/jmetal.component.rst @@ -1,13 +1,6 @@ jmetal.component package ======================== -Subpackages ------------ - -.. toctree:: - - jmetal.component.test - Submodules ---------- @@ -41,13 +34,4 @@ jmetal.component.observer module .. automodule:: jmetal.component.observer :members: :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.component - :members: - :undoc-members: - :show-inheritance: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/api/jmetal.component.test.rst b/docs/source/api/jmetal.component.test.rst deleted file mode 100644 index 94a0efc4..00000000 --- a/docs/source/api/jmetal.component.test.rst +++ /dev/null @@ -1,30 +0,0 @@ -jmetal.component.test package -============================= - -Submodules ----------- - -jmetal.component.test.test\_archive module ------------------------------------------- - -.. automodule:: jmetal.component.test.test_archive - :members: - :undoc-members: - :show-inheritance: - -jmetal.component.test.test\_density\_estimator module ------------------------------------------------------ - -.. automodule:: jmetal.component.test.test_density_estimator - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.component.test - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/jmetal.core.rst b/docs/source/api/jmetal.core.rst index 8e2c9d1b..efcea133 100644 --- a/docs/source/api/jmetal.core.rst +++ b/docs/source/api/jmetal.core.rst @@ -1,13 +1,6 @@ jmetal.core package =================== -Subpackages ------------ - -.. toctree:: - - jmetal.core.test - Submodules ---------- @@ -41,13 +34,4 @@ jmetal.core.solution module .. automodule:: jmetal.core.solution :members: :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.core - :members: - :undoc-members: - :show-inheritance: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/api/jmetal.core.test.rst b/docs/source/api/jmetal.core.test.rst deleted file mode 100644 index 0ddd8cc9..00000000 --- a/docs/source/api/jmetal.core.test.rst +++ /dev/null @@ -1,46 +0,0 @@ -jmetal.core.test package -======================== - -Submodules ----------- - -jmetal.core.test.test\_algorithm module ---------------------------------------- - -.. automodule:: jmetal.core.test.test_algorithm - :members: - :undoc-members: - :show-inheritance: - -jmetal.core.test.test\_operator module --------------------------------------- - -.. automodule:: jmetal.core.test.test_operator - :members: - :undoc-members: - :show-inheritance: - -jmetal.core.test.test\_problem module -------------------------------------- - -.. automodule:: jmetal.core.test.test_problem - :members: - :undoc-members: - :show-inheritance: - -jmetal.core.test.test\_solution module --------------------------------------- - -.. automodule:: jmetal.core.test.test_solution - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.core.test - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/jmetal.operator.rst b/docs/source/api/jmetal.operator.rst index 443da83b..17847757 100644 --- a/docs/source/api/jmetal.operator.rst +++ b/docs/source/api/jmetal.operator.rst @@ -1,13 +1,6 @@ jmetal.operator package ======================= -Subpackages ------------ - -.. toctree:: - - jmetal.operator.test - Submodules ---------- @@ -34,12 +27,3 @@ jmetal.operator.selection module :members: :undoc-members: :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.operator - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/jmetal.operator.test.rst b/docs/source/api/jmetal.operator.test.rst deleted file mode 100644 index f9ed52ff..00000000 --- a/docs/source/api/jmetal.operator.test.rst +++ /dev/null @@ -1,38 +0,0 @@ -jmetal.operator.test package -============================ - -Submodules ----------- - -jmetal.operator.test.test\_crossover module -------------------------------------------- - -.. automodule:: jmetal.operator.test.test_crossover - :members: - :undoc-members: - :show-inheritance: - -jmetal.operator.test.test\_mutation module ------------------------------------------- - -.. automodule:: jmetal.operator.test.test_mutation - :members: - :undoc-members: - :show-inheritance: - -jmetal.operator.test.test\_selection module -------------------------------------------- - -.. automodule:: jmetal.operator.test.test_selection - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.operator.test - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/jmetal.problem.multiobjective.rst b/docs/source/api/jmetal.problem.multiobjective.rst index 925a5f9b..5f2dbd13 100644 --- a/docs/source/api/jmetal.problem.multiobjective.rst +++ b/docs/source/api/jmetal.problem.multiobjective.rst @@ -1,13 +1,6 @@ jmetal.problem.multiobjective package ===================================== -Subpackages ------------ - -.. toctree:: - - jmetal.problem.multiobjective.test - Submodules ---------- @@ -41,13 +34,4 @@ jmetal.problem.multiobjective.zdt module .. automodule:: jmetal.problem.multiobjective.zdt :members: :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.problem.multiobjective - :members: - :undoc-members: - :show-inheritance: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/api/jmetal.problem.multiobjective.test.rst b/docs/source/api/jmetal.problem.multiobjective.test.rst deleted file mode 100644 index 03126d46..00000000 --- a/docs/source/api/jmetal.problem.multiobjective.test.rst +++ /dev/null @@ -1,38 +0,0 @@ -jmetal.problem.multiobjective.test package -========================================== - -Submodules ----------- - -jmetal.problem.multiobjective.test.test\_constrained module ------------------------------------------------------------ - -.. automodule:: jmetal.problem.multiobjective.test.test_constrained - :members: - :undoc-members: - :show-inheritance: - -jmetal.problem.multiobjective.test.test\_unconstrained module -------------------------------------------------------------- - -.. automodule:: jmetal.problem.multiobjective.test.test_unconstrained - :members: - :undoc-members: - :show-inheritance: - -jmetal.problem.multiobjective.test.test\_zdt module ---------------------------------------------------- - -.. automodule:: jmetal.problem.multiobjective.test.test_zdt - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.problem.multiobjective.test - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/jmetal.problem.rst b/docs/source/api/jmetal.problem.rst index c2f8aac9..ad6e281d 100644 --- a/docs/source/api/jmetal.problem.rst +++ b/docs/source/api/jmetal.problem.rst @@ -7,12 +7,4 @@ Subpackages .. toctree:: jmetal.problem.multiobjective - jmetal.problem.singleobjective - -Module contents ---------------- - -.. automodule:: jmetal.problem - :members: - :undoc-members: - :show-inheritance: + jmetal.problem.singleobjective \ No newline at end of file diff --git a/docs/source/api/jmetal.problem.singleobjective.rst b/docs/source/api/jmetal.problem.singleobjective.rst index cad885c1..f7dc5e6e 100644 --- a/docs/source/api/jmetal.problem.singleobjective.rst +++ b/docs/source/api/jmetal.problem.singleobjective.rst @@ -1,13 +1,6 @@ jmetal.problem.singleobjective package ====================================== -Subpackages ------------ - -.. toctree:: - - jmetal.problem.singleobjective.test - Submodules ---------- @@ -17,13 +10,4 @@ jmetal.problem.singleobjective.unconstrained module .. automodule:: jmetal.problem.singleobjective.unconstrained :members: :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.problem.singleobjective - :members: - :undoc-members: - :show-inheritance: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/api/jmetal.problem.singleobjective.test.rst b/docs/source/api/jmetal.problem.singleobjective.test.rst deleted file mode 100644 index 46d52079..00000000 --- a/docs/source/api/jmetal.problem.singleobjective.test.rst +++ /dev/null @@ -1,22 +0,0 @@ -jmetal.problem.singleobjective.test package -=========================================== - -Submodules ----------- - -jmetal.problem.singleobjective.test.test\_unconstrained module --------------------------------------------------------------- - -.. automodule:: jmetal.problem.singleobjective.test.test_unconstrained - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.problem.singleobjective.test - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/jmetal.rst b/docs/source/api/jmetal.rst index f9243e1e..63bbbac4 100644 --- a/docs/source/api/jmetal.rst +++ b/docs/source/api/jmetal.rst @@ -1,4 +1,4 @@ -jmetal package +jMetalPy API ============== Subpackages @@ -12,12 +12,4 @@ Subpackages jmetal.operator jmetal.problem jmetal.runner - jmetal.util - -Module contents ---------------- - -.. automodule:: jmetal - :members: - :undoc-members: - :show-inheritance: + jmetal.util \ No newline at end of file diff --git a/docs/source/api/jmetal.runner.multiobjective.rst b/docs/source/api/jmetal.runner.multiobjective.rst deleted file mode 100644 index 1e54ee58..00000000 --- a/docs/source/api/jmetal.runner.multiobjective.rst +++ /dev/null @@ -1,70 +0,0 @@ -jmetal.runner.multiobjective package -==================================== - -Submodules ----------- - -jmetal.runner.multiobjective.nsgaII\_standard\_settings\_plot\_interactive module ---------------------------------------------------------------------------------- - -.. automodule:: jmetal.runner.multiobjective.nsgaII_standard_settings_plot_interactive - :members: - :undoc-members: - :show-inheritance: - -jmetal.runner.multiobjective.nsgaII\_standard\_settings\_with\_observer\_basic module -------------------------------------------------------------------------------------- - -.. automodule:: jmetal.runner.multiobjective.nsgaII_standard_settings_with_observer_basic - :members: - :undoc-members: - :show-inheritance: - -jmetal.runner.multiobjective.nsgaii\_standard\_settings module --------------------------------------------------------------- - -.. automodule:: jmetal.runner.multiobjective.nsgaii_standard_settings - :members: - :undoc-members: - :show-inheritance: - -jmetal.runner.multiobjective.nsgaii\_standard\_settings\_with\_observer module ------------------------------------------------------------------------------- - -.. automodule:: jmetal.runner.multiobjective.nsgaii_standard_settings_with_observer - :members: - :undoc-members: - :show-inheritance: - -jmetal.runner.multiobjective.nsgaii\_standard\_settings\_with\_observer\_plot\_realtime module ----------------------------------------------------------------------------------------------- - -.. automodule:: jmetal.runner.multiobjective.nsgaii_standard_settings_with_observer_plot_realtime - :members: - :undoc-members: - :show-inheritance: - -jmetal.runner.multiobjective.nsgaii\_stopping\_by\_time module --------------------------------------------------------------- - -.. automodule:: jmetal.runner.multiobjective.nsgaii_stopping_by_time - :members: - :undoc-members: - :show-inheritance: - -jmetal.runner.multiobjective.smpso\_standard\_settings module -------------------------------------------------------------- - -.. automodule:: jmetal.runner.multiobjective.smpso_standard_settings - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.runner.multiobjective - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/jmetal.runner.rst b/docs/source/api/jmetal.runner.rst deleted file mode 100644 index c3388b49..00000000 --- a/docs/source/api/jmetal.runner.rst +++ /dev/null @@ -1,18 +0,0 @@ -jmetal.runner package -===================== - -Subpackages ------------ - -.. toctree:: - - jmetal.runner.multiobjective - jmetal.runner.singleobjective - -Module contents ---------------- - -.. automodule:: jmetal.runner - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/jmetal.runner.singleobjective.evolution_strategy.rst b/docs/source/api/jmetal.runner.singleobjective.evolution_strategy.rst deleted file mode 100644 index a7e6847d..00000000 --- a/docs/source/api/jmetal.runner.singleobjective.evolution_strategy.rst +++ /dev/null @@ -1,62 +0,0 @@ -jmetal.runner.singleobjective.evolution\_strategy package -========================================================= - -Submodules ----------- - -jmetal.runner.singleobjective.evolution\_strategy.elitist\_evolution\_strategy\_binary module ---------------------------------------------------------------------------------------------- - -.. automodule:: jmetal.runner.singleobjective.evolution_strategy.elitist_evolution_strategy_binary - :members: - :undoc-members: - :show-inheritance: - -jmetal.runner.singleobjective.evolution\_strategy.elitist\_evolution\_strategy\_float module --------------------------------------------------------------------------------------------- - -.. automodule:: jmetal.runner.singleobjective.evolution_strategy.elitist_evolution_strategy_float - :members: - :undoc-members: - :show-inheritance: - -jmetal.runner.singleobjective.evolution\_strategy.elitist\_evolution\_strategy\_running\_as\_a\_thread module -------------------------------------------------------------------------------------------------------------- - -.. automodule:: jmetal.runner.singleobjective.evolution_strategy.elitist_evolution_strategy_running_as_a_thread - :members: - :undoc-members: - :show-inheritance: - -jmetal.runner.singleobjective.evolution\_strategy.non\_elitist\_evolution\_strategy\_binary module --------------------------------------------------------------------------------------------------- - -.. automodule:: jmetal.runner.singleobjective.evolution_strategy.non_elitist_evolution_strategy_binary - :members: - :undoc-members: - :show-inheritance: - -jmetal.runner.singleobjective.evolution\_strategy.non\_elitist\_evolution\_strategy\_float module -------------------------------------------------------------------------------------------------- - -.. automodule:: jmetal.runner.singleobjective.evolution_strategy.non_elitist_evolution_strategy_float - :members: - :undoc-members: - :show-inheritance: - -jmetal.runner.singleobjective.evolution\_strategy.non\_elitist\_evolution\_strategy\_running\_as\_a\_thread module ------------------------------------------------------------------------------------------------------------------- - -.. automodule:: jmetal.runner.singleobjective.evolution_strategy.non_elitist_evolution_strategy_running_as_a_thread - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.runner.singleobjective.evolution_strategy - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/jmetal.runner.singleobjective.genetic_algorithm.rst b/docs/source/api/jmetal.runner.singleobjective.genetic_algorithm.rst deleted file mode 100644 index 7154d610..00000000 --- a/docs/source/api/jmetal.runner.singleobjective.genetic_algorithm.rst +++ /dev/null @@ -1,54 +0,0 @@ -jmetal.runner.singleobjective.genetic\_algorithm package -======================================================== - -Submodules ----------- - -jmetal.runner.singleobjective.genetic\_algorithm.generational\_genetic\_algorithm\_binary module ------------------------------------------------------------------------------------------------- - -.. automodule:: jmetal.runner.singleobjective.genetic_algorithm.generational_genetic_algorithm_binary - :members: - :undoc-members: - :show-inheritance: - -jmetal.runner.singleobjective.genetic\_algorithm.generational\_genetic\_algorithm\_float module ------------------------------------------------------------------------------------------------ - -.. automodule:: jmetal.runner.singleobjective.genetic_algorithm.generational_genetic_algorithm_float - :members: - :undoc-members: - :show-inheritance: - -jmetal.runner.singleobjective.genetic\_algorithm.generational\_genetic\_algorithm\_running\_as\_a\_thread module ----------------------------------------------------------------------------------------------------------------- - -.. automodule:: jmetal.runner.singleobjective.genetic_algorithm.generational_genetic_algorithm_running_as_a_thread - :members: - :undoc-members: - :show-inheritance: - -jmetal.runner.singleobjective.genetic\_algorithm.generational\_genetic\_algorithm\_stopping\_by\_time module ------------------------------------------------------------------------------------------------------------- - -.. automodule:: jmetal.runner.singleobjective.genetic_algorithm.generational_genetic_algorithm_stopping_by_time - :members: - :undoc-members: - :show-inheritance: - -jmetal.runner.singleobjective.genetic\_algorithm.generational\_genetic\_algorithm\_with\_observer module --------------------------------------------------------------------------------------------------------- - -.. automodule:: jmetal.runner.singleobjective.genetic_algorithm.generational_genetic_algorithm_with_observer - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.runner.singleobjective.genetic_algorithm - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/jmetal.runner.singleobjective.rst b/docs/source/api/jmetal.runner.singleobjective.rst deleted file mode 100644 index ccee8355..00000000 --- a/docs/source/api/jmetal.runner.singleobjective.rst +++ /dev/null @@ -1,18 +0,0 @@ -jmetal.runner.singleobjective package -===================================== - -Subpackages ------------ - -.. toctree:: - - jmetal.runner.singleobjective.evolution_strategy - jmetal.runner.singleobjective.genetic_algorithm - -Module contents ---------------- - -.. automodule:: jmetal.runner.singleobjective - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/jmetal.util.rst b/docs/source/api/jmetal.util.rst index c3147aa3..cf46b817 100644 --- a/docs/source/api/jmetal.util.rst +++ b/docs/source/api/jmetal.util.rst @@ -1,13 +1,6 @@ jmetal.util package =================== -Subpackages ------------ - -.. toctree:: - - jmetal.util.test - Submodules ---------- @@ -57,13 +50,4 @@ jmetal.util.time module .. automodule:: jmetal.util.time :members: :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.util - :members: - :undoc-members: - :show-inheritance: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/api/jmetal.util.test.rst b/docs/source/api/jmetal.util.test.rst deleted file mode 100644 index 6607bb62..00000000 --- a/docs/source/api/jmetal.util.test.rst +++ /dev/null @@ -1,46 +0,0 @@ -jmetal.util.test package -======================== - -Submodules ----------- - -jmetal.util.test.test\_comparator module ----------------------------------------- - -.. automodule:: jmetal.util.test.test_comparator - :members: - :undoc-members: - :show-inheritance: - -jmetal.util.test.test\_graphic module -------------------------------------- - -.. automodule:: jmetal.util.test.test_graphic - :members: - :undoc-members: - :show-inheritance: - -jmetal.util.test.test\_observable module ----------------------------------------- - -.. automodule:: jmetal.util.test.test_observable - :members: - :undoc-members: - :show-inheritance: - -jmetal.util.test.test\_ranking module -------------------------------------- - -.. automodule:: jmetal.util.test.test_ranking - :members: - :undoc-members: - :show-inheritance: - - -Module contents ---------------- - -.. automodule:: jmetal.util.test - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/runner.rst b/docs/source/runner.rst index e69de29b..8b18b56e 100644 --- a/docs/source/runner.rst +++ b/docs/source/runner.rst @@ -0,0 +1,2 @@ +Examples +============== \ No newline at end of file From 4bca3be69197105dd497f830c3ff5ae887413555 Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 7 May 2018 12:49:24 +0200 Subject: [PATCH 21/90] WIP documentation structure --- .../api/jmetal.algorithm.multiobjective.rst | 3 -- .../api/jmetal.algorithm.singleobjective.rst | 3 -- docs/source/api/jmetal.component.rst | 3 -- docs/source/api/jmetal.core.rst | 3 -- docs/source/api/jmetal.operator.rst | 3 -- .../api/jmetal.problem.multiobjective.rst | 3 -- .../api/jmetal.problem.singleobjective.rst | 5 +-- docs/source/api/jmetal.rst | 3 +- jmetal/problem/multiobjective/zdt.py | 41 ++++--------------- 9 files changed, 11 insertions(+), 56 deletions(-) diff --git a/docs/source/api/jmetal.algorithm.multiobjective.rst b/docs/source/api/jmetal.algorithm.multiobjective.rst index d2d309b9..0ad3c4fb 100644 --- a/docs/source/api/jmetal.algorithm.multiobjective.rst +++ b/docs/source/api/jmetal.algorithm.multiobjective.rst @@ -1,9 +1,6 @@ jmetal.algorithm.multiobjective package ======================================= -Submodules ----------- - jmetal.algorithm.multiobjective.nsgaii module --------------------------------------------- diff --git a/docs/source/api/jmetal.algorithm.singleobjective.rst b/docs/source/api/jmetal.algorithm.singleobjective.rst index 216438aa..ad4bfb04 100644 --- a/docs/source/api/jmetal.algorithm.singleobjective.rst +++ b/docs/source/api/jmetal.algorithm.singleobjective.rst @@ -1,9 +1,6 @@ jmetal.algorithm.singleobjective package ======================================== -Submodules ----------- - jmetal.algorithm.singleobjective.evolutionaryalgorithm module ------------------------------------------------------------- diff --git a/docs/source/api/jmetal.component.rst b/docs/source/api/jmetal.component.rst index 1ef57f82..4c3b094d 100644 --- a/docs/source/api/jmetal.component.rst +++ b/docs/source/api/jmetal.component.rst @@ -1,9 +1,6 @@ jmetal.component package ======================== -Submodules ----------- - jmetal.component.archive module ------------------------------- diff --git a/docs/source/api/jmetal.core.rst b/docs/source/api/jmetal.core.rst index efcea133..7b597d35 100644 --- a/docs/source/api/jmetal.core.rst +++ b/docs/source/api/jmetal.core.rst @@ -1,9 +1,6 @@ jmetal.core package =================== -Submodules ----------- - jmetal.core.algorithm module ---------------------------- diff --git a/docs/source/api/jmetal.operator.rst b/docs/source/api/jmetal.operator.rst index 17847757..c19283d4 100644 --- a/docs/source/api/jmetal.operator.rst +++ b/docs/source/api/jmetal.operator.rst @@ -1,9 +1,6 @@ jmetal.operator package ======================= -Submodules ----------- - jmetal.operator.crossover module -------------------------------- diff --git a/docs/source/api/jmetal.problem.multiobjective.rst b/docs/source/api/jmetal.problem.multiobjective.rst index 5f2dbd13..e0580fbe 100644 --- a/docs/source/api/jmetal.problem.multiobjective.rst +++ b/docs/source/api/jmetal.problem.multiobjective.rst @@ -1,9 +1,6 @@ jmetal.problem.multiobjective package ===================================== -Submodules ----------- - jmetal.problem.multiobjective.constrained module ------------------------------------------------ diff --git a/docs/source/api/jmetal.problem.singleobjective.rst b/docs/source/api/jmetal.problem.singleobjective.rst index f7dc5e6e..0b531a7c 100644 --- a/docs/source/api/jmetal.problem.singleobjective.rst +++ b/docs/source/api/jmetal.problem.singleobjective.rst @@ -1,13 +1,10 @@ jmetal.problem.singleobjective package ====================================== -Submodules ----------- - jmetal.problem.singleobjective.unconstrained module --------------------------------------------------- .. automodule:: jmetal.problem.singleobjective.unconstrained :members: :undoc-members: - :show-inheritance: \ No newline at end of file + :show-inheritance: diff --git a/docs/source/api/jmetal.rst b/docs/source/api/jmetal.rst index 63bbbac4..15cc0102 100644 --- a/docs/source/api/jmetal.rst +++ b/docs/source/api/jmetal.rst @@ -1,10 +1,11 @@ jMetalPy API ============== -Subpackages +Main packages ----------- .. toctree:: + :maxdepth: 1 jmetal.algorithm jmetal.component diff --git a/jmetal/problem/multiobjective/zdt.py b/jmetal/problem/multiobjective/zdt.py index 1b29532c..cb5522be 100644 --- a/jmetal/problem/multiobjective/zdt.py +++ b/jmetal/problem/multiobjective/zdt.py @@ -1,49 +1,24 @@ -""" - ============================================================ - :mod:`zdt` -- ZDT problem family of multi-objective problems - ============================================================ - - This module provides the implementation of the ZDT problems defined in: - - Zitzler, E., Deb, K., Thiele, L. - Comparison of multiobjective evolutionary algorithms: Empirical results. - Evolutionary Computation 8(2), pp: 173-195. 2000 - - DOI: https://doi.org/10.1162/106365600568202 - +from math import sqrt, pow, sin, pi, cos - These problems are scalable in the number of the decision variables, i.e. the Pareto front - is the same independently of the number of variables - - .. module:: jmetal.problem.multiobjective.zdt - - :platform: Unix, Windows - :synopsis: Module including the implementation of the ZDT problem family. - - .. moduleauthor:: Antonio J. Nebro +from jmetal.core.problem import FloatProblem +from jmetal.core.solution import FloatSolution """ +.. module:: `zdt` + :platform: Unix, Windows + :synopsis: ZDT problem family of multi-objective problems. - -from math import sqrt, exp, pow, sin, pi, cos - -from jmetal.core.problem import FloatProblem -from jmetal.core.solution import FloatSolution +.. moduleauthor:: Antonio J. Nebro +""" class ZDT1(FloatProblem): """ Problem ZDT1 - .. note:: Bi-objective unconstrained problem. The default number of variables is 30. - .. note:: Continuous problem having a convex Pareto front - """ def __init__(self, number_of_variables: int = 30): """Constructor - - Arguments: - :param number_of_variables: number of decision variables of the problem """ self.number_of_variables = number_of_variables From d9cf184152e92301f324fe9551cd8c20d3b8b38a Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 7 May 2018 12:52:40 +0200 Subject: [PATCH 22/90] Incremented toc depth --- docs/source/api/jmetal.rst | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/source/api/jmetal.rst b/docs/source/api/jmetal.rst index 15cc0102..2bca976a 100644 --- a/docs/source/api/jmetal.rst +++ b/docs/source/api/jmetal.rst @@ -1,11 +1,8 @@ jMetalPy API ============== -Main packages ------------ - .. toctree:: - :maxdepth: 1 + :maxdepth: 2 jmetal.algorithm jmetal.component From a8d59aafe7b85575e5d31f4dece1f3241fe28591 Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 7 May 2018 13:34:22 +0200 Subject: [PATCH 23/90] Added documentation to DTLZ --- docs/source/api/jmetal.rst | 15 +++++++++--- docs/source/index.rst | 11 ++++----- docs/source/modules.rst | 7 ------ jmetal/problem/multiobjective/dtlz.py | 33 +++++++-------------------- 4 files changed, 25 insertions(+), 41 deletions(-) delete mode 100644 docs/source/modules.rst diff --git a/docs/source/api/jmetal.rst b/docs/source/api/jmetal.rst index 2bca976a..34c7ecad 100644 --- a/docs/source/api/jmetal.rst +++ b/docs/source/api/jmetal.rst @@ -1,13 +1,22 @@ jMetalPy API ============== +Subpackages +----------- + .. toctree:: - :maxdepth: 2 jmetal.algorithm jmetal.component jmetal.core jmetal.operator jmetal.problem - jmetal.runner - jmetal.util \ No newline at end of file + jmetal.util + +Module contents +--------------- + +.. automodule:: jmetal + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/index.rst b/docs/source/index.rst index f6846f90..a06f73c1 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -3,9 +3,13 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -jMetalPy +jMetalPy Documentation ==================================== +.. warning:: + + Documentation is in process!! Some information may be missing. + .. toctree:: :maxdepth: 2 :caption: Contents: @@ -54,8 +58,3 @@ API documentation api/jmetal -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` diff --git a/docs/source/modules.rst b/docs/source/modules.rst deleted file mode 100644 index f4e2b81d..00000000 --- a/docs/source/modules.rst +++ /dev/null @@ -1,7 +0,0 @@ -jmetal -====== - -.. toctree:: - :maxdepth: 4 - - jmetal diff --git a/jmetal/problem/multiobjective/dtlz.py b/jmetal/problem/multiobjective/dtlz.py index bfb6f6bd..34e69e04 100644 --- a/jmetal/problem/multiobjective/dtlz.py +++ b/jmetal/problem/multiobjective/dtlz.py @@ -1,33 +1,16 @@ -""" - ============================================================ - :mod:`dtlz` -- DTLZ problem family of multi-objective problems - ============================================================ - - This module provides the implementation of the DTLZ problems defined in: - - ... - - DOI: ... - - - These problems are scalable in the number of the decision variables and the number of - objective functions - - .. module:: jmetal.problem.multiobjective.dtlz - - :platform: Unix, Windows - :synopsis: Module including the implementation of the DTLZ problem family. - - .. moduleauthor:: Antonio J. Nebro - -""" - - from math import pi, cos from jmetal.core.problem import FloatProblem from jmetal.core.solution import FloatSolution +""" +.. module:: `dtlz` + :platform: Unix, Windows + :synopsis: DTLZ problem family of multi-objective problems. + +.. moduleauthor:: Antonio J. Nebro +""" + class DTLZ1(FloatProblem): """ Problem DTLZ1 From ba5d41f61df6a7cf171a2e0f38eceb8311fd7099 Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 7 May 2018 13:52:01 +0200 Subject: [PATCH 24/90] New doctumentation structure --- .../api/jmetal.algorithm.multiobjective.rst | 17 +++++++++-------- docs/source/api/jmetal.algorithm.rst | 4 ++-- .../api/jmetal.algorithm.singleobjective.rst | 4 ++-- docs/source/api/jmetal.component.rst | 10 +++++----- docs/source/api/jmetal.core.rst | 14 ++++++++------ docs/source/api/jmetal.operator.rst | 8 ++++---- .../api/jmetal.problem.multiobjective.rst | 18 +++++++++--------- docs/source/api/jmetal.problem.rst | 4 ++-- .../api/jmetal.problem.singleobjective.rst | 4 ++-- docs/source/api/jmetal.rst | 13 +++---------- docs/source/api/jmetal.util.rst | 17 +++++++---------- docs/source/index.rst | 4 +--- 12 files changed, 54 insertions(+), 63 deletions(-) diff --git a/docs/source/api/jmetal.algorithm.multiobjective.rst b/docs/source/api/jmetal.algorithm.multiobjective.rst index 0ad3c4fb..eae1b5f5 100644 --- a/docs/source/api/jmetal.algorithm.multiobjective.rst +++ b/docs/source/api/jmetal.algorithm.multiobjective.rst @@ -1,7 +1,7 @@ -jmetal.algorithm.multiobjective package +Multiobjective algorithms ======================================= -jmetal.algorithm.multiobjective.nsgaii module +NSGA-II --------------------------------------------- .. automodule:: jmetal.algorithm.multiobjective.nsgaii @@ -9,18 +9,19 @@ jmetal.algorithm.multiobjective.nsgaii module :undoc-members: :show-inheritance: -jmetal.algorithm.multiobjective.randomSearch module ---------------------------------------------------- +SMPSO +-------------------------------------------- -.. automodule:: jmetal.algorithm.multiobjective.randomSearch +.. automodule:: jmetal.algorithm.multiobjective.smpso :members: :undoc-members: :show-inheritance: -jmetal.algorithm.multiobjective.smpso module --------------------------------------------- +Random Search +--------------------------------------------------- -.. automodule:: jmetal.algorithm.multiobjective.smpso +.. automodule:: jmetal.algorithm.multiobjective.randomSearch :members: :undoc-members: :show-inheritance: + diff --git a/docs/source/api/jmetal.algorithm.rst b/docs/source/api/jmetal.algorithm.rst index 1b59a800..7767e1bf 100644 --- a/docs/source/api/jmetal.algorithm.rst +++ b/docs/source/api/jmetal.algorithm.rst @@ -1,7 +1,7 @@ -jmetal.algorithm package +Algorithms ======================== -Subpackages +Algorithms ----------- .. toctree:: diff --git a/docs/source/api/jmetal.algorithm.singleobjective.rst b/docs/source/api/jmetal.algorithm.singleobjective.rst index ad4bfb04..c3a88057 100644 --- a/docs/source/api/jmetal.algorithm.singleobjective.rst +++ b/docs/source/api/jmetal.algorithm.singleobjective.rst @@ -1,7 +1,7 @@ -jmetal.algorithm.singleobjective package +Singleobjectives algorithms ======================================== -jmetal.algorithm.singleobjective.evolutionaryalgorithm module +Evolutionary Algorithm ------------------------------------------------------------- .. automodule:: jmetal.algorithm.singleobjective.evolutionaryalgorithm diff --git a/docs/source/api/jmetal.component.rst b/docs/source/api/jmetal.component.rst index 4c3b094d..ba9777ba 100644 --- a/docs/source/api/jmetal.component.rst +++ b/docs/source/api/jmetal.component.rst @@ -1,7 +1,7 @@ -jmetal.component package +Components ======================== -jmetal.component.archive module +Archive ------------------------------- .. automodule:: jmetal.component.archive @@ -9,7 +9,7 @@ jmetal.component.archive module :undoc-members: :show-inheritance: -jmetal.component.density\_estimator module +Density Estimator ------------------------------------------ .. automodule:: jmetal.component.density_estimator @@ -17,7 +17,7 @@ jmetal.component.density\_estimator module :undoc-members: :show-inheritance: -jmetal.component.evaluator module +Evaluator --------------------------------- .. automodule:: jmetal.component.evaluator @@ -25,7 +25,7 @@ jmetal.component.evaluator module :undoc-members: :show-inheritance: -jmetal.component.observer module +Observer -------------------------------- .. automodule:: jmetal.component.observer diff --git a/docs/source/api/jmetal.core.rst b/docs/source/api/jmetal.core.rst index 7b597d35..cee0a8ba 100644 --- a/docs/source/api/jmetal.core.rst +++ b/docs/source/api/jmetal.core.rst @@ -1,7 +1,9 @@ -jmetal.core package +Core =================== -jmetal.core.algorithm module +This subpackage store templates used in jMetalPy. + +Algorithm ---------------------------- .. automodule:: jmetal.core.algorithm @@ -9,7 +11,7 @@ jmetal.core.algorithm module :undoc-members: :show-inheritance: -jmetal.core.operator module +Operator --------------------------- .. automodule:: jmetal.core.operator @@ -17,7 +19,7 @@ jmetal.core.operator module :undoc-members: :show-inheritance: -jmetal.core.problem module +Problem -------------------------- .. automodule:: jmetal.core.problem @@ -25,10 +27,10 @@ jmetal.core.problem module :undoc-members: :show-inheritance: -jmetal.core.solution module +Solution --------------------------- .. automodule:: jmetal.core.solution :members: :undoc-members: - :show-inheritance: \ No newline at end of file + :show-inheritance: diff --git a/docs/source/api/jmetal.operator.rst b/docs/source/api/jmetal.operator.rst index c19283d4..41e8436a 100644 --- a/docs/source/api/jmetal.operator.rst +++ b/docs/source/api/jmetal.operator.rst @@ -1,7 +1,7 @@ -jmetal.operator package +Operator ======================= -jmetal.operator.crossover module +Crossover -------------------------------- .. automodule:: jmetal.operator.crossover @@ -9,7 +9,7 @@ jmetal.operator.crossover module :undoc-members: :show-inheritance: -jmetal.operator.mutation module +Mutation ------------------------------- .. automodule:: jmetal.operator.mutation @@ -17,7 +17,7 @@ jmetal.operator.mutation module :undoc-members: :show-inheritance: -jmetal.operator.selection module +Selection -------------------------------- .. automodule:: jmetal.operator.selection diff --git a/docs/source/api/jmetal.problem.multiobjective.rst b/docs/source/api/jmetal.problem.multiobjective.rst index e0580fbe..5894213c 100644 --- a/docs/source/api/jmetal.problem.multiobjective.rst +++ b/docs/source/api/jmetal.problem.multiobjective.rst @@ -1,7 +1,7 @@ -jmetal.problem.multiobjective package +Multiobjective problems ===================================== -jmetal.problem.multiobjective.constrained module +Constrained ------------------------------------------------ .. automodule:: jmetal.problem.multiobjective.constrained @@ -9,23 +9,23 @@ jmetal.problem.multiobjective.constrained module :undoc-members: :show-inheritance: -jmetal.problem.multiobjective.dtlz module ------------------------------------------ +Unconstrained +-------------------------------------------------- -.. automodule:: jmetal.problem.multiobjective.dtlz +.. automodule:: jmetal.problem.multiobjective.unconstrained :members: :undoc-members: :show-inheritance: -jmetal.problem.multiobjective.unconstrained module --------------------------------------------------- +DTLZ +----------------------------------------- -.. automodule:: jmetal.problem.multiobjective.unconstrained +.. automodule:: jmetal.problem.multiobjective.dtlz :members: :undoc-members: :show-inheritance: -jmetal.problem.multiobjective.zdt module +ZDT ---------------------------------------- .. automodule:: jmetal.problem.multiobjective.zdt diff --git a/docs/source/api/jmetal.problem.rst b/docs/source/api/jmetal.problem.rst index ad6e281d..7be5501d 100644 --- a/docs/source/api/jmetal.problem.rst +++ b/docs/source/api/jmetal.problem.rst @@ -1,7 +1,7 @@ -jmetal.problem package +Problems ====================== -Subpackages +Problems ----------- .. toctree:: diff --git a/docs/source/api/jmetal.problem.singleobjective.rst b/docs/source/api/jmetal.problem.singleobjective.rst index 0b531a7c..1e5266c4 100644 --- a/docs/source/api/jmetal.problem.singleobjective.rst +++ b/docs/source/api/jmetal.problem.singleobjective.rst @@ -1,7 +1,7 @@ -jmetal.problem.singleobjective package +Singleobjective problems ====================================== -jmetal.problem.singleobjective.unconstrained module +Unconstrained --------------------------------------------------- .. automodule:: jmetal.problem.singleobjective.unconstrained diff --git a/docs/source/api/jmetal.rst b/docs/source/api/jmetal.rst index 34c7ecad..d0c983a5 100644 --- a/docs/source/api/jmetal.rst +++ b/docs/source/api/jmetal.rst @@ -1,10 +1,11 @@ -jMetalPy API +User documentation ============== -Subpackages +Content ----------- .. toctree:: + :maxdepth: 2 jmetal.algorithm jmetal.component @@ -12,11 +13,3 @@ Subpackages jmetal.operator jmetal.problem jmetal.util - -Module contents ---------------- - -.. automodule:: jmetal - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/api/jmetal.util.rst b/docs/source/api/jmetal.util.rst index cf46b817..b38348c3 100644 --- a/docs/source/api/jmetal.util.rst +++ b/docs/source/api/jmetal.util.rst @@ -1,10 +1,7 @@ -jmetal.util package +Utils =================== -Submodules ----------- - -jmetal.util.comparator module +Comparator ----------------------------- .. automodule:: jmetal.util.comparator @@ -12,7 +9,7 @@ jmetal.util.comparator module :undoc-members: :show-inheritance: -jmetal.util.graphic module +Graphic -------------------------- .. automodule:: jmetal.util.graphic @@ -20,7 +17,7 @@ jmetal.util.graphic module :undoc-members: :show-inheritance: -jmetal.util.observable module +Observable ----------------------------- .. automodule:: jmetal.util.observable @@ -28,7 +25,7 @@ jmetal.util.observable module :undoc-members: :show-inheritance: -jmetal.util.ranking module +Ranking -------------------------- .. automodule:: jmetal.util.ranking @@ -36,7 +33,7 @@ jmetal.util.ranking module :undoc-members: :show-inheritance: -jmetal.util.solution\_list\_output module +Solution list output ----------------------------------------- .. automodule:: jmetal.util.solution_list_output @@ -44,7 +41,7 @@ jmetal.util.solution\_list\_output module :undoc-members: :show-inheritance: -jmetal.util.time module +Time ----------------------- .. automodule:: jmetal.util.time diff --git a/docs/source/index.rst b/docs/source/index.rst index a06f73c1..7f5f2f60 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -6,9 +6,7 @@ jMetalPy Documentation ==================================== -.. warning:: - - Documentation is in process!! Some information may be missing. +.. warning:: Documentation is in process!! Some information may be missing. .. toctree:: :maxdepth: 2 From e045633c89c84bf861eb232fe43fee1343aba474 Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 7 May 2018 13:56:27 +0200 Subject: [PATCH 25/90] Rename modules --- docs/source/api/jmetal.algorithm.rst | 2 +- docs/source/api/jmetal.problem.rst | 2 +- docs/source/api/jmetal.rst | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/source/api/jmetal.algorithm.rst b/docs/source/api/jmetal.algorithm.rst index 7767e1bf..0079983f 100644 --- a/docs/source/api/jmetal.algorithm.rst +++ b/docs/source/api/jmetal.algorithm.rst @@ -1,7 +1,7 @@ Algorithms ======================== -Algorithms +Algorithms available ----------- .. toctree:: diff --git a/docs/source/api/jmetal.problem.rst b/docs/source/api/jmetal.problem.rst index 7be5501d..de3159d3 100644 --- a/docs/source/api/jmetal.problem.rst +++ b/docs/source/api/jmetal.problem.rst @@ -1,7 +1,7 @@ Problems ====================== -Problems +Problems available ----------- .. toctree:: diff --git a/docs/source/api/jmetal.rst b/docs/source/api/jmetal.rst index d0c983a5..6b8889a4 100644 --- a/docs/source/api/jmetal.rst +++ b/docs/source/api/jmetal.rst @@ -5,7 +5,6 @@ Content ----------- .. toctree:: - :maxdepth: 2 jmetal.algorithm jmetal.component From c6acb9a2dd3639f7774049d6f5111631967321db Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 7 May 2018 14:07:58 +0200 Subject: [PATCH 26/90] Rename modules --- .../api/jmetal.algorithm.multiobjective.rst | 26 +++++++++ docs/source/api/jmetal.algorithm.rst | 56 +++++++++++++++++-- docs/source/api/jmetal.problem.rst | 3 - docs/source/api/jmetal.rst | 2 +- 4 files changed, 78 insertions(+), 9 deletions(-) diff --git a/docs/source/api/jmetal.algorithm.multiobjective.rst b/docs/source/api/jmetal.algorithm.multiobjective.rst index eae1b5f5..96caf4f7 100644 --- a/docs/source/api/jmetal.algorithm.multiobjective.rst +++ b/docs/source/api/jmetal.algorithm.multiobjective.rst @@ -25,3 +25,29 @@ Random Search :undoc-members: :show-inheritance: +Singleobjectives algorithms +======================================= + +NSGA-II +--------------------------------------------- + +.. automodule:: jmetal.algorithm.multiobjective.nsgaii + :members: + :undoc-members: + :show-inheritance: + +SMPSO +-------------------------------------------- + +.. automodule:: jmetal.algorithm.multiobjective.smpso + :members: + :undoc-members: + :show-inheritance: + +Random Search +--------------------------------------------------- + +.. automodule:: jmetal.algorithm.multiobjective.randomSearch + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/api/jmetal.algorithm.rst b/docs/source/api/jmetal.algorithm.rst index 0079983f..97faf983 100644 --- a/docs/source/api/jmetal.algorithm.rst +++ b/docs/source/api/jmetal.algorithm.rst @@ -1,10 +1,56 @@ Algorithms ======================== -Algorithms available ------------ +Multiobjective algorithms +--------------------------------------------- -.. toctree:: +NSGA-II +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - jmetal.algorithm.multiobjective - jmetal.algorithm.singleobjective +.. automodule:: jmetal.algorithm.multiobjective.nsgaii + :members: + :undoc-members: + :show-inheritance: + +SMPSO +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. automodule:: jmetal.algorithm.multiobjective.smpso + :members: + :undoc-members: + :show-inheritance: + +Random Search +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. automodule:: jmetal.algorithm.multiobjective.randomSearch + :members: + :undoc-members: + :show-inheritance: + +Singleobjectives algorithms +--------------------------------------------- + +NSGA-II +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. automodule:: jmetal.algorithm.multiobjective.nsgaii + :members: + :undoc-members: + :show-inheritance: + +SMPSO +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. automodule:: jmetal.algorithm.multiobjective.smpso + :members: + :undoc-members: + :show-inheritance: + +Random Search +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. automodule:: jmetal.algorithm.multiobjective.randomSearch + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/source/api/jmetal.problem.rst b/docs/source/api/jmetal.problem.rst index de3159d3..a7ff729b 100644 --- a/docs/source/api/jmetal.problem.rst +++ b/docs/source/api/jmetal.problem.rst @@ -1,9 +1,6 @@ Problems ====================== -Problems available ------------ - .. toctree:: jmetal.problem.multiobjective diff --git a/docs/source/api/jmetal.rst b/docs/source/api/jmetal.rst index 6b8889a4..ebe49142 100644 --- a/docs/source/api/jmetal.rst +++ b/docs/source/api/jmetal.rst @@ -1,7 +1,7 @@ User documentation ============== -Content +Components ----------- .. toctree:: From 322cbf2e0a1520ba64439b65432d2a71b5eb07e6 Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 7 May 2018 14:36:52 +0200 Subject: [PATCH 27/90] Improved documentation --- README.md | 2 +- docs/source/about.rst | 10 ++- docs/source/api/jmetal.algorithm.rst | 55 +------------ docs/source/api/jmetal.operator.rst | 2 +- docs/source/api/jmetal.rst | 3 - docs/source/index.rst | 17 +--- docs/source/runner.rst | 100 ++++++++++++++++++++++- jmetal/algorithm/multiobjective/smpso.py | 2 +- jmetal/util/graphic.py | 9 +- 9 files changed, 119 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index ccb05066..5dab9e05 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ # jMetalPy: Python version of the jMetal framework [![Build Status](https://img.shields.io/travis/jMetal/jMetalPy.svg?style=flat-square)](https://travis-ci.org/jMetal/jMetalPy) -[![PyPI Version](https://img.shields.io/pypi/v/jMetalPy.svg?style=flat-square)]() +[![Read the Docs](https://img.shields.io/readthedocs/jmetalpy.svg?style=flat-square)]() [![PyPI License](https://img.shields.io/pypi/l/jMetalPy.svg?style=flat-square)]() [![PyPI Python version](https://img.shields.io/pypi/pyversions/jMetalPy.svg?style=flat-square)]() diff --git a/docs/source/about.rst b/docs/source/about.rst index f0142046..f98ea0d2 100644 --- a/docs/source/about.rst +++ b/docs/source/about.rst @@ -1,2 +1,10 @@ About -============== \ No newline at end of file +============== + +jMetalPy is being developed by `Antonio J. Nebro `_, associate professor at the University of Málaga, and Antonio Benítez-Hidalgo. + +References +-------------------------------- + +1. J.J. Durillo, A.J. Nebro jMetal: a Java Framework for Multi-Objective Optimization. Advances in Engineering Software 42 (2011) 760-771. +2. A.J. Nebro, J.J. Durillo, M. Vergne Redesigning the jMetal Multi-Objective Optimization Framework. GECCO (Companion) 2015, pp: 1093-1100. July 2015. \ No newline at end of file diff --git a/docs/source/api/jmetal.algorithm.rst b/docs/source/api/jmetal.algorithm.rst index 97faf983..908deebd 100644 --- a/docs/source/api/jmetal.algorithm.rst +++ b/docs/source/api/jmetal.algorithm.rst @@ -1,56 +1,7 @@ Algorithms ======================== -Multiobjective algorithms ---------------------------------------------- +.. toctree:: -NSGA-II -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: jmetal.algorithm.multiobjective.nsgaii - :members: - :undoc-members: - :show-inheritance: - -SMPSO -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: jmetal.algorithm.multiobjective.smpso - :members: - :undoc-members: - :show-inheritance: - -Random Search -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: jmetal.algorithm.multiobjective.randomSearch - :members: - :undoc-members: - :show-inheritance: - -Singleobjectives algorithms ---------------------------------------------- - -NSGA-II -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: jmetal.algorithm.multiobjective.nsgaii - :members: - :undoc-members: - :show-inheritance: - -SMPSO -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: jmetal.algorithm.multiobjective.smpso - :members: - :undoc-members: - :show-inheritance: - -Random Search -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. automodule:: jmetal.algorithm.multiobjective.randomSearch - :members: - :undoc-members: - :show-inheritance: + jmetal.algorithm.multiobjective + jmetal.algorithm.singleobjective \ No newline at end of file diff --git a/docs/source/api/jmetal.operator.rst b/docs/source/api/jmetal.operator.rst index 41e8436a..31822cf3 100644 --- a/docs/source/api/jmetal.operator.rst +++ b/docs/source/api/jmetal.operator.rst @@ -1,4 +1,4 @@ -Operator +Operators ======================= Crossover diff --git a/docs/source/api/jmetal.rst b/docs/source/api/jmetal.rst index ebe49142..886d0001 100644 --- a/docs/source/api/jmetal.rst +++ b/docs/source/api/jmetal.rst @@ -1,9 +1,6 @@ User documentation ============== -Components ------------ - .. toctree:: jmetal.algorithm diff --git a/docs/source/index.rst b/docs/source/index.rst index 7f5f2f60..c1fbc905 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -3,19 +3,11 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -jMetalPy Documentation +jMetalPy: Python version of the jMetal framework ==================================== .. warning:: Documentation is in process!! Some information may be missing. -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - changelog - runner - about - Installation ------------ @@ -49,10 +41,3 @@ Basic Usage algorithm.run() result = algorithm.get_result() -API documentation ------------------ - -.. toctree:: - - api/jmetal - diff --git a/docs/source/runner.rst b/docs/source/runner.rst index 8b18b56e..e45eb29a 100644 --- a/docs/source/runner.rst +++ b/docs/source/runner.rst @@ -1,2 +1,100 @@ Examples -============== \ No newline at end of file +============== + +Common imports: + +.. code-block:: python + from jmetal.algorithm.multiobjective.nsgaii import NSGAII + from jmetal.core.solution import FloatSolution + + from jmetal.operator.mutation import Polynomial + from jmetal.operator.crossover import SBX + from jmetal.operator.selection import BinaryTournamentSelection + from jmetal.util.comparator import RankingAndCrowdingDistanceComparator + +NSGA-II with standard settings +------------ + +.. code-block:: python + algorithm = NSGAII[FloatSolution, List[FloatSolution]]( + problem=problem, + population_size=100, + max_evaluations=25000, + mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), + crossover=SBX(1.0, distribution_index=20), + selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) + + algorithm.run() + result = algorithm.get_result() + +NSGA-II with observer +------------ + +.. code-block:: python + from jmetal.component.observer import WriteFrontToFileObserver + + algorithm = NSGAII[FloatSolution, List[FloatSolution]]( + problem, + population_size=100, + max_evaluations=25000, + mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), + crossover=SBX(1.0, distribution_index=20), + selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) + + observer = WriteFrontToFileObserver("output_directory") + algorithm.observable.register(observer=observer) + + algorithm.run() + result = algorithm.get_result() + +NSGA-II with plot in real-time +------------ + +.. code-block:: python + from jmetal.component.observer import AlgorithmObserver + + algorithm = NSGAII[FloatSolution, List[FloatSolution]]( + problem, + population_size=100, + max_evaluations=25000, + mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), + crossover=SBX(1.0, distribution_index=20), + selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) + + + observer = AlgorithmObserver(animation_speed=1*10e-8) + algorithm.observable.register(observer=observer) + + algorithm.run() + result = algorithm.get_result() + +NSGA-II stopping by time +------------ + +.. code-block:: python + from typing import List, TypeVar + + S = TypeVar('S') + R = TypeVar(List[S]) + + def main(): + class NSGA2b(NSGAII[S, R]): + def is_stopping_condition_reached(self): + # Re-define the stopping condition + reached = [False, True][self.get_current_computing_time() > 4] + + if reached: + logger.info("Stopping condition reached!") + + return reached + + algorithm = NSGA2b[FloatSolution, List[FloatSolution]]( + problem, + population_size=100, + max_evaluations=25000, + mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), + crossover=SBX(1.0, distribution_index=20), + selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) + + algorithm.run() + result = algorithm.get_result() \ No newline at end of file diff --git a/jmetal/algorithm/multiobjective/smpso.py b/jmetal/algorithm/multiobjective/smpso.py index 35990b41..c1466db6 100644 --- a/jmetal/algorithm/multiobjective/smpso.py +++ b/jmetal/algorithm/multiobjective/smpso.py @@ -40,7 +40,7 @@ def __init__(self, * MCDM 2009. DOI: ``_. The implementation of SMPSO provided in jMetalPy follows the - algorithm template described in the algorithm templates section (:mod:`algorithm`) of the documentation. + algorithm template described in the algorithm templates section of the documentation. :param problem: The problem to solve. :param swarm_size: diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index 26ff0ca4..d6a4af55 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -22,10 +22,9 @@ class ScatterPlot(): def __init__(self, plot_title: str, animation_speed: float = 1*10e-10): """ Creates a new :class:`ScatterPlot` instance. - Args: - plot_title (str): Title of the scatter diagram. - animation_speed (float): Delay (for live plot only). Allow time for the gui event loops to trigger - and update the display. + + :param plot_title: Title of the scatter diagram. + :param animation_speed: TDelay (for live plot only). Allow time for the gui event loops to trigger and update the display. """ self.plot_title = plot_title self.fig = plt.figure() @@ -63,7 +62,7 @@ def retrieve_info(self, solution: Solution) -> None: pass def __search_solution(self, solution_list: List[S], x_val: float, y_val: float) -> None: - """ Return a solution object associated with some values of (x,y). """ + """ :return: A solution object associated with some values of (x,y). """ sol = next((solution for solution in solution_list if solution.objectives[0] == x_val and solution.objectives[1]), None) From 8cc68c0cd9901fe283470ba0583a00ed48256ba9 Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 7 May 2018 14:40:19 +0200 Subject: [PATCH 28/90] Fixed TOC --- docs/source/index.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/source/index.rst b/docs/source/index.rst index c1fbc905..a42ace8f 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -8,6 +8,14 @@ jMetalPy: Python version of the jMetal framework .. warning:: Documentation is in process!! Some information may be missing. +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + changelog + runner + about + Installation ------------ From 4a0fa2e79c7bf99f7315e083f9c4dfcf28d00e95 Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 7 May 2018 14:42:28 +0200 Subject: [PATCH 29/90] Fixed TOC --- docs/source/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/source/index.rst b/docs/source/index.rst index a42ace8f..dfdb9f28 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -15,6 +15,7 @@ jMetalPy: Python version of the jMetal framework changelog runner about + jmetal.algorithm Installation ------------ From 16b8c58d9b1dc8b6ff4b954b20665d16031d6886 Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 7 May 2018 14:55:43 +0200 Subject: [PATCH 30/90] Improved documentation --- README.md | 2 +- .../api/jmetal.algorithm.multiobjective.rst | 27 ---- docs/source/index.rst | 7 +- docs/source/runner.rst | 122 +++++++++--------- jmetal/problem/multiobjective/dtlz.py | 10 +- jmetal/problem/multiobjective/zdt.py | 1 + jmetal/util/test/test_graphic.py | 2 +- 7 files changed, 71 insertions(+), 100 deletions(-) diff --git a/README.md b/README.md index 5dab9e05..5f0b7bdb 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ # jMetalPy: Python version of the jMetal framework [![Build Status](https://img.shields.io/travis/jMetal/jMetalPy.svg?style=flat-square)](https://travis-ci.org/jMetal/jMetalPy) -[![Read the Docs](https://img.shields.io/readthedocs/jmetalpy.svg?style=flat-square)]() +[![Read the Docs](https://img.shields.io/readthedocs/jmetalpy.svg?style=flat-square)](https://readthedocs.org/projects/jmetalpy/) [![PyPI License](https://img.shields.io/pypi/l/jMetalPy.svg?style=flat-square)]() [![PyPI Python version](https://img.shields.io/pypi/pyversions/jMetalPy.svg?style=flat-square)]() diff --git a/docs/source/api/jmetal.algorithm.multiobjective.rst b/docs/source/api/jmetal.algorithm.multiobjective.rst index 96caf4f7..8a8e0988 100644 --- a/docs/source/api/jmetal.algorithm.multiobjective.rst +++ b/docs/source/api/jmetal.algorithm.multiobjective.rst @@ -24,30 +24,3 @@ Random Search :members: :undoc-members: :show-inheritance: - -Singleobjectives algorithms -======================================= - -NSGA-II ---------------------------------------------- - -.. automodule:: jmetal.algorithm.multiobjective.nsgaii - :members: - :undoc-members: - :show-inheritance: - -SMPSO --------------------------------------------- - -.. automodule:: jmetal.algorithm.multiobjective.smpso - :members: - :undoc-members: - :show-inheritance: - -Random Search ---------------------------------------------------- - -.. automodule:: jmetal.algorithm.multiobjective.randomSearch - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/index.rst b/docs/source/index.rst index dfdb9f28..fdb2e3ad 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -4,18 +4,17 @@ contain the root `toctree` directive. jMetalPy: Python version of the jMetal framework -==================================== +================================================ .. warning:: Documentation is in process!! Some information may be missing. .. toctree:: - :maxdepth: 2 + :maxdepth: 1 :caption: Contents: - changelog runner about - jmetal.algorithm + api/jmetal Installation ------------ diff --git a/docs/source/runner.rst b/docs/source/runner.rst index e45eb29a..2cc4dfa9 100644 --- a/docs/source/runner.rst +++ b/docs/source/runner.rst @@ -4,97 +4,101 @@ Examples Common imports: .. code-block:: python - from jmetal.algorithm.multiobjective.nsgaii import NSGAII - from jmetal.core.solution import FloatSolution - from jmetal.operator.mutation import Polynomial - from jmetal.operator.crossover import SBX - from jmetal.operator.selection import BinaryTournamentSelection - from jmetal.util.comparator import RankingAndCrowdingDistanceComparator + from jmetal.algorithm.multiobjective.nsgaii import NSGAII + from jmetal.core.solution import FloatSolution + + from jmetal.operator.mutation import Polynomial + from jmetal.operator.crossover import SBX + from jmetal.operator.selection import BinaryTournamentSelection + from jmetal.util.comparator import RankingAndCrowdingDistanceComparator NSGA-II with standard settings ------------ .. code-block:: python - algorithm = NSGAII[FloatSolution, List[FloatSolution]]( - problem=problem, - population_size=100, - max_evaluations=25000, - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) - algorithm.run() - result = algorithm.get_result() + algorithm = NSGAII[FloatSolution, List[FloatSolution]]( + problem=problem, + population_size=100, + max_evaluations=25000, + mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), + crossover=SBX(1.0, distribution_index=20), + selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) + + algorithm.run() + result = algorithm.get_result() NSGA-II with observer ------------ .. code-block:: python - from jmetal.component.observer import WriteFrontToFileObserver - algorithm = NSGAII[FloatSolution, List[FloatSolution]]( - problem, - population_size=100, - max_evaluations=25000, - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) + from jmetal.component.observer import WriteFrontToFileObserver - observer = WriteFrontToFileObserver("output_directory") - algorithm.observable.register(observer=observer) + algorithm = NSGAII[FloatSolution, List[FloatSolution]]( + problem, + population_size=100, + max_evaluations=25000, + mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), + crossover=SBX(1.0, distribution_index=20), + selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) - algorithm.run() - result = algorithm.get_result() + observer = WriteFrontToFileObserver("output_directory") + algorithm.observable.register(observer=observer) + + algorithm.run() + result = algorithm.get_result() NSGA-II with plot in real-time ------------ .. code-block:: python - from jmetal.component.observer import AlgorithmObserver - algorithm = NSGAII[FloatSolution, List[FloatSolution]]( - problem, - population_size=100, - max_evaluations=25000, - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) + from jmetal.component.observer import AlgorithmObserver + + algorithm = NSGAII[FloatSolution, List[FloatSolution]]( + problem, + population_size=100, + max_evaluations=25000, + mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), + crossover=SBX(1.0, distribution_index=20), + selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) - observer = AlgorithmObserver(animation_speed=1*10e-8) - algorithm.observable.register(observer=observer) + observer = AlgorithmObserver(animation_speed=1*10e-8) + algorithm.observable.register(observer=observer) - algorithm.run() - result = algorithm.get_result() + algorithm.run() + result = algorithm.get_result() NSGA-II stopping by time ------------ .. code-block:: python - from typing import List, TypeVar + from typing import List, TypeVar - S = TypeVar('S') - R = TypeVar(List[S]) + S = TypeVar('S') + R = TypeVar(List[S]) - def main(): - class NSGA2b(NSGAII[S, R]): - def is_stopping_condition_reached(self): - # Re-define the stopping condition - reached = [False, True][self.get_current_computing_time() > 4] + def main(): + class NSGA2b(NSGAII[S, R]): + def is_stopping_condition_reached(self): + # Re-define the stopping condition + reached = [False, True][self.get_current_computing_time() > 4] - if reached: - logger.info("Stopping condition reached!") + if reached: + logger.info("Stopping condition reached!") - return reached + return reached - algorithm = NSGA2b[FloatSolution, List[FloatSolution]]( - problem, - population_size=100, - max_evaluations=25000, - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) + algorithm = NSGA2b[FloatSolution, List[FloatSolution]]( + problem, + population_size=100, + max_evaluations=25000, + mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), + crossover=SBX(1.0, distribution_index=20), + selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) - algorithm.run() - result = algorithm.get_result() \ No newline at end of file + algorithm.run() + result = algorithm.get_result() \ No newline at end of file diff --git a/jmetal/problem/multiobjective/dtlz.py b/jmetal/problem/multiobjective/dtlz.py index 34e69e04..a1f915c5 100644 --- a/jmetal/problem/multiobjective/dtlz.py +++ b/jmetal/problem/multiobjective/dtlz.py @@ -14,18 +14,12 @@ class DTLZ1(FloatProblem): """ Problem DTLZ1 - - .. note:: Unconstrained problem. The default number of variables and objectives are, - respectively, 7 and 3. - + .. note:: Unconstrained problem. The default number of variables and objectives are, respectively, 7 and 3. .. note:: Continuous problem having a convex Pareto front - """ + def __init__(self, number_of_variables: int = 30, number_of_objectives = 3): """Constructor - - Arguments: - :param number_of_variables: number of decision variables of the problem """ self.number_of_variables = number_of_variables diff --git a/jmetal/problem/multiobjective/zdt.py b/jmetal/problem/multiobjective/zdt.py index cb5522be..c30ace35 100644 --- a/jmetal/problem/multiobjective/zdt.py +++ b/jmetal/problem/multiobjective/zdt.py @@ -17,6 +17,7 @@ class ZDT1(FloatProblem): .. note:: Bi-objective unconstrained problem. The default number of variables is 30. .. note:: Continuous problem having a convex Pareto front """ + def __init__(self, number_of_variables: int = 30): """Constructor :param number_of_variables: number of decision variables of the problem diff --git a/jmetal/util/test/test_graphic.py b/jmetal/util/test/test_graphic.py index 15829b8c..47636a27 100644 --- a/jmetal/util/test/test_graphic.py +++ b/jmetal/util/test/test_graphic.py @@ -40,13 +40,13 @@ def test_should_raise_an_exception_when_format_is_not_supported(self): with self.assertRaises(Exception): plot.simple_plot(solution_list=solution_list, file_name="file", fmt="null", save=True) - """ def test_should_raise_an_exception_when_updating_a_plot_that_doesnt_exist(self): plot = ScatterPlot(plot_title="title", animation_speed=1*10e-10) with self.assertRaises(Exception): plot.update(solution_list=None) + """ if __name__ == "__main__": From 8b2d2cd6e26c1252041288b7f52883c78e5f9802 Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 8 May 2018 14:48:19 +0200 Subject: [PATCH 31/90] Minor changes --- jmetal/core/solution.py | 5 +++-- jmetal/core/test/test_algorithm.py | 32 ------------------------------ jmetal/core/test/test_operator.py | 0 jmetal/core/test/test_problem.py | 6 +++++- 4 files changed, 8 insertions(+), 35 deletions(-) delete mode 100644 jmetal/core/test/test_algorithm.py delete mode 100644 jmetal/core/test/test_operator.py diff --git a/jmetal/core/solution.py b/jmetal/core/solution.py index 9233fcfd..7b707ebe 100644 --- a/jmetal/core/solution.py +++ b/jmetal/core/solution.py @@ -11,8 +11,9 @@ def __init__(self, number_of_variables : int, number_of_objectives : int, number self.number_of_objectives: int = number_of_objectives self.number_of_variables: int = number_of_variables self.number_of_constraints: int = number_of_constraints - self.objectives = [0.0 for x in range(self.number_of_objectives)] - self.variables = [[] for x in range(self.number_of_variables)] + self.objectives = [0.0 for _ in range(self.number_of_objectives)] + self.normalized_objectives = [0.0 for _ in range(self.number_of_objectives)] + self.variables = [[] for _ in range(self.number_of_variables)] self.attributes = {} diff --git a/jmetal/core/test/test_algorithm.py b/jmetal/core/test/test_algorithm.py deleted file mode 100644 index a6903253..00000000 --- a/jmetal/core/test/test_algorithm.py +++ /dev/null @@ -1,32 +0,0 @@ -import logging - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - -""" ->>>>>>> 5fdebfdf33c118dab271bc7ab380a121b396fde5 -class AlgorithmTestIntegrationTestCases(unittest.TestCase): - - def setUp(self): - bits = 512 - self.problem = OneMax(bits) - self.algorithm = GenerationalGeneticAlgorithm[BinarySolution, BinarySolution]( - self.problem, - population_size=100, - max_evaluations=25000, - mutation=BitFlip(1.0 / bits), - crossover=SinglePoint(0.9), - selection=BinaryTournament()) - - - def test_genetic_algorithm(self): - self.algorithm.run() - result = self.algorithm.get_result() - logger.info("Algorithm (binary problem): " + self.algorithm.get_name()) - logger.info("Problem: " + self.problem.get_name()) - logger.info("Solution: " + str(result.variables[0])) - logger.info("Fitness: " + str(result.objectives[0])) - - - assert(-500 <= result.objectives[0] <= -300 or 300 <= result.objectives[0] <= 500) -""" \ No newline at end of file diff --git a/jmetal/core/test/test_operator.py b/jmetal/core/test/test_operator.py deleted file mode 100644 index e69de29b..00000000 diff --git a/jmetal/core/test/test_problem.py b/jmetal/core/test/test_problem.py index 8d5bf1d9..1d7ac345 100644 --- a/jmetal/core/test/test_problem.py +++ b/jmetal/core/test/test_problem.py @@ -70,4 +70,8 @@ def test_should_create_solution_create_a_valid_solution(self) -> None: solution = problem.create_solution() self.assertNotEqual(None, solution) self.assertTrue(-1 <= solution.variables[0] <= 1) - self.assertTrue(-2 <= solution.variables[1] <= 2) \ No newline at end of file + self.assertTrue(-2 <= solution.variables[1] <= 2) + + +if __name__ == '__main__': + unittest.main() \ No newline at end of file From 4bd86859aefc94c88c328f311d2ee279c6ead2e7 Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 8 May 2018 14:48:52 +0200 Subject: [PATCH 32/90] Hypervolume indicator from Simon Wessing --- docs/source/api/jmetal.util.rst | 8 + docs/source/runner.rst | 1 + jmetal/util/quality_indicator.py | 272 +++++++++++++++++++++ jmetal/util/test/test_quality_indicator.py | 21 ++ 4 files changed, 302 insertions(+) create mode 100644 jmetal/util/quality_indicator.py create mode 100644 jmetal/util/test/test_quality_indicator.py diff --git a/docs/source/api/jmetal.util.rst b/docs/source/api/jmetal.util.rst index b38348c3..8d5f7c5c 100644 --- a/docs/source/api/jmetal.util.rst +++ b/docs/source/api/jmetal.util.rst @@ -1,6 +1,14 @@ Utils =================== +Quality indicator +----------------------------- + +.. automodule:: jmetal.util.quality_indicator + :members: + :undoc-members: + :show-inheritance: + Comparator ----------------------------- diff --git a/docs/source/runner.rst b/docs/source/runner.rst index 2cc4dfa9..0f783c58 100644 --- a/docs/source/runner.rst +++ b/docs/source/runner.rst @@ -76,6 +76,7 @@ NSGA-II stopping by time ------------ .. code-block:: python + from typing import List, TypeVar S = TypeVar('S') diff --git a/jmetal/util/quality_indicator.py b/jmetal/util/quality_indicator.py new file mode 100644 index 00000000..fabee56e --- /dev/null +++ b/jmetal/util/quality_indicator.py @@ -0,0 +1,272 @@ +# Copyright (C) 2010 Simon Wessing +# TU Dortmund University +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + + +""" +.. module:: HyperVolume + :platform: Unix, Windows + :synopsis: Hypervolume implementation. + +.. moduleauthor:: Simon Wessing +""" + + +class HyperVolume: + """ + Hypervolume computation based on variant 3 of the algorithm in the paper: + C. M. Fonseca, L. Paquete, and M. Lopez-Ibanez. An improved dimension-sweep + algorithm for the hypervolume indicator. In IEEE Congress on Evolutionary + Computation, pages 1157-1163, Vancouver, Canada, July 2006. + + Minimization is implicitly assumed here! + """ + + def __init__(self, referencePoint): + """Constructor.""" + self.referencePoint = referencePoint + self.list: MultiList = [] + + def compute(self, front): + """Returns the hypervolume that is dominated by a non-dominated front. + + Before the HV computation, front and reference point are translated, so + that the reference point is [0, ..., 0]. + """ + + def weaklyDominates(point, other): + for i in range(len(point)): + if point[i] > other[i]: + return False + return True + + relevantPoints = [] + referencePoint = self.referencePoint + dimensions = len(referencePoint) + for point in front: + # only consider points that dominate the reference point + if weaklyDominates(point, referencePoint): + relevantPoints.append(point) + if any(referencePoint): + # shift points so that referencePoint == [0, ..., 0] + # this way the reference point doesn't have to be explicitly used + # in the HV computation + for j in range(len(relevantPoints)): + relevantPoints[j] = [relevantPoints[j][i] - referencePoint[i] for i in range(dimensions)] + self.preProcess(relevantPoints) + bounds = [-1.0e308] * dimensions + hyperVolume = self.hvRecursive(dimensions - 1, len(relevantPoints), bounds) + return hyperVolume + + def hvRecursive(self, dimIndex, length, bounds): + """Recursive call to hypervolume calculation. + + In contrast to the paper, the code assumes that the reference point + is [0, ..., 0]. This allows the avoidance of a few operations. + """ + hvol = 0.0 + sentinel = self.list.sentinel + if length == 0: + return hvol + elif dimIndex == 0: + # special case: only one dimension + # why using hypervolume at all? + return -sentinel.next[0].cargo[0] + elif dimIndex == 1: + # special case: two dimensions, end recursion + q = sentinel.next[1] + h = q.cargo[0] + p = q.next[1] + while p is not sentinel: + pCargo = p.cargo + hvol += h * (q.cargo[1] - pCargo[1]) + if pCargo[0] < h: + h = pCargo[0] + q = p + p = q.next[1] + hvol += h * q.cargo[1] + return hvol + else: + remove = self.list.remove + reinsert = self.list.reinsert + hvRecursive = self.hvRecursive + p = sentinel + q = p.prev[dimIndex] + while q.cargo != None: + if q.ignore < dimIndex: + q.ignore = 0 + q = q.prev[dimIndex] + q = p.prev[dimIndex] + while length > 1 and ( + q.cargo[dimIndex] > bounds[dimIndex] or q.prev[dimIndex].cargo[dimIndex] >= bounds[dimIndex]): + p = q + remove(p, dimIndex, bounds) + q = p.prev[dimIndex] + length -= 1 + qArea = q.area + qCargo = q.cargo + qPrevDimIndex = q.prev[dimIndex] + if length > 1: + hvol = qPrevDimIndex.volume[dimIndex] + qPrevDimIndex.area[dimIndex] * ( + qCargo[dimIndex] - qPrevDimIndex.cargo[dimIndex]) + else: + qArea[0] = 1 + qArea[1:dimIndex + 1] = [qArea[i] * -qCargo[i] for i in range(dimIndex)] + q.volume[dimIndex] = hvol + if q.ignore >= dimIndex: + qArea[dimIndex] = qPrevDimIndex.area[dimIndex] + else: + qArea[dimIndex] = hvRecursive(dimIndex - 1, length, bounds) + if qArea[dimIndex] <= qPrevDimIndex.area[dimIndex]: + q.ignore = dimIndex + while p is not sentinel: + pCargoDimIndex = p.cargo[dimIndex] + hvol += q.area[dimIndex] * (pCargoDimIndex - q.cargo[dimIndex]) + bounds[dimIndex] = pCargoDimIndex + reinsert(p, dimIndex, bounds) + length += 1 + q = p + p = p.next[dimIndex] + q.volume[dimIndex] = hvol + if q.ignore >= dimIndex: + q.area[dimIndex] = q.prev[dimIndex].area[dimIndex] + else: + q.area[dimIndex] = hvRecursive(dimIndex - 1, length, bounds) + if q.area[dimIndex] <= q.prev[dimIndex].area[dimIndex]: + q.ignore = dimIndex + hvol -= q.area[dimIndex] * q.cargo[dimIndex] + return hvol + + def preProcess(self, front): + """Sets up the list data structure needed for calculation.""" + dimensions = len(self.referencePoint) + nodeList = MultiList(dimensions) + nodes = [MultiList.Node(dimensions, point) for point in front] + for i in range(dimensions): + self.sortByDimension(nodes, i) + nodeList.extend(nodes, i) + self.list = nodeList + + def sortByDimension(self, nodes, i): + """Sorts the list of nodes by the i-th value of the contained points.""" + # build a list of tuples of (point[i], node) + decorated = [(node.cargo[i], node) for node in nodes] + # sort by this value + decorated.sort() + # write back to original list + nodes[:] = [node for (_, node) in decorated] + + +class MultiList: + """A special data structure needed by FonsecaHyperVolume. + + It consists of several doubly linked lists that share common nodes. So, + every node has multiple predecessors and successors, one in every list. + """ + + class Node: + + def __init__(self, numberLists, cargo=None): + self.cargo = cargo + self.next = [None] * numberLists + self.prev = [None] * numberLists + self.ignore = 0 + self.area = [0.0] * numberLists + self.volume = [0.0] * numberLists + + def __str__(self): + return str(self.cargo) + + def __init__(self, numberLists): + """Constructor. + + Builds 'numberLists' doubly linked lists. + + """ + self.numberLists = numberLists + self.sentinel = MultiList.Node(numberLists) + self.sentinel.next = [self.sentinel] * numberLists + self.sentinel.prev = [self.sentinel] * numberLists + + def __str__(self): + strings = [] + for i in range(self.numberLists): + currentList = [] + node = self.sentinel.next[i] + while node != self.sentinel: + currentList.append(str(node)) + node = node.next[i] + strings.append(str(currentList)) + stringRepr = "" + for string in strings: + stringRepr += string + "\n" + return stringRepr + + def __len__(self): + """Returns the number of lists that are included in this MultiList.""" + return self.numberLists + + def getLength(self, i): + """Returns the length of the i-th list.""" + length = 0 + sentinel = self.sentinel + node = sentinel.next[i] + while node != sentinel: + length += 1 + node = node.next[i] + return length + + def append(self, node, index): + """Appends a node to the end of the list at the given index.""" + lastButOne = self.sentinel.prev[index] + node.next[index] = self.sentinel + node.prev[index] = lastButOne + # set the last element as the new one + self.sentinel.prev[index] = node + lastButOne.next[index] = node + + def extend(self, nodes, index): + """Extends the list at the given index with the nodes.""" + sentinel = self.sentinel + for node in nodes: + lastButOne = sentinel.prev[index] + node.next[index] = sentinel + node.prev[index] = lastButOne + # set the last element as the new one + sentinel.prev[index] = node + lastButOne.next[index] = node + + def remove(self, node, index, bounds): + """Removes and returns 'node' from all lists in [0, 'index'[.""" + for i in range(index): + predecessor = node.prev[i] + successor = node.next[i] + predecessor.next[i] = successor + successor.prev[i] = predecessor + if bounds[i] > node.cargo[i]: + bounds[i] = node.cargo[i] + return node + + def reinsert(self, node, index, bounds): + """ + Inserts 'node' at the position it had in all lists in [0, 'index'[ + before it was removed. This method assumes that the next and previous + nodes of the node that is reinserted are in the list. + """ + for i in range(index): + node.prev[i].next[i] = node + node.next[i].prev[i] = node + if bounds[i] > node.cargo[i]: + bounds[i] = node.cargo[i] diff --git a/jmetal/util/test/test_quality_indicator.py b/jmetal/util/test/test_quality_indicator.py new file mode 100644 index 00000000..8f0d93f0 --- /dev/null +++ b/jmetal/util/test/test_quality_indicator.py @@ -0,0 +1,21 @@ +import unittest + +from jmetal.util.quality_indicator import HyperVolume + + +class HyperVolumeTestCases(unittest.TestCase): + + def setUp(self): + pass + + def test_should_hyper_volume_return_5_0(self): + reference_point = [2, 2, 2] + front = [[1, 0, 1], [0, 1, 0]] + + hv = HyperVolume(reference_point) + value = hv.compute(front) + + self.assertEqual(5.0, value) + +if __name__ == '__main__': + unittest.main() From 474dc3832055af0ab2161b7070f4bbce1d0e4174 Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 8 May 2018 14:49:08 +0200 Subject: [PATCH 33/90] New version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 15796d76..baca4b7b 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages setup(name='jmetalpy', - version='0.1', + version='0.5', description='JMetalPy. Python version of the jMetal framework', author='Antonio J. Nebro', author_email='ajnebro@uma.es', From 536ae0ee56f30292b954c9a5eafbe5aac9a03d95 Mon Sep 17 00:00:00 2001 From: ajnebro Date: Wed, 9 May 2018 09:49:21 +0200 Subject: [PATCH 34/90] Add reference front of problem ZDT1 --- jmetal/util/FrontUtils.py | 0 resources/data/ZDT1.pf | 1001 +++++++++++++++++++++++++++++++++++++ 2 files changed, 1001 insertions(+) create mode 100644 jmetal/util/FrontUtils.py create mode 100644 resources/data/ZDT1.pf diff --git a/jmetal/util/FrontUtils.py b/jmetal/util/FrontUtils.py new file mode 100644 index 00000000..e69de29b diff --git a/resources/data/ZDT1.pf b/resources/data/ZDT1.pf new file mode 100644 index 00000000..78593afa --- /dev/null +++ b/resources/data/ZDT1.pf @@ -0,0 +1,1001 @@ +0 1 +0.001 0.968377 +0.002 0.955279 +0.003 0.945228 +0.004 0.936754 +0.005 0.929289 +0.006 0.92254 +0.007 0.916334 +0.008 0.910557 +0.009 0.905132 +0.01 0.9 +0.011 0.895119 +0.012 0.890455 +0.013 0.885982 +0.014 0.881678 +0.015 0.877526 +0.016 0.873509 +0.017 0.869616 +0.018 0.865836 +0.019 0.86216 +0.02 0.858579 +0.021 0.855086 +0.022 0.851676 +0.023 0.848342 +0.024 0.845081 +0.025 0.841886 +0.026 0.838755 +0.027 0.835683 +0.028 0.832668 +0.029 0.829706 +0.03 0.826795 +0.031 0.823932 +0.032 0.821115 +0.033 0.818341 +0.034 0.815609 +0.035 0.812917 +0.036 0.810263 +0.037 0.807646 +0.038 0.805064 +0.039 0.802516 +0.04 0.8 +0.041 0.797515 +0.042 0.795061 +0.043 0.792636 +0.044 0.790238 +0.045 0.787868 +0.046 0.785524 +0.047 0.783205 +0.048 0.780911 +0.049 0.778641 +0.05 0.776393 +0.051 0.774168 +0.052 0.771965 +0.053 0.769783 +0.054 0.767621 +0.055 0.765479 +0.056 0.763357 +0.057 0.761253 +0.058 0.759168 +0.059 0.757101 +0.06 0.755051 +0.061 0.753018 +0.062 0.751002 +0.063 0.749002 +0.064 0.747018 +0.065 0.745049 +0.066 0.743095 +0.067 0.741156 +0.068 0.739232 +0.069 0.737321 +0.07 0.735425 +0.071 0.733542 +0.072 0.731672 +0.073 0.729815 +0.074 0.727971 +0.075 0.726139 +0.076 0.724319 +0.077 0.722511 +0.078 0.720715 +0.079 0.718931 +0.08 0.717157 +0.081 0.715395 +0.082 0.713644 +0.083 0.711903 +0.084 0.710172 +0.085 0.708452 +0.086 0.706742 +0.087 0.705042 +0.088 0.703352 +0.089 0.701671 +0.09 0.7 +0.091 0.698338 +0.092 0.696685 +0.093 0.695041 +0.094 0.693406 +0.095 0.691779 +0.096 0.690161 +0.097 0.688552 +0.098 0.68695 +0.099 0.685357 +0.1 0.683772 +0.101 0.682195 +0.102 0.680626 +0.103 0.679064 +0.104 0.67751 +0.105 0.675963 +0.106 0.674424 +0.107 0.672891 +0.108 0.671366 +0.109 0.669849 +0.11 0.668338 +0.111 0.666833 +0.112 0.665336 +0.113 0.663845 +0.114 0.662361 +0.115 0.660884 +0.116 0.659412 +0.117 0.657947 +0.118 0.656489 +0.119 0.655036 +0.12 0.65359 +0.121 0.652149 +0.122 0.650715 +0.123 0.649286 +0.124 0.647864 +0.125 0.646447 +0.126 0.645035 +0.127 0.643629 +0.128 0.642229 +0.129 0.640834 +0.13 0.639445 +0.131 0.638061 +0.132 0.636682 +0.133 0.635308 +0.134 0.63394 +0.135 0.632577 +0.136 0.631218 +0.137 0.629865 +0.138 0.628516 +0.139 0.627173 +0.14 0.625834 +0.141 0.6245 +0.142 0.623171 +0.143 0.621847 +0.144 0.620527 +0.145 0.619211 +0.146 0.617901 +0.147 0.616594 +0.148 0.615292 +0.149 0.613995 +0.15 0.612702 +0.151 0.611413 +0.152 0.610128 +0.153 0.608848 +0.154 0.607572 +0.155 0.6063 +0.156 0.605032 +0.157 0.603768 +0.158 0.602508 +0.159 0.601252 +0.16 0.6 +0.161 0.598752 +0.162 0.597508 +0.163 0.596267 +0.164 0.595031 +0.165 0.593798 +0.166 0.592569 +0.167 0.591344 +0.168 0.590122 +0.169 0.588904 +0.17 0.587689 +0.171 0.586479 +0.172 0.585271 +0.173 0.584067 +0.174 0.582867 +0.175 0.58167 +0.176 0.580476 +0.177 0.579286 +0.178 0.5781 +0.179 0.576916 +0.18 0.575736 +0.181 0.574559 +0.182 0.573385 +0.183 0.572215 +0.184 0.571048 +0.185 0.569884 +0.186 0.568723 +0.187 0.567565 +0.188 0.56641 +0.189 0.565259 +0.19 0.56411 +0.191 0.562965 +0.192 0.561822 +0.193 0.560682 +0.194 0.559546 +0.195 0.558412 +0.196 0.557281 +0.197 0.556153 +0.198 0.555028 +0.199 0.553906 +0.2 0.552786 +0.201 0.55167 +0.202 0.550556 +0.203 0.549445 +0.204 0.548336 +0.205 0.547231 +0.206 0.546128 +0.207 0.545027 +0.208 0.54393 +0.209 0.542835 +0.21 0.541742 +0.211 0.540653 +0.212 0.539565 +0.213 0.538481 +0.214 0.537399 +0.215 0.536319 +0.216 0.535242 +0.217 0.534167 +0.218 0.533095 +0.219 0.532026 +0.22 0.530958 +0.221 0.529894 +0.222 0.528831 +0.223 0.527771 +0.224 0.526714 +0.225 0.525658 +0.226 0.524605 +0.227 0.523555 +0.228 0.522507 +0.229 0.521461 +0.23 0.520417 +0.231 0.519375 +0.232 0.518336 +0.233 0.517299 +0.234 0.516265 +0.235 0.515232 +0.236 0.514202 +0.237 0.513174 +0.238 0.512148 +0.239 0.511124 +0.24 0.510102 +0.241 0.509082 +0.242 0.508065 +0.243 0.50705 +0.244 0.506036 +0.245 0.505025 +0.246 0.504016 +0.247 0.503009 +0.248 0.502004 +0.249 0.501001 +0.25 0.5 +0.251 0.499001 +0.252 0.498004 +0.253 0.497009 +0.254 0.496016 +0.255 0.495025 +0.256 0.494036 +0.257 0.493048 +0.258 0.492063 +0.259 0.49108 +0.26 0.490098 +0.261 0.489118 +0.262 0.488141 +0.263 0.487165 +0.264 0.486191 +0.265 0.485218 +0.266 0.484248 +0.267 0.48328 +0.268 0.482313 +0.269 0.481348 +0.27 0.480385 +0.271 0.479423 +0.272 0.478464 +0.273 0.477506 +0.274 0.47655 +0.275 0.475596 +0.276 0.474643 +0.277 0.473692 +0.278 0.472743 +0.279 0.471795 +0.28 0.47085 +0.281 0.469906 +0.282 0.468963 +0.283 0.468023 +0.284 0.467083 +0.285 0.466146 +0.286 0.46521 +0.287 0.464276 +0.288 0.463344 +0.289 0.462413 +0.29 0.461484 +0.291 0.460556 +0.292 0.45963 +0.293 0.458705 +0.294 0.457782 +0.295 0.456861 +0.296 0.455941 +0.297 0.455023 +0.298 0.454106 +0.299 0.453191 +0.3 0.452277 +0.301 0.451365 +0.302 0.450455 +0.303 0.449546 +0.304 0.448638 +0.305 0.447732 +0.306 0.446827 +0.307 0.445924 +0.308 0.445023 +0.309 0.444122 +0.31 0.443224 +0.311 0.442326 +0.312 0.44143 +0.313 0.440536 +0.314 0.439643 +0.315 0.438751 +0.316 0.437861 +0.317 0.436972 +0.318 0.436085 +0.319 0.435199 +0.32 0.434315 +0.321 0.433431 +0.322 0.43255 +0.323 0.431669 +0.324 0.43079 +0.325 0.429912 +0.326 0.429036 +0.327 0.428161 +0.328 0.427287 +0.329 0.426415 +0.33 0.425544 +0.331 0.424674 +0.332 0.423806 +0.333 0.422938 +0.334 0.422073 +0.335 0.421208 +0.336 0.420345 +0.337 0.419483 +0.338 0.418622 +0.339 0.417763 +0.34 0.416905 +0.341 0.416048 +0.342 0.415192 +0.343 0.414338 +0.344 0.413485 +0.345 0.412633 +0.346 0.411782 +0.347 0.410933 +0.348 0.410085 +0.349 0.409238 +0.35 0.408392 +0.351 0.407547 +0.352 0.406704 +0.353 0.405862 +0.354 0.405021 +0.355 0.404181 +0.356 0.403343 +0.357 0.402505 +0.358 0.401669 +0.359 0.400834 +0.36 0.4 +0.361 0.399167 +0.362 0.398336 +0.363 0.397505 +0.364 0.396676 +0.365 0.395848 +0.366 0.395021 +0.367 0.394195 +0.368 0.39337 +0.369 0.392546 +0.37 0.391724 +0.371 0.390902 +0.372 0.390082 +0.373 0.389263 +0.374 0.388445 +0.375 0.387628 +0.376 0.386812 +0.377 0.385997 +0.378 0.385183 +0.379 0.38437 +0.38 0.383559 +0.381 0.382748 +0.382 0.381939 +0.383 0.38113 +0.384 0.380323 +0.385 0.379516 +0.386 0.378711 +0.387 0.377907 +0.388 0.377104 +0.389 0.376301 +0.39 0.3755 +0.391 0.3747 +0.392 0.373901 +0.393 0.373103 +0.394 0.372306 +0.395 0.37151 +0.396 0.370715 +0.397 0.369921 +0.398 0.369128 +0.399 0.368336 +0.4 0.367544 +0.401 0.366754 +0.402 0.365965 +0.403 0.365177 +0.404 0.36439 +0.405 0.363604 +0.406 0.362819 +0.407 0.362034 +0.408 0.361251 +0.409 0.360469 +0.41 0.359688 +0.411 0.358907 +0.412 0.358128 +0.413 0.357349 +0.414 0.356572 +0.415 0.355795 +0.416 0.355019 +0.417 0.354245 +0.418 0.353471 +0.419 0.352698 +0.42 0.351926 +0.421 0.351155 +0.422 0.350385 +0.423 0.349615 +0.424 0.348847 +0.425 0.34808 +0.426 0.347313 +0.427 0.346548 +0.428 0.345783 +0.429 0.345019 +0.43 0.344256 +0.431 0.343494 +0.432 0.342733 +0.433 0.341973 +0.434 0.341213 +0.435 0.340455 +0.436 0.339697 +0.437 0.33894 +0.438 0.338184 +0.439 0.337429 +0.44 0.336675 +0.441 0.335922 +0.442 0.335169 +0.443 0.334418 +0.444 0.333667 +0.445 0.332917 +0.446 0.332168 +0.447 0.331419 +0.448 0.330672 +0.449 0.329925 +0.45 0.32918 +0.451 0.328435 +0.452 0.327691 +0.453 0.326947 +0.454 0.326205 +0.455 0.325463 +0.456 0.324722 +0.457 0.323982 +0.458 0.323243 +0.459 0.322505 +0.46 0.321767 +0.461 0.32103 +0.462 0.320294 +0.463 0.319559 +0.464 0.318825 +0.465 0.318091 +0.466 0.317358 +0.467 0.316626 +0.468 0.315895 +0.469 0.315164 +0.47 0.314435 +0.471 0.313706 +0.472 0.312977 +0.473 0.31225 +0.474 0.311523 +0.475 0.310798 +0.476 0.310072 +0.477 0.309348 +0.478 0.308625 +0.479 0.307902 +0.48 0.30718 +0.481 0.306458 +0.482 0.305738 +0.483 0.305018 +0.484 0.304299 +0.485 0.303581 +0.486 0.302863 +0.487 0.302146 +0.488 0.30143 +0.489 0.300715 +0.49 0.3 +0.491 0.299286 +0.492 0.298573 +0.493 0.29786 +0.494 0.297149 +0.495 0.296438 +0.496 0.295727 +0.497 0.295018 +0.498 0.294309 +0.499 0.293601 +0.5 0.292893 +0.501 0.292186 +0.502 0.29148 +0.503 0.290775 +0.504 0.29007 +0.505 0.289366 +0.506 0.288663 +0.507 0.287961 +0.508 0.287259 +0.509 0.286558 +0.51 0.285857 +0.511 0.285157 +0.512 0.284458 +0.513 0.28376 +0.514 0.283062 +0.515 0.282365 +0.516 0.281669 +0.517 0.280973 +0.518 0.280278 +0.519 0.279583 +0.52 0.27889 +0.521 0.278197 +0.522 0.277504 +0.523 0.276813 +0.524 0.276122 +0.525 0.275431 +0.526 0.274741 +0.527 0.274052 +0.528 0.273364 +0.529 0.272676 +0.53 0.271989 +0.531 0.271303 +0.532 0.270617 +0.533 0.269932 +0.534 0.269247 +0.535 0.268563 +0.536 0.26788 +0.537 0.267197 +0.538 0.266515 +0.539 0.265834 +0.54 0.265153 +0.541 0.264473 +0.542 0.263794 +0.543 0.263115 +0.544 0.262436 +0.545 0.261759 +0.546 0.261082 +0.547 0.260406 +0.548 0.25973 +0.549 0.259055 +0.55 0.25838 +0.551 0.257706 +0.552 0.257033 +0.553 0.25636 +0.554 0.255688 +0.555 0.255017 +0.556 0.254346 +0.557 0.253676 +0.558 0.253006 +0.559 0.252337 +0.56 0.251669 +0.561 0.251001 +0.562 0.250333 +0.563 0.249667 +0.564 0.249001 +0.565 0.248335 +0.566 0.24767 +0.567 0.247006 +0.568 0.246342 +0.569 0.245679 +0.57 0.245017 +0.571 0.244355 +0.572 0.243693 +0.573 0.243032 +0.574 0.242372 +0.575 0.241712 +0.576 0.241053 +0.577 0.240395 +0.578 0.239737 +0.579 0.23908 +0.58 0.238423 +0.581 0.237766 +0.582 0.237111 +0.583 0.236456 +0.584 0.235801 +0.585 0.235147 +0.586 0.234494 +0.587 0.233841 +0.588 0.233188 +0.589 0.232537 +0.59 0.231885 +0.591 0.231235 +0.592 0.230585 +0.593 0.229935 +0.594 0.229286 +0.595 0.228638 +0.596 0.22799 +0.597 0.227342 +0.598 0.226695 +0.599 0.226049 +0.6 0.225403 +0.601 0.224758 +0.602 0.224113 +0.603 0.223469 +0.604 0.222826 +0.605 0.222183 +0.606 0.22154 +0.607 0.220898 +0.608 0.220256 +0.609 0.219615 +0.61 0.218975 +0.611 0.218335 +0.612 0.217696 +0.613 0.217057 +0.614 0.216418 +0.615 0.215781 +0.616 0.215143 +0.617 0.214507 +0.618 0.21387 +0.619 0.213234 +0.62 0.212599 +0.621 0.211964 +0.622 0.21133 +0.623 0.210697 +0.624 0.210063 +0.625 0.209431 +0.626 0.208798 +0.627 0.208167 +0.628 0.207535 +0.629 0.206905 +0.63 0.206275 +0.631 0.205645 +0.632 0.205016 +0.633 0.204387 +0.634 0.203759 +0.635 0.203131 +0.636 0.202504 +0.637 0.201877 +0.638 0.201251 +0.639 0.200625 +0.64 0.2 +0.641 0.199375 +0.642 0.198751 +0.643 0.198127 +0.644 0.197504 +0.645 0.196881 +0.646 0.196259 +0.647 0.195637 +0.648 0.195016 +0.649 0.194395 +0.65 0.193774 +0.651 0.193154 +0.652 0.192535 +0.653 0.191916 +0.654 0.191297 +0.655 0.190679 +0.656 0.190062 +0.657 0.189445 +0.658 0.188828 +0.659 0.188212 +0.66 0.187596 +0.661 0.186981 +0.662 0.186366 +0.663 0.185752 +0.664 0.185138 +0.665 0.184525 +0.666 0.183912 +0.667 0.183299 +0.668 0.182687 +0.669 0.182076 +0.67 0.181465 +0.671 0.180854 +0.672 0.180244 +0.673 0.179634 +0.674 0.179025 +0.675 0.178416 +0.676 0.177808 +0.677 0.1772 +0.678 0.176592 +0.679 0.175985 +0.68 0.175379 +0.681 0.174773 +0.682 0.174167 +0.683 0.173562 +0.684 0.172957 +0.685 0.172353 +0.686 0.171749 +0.687 0.171145 +0.688 0.170542 +0.689 0.16994 +0.69 0.169338 +0.691 0.168736 +0.692 0.168135 +0.693 0.167534 +0.694 0.166933 +0.695 0.166333 +0.696 0.165734 +0.697 0.165135 +0.698 0.164536 +0.699 0.163938 +0.7 0.16334 +0.701 0.162743 +0.702 0.162146 +0.703 0.161549 +0.704 0.160953 +0.705 0.160357 +0.706 0.159762 +0.707 0.159167 +0.708 0.158573 +0.709 0.157979 +0.71 0.157385 +0.711 0.156792 +0.712 0.156199 +0.713 0.155607 +0.714 0.155015 +0.715 0.154423 +0.716 0.153832 +0.717 0.153241 +0.718 0.152651 +0.719 0.152061 +0.72 0.151472 +0.721 0.150883 +0.722 0.150294 +0.723 0.149706 +0.724 0.149118 +0.725 0.148531 +0.726 0.147944 +0.727 0.147357 +0.728 0.146771 +0.729 0.146185 +0.73 0.1456 +0.731 0.145015 +0.732 0.14443 +0.733 0.143846 +0.734 0.143262 +0.735 0.142679 +0.736 0.142096 +0.737 0.141513 +0.738 0.140931 +0.739 0.140349 +0.74 0.139767 +0.741 0.139186 +0.742 0.138606 +0.743 0.138026 +0.744 0.137446 +0.745 0.136866 +0.746 0.136287 +0.747 0.135708 +0.748 0.13513 +0.749 0.134552 +0.75 0.133975 +0.751 0.133397 +0.752 0.132821 +0.753 0.132244 +0.754 0.131668 +0.755 0.131093 +0.756 0.130517 +0.757 0.129943 +0.758 0.129368 +0.759 0.128794 +0.76 0.12822 +0.761 0.127647 +0.762 0.127074 +0.763 0.126501 +0.764 0.125929 +0.765 0.125357 +0.766 0.124786 +0.767 0.124215 +0.768 0.123644 +0.769 0.123074 +0.77 0.122504 +0.771 0.121934 +0.772 0.121365 +0.773 0.120796 +0.774 0.120227 +0.775 0.119659 +0.776 0.119091 +0.777 0.118524 +0.778 0.117957 +0.779 0.11739 +0.78 0.116824 +0.781 0.116258 +0.782 0.115692 +0.783 0.115127 +0.784 0.114562 +0.785 0.113998 +0.786 0.113434 +0.787 0.11287 +0.788 0.112306 +0.789 0.111743 +0.79 0.111181 +0.791 0.110618 +0.792 0.110056 +0.793 0.109495 +0.794 0.108933 +0.795 0.108372 +0.796 0.107812 +0.797 0.107251 +0.798 0.106692 +0.799 0.106132 +0.8 0.105573 +0.801 0.105014 +0.802 0.104455 +0.803 0.103897 +0.804 0.10334 +0.805 0.102782 +0.806 0.102225 +0.807 0.101668 +0.808 0.101112 +0.809 0.100556 +0.81 0.1 +0.811 0.0994446 +0.812 0.0988896 +0.813 0.0983349 +0.814 0.0977805 +0.815 0.0972265 +0.816 0.0966728 +0.817 0.0961195 +0.818 0.0955665 +0.819 0.0950138 +0.82 0.0944615 +0.821 0.0939095 +0.822 0.0933578 +0.823 0.0928065 +0.824 0.0922555 +0.825 0.0917049 +0.826 0.0911546 +0.827 0.0906046 +0.828 0.0900549 +0.829 0.0895056 +0.83 0.0889566 +0.831 0.088408 +0.832 0.0878597 +0.833 0.0873117 +0.834 0.086764 +0.835 0.0862167 +0.836 0.0856696 +0.837 0.085123 +0.838 0.0845766 +0.839 0.0840306 +0.84 0.0834849 +0.841 0.0829395 +0.842 0.0823944 +0.843 0.0818497 +0.844 0.0813053 +0.845 0.0807612 +0.846 0.0802174 +0.847 0.079674 +0.848 0.0791308 +0.849 0.078588 +0.85 0.0780456 +0.851 0.0775034 +0.852 0.0769615 +0.853 0.07642 +0.854 0.0758788 +0.855 0.0753379 +0.856 0.0747973 +0.857 0.0742571 +0.858 0.0737171 +0.859 0.0731775 +0.86 0.0726382 +0.861 0.0720991 +0.862 0.0715604 +0.863 0.0710221 +0.864 0.070484 +0.865 0.0699462 +0.866 0.0694088 +0.867 0.0688717 +0.868 0.0683348 +0.869 0.0677983 +0.87 0.0672621 +0.871 0.0667262 +0.872 0.0661906 +0.873 0.0656553 +0.874 0.0651203 +0.875 0.0645857 +0.876 0.0640513 +0.877 0.0635172 +0.878 0.0629835 +0.879 0.06245 +0.88 0.0619168 +0.881 0.061384 +0.882 0.0608514 +0.883 0.0603192 +0.884 0.0597873 +0.885 0.0592556 +0.886 0.0587243 +0.887 0.0581932 +0.888 0.0576625 +0.889 0.057132 +0.89 0.0566019 +0.891 0.056072 +0.892 0.0555425 +0.893 0.0550132 +0.894 0.0544843 +0.895 0.0539556 +0.896 0.0534272 +0.897 0.0528992 +0.898 0.0523714 +0.899 0.0518439 +0.9 0.0513167 +0.901 0.0507898 +0.902 0.0502632 +0.903 0.0497369 +0.904 0.0492109 +0.905 0.0486851 +0.906 0.0481597 +0.907 0.0476345 +0.908 0.0471097 +0.909 0.0465851 +0.91 0.0460608 +0.911 0.0455368 +0.912 0.0450131 +0.913 0.0444897 +0.914 0.0439665 +0.915 0.0434437 +0.916 0.0429211 +0.917 0.0423988 +0.918 0.0418768 +0.919 0.0413551 +0.92 0.0408337 +0.921 0.0403126 +0.922 0.0397917 +0.923 0.0392711 +0.924 0.0387508 +0.925 0.0382308 +0.926 0.0377111 +0.927 0.0371916 +0.928 0.0366724 +0.929 0.0361535 +0.93 0.0356349 +0.931 0.0351166 +0.932 0.0345985 +0.933 0.0340807 +0.934 0.0335632 +0.935 0.033046 +0.936 0.0325291 +0.937 0.0320124 +0.938 0.031496 +0.939 0.0309799 +0.94 0.030464 +0.941 0.0299485 +0.942 0.0294332 +0.943 0.0289181 +0.944 0.0284034 +0.945 0.0278889 +0.946 0.0273747 +0.947 0.0268607 +0.948 0.0263471 +0.949 0.0258337 +0.95 0.0253206 +0.951 0.0248077 +0.952 0.0242951 +0.953 0.0237828 +0.954 0.0232708 +0.955 0.022759 +0.956 0.0222475 +0.957 0.0217362 +0.958 0.0212253 +0.959 0.0207145 +0.96 0.0202041 +0.961 0.0196939 +0.962 0.019184 +0.963 0.0186744 +0.964 0.018165 +0.965 0.0176559 +0.966 0.017147 +0.967 0.0166384 +0.968 0.0161301 +0.969 0.015622 +0.97 0.0151142 +0.971 0.0146067 +0.972 0.0140994 +0.973 0.0135924 +0.974 0.0130856 +0.975 0.0125791 +0.976 0.0120729 +0.977 0.0115669 +0.978 0.0110612 +0.979 0.0105557 +0.98 0.0100505 +0.981 0.00954556 +0.982 0.00904087 +0.983 0.00853644 +0.984 0.00803226 +0.985 0.00752834 +0.986 0.00702467 +0.987 0.00652126 +0.988 0.00601811 +0.989 0.00551521 +0.99 0.00501256 +0.991 0.00451017 +0.992 0.00400803 +0.993 0.00350615 +0.994 0.00300451 +0.995 0.00250313 +0.996 0.002002 +0.997 0.00150113 +0.998 0.0010005 +0.999 0.000500125 +1 0 \ No newline at end of file From cb27838ab7bd40cac94498dd41a7fbca4657466d Mon Sep 17 00:00:00 2001 From: ajnebro Date: Wed, 9 May 2018 09:50:15 +0200 Subject: [PATCH 35/90] Add file FrontUtils.py --- jmetal/util/FrontUtils.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/jmetal/util/FrontUtils.py b/jmetal/util/FrontUtils.py index e69de29b..d3acc13a 100644 --- a/jmetal/util/FrontUtils.py +++ b/jmetal/util/FrontUtils.py @@ -0,0 +1,13 @@ + + +def read_front_from_file(file_name: str): + """ Reads a front from a file and returns a list + """ + front = [] + file = open(file_name) + for line in file: + vector = [float(x) for x in line.split()] + front.append(vector) + + return front + From 4857268f25cb73345598baaca07ab46e22b8e58b Mon Sep 17 00:00:00 2001 From: ajnebro Date: Wed, 9 May 2018 09:50:41 +0200 Subject: [PATCH 36/90] Add new test case in file test_quality_indicator.py --- jmetal/util/test/test_quality_indicator.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/jmetal/util/test/test_quality_indicator.py b/jmetal/util/test/test_quality_indicator.py index 8f0d93f0..ba502b90 100644 --- a/jmetal/util/test/test_quality_indicator.py +++ b/jmetal/util/test/test_quality_indicator.py @@ -1,5 +1,6 @@ import unittest +from jmetal.util.FrontUtils import read_front_from_file from jmetal.util.quality_indicator import HyperVolume @@ -8,7 +9,7 @@ class HyperVolumeTestCases(unittest.TestCase): def setUp(self): pass - def test_should_hyper_volume_return_5_0(self): + def test_should_hypervolume_return_5_0(self): reference_point = [2, 2, 2] front = [[1, 0, 1], [0, 1, 0]] @@ -17,5 +18,15 @@ def test_should_hyper_volume_return_5_0(self): self.assertEqual(5.0, value) + def test_should_hypervolume_return_the_correct_value_when_applied_to_the_ZDT1_reference_front(self): + reference_point = [1, 1] + front = read_front_from_file("../../../resources/data/ZDT1.pf") + + hv = HyperVolume(reference_point) + value = hv.compute(front) + + self.assertAlmostEqual(0.666, value, delta=0.001) + + if __name__ == '__main__': unittest.main() From 6d1ff861bd9d0dbf62649b72709c2415406dcef7 Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 11 May 2018 12:12:31 +0200 Subject: [PATCH 37/90] Added SMPSO/RP and archives --- docs/source/examples.rst | 10 ++ docs/source/index.rst | 2 +- docs/source/{runner.rst => runner/nsgaii.rst} | 17 ++- docs/source/runner/smpso.rst | 59 ++++++++ jmetal/algorithm/multiobjective/smpso.py | 119 +++++++++++++-- jmetal/component/archive.py | 135 +++++++++++++----- ..._standard_settings_with_reference_point.py | 38 +++++ .../smpsorp_standard_settings.py | 49 +++++++ jmetal/util/comparator.py | 12 +- 9 files changed, 387 insertions(+), 54 deletions(-) create mode 100644 docs/source/examples.rst rename docs/source/{runner.rst => runner/nsgaii.rst} (95%) create mode 100644 docs/source/runner/smpso.rst create mode 100644 jmetal/runner/multiobjective/smpso_standard_settings_with_reference_point.py create mode 100644 jmetal/runner/multiobjective/smpsorp_standard_settings.py diff --git a/docs/source/examples.rst b/docs/source/examples.rst new file mode 100644 index 00000000..68f89264 --- /dev/null +++ b/docs/source/examples.rst @@ -0,0 +1,10 @@ +Examples +============== + + +.. toctree:: + :maxdepth: 2 + :caption: Algorithms: + + runner/nsgaii + runner/smpso \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index fdb2e3ad..13329c29 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -12,7 +12,7 @@ jMetalPy: Python version of the jMetal framework :maxdepth: 1 :caption: Contents: - runner + examples about api/jmetal diff --git a/docs/source/runner.rst b/docs/source/runner/nsgaii.rst similarity index 95% rename from docs/source/runner.rst rename to docs/source/runner/nsgaii.rst index 0f783c58..a44704ad 100644 --- a/docs/source/runner.rst +++ b/docs/source/runner/nsgaii.rst @@ -1,5 +1,5 @@ -Examples -============== +NSGA-II +======================== Common imports: @@ -24,7 +24,8 @@ NSGA-II with standard settings max_evaluations=25000, mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) + selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator()) + ) algorithm.run() result = algorithm.get_result() @@ -42,7 +43,8 @@ NSGA-II with observer max_evaluations=25000, mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) + selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator()) + ) observer = WriteFrontToFileObserver("output_directory") algorithm.observable.register(observer=observer) @@ -63,8 +65,8 @@ NSGA-II with plot in real-time max_evaluations=25000, mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) - + selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator()) + ) observer = AlgorithmObserver(animation_speed=1*10e-8) algorithm.observable.register(observer=observer) @@ -99,7 +101,8 @@ NSGA-II stopping by time max_evaluations=25000, mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) + selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator()) + ) algorithm.run() result = algorithm.get_result() \ No newline at end of file diff --git a/docs/source/runner/smpso.rst b/docs/source/runner/smpso.rst new file mode 100644 index 00000000..c75e85e0 --- /dev/null +++ b/docs/source/runner/smpso.rst @@ -0,0 +1,59 @@ +SMPSO +======================== + +Common imports: + +.. code-block:: python + + from jmetal.core.solution import FloatSolution + + from jmetal.operator.mutation import Polynomial + from jmetal.component.archive import CrowdingDistanceArchive + +SMPSO with standard settings +------------ + +.. code-block:: python + + from jmetal.algorithm.multiobjective.smpso import SMPSO + + algorithm = SMPSO( + problem=problem, + swarm_size=100, + max_evaluations=25000, + mutation=Polynomial(probability=1.0/problem.number_of_variables, distribution_index=20), + leaders=CrowdingDistanceArchive(100) + ) + + algorithm.run() + result = algorithm.get_result() + +SMPSO/RP with standard settings +------------ + +.. code-block:: python + + from jmetal.algorithm.multiobjective.smpso import SMPSORP + from jmetal.component.archive import CrowdingDistanceArchiveWithReferencePoint + + swarm_size = 100 + + reference_points = [[0.8, 0.2], [0.4, 0.6]] + archives_with_reference_points = [] + + for point in reference_points: + archives_with_reference_points.append( + CrowdingDistanceArchiveWithReferencePoint(swarm_size, point) + ) + + algorithm = SMPSORP( + problem=problem, + swarm_size=swarm_size, + max_evaluations=25000, + mutation=Polynomial(probability=1.0/problem.number_of_variables, distribution_index=20), + reference_points=reference_points, + leaders=archives_with_reference_points + ) + + algorithm.run() + result = algorithm.get_result() \ No newline at end of file diff --git a/jmetal/algorithm/multiobjective/smpso.py b/jmetal/algorithm/multiobjective/smpso.py index c1466db6..b96aba6a 100644 --- a/jmetal/algorithm/multiobjective/smpso.py +++ b/jmetal/algorithm/multiobjective/smpso.py @@ -31,7 +31,7 @@ def __init__(self, swarm_size: int, max_evaluations: int, mutation: Mutation[FloatSolution], - leaders: BoundedArchive[FloatSolution], + leaders: BoundedArchive[FloatSolution] or None, observable: Observable = DefaultObservable(), evaluator: Evaluator[FloatSolution] = SequentialEvaluator[FloatSolution]()): """ This class implements the SMPSO algorithm described in @@ -50,7 +50,7 @@ def __init__(self, :param observable: :param evaluator: An evaluator object to evaluate the solutions in the population. """ - super(SMPSO, self).__init__() + super().__init__() self.problem = problem self.swarm_size = swarm_size self.max_evaluations = max_evaluations @@ -125,7 +125,7 @@ def initialize_velocity(self, swarm: List[FloatSolution]) -> None: def update_velocity(self, swarm: List[FloatSolution]) -> None: for i in range(self.swarm_size): best_particle = copy(swarm[i].attributes["local_best"]) - best_global = self.__select_global_best() + best_global = self.select_global_best() r1 = round(random.uniform(self.r1_min, self.r1_max), 1) r2 = round(random.uniform(self.r2_min, self.r2_max), 1) @@ -180,12 +180,18 @@ def update_particle_best(self, swarm: List[FloatSolution]) -> None: def get_result(self) -> List[FloatSolution]: return self.leaders.solution_list - def __select_global_best(self) -> FloatSolution: - particles = random.sample(self.leaders.solution_list, 2) - if self.leaders.get_comparator().compare(particles[0], particles[1]) < 1: - best_global = copy(particles[0]) + def select_global_best(self) -> FloatSolution: + leaders = self.leaders.solution_list + + if len(leaders) > 2: + particles = random.sample(leaders, 2) + + if self.leaders.get_comparator().compare(particles[0], particles[1]) < 1: + best_global = copy(particles[0]) + else: + best_global = copy(particles[1]) else: - best_global = copy(particles[1]) + best_global = copy(self.leaders.solution_list[0]) return best_global @@ -209,3 +215,100 @@ def __constriction_coefficient(self, c1: float, c2: float) -> float: result = 2.0 / (2.0 - rho - sqrt(pow(rho, 2.0) - 4.0 * rho)) return result + + +class SMPSORP(SMPSO): + def __init__(self, problem: FloatProblem, + swarm_size: int, + max_evaluations: int, + mutation: Mutation[FloatSolution], + reference_points: List[List], + leaders: List[BoundedArchive[FloatSolution]], + observable: Observable = DefaultObservable(), + evaluator: Evaluator[FloatSolution] = SequentialEvaluator[FloatSolution]()): + """ This class implements the SMPSORP algorithm. + + :param problem: The problem to solve. + :param swarm_size: + :param max_evaluations: + :param mutation: + :param leaders: List of bounded archives. + :param observable: + :param evaluator: An evaluator object to evaluate the solutions in the population. + """ + super().__init__( + problem, + swarm_size, + max_evaluations, + mutation, + None, + observable, + evaluator) + self.reference_points = reference_points + self.leaders = leaders + + def update_leaders_density_estimator(self): + for leader in self.leaders: + leader.compute_density_estimator() + + def init_progress(self) -> None: + self.evaluations = self.swarm_size + self.update_leaders_density_estimator() + + def update_progress(self) -> None: + self.evaluations += self.swarm_size + self.update_leaders_density_estimator() + + reference_points = [] + for i, _ in enumerate(self.reference_points): + point = self.problem.create_solution() + point.objectives = self.reference_points[i] + reference_points.append(point) + + observable_data = {'evaluations': self.evaluations, + 'population': self.get_result() + reference_points, + 'computing time': self.get_current_computing_time()} + + self.observable.notify_all(**observable_data) + + def initialize_global_best(self, swarm: List[FloatSolution]) -> None: + for particle in swarm: + for leader in self.leaders: + leader.add(copy(particle)) + + def update_global_best(self, swarm: List[FloatSolution]) -> None: + for particle in swarm: + for leader in self.leaders: + leader.add(copy(particle)) + + def get_result(self) -> List[FloatSolution]: + result = [] + + for leader in self.leaders: + for solution in leader.get_solution_list(): + result.append(solution) + + return result + + def select_global_best(self) -> FloatSolution: + selected = False + selected_swarm_index = 0 + + while not selected: + selected_swarm_index = random.randint(0, len(self.leaders) - 1) + if len(self.leaders[selected_swarm_index].solution_list) != 0: + selected = True + + leaders = self.leaders[selected_swarm_index].solution_list + + if len(leaders) > 2: + particles = random.sample(leaders, 2) + + if self.leaders[selected_swarm_index].get_comparator().compare(particles[0], particles[1]) < 1: + best_global = copy(particles[0]) + else: + best_global = copy(particles[1]) + else: + best_global = copy(self.leaders[selected_swarm_index].solution_list[0]) + + return best_global diff --git a/jmetal/component/archive.py b/jmetal/component/archive.py index 4a2a670d..f53b3d3b 100644 --- a/jmetal/component/archive.py +++ b/jmetal/component/archive.py @@ -1,7 +1,10 @@ +import random from typing import TypeVar, Generic, List -from jmetal.component.density_estimator import CrowdingDistance -from jmetal.util.comparator import DominanceComparator, EqualSolutionsComparator, SolutionAttributeComparator +import copy + +from jmetal.component.density_estimator import CrowdingDistance, DensityEstimator +from jmetal.util.comparator import Comparator, DominanceComparator, EqualSolutionsComparator, SolutionAttributeComparator S = TypeVar('S') @@ -35,18 +38,45 @@ def get_comparator(self): class BoundedArchive(Archive[S]): - def __init__(self, maximum_size: int): + def __init__(self, maximum_size: int, comparator: Comparator[S], density_estimator: DensityEstimator): super(BoundedArchive, self).__init__() self.maximum_size = maximum_size + self.comparator = comparator + self.density_estimator = density_estimator + self.non_dominated_solution_archive = NonDominatedSolutionListArchive() + self.solution_list = self.non_dominated_solution_archive.get_solution_list() def get_max_size(self) -> int: return self.maximum_size def compute_density_estimator(self): - pass + self.density_estimator.compute_density_estimator(self.get_solution_list()) - def sort(self): - pass + def add(self, solution: S) -> bool: + success: bool = self.non_dominated_solution_archive.add(solution) + if success: + if self.size() > self.get_max_size(): + self.compute_density_estimator() + worst_solution = self.__find_worst_solution(self.get_solution_list()) + self.get_solution_list().remove(worst_solution) + + return success + + def __find_worst_solution(self, solution_list: List[S]) -> S: + if solution_list is None: + raise Exception("The solution list is None") + elif len(solution_list) is 0: + raise Exception("The solution list is empty") + + worst_solution = solution_list[0] + for solution in solution_list[1:]: + if self.comparator.compare(worst_solution, solution) < 0: + worst_solution = solution + + return worst_solution + + def get_comparator(self): + return self.comparator class NonDominatedSolutionListArchive(Archive[S]): @@ -90,38 +120,79 @@ def get_comparator(self): class CrowdingDistanceArchive(BoundedArchive[S]): def __init__(self, maximum_size: int): - super(CrowdingDistanceArchive, self).__init__(maximum_size) + super(CrowdingDistanceArchive, self).__init__( + maximum_size=maximum_size, + comparator=SolutionAttributeComparator("crowding_distance", lowest_is_best=False), + density_estimator=CrowdingDistance()) + - self.__non_dominated_solution_archive = NonDominatedSolutionListArchive[S]() - self.__comparator = SolutionAttributeComparator("crowding_distance", lowest_is_best=False) - self.__crowding_distance = CrowdingDistance() - self.solution_list = self.__non_dominated_solution_archive.get_solution_list() +class ArchiveWithReferencePoint(BoundedArchive[S]): + def __init__(self, maximum_size: int, reference_point: List[float], comparator: Comparator[S], density_estimator: DensityEstimator): + super(ArchiveWithReferencePoint, self).__init__(maximum_size, comparator, density_estimator) + self.__reference_point = reference_point + self.__comparator = comparator + self.__density_estimator = density_estimator + self.__reference_point_solution: S = None def add(self, solution: S) -> bool: - success: bool = self.__non_dominated_solution_archive.add(solution) - if success: - if self.size() > self.get_max_size(): - self.compute_density_estimator() - worst_solution = self.__find_worst_solution(self.get_solution_list()) - self.get_solution_list().remove(worst_solution) + if self.__reference_point_solution is None: + self.__reference_point_solution = copy.deepcopy(solution) + + self.__reference_point_solution.objectives = [value for value in self.__reference_point] + + dominated_solution = None + + if self.__dominance_test(solution, self.__reference_point_solution) == 0: + if len(self.get_solution_list()) == 0: + result = True + else: + if random.uniform(0.0, 1.0) < 0.05: + result = True + dominated_solution = solution + else: + result = False + else: + result = True - return success + if result: + result = super(ArchiveWithReferencePoint, self).add(solution) - def compute_density_estimator(self): - self.__crowding_distance.compute_density_estimator(self.get_solution_list()) + if result and dominated_solution is not None and len(self.get_solution_list()) > 1: + self.get_solution_list().remove(dominated_solution) - def __find_worst_solution(self, solution_list: List[S]) -> S: - if solution_list is None: - raise Exception("The solution list is None") - elif len(solution_list) is 0: - raise Exception("The solution list is empty") + if result and len(self.get_solution_list()) > self.maximum_size: + self.compute_density_estimator() - worst_solution = solution_list[0] - for solution in solution_list[1:]: - if self.__comparator.compare(worst_solution, solution) < 0: - worst_solution = solution + return result - return worst_solution + def get_reference_point(self)->List[float]: + return self.__reference_point - def get_comparator(self): - return self.__comparator + def __dominance_test(self, solution1:S, solution2:S)->int: + best_is_one = 0 + best_is_two = 0 + + for value1, value2 in zip(solution1.objectives, solution2.objectives): + if value1 != value2: + if value1 < value2: + best_is_one = 1 + if value2 < value1: + best_is_two = 1 + + if best_is_one > best_is_two: + result = -1 + elif best_is_two > best_is_one: + result = 1 + else: + result = 0 + + return result + + +class CrowdingDistanceArchiveWithReferencePoint(ArchiveWithReferencePoint[S]): + def __init__(self, maximum_size: int, reference_point:List[float]): + super(CrowdingDistanceArchiveWithReferencePoint, self).__init__( + maximum_size=maximum_size, + reference_point=reference_point, + comparator=SolutionAttributeComparator("crowding_distance", lowest_is_best=False), + density_estimator=CrowdingDistance()) diff --git a/jmetal/runner/multiobjective/smpso_standard_settings_with_reference_point.py b/jmetal/runner/multiobjective/smpso_standard_settings_with_reference_point.py new file mode 100644 index 00000000..2a86fa60 --- /dev/null +++ b/jmetal/runner/multiobjective/smpso_standard_settings_with_reference_point.py @@ -0,0 +1,38 @@ +import logging + +from jmetal.algorithm.multiobjective.smpso import SMPSO +from jmetal.component.archive import CrowdingDistanceArchiveWithReferencePoint +from jmetal.component.observer import AlgorithmObserver +from jmetal.core.solution import FloatSolution +from jmetal.operator.mutation import Polynomial +from jmetal.problem.multiobjective.zdt import ZDT1 +from jmetal.util.solution_list_output import SolutionListOutput + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +def main() -> None: + problem = ZDT1() + algorithm = SMPSO( + problem=problem, + swarm_size=100, + max_evaluations=25000, + mutation=Polynomial(probability=1.0/problem.number_of_variables, distribution_index=20), + leaders=CrowdingDistanceArchiveWithReferencePoint(100, reference_point=[1.0, 1.0]) + ) + + observer = AlgorithmObserver(animation_speed=1*10e-8) + algorithm.observable.register(observer=observer) + + algorithm.run() + result = algorithm.get_result() + + SolutionListOutput[FloatSolution].plot_scatter_to_screen(result) + + logger.info("Algorithm (continuous problem): " + algorithm.get_name()) + logger.info("Problem: " + problem.get_name()) + + +if __name__ == '__main__': + main() diff --git a/jmetal/runner/multiobjective/smpsorp_standard_settings.py b/jmetal/runner/multiobjective/smpsorp_standard_settings.py new file mode 100644 index 00000000..0b46c344 --- /dev/null +++ b/jmetal/runner/multiobjective/smpsorp_standard_settings.py @@ -0,0 +1,49 @@ +import logging + +from jmetal.algorithm.multiobjective.smpso import SMPSORP +from jmetal.component.archive import CrowdingDistanceArchiveWithReferencePoint +from jmetal.component.observer import AlgorithmObserver +from jmetal.core.solution import FloatSolution +from jmetal.operator.mutation import Polynomial +from jmetal.problem.multiobjective.zdt import ZDT1 +from jmetal.util.solution_list_output import SolutionListOutput + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +def main() -> None: + problem = ZDT1() + swarm_size = 100 + + reference_points = [[0.8, 0.2], [0.4, 0.6]] + archives_with_reference_points = [] + + for point in reference_points: + archives_with_reference_points.append( + CrowdingDistanceArchiveWithReferencePoint(swarm_size, point) + ) + + algorithm = SMPSORP( + problem=problem, + swarm_size=swarm_size, + max_evaluations=25000, + mutation=Polynomial(probability=1.0/problem.number_of_variables, distribution_index=20), + reference_points=reference_points, + leaders=archives_with_reference_points + ) + + observer = AlgorithmObserver(animation_speed=1*10e-8) + algorithm.observable.register(observer=observer) + + algorithm.run() + result = algorithm.get_result() + + SolutionListOutput[FloatSolution].plot_scatter_to_screen(result) + + logger.info("Algorithm (continuous problem): " + algorithm.get_name()) + logger.info("Problem: " + problem.get_name()) + + +if __name__ == '__main__': + main() diff --git a/jmetal/util/comparator.py b/jmetal/util/comparator.py index e02a5a54..77a4d238 100644 --- a/jmetal/util/comparator.py +++ b/jmetal/util/comparator.py @@ -1,16 +1,16 @@ -from typing import TypeVar +from typing import TypeVar, Generic from jmetal.core.solution import Solution S = TypeVar('S') -class Comparator(): +class Comparator(Generic[S]): def compare(self, object1: S, object2: S) -> int: pass -class EqualSolutionsComparator(): +class EqualSolutionsComparator(Comparator): def compare(self, solution1: Solution, solution2: Solution) -> int: if solution1 is None: return 1 @@ -24,7 +24,7 @@ def compare(self, solution1: Solution, solution2: Solution) -> int: value1 = solution1.objectives[i] value2 = solution2.objectives[i] - if value1 value2: flag = 1 @@ -44,7 +44,7 @@ def compare(self, solution1: Solution, solution2: Solution) -> int: return 1 -class SolutionAttributeComparator(): +class SolutionAttributeComparator(Comparator): def __init__(self, key: str, lowest_is_best: bool = True): self.key = key self.lowest_is_best = lowest_is_best @@ -86,7 +86,7 @@ def compare(self, solution1: Solution, solution2: Solution) -> int: return result -class DominanceComparator(): +class DominanceComparator(Comparator): def __init__(self, constraint_comparator = SolutionAttributeComparator("overall_constraint_violation", lowest_is_best=False)): self.constraint_comparator = constraint_comparator From a976cdeae2c8e8333eb3ee6526586b9fbaf6cf4c Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 11 May 2018 12:12:46 +0200 Subject: [PATCH 38/90] Improve docs --- jmetal/util/quality_indicator.py | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/jmetal/util/quality_indicator.py b/jmetal/util/quality_indicator.py index fabee56e..6dd56df3 100644 --- a/jmetal/util/quality_indicator.py +++ b/jmetal/util/quality_indicator.py @@ -25,9 +25,9 @@ class HyperVolume: - """ - Hypervolume computation based on variant 3 of the algorithm in the paper: - C. M. Fonseca, L. Paquete, and M. Lopez-Ibanez. An improved dimension-sweep + """ Hypervolume computation based on variant 3 of the algorithm in the paper: + + * C. M. Fonseca, L. Paquete, and M. Lopez-Ibanez. An improved dimension-sweep algorithm for the hypervolume indicator. In IEEE Congress on Evolutionary Computation, pages 1157-1163, Vancouver, Canada, July 2006. @@ -40,10 +40,10 @@ def __init__(self, referencePoint): self.list: MultiList = [] def compute(self, front): - """Returns the hypervolume that is dominated by a non-dominated front. - - Before the HV computation, front and reference point are translated, so + """Before the HV computation, front and reference point are translated, so that the reference point is [0, ..., 0]. + + :return: The hypervolume that is dominated by a non-dominated front. """ def weaklyDominates(point, other): @@ -190,10 +190,7 @@ def __str__(self): return str(self.cargo) def __init__(self, numberLists): - """Constructor. - - Builds 'numberLists' doubly linked lists. - + """ Builds 'numberLists' doubly linked lists. """ self.numberLists = numberLists self.sentinel = MultiList.Node(numberLists) @@ -229,7 +226,7 @@ def getLength(self, i): return length def append(self, node, index): - """Appends a node to the end of the list at the given index.""" + """ Appends a node to the end of the list at the given index.""" lastButOne = self.sentinel.prev[index] node.next[index] = self.sentinel node.prev[index] = lastButOne @@ -238,7 +235,7 @@ def append(self, node, index): lastButOne.next[index] = node def extend(self, nodes, index): - """Extends the list at the given index with the nodes.""" + """ Extends the list at the given index with the nodes.""" sentinel = self.sentinel for node in nodes: lastButOne = sentinel.prev[index] @@ -249,7 +246,7 @@ def extend(self, nodes, index): lastButOne.next[index] = node def remove(self, node, index, bounds): - """Removes and returns 'node' from all lists in [0, 'index'[.""" + """ Removes and returns 'node' from all lists in [0, 'index'[.""" for i in range(index): predecessor = node.prev[i] successor = node.next[i] @@ -260,8 +257,7 @@ def remove(self, node, index, bounds): return node def reinsert(self, node, index, bounds): - """ - Inserts 'node' at the position it had in all lists in [0, 'index'[ + """ Inserts 'node' at the position it had in all lists in [0, 'index'[ before it was removed. This method assumes that the next and previous nodes of the node that is reinserted are in the list. """ From 37e80ca429c59f7fc932278a1f138c9261968e2a Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 11 May 2018 12:17:41 +0200 Subject: [PATCH 39/90] Renamed class --- jmetal/util/FrontUtils.py | 13 ------------- jmetal/util/front_utils.py | 13 +++++++++++++ jmetal/util/test/test_quality_indicator.py | 7 +++++-- 3 files changed, 18 insertions(+), 15 deletions(-) delete mode 100644 jmetal/util/FrontUtils.py create mode 100644 jmetal/util/front_utils.py diff --git a/jmetal/util/FrontUtils.py b/jmetal/util/FrontUtils.py deleted file mode 100644 index d3acc13a..00000000 --- a/jmetal/util/FrontUtils.py +++ /dev/null @@ -1,13 +0,0 @@ - - -def read_front_from_file(file_name: str): - """ Reads a front from a file and returns a list - """ - front = [] - file = open(file_name) - for line in file: - vector = [float(x) for x in line.split()] - front.append(vector) - - return front - diff --git a/jmetal/util/front_utils.py b/jmetal/util/front_utils.py new file mode 100644 index 00000000..9c342770 --- /dev/null +++ b/jmetal/util/front_utils.py @@ -0,0 +1,13 @@ + + +def read_front_from_file(file_name: str): + """ Reads a front from a file and returns a list + """ + front = [] + with open(file_name) as file: + for line in file: + vector = [float(x) for x in line.split()] + front.append(vector) + + return front + diff --git a/jmetal/util/test/test_quality_indicator.py b/jmetal/util/test/test_quality_indicator.py index ba502b90..8cd1dcb7 100644 --- a/jmetal/util/test/test_quality_indicator.py +++ b/jmetal/util/test/test_quality_indicator.py @@ -1,8 +1,11 @@ +import os import unittest -from jmetal.util.FrontUtils import read_front_from_file +from jmetal.util.front_utils import read_front_from_file from jmetal.util.quality_indicator import HyperVolume +FILE_DIR = os.path.dirname(os.path.realpath('__file__')) + class HyperVolumeTestCases(unittest.TestCase): @@ -20,7 +23,7 @@ def test_should_hypervolume_return_5_0(self): def test_should_hypervolume_return_the_correct_value_when_applied_to_the_ZDT1_reference_front(self): reference_point = [1, 1] - front = read_front_from_file("../../../resources/data/ZDT1.pf") + front = read_front_from_file(os.path.join(FILE_DIR, "../../../resources/data/ZDT1.pf")) hv = HyperVolume(reference_point) value = hv.compute(front) From bcf568aa5d186fa8e3736129d9c3da7112302f9b Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 11 May 2018 12:54:07 +0200 Subject: [PATCH 40/90] Fix tests --- jmetal/component/archive.py | 4 +- jmetal/component/test/test_archive.py | 113 +++++++++------------ jmetal/operator/test/test_selection.py | 87 ++++++++-------- jmetal/util/test/test_quality_indicator.py | 16 ++- 4 files changed, 106 insertions(+), 114 deletions(-) diff --git a/jmetal/component/archive.py b/jmetal/component/archive.py index f53b3d3b..a700a64b 100644 --- a/jmetal/component/archive.py +++ b/jmetal/component/archive.py @@ -38,7 +38,7 @@ def get_comparator(self): class BoundedArchive(Archive[S]): - def __init__(self, maximum_size: int, comparator: Comparator[S], density_estimator: DensityEstimator): + def __init__(self, maximum_size: int, comparator: Comparator[S]=None, density_estimator: DensityEstimator=None): super(BoundedArchive, self).__init__() self.maximum_size = maximum_size self.comparator = comparator @@ -132,7 +132,7 @@ def __init__(self, maximum_size: int, reference_point: List[float], comparator: self.__reference_point = reference_point self.__comparator = comparator self.__density_estimator = density_estimator - self.__reference_point_solution: S = None + self.__reference_point_solution = None def add(self, solution: S) -> bool: if self.__reference_point_solution is None: diff --git a/jmetal/component/test/test_archive.py b/jmetal/component/test/test_archive.py index ff5ab136..59472af1 100644 --- a/jmetal/component/test/test_archive.py +++ b/jmetal/component/test/test_archive.py @@ -6,7 +6,7 @@ class ArchiveTestCases(unittest.TestCase): def setUp(self): - self.archive = Archive[Solution]() + self.archive = Archive() def test_should_constructor_create_a_non_null_object(self): self.assertIsNotNone(self.archive) @@ -17,7 +17,7 @@ def test_should_constructor_create_an_empty_list(self): class BoundedArchiveTestCases(unittest.TestCase): def setUp(self): - self.archive = BoundedArchive[Solution](5) + self.archive = BoundedArchive(5) def test_should_constructor_create_a_non_null_object(self): self.assertIsNotNone(self.archive) @@ -28,7 +28,7 @@ def test_should_constructor_set_the_max_size(self): class NonDominatedSolutionListArchiveTestCases(unittest.TestCase): def setUp(self): - self.archive = NonDominatedSolutionListArchive[Solution]() + self.archive = NonDominatedSolutionListArchive() def test_should_constructor_create_a_non_null_object(self): self.assertIsNotNone(self.archive) @@ -109,70 +109,59 @@ def test_should_adding_three_solutions_work_properly_if_two_of_them_are_equal(se class CrowdingDistanceArchiveTestCases(unittest.TestCase): def setUp(self): - pass + self.archive = CrowdingDistanceArchive[Solution](5) def test_should_constructor_create_a_non_null_object(self): - archive = CrowdingDistanceArchive[Solution](5) - self.assertIsNotNone(archive) + self.assertIsNotNone(self.archive) def test_should_constructor_set_the_max_size(self): - archive = CrowdingDistanceArchive[Solution](5) - self.assertEqual(5, archive.get_max_size()) + self.assertEqual(5, self.archive.get_max_size()) def test_should_constructor_create_an_empty_archive(self): - archive = CrowdingDistanceArchive[Solution](5) - self.assertEqual(0, archive.size()) + self.assertEqual(0, self.archive.size()) def test_should_add_a_solution_when_the_archive_is_empty_work_properly(self): - archive = CrowdingDistanceArchive[Solution](5) - solution = Solution(2, 3) - archive.add(solution) + self.archive.add(solution) - self.assertEqual(1, archive.size()) - self.assertEqual(solution, archive.get(0)) + self.assertEqual(1, self.archive.size()) + self.assertEqual(solution, self.archive.get(0)) def test_should_add_work_properly_case1(self) : """ Case 1: add a dominated solution when the archive size is 1 must not include the solution """ - archive = CrowdingDistanceArchive[Solution](5) - solution1 = Solution(2, 2) solution1.objectives = [1, 2] solution2 = Solution(2, 2) solution2.objectives = [3, 4] - archive.add(solution1) - archive.add(solution2) + self.archive.add(solution1) + self.archive.add(solution2) - self.assertEqual(1, archive.size()) - self.assertEqual(solution1, archive.get(0)) + self.assertEqual(1, self.archive.size()) + self.assertEqual(solution1, self.archive.get(0)) def test_should_add_work_properly_case2(self) : """ Case 2: add a non-dominated solution when the archive size is 1 must include the solution """ - archive = CrowdingDistanceArchive[Solution](5) - solution1 = Solution(2, 2) solution1.objectives = [1, 2] solution2 = Solution(2, 2) solution2.objectives = [0, 4] - archive.add(solution1) - archive.add(solution2) + self.archive.add(solution1) + self.archive.add(solution2) - self.assertEqual(2, archive.size()) - self.assertTrue(solution1 in archive.get_solution_list()) - self.assertTrue(solution2 in archive.get_solution_list()) + self.assertEqual(2, self.archive.size()) + self.assertTrue(solution1 in self.archive.get_solution_list()) + self.assertTrue(solution2 in self.archive.get_solution_list()) def test_should_add_work_properly_case3(self) : """ Case 3: add a non-dominated solution when the archive size is 3 must include the solution """ - archive = CrowdingDistanceArchive[Solution](5) - solution1 = Solution(2, 2) solution1.objectives = [1.0, 2.0] solution2 = Solution(2, 2) @@ -182,23 +171,21 @@ def test_should_add_work_properly_case3(self) : solution4 = Solution(2, 2) solution4.objectives = [1.6, 1.2] - archive.add(solution1) - archive.add(solution2) - archive.add(solution3) - archive.add(solution4) + self.archive.add(solution1) + self.archive.add(solution2) + self.archive.add(solution3) + self.archive.add(solution4) - self.assertEqual(4, archive.size()) - self.assertTrue(solution1 in archive.get_solution_list()) - self.assertTrue(solution2 in archive.get_solution_list()) - self.assertTrue(solution3 in archive.get_solution_list()) - self.assertTrue(solution4 in archive.get_solution_list()) + self.assertEqual(4, self.archive.size()) + self.assertTrue(solution1 in self.archive.get_solution_list()) + self.assertTrue(solution2 in self.archive.get_solution_list()) + self.assertTrue(solution3 in self.archive.get_solution_list()) + self.assertTrue(solution4 in self.archive.get_solution_list()) def test_should_add_work_properly_case4(self) : """ Case 4: add a dominated solution when the archive size is 3 must not include the solution """ - archive = CrowdingDistanceArchive[Solution](5) - solution1 = Solution(2, 2) solution1.objectives = [1.0, 2.0] solution2 = Solution(2, 2) @@ -208,22 +195,20 @@ def test_should_add_work_properly_case4(self) : solution4 = Solution(2, 2) solution4.objectives = [5.0, 6.0] - archive.add(solution1) - archive.add(solution2) - archive.add(solution3) - archive.add(solution4) + self.archive.add(solution1) + self.archive.add(solution2) + self.archive.add(solution3) + self.archive.add(solution4) - self.assertEqual(3, archive.size()) - self.assertTrue(solution1 in archive.get_solution_list()) - self.assertTrue(solution2 in archive.get_solution_list()) - self.assertTrue(solution3 in archive.get_solution_list()) + self.assertEqual(3, self.archive.size()) + self.assertTrue(solution1 in self.archive.get_solution_list()) + self.assertTrue(solution2 in self.archive.get_solution_list()) + self.assertTrue(solution3 in self.archive.get_solution_list()) def test_should_add_work_properly_case5(self) : """ Case 5: add a dominated solution when the archive is full should not include the solution """ - archive = CrowdingDistanceArchive[Solution](3) - solution1 = Solution(2, 2) solution1.objectives = [1.0, 2.0] solution2 = Solution(2, 2) @@ -233,22 +218,22 @@ def test_should_add_work_properly_case5(self) : solution4 = Solution(2, 2) solution4.objectives = [5.0, 6.0] - archive.add(solution1) - archive.add(solution2) - archive.add(solution3) - archive.add(solution4) + self.archive.add(solution1) + self.archive.add(solution2) + self.archive.add(solution3) + self.archive.add(solution4) - self.assertEqual(3, archive.size()) - self.assertTrue(solution1 in archive.get_solution_list()) - self.assertTrue(solution2 in archive.get_solution_list()) - self.assertTrue(solution3 in archive.get_solution_list()) + self.assertEqual(3, self.archive.size()) + self.assertTrue(solution1 in self.archive.get_solution_list()) + self.assertTrue(solution2 in self.archive.get_solution_list()) + self.assertTrue(solution3 in self.archive.get_solution_list()) def test_should_add_work_properly_case6(self) : """ Case 6: add a non-dominated solution when the archive is full should not include the solution if it has the highest distance crowding value """ - archive = CrowdingDistanceArchive[Solution](4) + archive = CrowdingDistanceArchive(4) solution1 = Solution(2, 2) solution1.objectives = [0.0, 3.0] @@ -276,7 +261,7 @@ def test_should_add_work_properly_case7(self) : Case 7: add a non-dominated solution when the archive is full should remove all the dominated solutions """ - archive = CrowdingDistanceArchive[Solution](4) + archive = CrowdingDistanceArchive(4) solution1 = Solution(2, 2) solution1.objectives = [0.0, 3.0] @@ -303,7 +288,7 @@ def test_should_compute_density_estimator_work_properly_case1(self) : """ Case 1: The archive contains one solution """ - archive = CrowdingDistanceArchive[Solution](4) + archive = CrowdingDistanceArchive(4) solution1 = Solution(2, 2) solution1.objectives = [0.0, 3.0] @@ -318,7 +303,7 @@ def test_should_compute_density_estimator_work_properly_case2(self) : """ Case 2: The archive contains two solutions """ - archive = CrowdingDistanceArchive[Solution](4) + archive = CrowdingDistanceArchive(4) solution1 = Solution(2, 2) solution1.objectives = [0.0, 3.0] @@ -338,7 +323,7 @@ def test_should_compute_density_estimator_work_properly_case3(self) : """ Case 3: The archive contains two solutions """ - archive = CrowdingDistanceArchive[Solution](4) + archive = CrowdingDistanceArchive(4) solution1 = Solution(2, 2) solution1.objectives = [0.0, 3.0] diff --git a/jmetal/operator/test/test_selection.py b/jmetal/operator/test/test_selection.py index 91267046..6cad5383 100644 --- a/jmetal/operator/test/test_selection.py +++ b/jmetal/operator/test/test_selection.py @@ -1,6 +1,6 @@ import unittest -from hamcrest import * +from hamcrest import assert_that, any_of from jmetal.core.solution import Solution from jmetal.operator.selection import BinaryTournamentSelection, BestSolutionSelection, RandomSolutionSelection, \ @@ -29,25 +29,25 @@ def test_should_execute_raise_an_exception_if_the_list_of_solutions_is_empty(sel self.selection.execute(solution_list) def test_should_execute_return_the_solution_in_a_list_with_one_solution(self): - solution = Solution(3,2) + solution = Solution(3, 2) solution_list = [solution] self.assertEqual(solution, self.selection.execute(solution_list)) def test_should_execute_work_if_the_solution_list_contains_two_non_dominated_solutions(self): - solution1 = Solution(2,2) + solution1 = Solution(2, 2) solution1.variables = [1.0, 2.0] - solution2 = Solution(2,2) + solution2 = Solution(2, 2) solution2.variables = [0.0, 3.0] solution_list = [solution1, solution2] - assert_that(any_of(solution1 , solution2), self.selection.execute(solution_list)) + assert_that(any_of(solution1, solution2), self.selection.execute(solution_list)) def test_should_execute_work_if_the_solution_list_contains_two_solutions_and_one_them_is_dominated(self): - solution1 = Solution(2,2) + solution1 = Solution(2, 2) solution1.variables = [1.0, 4.0] - solution2 = Solution(2,2) + solution2 = Solution(2, 2) solution2.variables = [0.0, 3.0] solution_list = [solution1, solution2] @@ -74,15 +74,15 @@ def test_should_execute_raise_an_exception_if_the_list_of_solutions_is_empty(sel self.selection.execute(solution_list) def test_should_execute_return_the_solution_in_a_list_with_one_solution(self): - solution = Solution(3,2) + solution = Solution(3, 2) solution_list = [solution] self.assertEqual(solution, self.selection.execute(solution_list)) def test_should_execute_work_if_the_solution_list_contains_two_non_dominated_solutions(self): - solution1 = Solution(2,2) + solution1 = Solution(2, 2) solution1.objectives = [1.0, 2.0] - solution2 = Solution(2,2) + solution2 = Solution(2, 2) solution2.objectives = [0.0, 3.0] solution_list = [solution1, solution2] @@ -90,9 +90,9 @@ def test_should_execute_work_if_the_solution_list_contains_two_non_dominated_sol self.assertTrue(self.selection.execute(solution_list) in solution_list) def test_should_execute_work_if_the_solution_list_contains_two_solutions_and_one_them_is_dominated(self): - solution1 = Solution(2,2) + solution1 = Solution(2, 2) solution1.objectives = [1.0, 4.0] - solution2 = Solution(2,2) + solution2 = Solution(2, 2) solution2.objectives = [0.0, 3.0] solution_list = [solution1, solution2] @@ -100,15 +100,15 @@ def test_should_execute_work_if_the_solution_list_contains_two_solutions_and_one self.assertEqual(solution2, self.selection.execute(solution_list)) def test_should_execute_work_if_the_solution_list_contains_five_solutions_and_one_them_is_dominated(self): - solution1 = Solution(2,2) + solution1 = Solution(2, 2) solution1.objectives = [1.0, 4.0] - solution2 = Solution(2,2) + solution2 = Solution(2, 2) solution2.objectives = [0.0, 3.0] - solution3 = Solution(2,2) + solution3 = Solution(2, 2) solution3.objectives = [0.0, 4.0] - solution4 = Solution(2,2) + solution4 = Solution(2, 2) solution4.objectives = [1.0, 3.0] - solution5 = Solution(2,2) + solution5 = Solution(2, 2) solution5.objectives = [0.2, 4.4] solution_list = [solution1, solution2, solution3, solution4, solution5] @@ -135,15 +135,15 @@ def test_should_execute_raise_an_exception_if_the_list_of_solutions_is_empty(sel self.selection.execute(solution_list) def test_should_execute_return_the_solution_in_a_list_with_one_solution(self): - solution = Solution(3,2) + solution = Solution(3, 2) solution_list = [solution] self.assertEqual(solution, self.selection.execute(solution_list)) def test_should_execute_work_if_the_solution_list_contains_two_non_dominated_solutions(self): - solution1 = Solution(2,2) + solution1 = Solution(2, 2) solution1.objectives = [1.0, 2.0] - solution2 = Solution(2,2) + solution2 = Solution(2, 2) solution2.objectives = [0.0, 3.0] solution_list = [solution1, solution2] @@ -151,9 +151,9 @@ def test_should_execute_work_if_the_solution_list_contains_two_non_dominated_sol self.assertTrue(self.selection.execute(solution_list) in solution_list) def test_should_execute_work_if_the_solution_list_contains_two_solutions_and_one_them_is_dominated(self): - solution1 = Solution(2,2) + solution1 = Solution(2, 2) solution1.objectives = [1.0, 4.0] - solution2 = Solution(2,2) + solution2 = Solution(2, 2) solution2.objectives = [0.0, 3.0] solution_list = [solution1, solution2] @@ -161,15 +161,15 @@ def test_should_execute_work_if_the_solution_list_contains_two_solutions_and_one self.assertTrue(self.selection.execute(solution_list) in solution_list) def test_should_execute_work_if_the_solution_list_contains_five_solutions_and_one_them_is_dominated(self): - solution1 = Solution(2,2) + solution1 = Solution(2, 2) solution1.objectives = [1.0, 4.0] - solution2 = Solution(2,2) + solution2 = Solution(2, 2) solution2.objectives = [0.0, 3.0] - solution3 = Solution(2,2) + solution3 = Solution(2, 2) solution3.objectives = [0.0, 4.0] - solution4 = Solution(2,2) + solution4 = Solution(2, 2) solution4.objectives = [1.0, 3.0] - solution5 = Solution(2,2) + solution5 = Solution(2, 2) solution5.objectives = [0.2, 4.4] solution_list = [solution1, solution2, solution3, solution4, solution5] @@ -199,26 +199,26 @@ def test_should_execute_raise_an_exception_if_the_list_of_solutions_is_empty(sel selection = NaryRandomSolutionSelection[Solution]() solution_list = [] with self.assertRaises(Exception): - selection.execute(solution_list) + selection.execute(solution_list) def test_should_execute_raise_an_exception_if_the_list_of_solutions_is_smaller_than_required(self): selection = NaryRandomSolutionSelection[Solution](4) - solution_list = [Solution(1,1), Solution(1,1)] + solution_list = [Solution(1, 1), Solution(1, 1)] with self.assertRaises(Exception): - selection.execute(solution_list) + selection.execute(solution_list) def test_should_execute_return_the_solution_in_a_list_with_one_solution(self): selection = NaryRandomSolutionSelection[Solution](1) - solution = Solution(3,2) + solution = Solution(3, 2) solution_list = [solution] self.assertEqual([solution], selection.execute(solution_list)) def test_should_execute_work_if_the_solution_list_contains_two_non_dominated_solutions(self): selection = NaryRandomSolutionSelection[Solution](2) - solution1 = Solution(2,2) + solution1 = Solution(2, 2) solution1.objectives = [1.0, 2.0] - solution2 = Solution(2,2) + solution2 = Solution(2, 2) solution2.objectives = [0.0, 3.0] solution_list = [solution1, solution2] @@ -229,15 +229,15 @@ def test_should_execute_work_if_the_solution_list_contains_two_non_dominated_sol def test_should_execute_work_if_the_solution_list_contains_five_solutions_and_one_them_is_dominated(self): selection = NaryRandomSolutionSelection[Solution](1) - solution1 = Solution(2,2) + solution1 = Solution(2, 2) solution1.objectives = [1.0, 4.0] - solution2 = Solution(2,2) + solution2 = Solution(2, 2) solution2.objectives = [0.0, 3.0] - solution3 = Solution(2,2) + solution3 = Solution(2, 2) solution3.objectives = [0.0, 4.0] - solution4 = Solution(2,2) + solution4 = Solution(2, 2) solution4.objectives = [1.0, 3.0] - solution5 = Solution(2,2) + solution5 = Solution(2, 2) solution5.objectives = [0.2, 4.4] solution_list = [solution1, solution2, solution3, solution4, solution5] @@ -312,17 +312,16 @@ def test_should_operator_raise_an_exception_if_the_list_of_comparators_is_empty( selection.execute(solution_list) def test_should_execute_return_the_solution_in_a_list_with_one_solution(self): - solution = Solution(3,2) + solution = Solution(3, 2) solution_list = [solution] selection = BinaryTournament2Selection[Solution]([Comparator()]) self.assertEqual(solution, selection.execute(solution_list)) - def test_should_execute_work_properly_case1(self): - solution1 = Solution(3,2) + solution1 = Solution(3, 2) solution1.objectives = [2, 3] - solution2 = Solution(3,2) + solution2 = Solution(3, 2) solution2.objectives = [1, 4] solution1.attributes["dominance_ranking"] = 1 solution2.attributes["dominance_ranking"] = 1 @@ -330,9 +329,9 @@ def test_should_execute_work_properly_case1(self): solution_list = [solution1, solution2] operator = BinaryTournament2Selection[Solution]([SolutionAttributeComparator("key")]) selection1 = operator.execute(solution_list) - selection2 = operator.execute(solution_list) - self.assertTrue(1, selection1.attributes["dominance_ranking"]) + self.assertTrue(1, selection1.attributes["dominance_ranking"]) + if __name__ == '__main__': unittest.main() diff --git a/jmetal/util/test/test_quality_indicator.py b/jmetal/util/test/test_quality_indicator.py index 8cd1dcb7..ae6fa2cb 100644 --- a/jmetal/util/test/test_quality_indicator.py +++ b/jmetal/util/test/test_quality_indicator.py @@ -1,10 +1,19 @@ -import os +from os.path import dirname, realpath, join import unittest from jmetal.util.front_utils import read_front_from_file from jmetal.util.quality_indicator import HyperVolume -FILE_DIR = os.path.dirname(os.path.realpath('__file__')) +BASE_PATH = dirname(realpath('__file__')) +FILE_PATH = dirname(join(dirname(__file__))) + + +def walk_up_folder(path, depth: int =1): + _cur_depth = 1 + while _cur_depth < depth: + path = dirname(path) + _cur_depth += 1 + return path class HyperVolumeTestCases(unittest.TestCase): @@ -23,8 +32,7 @@ def test_should_hypervolume_return_5_0(self): def test_should_hypervolume_return_the_correct_value_when_applied_to_the_ZDT1_reference_front(self): reference_point = [1, 1] - front = read_front_from_file(os.path.join(FILE_DIR, "../../../resources/data/ZDT1.pf")) - + front = read_front_from_file(join(walk_up_folder(FILE_PATH, 3), 'resources/data/ZDT1.pf')) hv = HyperVolume(reference_point) value = hv.compute(front) From ba70e1a10edf409e6e50311267f839c061e34e57 Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 11 May 2018 13:52:24 +0200 Subject: [PATCH 41/90] Added reference pareto front visualization (if any) --- jmetal/algorithm/multiobjective/smpso.py | 8 ++++--- .../singleobjective/evolutionaryalgorithm.py | 10 ++++---- jmetal/core/problem.py | 22 +++++++++++++---- jmetal/core/solution.py | 10 ++++---- jmetal/problem/multiobjective/zdt.py | 16 ++++++------- jmetal/util/front_utils.py | 24 +++++++++++++++++++ jmetal/util/graphic.py | 13 +++++----- jmetal/util/test/test_quality_indicator.py | 13 ++-------- 8 files changed, 73 insertions(+), 43 deletions(-) diff --git a/jmetal/algorithm/multiobjective/smpso.py b/jmetal/algorithm/multiobjective/smpso.py index b96aba6a..438c82ba 100644 --- a/jmetal/algorithm/multiobjective/smpso.py +++ b/jmetal/algorithm/multiobjective/smpso.py @@ -93,9 +93,11 @@ def update_progress(self) -> None: self.evaluations += self.swarm_size self.leaders.compute_density_estimator() - observable_data = {'evaluations': self.evaluations, - 'population': self.leaders.solution_list, - 'computing time': self.get_current_computing_time()} + observable_data = {'evaluations': self.evaluations, 'computing time': self.get_current_computing_time()} + if self.problem.reference_front_path: + observable_data['population'] = self.leaders.solution_list+self.problem.get_reference_front() + else: + observable_data['population'] = self.leaders.solution_list self.observable.notify_all(**observable_data) diff --git a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py index aa429bf1..0abd95b4 100644 --- a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py +++ b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py @@ -134,10 +134,12 @@ def init_progress(self): def update_progress(self): self.evaluations += self.population_size - observable_data = {'evaluations': self.evaluations, - 'population': self.population, - 'computing time': self.get_current_computing_time()} - + observable_data = {'evaluations': self.evaluations, 'computing time': self.get_current_computing_time()} + if self.problem.reference_front_path: + observable_data['population'] = self.population+self.problem.get_reference_front() + else: + observable_data['population'] = self.population + self.observable.notify_all(**observable_data) def is_stopping_condition_reached(self) -> bool: diff --git a/jmetal/core/problem.py b/jmetal/core/problem.py index f1d6a63a..5fa0c948 100644 --- a/jmetal/core/problem.py +++ b/jmetal/core/problem.py @@ -1,9 +1,11 @@ -import random +from os.path import dirname, join from typing import Generic, TypeVar +import random from jmetal.core.solution import BinarySolution, FloatSolution, IntegerSolution +from jmetal.util.front_utils import walk_up_folder, read_front_from_file_as_solutions -__author__ = "Antonio J. Nebro" +FILE_PATH = dirname(join(dirname(__file__))) S = TypeVar('S') @@ -15,6 +17,7 @@ def __init__(self): self.number_of_variables: int = None self.number_of_objectives: int = None self.number_of_constraints: int = None + self.reference_front_path: str = False def evaluate(self, solution: S) -> None: pass @@ -25,7 +28,16 @@ def evaluate_constraints(self, solution: S): def create_solution(self) -> S: pass - def get_name(self) -> str : + def get_reference_front(self) -> list: + front = [] + + if self.reference_front_path: + computed_path = join(walk_up_folder(FILE_PATH, 2), self.reference_front_path) + front = read_front_from_file_as_solutions(computed_path) + + return front + + def get_name(self) -> str: pass @@ -44,8 +56,8 @@ class FloatProblem(Problem[FloatSolution]): def __init__(self): super().__init__() - self.lower_bound : [] = None - self.upper_bound : [] = None + self.lower_bound: [] = None + self.upper_bound: [] = None def create_solution(self) -> FloatSolution: new_solution = FloatSolution(self.number_of_variables, self.number_of_objectives, self.number_of_constraints, diff --git a/jmetal/core/solution.py b/jmetal/core/solution.py index 7b707ebe..501cc705 100644 --- a/jmetal/core/solution.py +++ b/jmetal/core/solution.py @@ -7,7 +7,7 @@ class Solution(Generic[S]): """ Class representing solutions """ - def __init__(self, number_of_variables : int, number_of_objectives : int, number_of_constraints = 0): + def __init__(self, number_of_variables: int, number_of_objectives: int, number_of_constraints: int = 0): self.number_of_objectives: int = number_of_objectives self.number_of_variables: int = number_of_variables self.number_of_constraints: int = number_of_constraints @@ -44,8 +44,8 @@ def get_total_number_of_bits(self) -> int: class FloatSolution(Solution[float]): """ Class representing float solutions """ - def __init__(self, number_of_variables : int, number_of_objectives : int, number_of_constraints : int, - lower_bound : List[float], upper_bound : List[float]): + def __init__(self, number_of_variables: int, number_of_objectives: int, number_of_constraints: int, + lower_bound: List[float], upper_bound: List[float]): super(FloatSolution, self).__init__(number_of_variables, number_of_objectives, number_of_constraints) self.lower_bound = lower_bound self.upper_bound = upper_bound @@ -66,8 +66,8 @@ def __copy__(self): class IntegerSolution(Solution[int]): """ Class representing integer solutions """ - def __init__(self, number_of_variables : int, number_of_objectives : int, number_of_constraints : int, - lower_bound : List[int], upper_bound : List[int]): + def __init__(self, number_of_variables: int, number_of_objectives: int, number_of_constraints: int, + lower_bound: List[int], upper_bound: List[int]): super(IntegerSolution, self).__init__(number_of_variables, number_of_objectives, number_of_constraints) self.lower_bound = lower_bound self.upper_bound = upper_bound diff --git a/jmetal/problem/multiobjective/zdt.py b/jmetal/problem/multiobjective/zdt.py index c30ace35..e7f712fd 100644 --- a/jmetal/problem/multiobjective/zdt.py +++ b/jmetal/problem/multiobjective/zdt.py @@ -14,6 +14,7 @@ class ZDT1(FloatProblem): """ Problem ZDT1 + .. note:: Bi-objective unconstrained problem. The default number of variables is 30. .. note:: Continuous problem having a convex Pareto front """ @@ -22,6 +23,7 @@ def __init__(self, number_of_variables: int = 30): """Constructor :param number_of_variables: number of decision variables of the problem """ + super().__init__() self.number_of_variables = number_of_variables self.number_of_objectives = 2 self.number_of_constraints = 0 @@ -32,6 +34,8 @@ def __init__(self, number_of_variables: int = 30): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound + self.reference_front_path = 'resources/data/ZDT1.pf' + def evaluate(self, solution: FloatSolution): g = self.__eval_g(solution) h = self.__eval_h(solution.variables[0], g) @@ -58,11 +62,10 @@ class ZDT2(FloatProblem): """ Problem ZDT2 .. note:: Bi-objective unconstrained problem. The default number of variables is 30. - .. note:: Continuous problem having a non-convex Pareto front - """ def __init__(self, number_of_variables: int = 30): + super().__init__() self.number_of_variables = number_of_variables self.number_of_objectives = 2 self.number_of_constraints = 0 @@ -99,11 +102,10 @@ class ZDT3(FloatProblem): """ Problem ZDT3 .. note:: Bi-objective unconstrained problem. The default number of variables is 30. - .. note:: Continuous problem having a partitioned Pareto front - """ def __init__(self, number_of_variables: int = 30): + super().__init__() self.number_of_variables = number_of_variables self.number_of_objectives = 2 self.number_of_constraints = 0 @@ -140,11 +142,10 @@ class ZDT4(FloatProblem): """ Problem ZDT4 .. note:: Bi-objective unconstrained problem. The default number of variables is 10. - .. note:: Continuous multi-modal problem having a convex Pareto front - """ def __init__(self, number_of_variables: int = 10): + super().__init__() self.number_of_variables = number_of_variables self.number_of_objectives = 2 self.number_of_constraints = 0 @@ -185,11 +186,10 @@ class ZDT6(FloatProblem): """ Problem ZDT6 .. note:: Bi-objective unconstrained problem. The default number of variables is 10. - .. note:: Continuous problem having a non-convex Pareto front - """ def __init__(self, number_of_variables: int = 10): + super().__init__() self.number_of_variables = number_of_variables self.number_of_objectives = 2 self.number_of_constraints = 0 diff --git a/jmetal/util/front_utils.py b/jmetal/util/front_utils.py index 9c342770..53cc4ab3 100644 --- a/jmetal/util/front_utils.py +++ b/jmetal/util/front_utils.py @@ -1,3 +1,6 @@ +from os.path import dirname + +from jmetal.core.solution import FloatSolution def read_front_from_file(file_name: str): @@ -8,6 +11,27 @@ def read_front_from_file(file_name: str): for line in file: vector = [float(x) for x in line.split()] front.append(vector) + return front + + +def read_front_from_file_as_solutions(file_name: str): + """ Reads a front from a file and returns a list of solution objects + """ + front = [] + with open(file_name) as file: + for line in file: + vector = [float(x) for x in line.split()] + solution = FloatSolution(2, 2, 0, [], []) + solution.objectives = vector + + front.append(solution) return front + +def walk_up_folder(path, depth: int =1): + _cur_depth = 1 + while _cur_depth < depth: + path = dirname(path) + _cur_depth += 1 + return path \ No newline at end of file diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index d6a4af55..21c29b5a 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -19,8 +19,8 @@ """ -class ScatterPlot(): - def __init__(self, plot_title: str, animation_speed: float = 1*10e-10): +class ScatterPlot: + def __init__(self, plot_title: str, animation_speed: float = 1 * 10e-10): """ Creates a new :class:`ScatterPlot` instance. :param plot_title: Title of the scatter diagram. @@ -48,7 +48,6 @@ def __init_plot(self, is_auto_scalable: bool = True) -> None: def __get_data_points(self, solution_list: List[S]) -> Tuple[list, list]: """ Get coords (x,y) from a solution_list. """ - if solution_list is None: raise Exception("Solution list is none!") @@ -63,7 +62,6 @@ def retrieve_info(self, solution: Solution) -> None: def __search_solution(self, solution_list: List[S], x_val: float, y_val: float) -> None: """ :return: A solution object associated with some values of (x,y). """ - sol = next((solution for solution in solution_list if solution.objectives[0] == x_val and solution.objectives[1]), None) @@ -87,7 +85,7 @@ def simple_plot(self, solution_list: List[S], file_name: str = "output", self.__init_plot() x_values, y_values = self.__get_data_points(solution_list) - self.sc, = self.axis.plot(x_values, y_values, 'go', markersize=5, picker=10) + self.sc, = self.axis.plot(x_values, y_values, 'go', markersize=3, picker=10) if save: supported_formats = ["eps", "jpeg", "jpg", "pdf", "pgf", "png", "ps", @@ -121,12 +119,13 @@ def update(self, solution_list: List[S], evaluations: int = 0, computing_time: f # Update points self.sc.set_data(x_values, y_values) - event_handler = self.fig.canvas.mpl_connect('pick_event', lambda event: self.__pick_handler(event, solution_list)) + event_handler = self.fig.canvas.mpl_connect('pick_event', + lambda event: self.__pick_handler(event, solution_list)) # Update title self.fig.suptitle(self.plot_title + ', \n Eval: ' + str(evaluations) - + ', Time: ' + str('%.3f'%computing_time), fontsize=14, fontweight='bold') + + ', Time: ' + str('%.3f' % computing_time), fontsize=14, fontweight='bold') # Re-align the axis. self.axis.relim() diff --git a/jmetal/util/test/test_quality_indicator.py b/jmetal/util/test/test_quality_indicator.py index ae6fa2cb..b91296d0 100644 --- a/jmetal/util/test/test_quality_indicator.py +++ b/jmetal/util/test/test_quality_indicator.py @@ -1,21 +1,12 @@ -from os.path import dirname, realpath, join +from os.path import dirname, join import unittest -from jmetal.util.front_utils import read_front_from_file +from jmetal.util.front_utils import read_front_from_file, walk_up_folder from jmetal.util.quality_indicator import HyperVolume -BASE_PATH = dirname(realpath('__file__')) FILE_PATH = dirname(join(dirname(__file__))) -def walk_up_folder(path, depth: int =1): - _cur_depth = 1 - while _cur_depth < depth: - path = dirname(path) - _cur_depth += 1 - return path - - class HyperVolumeTestCases(unittest.TestCase): def setUp(self): From 5d5b73b58b842fd364f57cd8c5d6614843c86404 Mon Sep 17 00:00:00 2001 From: ajnebro Date: Tue, 15 May 2018 18:09:08 +0200 Subject: [PATCH 42/90] Minor changes --- jmetal/component/evaluator.py | 17 ++++ jmetal/component/test/test_evaluator.py | 84 +++++++++++++++++++ jmetal/core/problem.py | 10 ++- .../nsgaii_standard_settings.py | 3 + requirements.txt | 3 +- 5 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 jmetal/component/test/test_evaluator.py diff --git a/jmetal/component/evaluator.py b/jmetal/component/evaluator.py index 3ab4641d..c11073cb 100644 --- a/jmetal/component/evaluator.py +++ b/jmetal/component/evaluator.py @@ -1,5 +1,6 @@ from multiprocessing.pool import ThreadPool from typing import TypeVar, List, Generic +from dask.distributed import Client, as_completed from jmetal.core.problem import Problem @@ -33,3 +34,19 @@ def evaluate(self, solution_list: List[S], problem: Problem) -> List[S]: self.pool.map(lambda solution: Evaluator[S].evaluate_solution(solution, problem), solution_list) return solution_list + + +class DaskMultithreadedEvaluator(Evaluator[S]): + def __init__(self): + self.client = Client() + + def evaluate(self, solution_list: List[S], problem: Problem) -> List[S]: + futures = [] + for solution in solution_list: + futures.append(self.client.submit(problem.evaluate, solution)) + + evaluated_list = [] + for future in as_completed(futures): + evaluated_list.append(future.result()) + + return evaluated_list diff --git a/jmetal/component/test/test_evaluator.py b/jmetal/component/test/test_evaluator.py new file mode 100644 index 00000000..5bd111e7 --- /dev/null +++ b/jmetal/component/test/test_evaluator.py @@ -0,0 +1,84 @@ +import math +import unittest + +from jmetal.component.evaluator import SequentialEvaluator, DaskMultithreadedEvaluator +from jmetal.core.problem import Problem, FloatProblem +from jmetal.core.solution import FloatSolution + + +class MockedProblem(FloatProblem): + def __init__(self, number_of_variables: int = 3): + self.number_of_objectives = 2 + self.number_of_variables = number_of_variables + self.number_of_constraints = 0 + + self.lower_bound = [-5.0 for _ in range(number_of_variables)] + self.upper_bound = [5.0 for _ in range(number_of_variables)] + + FloatSolution.lower_bound = self.lower_bound + FloatSolution.upper_bound = self.upper_bound + + def evaluate(self, solution: FloatSolution): + solution.objectives[0] = 1.2 + solution.objectives[1] = 2.3 + + return solution + + +class SequentialEvaluatorTestCases(unittest.TestCase): + def setUp(self): + self.evaluator = SequentialEvaluator() + self.problem = MockedProblem() + + def test_should_constructor_create_a_non_null_object(self): + self.assertIsNotNone(self.evaluator) + + def test_should_evaluate_a_list_of_problem_work_properly_with_a_solution(self): + problem_list = [self.problem.create_solution() for i in range(1)] + + self.evaluator.evaluate(problem_list, self.problem) + + self.assertEquals(1.2, problem_list[0].objectives[0]) + self.assertEquals(2.3, problem_list[0].objectives[1]) + + def test_should_evaluate_a_list_of_problem_work_properly(self): + problem_list = [self.problem.create_solution() for i in range(10)] + + self.evaluator.evaluate(problem_list, self.problem) + + for i in range(10): + self.assertEquals(1.2, problem_list[i].objectives[0]) + self.assertEquals(2.3, problem_list[i].objectives[1]) + + +class DaskMultithreadedEvaluatorTestCases(unittest.TestCase): + def setUp(self): + self.evaluator = DaskMultithreadedEvaluator() + self.problem = MockedProblem() + + def test_should_constructor_create_a_non_null_object(self): + self.assertIsNotNone(self.evaluator) + + def test_should_evaluate_a_list_of_problem_work_properly_with_a_solution(self): + problem_list = [self.problem.create_solution() for i in range(1)] + + evaluated_list = self.evaluator.evaluate(problem_list, self.problem) + + self.assertEquals(1.2, evaluated_list[0].objectives[0]) + self.assertEquals(2.3, evaluated_list[0].objectives[1]) + + self.assertEquals(problem_list[0].variables[0], evaluated_list[0].variables[0]) + + def test_should_evaluate_a_list_of_problem_work_properly(self): + problem_list = [self.problem.create_solution() for i in range(10)] + + evaluated_list = self.evaluator.evaluate(problem_list, self.problem) + + for i in range(10): + self.assertEquals(1.2, evaluated_list[i].objectives[0]) + self.assertEquals(2.3, evaluated_list[i].objectives[1]) + self.assertEquals(len(problem_list), len(evaluated_list)) + + +if __name__ == "__main__": + unittest.main() diff --git a/jmetal/core/problem.py b/jmetal/core/problem.py index 5fa0c948..879fcc86 100644 --- a/jmetal/core/problem.py +++ b/jmetal/core/problem.py @@ -19,8 +19,14 @@ def __init__(self): self.number_of_constraints: int = None self.reference_front_path: str = False - def evaluate(self, solution: S) -> None: - pass + def evaluate(self, solution: S) -> S: + for i in range(self.number_of_objectives): + if self.objectives[i].is_a_minimization_objective(): + solution.objectives[i] = self.objectives[i].compute(solution, self) + else: + solution.objectives[i] = -1.0 * self.objectives[i].compute(solution, self) + + return solution def evaluate_constraints(self, solution: S): pass diff --git a/jmetal/runner/multiobjective/nsgaii_standard_settings.py b/jmetal/runner/multiobjective/nsgaii_standard_settings.py index df3334d1..6258345a 100644 --- a/jmetal/runner/multiobjective/nsgaii_standard_settings.py +++ b/jmetal/runner/multiobjective/nsgaii_standard_settings.py @@ -1,6 +1,8 @@ import logging from typing import List +from jmetal.component.evaluator import SequentialEvaluator, DaskMultithreadedEvaluator, ParallelEvaluator + from jmetal.algorithm.multiobjective.nsgaii import NSGAII from jmetal.core.solution import FloatSolution from jmetal.operator.crossover import SBX @@ -20,6 +22,7 @@ def main() -> None: problem=problem, population_size=100, max_evaluations=25000, + #evaluator=DaskMultithreadedEvaluator(), mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), crossover=SBX(1.0, distribution_index=20), #selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) diff --git a/requirements.txt b/requirements.txt index ba424c05..4666e8c3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,5 @@ pytest==3.1.2 PyHamcrest==1.9.0 mockito==1.0.11 matplotlib==2.0.2 -numpy==1.13.1 \ No newline at end of file +numpy==1.13.1 +dask=0.17.4 \ No newline at end of file From 2ed5fa26f362a3e7d8a27e7ec94ffe9d0c2c1cee Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 21 May 2018 13:25:11 +0200 Subject: [PATCH 43/90] Added reference front plotting (if any) --- jmetal/algorithm/multiobjective/smpso.py | 16 ++- .../singleobjective/evolutionaryalgorithm.py | 8 +- jmetal/component/observer.py | 9 +- jmetal/core/problem.py | 2 +- .../problem/multiobjective/unconstrained.py | 1 + ...gaII_standard_settings_plot_interactive.py | 6 +- .../nsgaii_standard_settings.py | 19 ++- ...rd_settings_with_observer_plot_realtime.py | 8 +- .../multiobjective/smpso_standard_settings.py | 6 +- ..._standard_settings_with_reference_point.py | 6 +- .../smpsorp_standard_settings.py | 6 +- jmetal/util/graphic.py | 120 +++++++++--------- jmetal/util/solution_list_output.py | 35 +++-- 13 files changed, 124 insertions(+), 118 deletions(-) diff --git a/jmetal/algorithm/multiobjective/smpso.py b/jmetal/algorithm/multiobjective/smpso.py index 438c82ba..ad17b011 100644 --- a/jmetal/algorithm/multiobjective/smpso.py +++ b/jmetal/algorithm/multiobjective/smpso.py @@ -93,11 +93,11 @@ def update_progress(self) -> None: self.evaluations += self.swarm_size self.leaders.compute_density_estimator() - observable_data = {'evaluations': self.evaluations, 'computing time': self.get_current_computing_time()} + observable_data = {'evaluations': self.evaluations, 'computing time': self.get_current_computing_time(), + 'population': self.leaders.solution_list} + if self.problem.reference_front_path: - observable_data['population'] = self.leaders.solution_list+self.problem.get_reference_front() - else: - observable_data['population'] = self.leaders.solution_list + observable_data['reference'] = self.problem.get_reference_front() self.observable.notify_all(**observable_data) @@ -267,9 +267,11 @@ def update_progress(self) -> None: point.objectives = self.reference_points[i] reference_points.append(point) - observable_data = {'evaluations': self.evaluations, - 'population': self.get_result() + reference_points, - 'computing time': self.get_current_computing_time()} + observable_data = {'evaluations': self.evaluations, 'computing time': self.get_current_computing_time(), + 'population': self.get_result() + reference_points} + + if self.problem.reference_front_path: + observable_data['reference'] = self.problem.get_reference_front() self.observable.notify_all(**observable_data) diff --git a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py index 0abd95b4..5da3c301 100644 --- a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py +++ b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py @@ -134,11 +134,11 @@ def init_progress(self): def update_progress(self): self.evaluations += self.population_size - observable_data = {'evaluations': self.evaluations, 'computing time': self.get_current_computing_time()} + observable_data = {'evaluations': self.evaluations, 'computing time': self.get_current_computing_time(), + 'population': self.population} + if self.problem.reference_front_path: - observable_data['population'] = self.population+self.problem.get_reference_front() - else: - observable_data['population'] = self.population + observable_data['reference'] = self.problem.get_reference_front() self.observable.notify_all(**observable_data) diff --git a/jmetal/component/observer.py b/jmetal/component/observer.py index 9b5e953f..39f1afcf 100644 --- a/jmetal/component/observer.py +++ b/jmetal/component/observer.py @@ -41,16 +41,17 @@ def update(self, *args, **kwargs): self.counter += 1 -class AlgorithmObserver(Observer): +class VisualizerObserver(Observer): def __init__(self, animation_speed: float, frequency: float = 1.0) -> None: self.animation_speed = animation_speed self.display_frequency = frequency def update(self, *args, **kwargs): evaluations = kwargs["evaluations"] - population = kwargs["population"] computing_time = kwargs["computing time"] + solution_list = kwargs["population"] + reference_solution_list = kwargs.get("reference", None) if (evaluations % self.display_frequency) == 0: - SolutionListOutput.plot_scatter_real_time(population, evaluations, computing_time, - self.animation_speed) + SolutionListOutput.plot_frontier_interactive(solution_list, reference_solution_list, evaluations, + computing_time, self.animation_speed) diff --git a/jmetal/core/problem.py b/jmetal/core/problem.py index 5fa0c948..f3f34df5 100644 --- a/jmetal/core/problem.py +++ b/jmetal/core/problem.py @@ -17,7 +17,7 @@ def __init__(self): self.number_of_variables: int = None self.number_of_objectives: int = None self.number_of_constraints: int = None - self.reference_front_path: str = False + self.reference_front_path: str = None def evaluate(self, solution: S) -> None: pass diff --git a/jmetal/problem/multiobjective/unconstrained.py b/jmetal/problem/multiobjective/unconstrained.py index 0bbce645..e29bdc29 100644 --- a/jmetal/problem/multiobjective/unconstrained.py +++ b/jmetal/problem/multiobjective/unconstrained.py @@ -9,6 +9,7 @@ class Kursawe(FloatProblem): """ Class representing problem Kursawe """ def __init__(self, number_of_variables: int = 3): + super().__init__() self.number_of_objectives = 2 self.number_of_variables = number_of_variables self.number_of_constraints = 0 diff --git a/jmetal/runner/multiobjective/nsgaII_standard_settings_plot_interactive.py b/jmetal/runner/multiobjective/nsgaII_standard_settings_plot_interactive.py index 744df195..0c12a30a 100644 --- a/jmetal/runner/multiobjective/nsgaII_standard_settings_plot_interactive.py +++ b/jmetal/runner/multiobjective/nsgaII_standard_settings_plot_interactive.py @@ -26,9 +26,9 @@ def main() -> None: algorithm.run() result = algorithm.get_result() - SolutionListOutput[FloatSolution].plot_scatter_to_file(result, file_name="FUN."+problem.get_name(), - output_format='eps', dpi=200) - SolutionListOutput[FloatSolution].plot_scatter_to_screen(result) + SolutionListOutput[FloatSolution].plot_frontier_to_file(result, file_name="FUN." + problem.get_name(), + output_format='eps', dpi=200) + SolutionListOutput[FloatSolution].plot_frontier_to_screen(result) logger.info("Algorithm (continuous problem): " + algorithm.get_name()) logger.info("Problem: " + problem.get_name()) diff --git a/jmetal/runner/multiobjective/nsgaii_standard_settings.py b/jmetal/runner/multiobjective/nsgaii_standard_settings.py index df3334d1..56e1a45f 100644 --- a/jmetal/runner/multiobjective/nsgaii_standard_settings.py +++ b/jmetal/runner/multiobjective/nsgaii_standard_settings.py @@ -2,6 +2,7 @@ from typing import List from jmetal.algorithm.multiobjective.nsgaii import NSGAII +from jmetal.component.observer import VisualizerObserver from jmetal.core.solution import FloatSolution from jmetal.operator.crossover import SBX from jmetal.operator.mutation import Polynomial @@ -9,6 +10,7 @@ from jmetal.problem.multiobjective.zdt import ZDT1 from jmetal.util.comparator import SolutionAttributeComparator from jmetal.util.solution_list_output import SolutionListOutput +from jmetal.problem.multiobjective.unconstrained import Kursawe logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @@ -20,20 +22,27 @@ def main() -> None: problem=problem, population_size=100, max_evaluations=25000, - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), + mutation=Polynomial(1.0 / problem.number_of_variables, distribution_index=20), crossover=SBX(1.0, distribution_index=20), - #selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) - selection = BinaryTournament2Selection([SolutionAttributeComparator("dominance_ranking"), - SolutionAttributeComparator("crowding_distance", lowest_is_best=False)])) + # selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) + selection=BinaryTournament2Selection([SolutionAttributeComparator("dominance_ranking"), + SolutionAttributeComparator("crowding_distance", lowest_is_best=False)])) + + observer = VisualizerObserver(animation_speed=1 * 10e-8) + algorithm.observable.register(observer=observer) algorithm.run() result = algorithm.get_result() - SolutionListOutput[FloatSolution].print_function_values_to_file("FUN."+problem.get_name(), result) + SolutionListOutput[FloatSolution].plot_frontier_to_file(result, None, file_name="NSGAII." + problem.get_name(), + output_format='png', dpi=200) + SolutionListOutput[FloatSolution].plot_frontier_to_screen(result) + SolutionListOutput[FloatSolution].print_function_values_to_file("NSGAII." + problem.get_name(), result) logger.info("Algorithm (continuous problem): " + algorithm.get_name()) logger.info("Problem: " + problem.get_name()) logger.info("Computing time: " + str(algorithm.total_computing_time)) + if __name__ == '__main__': main() diff --git a/jmetal/runner/multiobjective/nsgaii_standard_settings_with_observer_plot_realtime.py b/jmetal/runner/multiobjective/nsgaii_standard_settings_with_observer_plot_realtime.py index 87a00d5a..87d7a102 100644 --- a/jmetal/runner/multiobjective/nsgaii_standard_settings_with_observer_plot_realtime.py +++ b/jmetal/runner/multiobjective/nsgaii_standard_settings_with_observer_plot_realtime.py @@ -2,12 +2,12 @@ from typing import List from jmetal.algorithm.multiobjective.nsgaii import NSGAII -from jmetal.component.observer import AlgorithmObserver +from jmetal.component.observer import VisualizerObserver from jmetal.core.solution import FloatSolution from jmetal.operator.crossover import SBX from jmetal.operator.mutation import Polynomial from jmetal.operator.selection import BinaryTournament2Selection -from jmetal.problem.multiobjective.zdt import ZDT4 +from jmetal.problem.multiobjective.zdt import ZDT1, ZDT4 from jmetal.util.comparator import SolutionAttributeComparator logging.basicConfig(level=logging.INFO) @@ -15,7 +15,7 @@ def main() -> None: - problem = ZDT4() + problem = ZDT1() algorithm = NSGAII[FloatSolution, List[FloatSolution]]( problem, population_size=100, @@ -25,7 +25,7 @@ def main() -> None: selection=BinaryTournament2Selection([SolutionAttributeComparator("dominance_ranking"), SolutionAttributeComparator("crowding_distance", lowest_is_best=False)])) - observer = AlgorithmObserver(animation_speed=1*10e-8) + observer = VisualizerObserver(animation_speed=1 * 10e-8) algorithm.observable.register(observer=observer) algorithm.run() diff --git a/jmetal/runner/multiobjective/smpso_standard_settings.py b/jmetal/runner/multiobjective/smpso_standard_settings.py index 60b87672..de3508de 100644 --- a/jmetal/runner/multiobjective/smpso_standard_settings.py +++ b/jmetal/runner/multiobjective/smpso_standard_settings.py @@ -2,7 +2,7 @@ from jmetal.algorithm.multiobjective.smpso import SMPSO from jmetal.component.archive import CrowdingDistanceArchive -from jmetal.component.observer import AlgorithmObserver +from jmetal.component.observer import VisualizerObserver from jmetal.core.solution import FloatSolution from jmetal.operator.mutation import Polynomial from jmetal.problem.multiobjective.zdt import ZDT1 @@ -22,13 +22,13 @@ def main() -> None: leaders=CrowdingDistanceArchive(100) ) - observer = AlgorithmObserver(animation_speed=1*10e-8) + observer = VisualizerObserver(animation_speed=1 * 10e-8) algorithm.observable.register(observer=observer) algorithm.run() result = algorithm.get_result() - SolutionListOutput[FloatSolution].plot_scatter_to_screen(result) + SolutionListOutput[FloatSolution].plot_frontier_to_screen(result) logger.info("Algorithm (continuous problem): " + algorithm.get_name()) logger.info("Problem: " + problem.get_name()) diff --git a/jmetal/runner/multiobjective/smpso_standard_settings_with_reference_point.py b/jmetal/runner/multiobjective/smpso_standard_settings_with_reference_point.py index 2a86fa60..d28705b0 100644 --- a/jmetal/runner/multiobjective/smpso_standard_settings_with_reference_point.py +++ b/jmetal/runner/multiobjective/smpso_standard_settings_with_reference_point.py @@ -2,7 +2,7 @@ from jmetal.algorithm.multiobjective.smpso import SMPSO from jmetal.component.archive import CrowdingDistanceArchiveWithReferencePoint -from jmetal.component.observer import AlgorithmObserver +from jmetal.component.observer import VisualizerObserver from jmetal.core.solution import FloatSolution from jmetal.operator.mutation import Polynomial from jmetal.problem.multiobjective.zdt import ZDT1 @@ -22,13 +22,13 @@ def main() -> None: leaders=CrowdingDistanceArchiveWithReferencePoint(100, reference_point=[1.0, 1.0]) ) - observer = AlgorithmObserver(animation_speed=1*10e-8) + observer = VisualizerObserver(animation_speed=1 * 10e-8) algorithm.observable.register(observer=observer) algorithm.run() result = algorithm.get_result() - SolutionListOutput[FloatSolution].plot_scatter_to_screen(result) + SolutionListOutput[FloatSolution].plot_frontier_to_screen(result) logger.info("Algorithm (continuous problem): " + algorithm.get_name()) logger.info("Problem: " + problem.get_name()) diff --git a/jmetal/runner/multiobjective/smpsorp_standard_settings.py b/jmetal/runner/multiobjective/smpsorp_standard_settings.py index 0b46c344..ed53785c 100644 --- a/jmetal/runner/multiobjective/smpsorp_standard_settings.py +++ b/jmetal/runner/multiobjective/smpsorp_standard_settings.py @@ -2,7 +2,7 @@ from jmetal.algorithm.multiobjective.smpso import SMPSORP from jmetal.component.archive import CrowdingDistanceArchiveWithReferencePoint -from jmetal.component.observer import AlgorithmObserver +from jmetal.component.observer import VisualizerObserver from jmetal.core.solution import FloatSolution from jmetal.operator.mutation import Polynomial from jmetal.problem.multiobjective.zdt import ZDT1 @@ -33,14 +33,12 @@ def main() -> None: leaders=archives_with_reference_points ) - observer = AlgorithmObserver(animation_speed=1*10e-8) + observer = VisualizerObserver(animation_speed=1 * 10e-8) algorithm.observable.register(observer=observer) algorithm.run() result = algorithm.get_result() - SolutionListOutput[FloatSolution].plot_scatter_to_screen(result) - logger.info("Algorithm (continuous problem): " + algorithm.get_name()) logger.info("Problem: " + problem.get_name()) diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index 21c29b5a..0652cb72 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -9,6 +9,7 @@ logger = logging.getLogger(__name__) S = TypeVar('S') +SUPPORTED_FORMATS = ["eps", "jpeg", "jpg", "pdf", "pgf", "png", "ps", "raw", "rgba", "svg", "svgz", "tif", "tiff"] """ .. module:: graphics @@ -20,7 +21,8 @@ class ScatterPlot: - def __init__(self, plot_title: str, animation_speed: float = 1 * 10e-10): + + def __init__(self, plot_title: str, animation_speed: float=1 * 10e-10): """ Creates a new :class:`ScatterPlot` instance. :param plot_title: Title of the scatter diagram. @@ -29,11 +31,15 @@ def __init__(self, plot_title: str, animation_speed: float = 1 * 10e-10): self.plot_title = plot_title self.fig = plt.figure() self.axis = self.fig.add_subplot(111) + self.sc = None # Real-time plotting options self.animation_speed = animation_speed + # Initialize a plot + self.__init_plot() + def __init_plot(self, is_auto_scalable: bool = True) -> None: """ Initialize the scatter plot the first time. """ if is_auto_scalable: @@ -44,90 +50,54 @@ def __init_plot(self, is_auto_scalable: bool = True) -> None: # Style options self.axis.grid(color='#f0f0f5', linestyle='-', linewidth=2, alpha=0.5) - self.fig.suptitle(self.plot_title, fontsize=14, fontweight='bold') - - def __get_data_points(self, solution_list: List[S]) -> Tuple[list, list]: - """ Get coords (x,y) from a solution_list. """ - if solution_list is None: - raise Exception("Solution list is none!") + self.fig.suptitle(self.plot_title, fontsize=13) - points = list(solution.objectives for solution in solution_list) - x_values, y_values = [point[0] for point in points], [point[1] for point in points] + def plot(self, solution_list: List[S], reference_solution_list: List[S], + save: bool = True, fmt: str='eps', dpi: int=200, file_name: str="OUT") -> None: + if reference_solution_list: + reference_x_values, reference_y_values = self.__get_data_points(reference_solution_list) + self.axis.plot(reference_x_values, reference_y_values, 'b', markersize=3, picker=10) - return x_values, y_values - - def retrieve_info(self, solution: Solution) -> None: - """ Retrieve more information about a solution object. """ - pass - - def __search_solution(self, solution_list: List[S], x_val: float, y_val: float) -> None: - """ :return: A solution object associated with some values of (x,y). """ - sol = next((solution for solution in solution_list - if solution.objectives[0] == x_val and solution.objectives[1]), None) - - if sol is not None: - logger.info('Solution associated to ({0}, {1}): {2}'.format(x_val, y_val, sol)) - self.retrieve_info(sol) - else: - raise Exception("Solution is none.") - - def __pick_handler(self, event, solution_list: List[S]): - """ Handler for picking points from the plot. """ - line, ind = event.artist, event.ind[0] - x, y = line.get_xdata(), line.get_ydata() - - logger.info('Selected data point ({0}): ({1}, {2})'.format(ind, x[ind], y[ind])) - self.__search_solution(solution_list, x[ind], y[ind]) - - def simple_plot(self, solution_list: List[S], file_name: str = "output", - fmt: str = 'eps', dpi: int = 200, save: bool = True) -> None: - """ Create a simple plot. """ - self.__init_plot() x_values, y_values = self.__get_data_points(solution_list) - self.sc, = self.axis.plot(x_values, y_values, 'go', markersize=3, picker=10) if save: - supported_formats = ["eps", "jpeg", "jpg", "pdf", "pgf", "png", "ps", - "raw", "rgba", "svg", "svgz", "tif", "tiff"] - if fmt not in supported_formats: - raise Exception(fmt + " is not a valid format! Use one of these instead: " - + str(supported_formats)) - + if fmt not in SUPPORTED_FORMATS: + raise Exception("{0} is not a valid format! Use one of these instead: {0}".format(fmt, SUPPORTED_FORMATS)) self.fig.savefig(file_name + '.' + fmt, format=fmt, dpi=dpi) - logger.info("Output file (function plot): " + file_name + '.' + fmt) - def interactive_plot(self, solution_list: List[S]) -> None: + def plot_interactive(self, solution_list: List[S]) -> None: """ Create a plot to get to directly access the coords (x,y) of a point by a mouse click. """ - self.__init_plot() x_values, y_values = self.__get_data_points(solution_list) - self.sc, = self.axis.plot(x_values, y_values, 'go', markersize=5, picker=10) + self.sc, = self.axis.plot(x_values, y_values, 'go', markersize=3, picker=10) self.fig.canvas.mpl_connect('pick_event', lambda event: self.__pick_handler(event, solution_list)) plt.show() - def update(self, solution_list: List[S], evaluations: int = 0, computing_time: float = 0) -> None: - """ Update a simple_plot(). Note that the plot must be initialized first. """ + def retrieve_info(self, solution: Solution) -> None: + """ Retrieve more information about a solution object. """ + pass + def update(self, solution_list: List[S], evaluations: int=0, computing_time: float=0) -> None: + """ Update a plot(). Note that the plot must be initialized first. """ if self.sc is None: - raise Exception("Error while updating! Initialize plot first with " - "simple_plot(solution_list: List[S])") + raise Exception("Error while updating: Initialize plot first!") x_values, y_values = self.__get_data_points(solution_list) - # Update points + # Replace with new points self.sc.set_data(x_values, y_values) - event_handler = self.fig.canvas.mpl_connect('pick_event', - lambda event: self.__pick_handler(event, solution_list)) - # Update title - self.fig.suptitle(self.plot_title - + ', \n Eval: ' + str(evaluations) - + ', Time: ' + str('%.3f' % computing_time), fontsize=14, fontweight='bold') + # Also, we need to add (every time and on) the event handler + event_handler = \ + self.fig.canvas.mpl_connect('pick_event', lambda event: self.__pick_handler(event, solution_list)) - # Re-align the axis. + # Update title with new times and evaluations + self.fig.suptitle('{0}, Eval: {1}, Time: {2}'.format(self.plot_title, evaluations, computing_time), fontsize=13) + + # Re-align the axis self.axis.relim() self.axis.autoscale_view(True, True, True) @@ -137,3 +107,31 @@ def update(self, solution_list: List[S], evaluations: int = 0, computing_time: f # Disconnect the pick event for the next update self.fig.canvas.mpl_disconnect(event_handler) + + def __get_data_points(self, solution_list: List[S]) -> Tuple[list, list]: + """ Get coords (x,y) from a solution_list. """ + if solution_list is None: + raise Exception("Solution list is none!") + + points = list(solution.objectives for solution in solution_list) + x_values, y_values = [point[0] for point in points], [point[1] for point in points] + + return x_values, y_values + + def __search_solution(self, solution_list: List[S], x_val: float, y_val: float) -> None: + """ :return: A solution object associated with some values of (x,y) """ + sol = next((solution for solution in solution_list + if solution.objectives[0] == x_val and solution.objectives[1]), None) + + if sol is not None: + self.retrieve_info(sol) + else: + raise Exception("Solution is none.") + + def __pick_handler(self, event, solution_list: List[S]): + """ Handler for picking points from the plot. """ + line, ind = event.artist, event.ind[0] + x, y = line.get_xdata(), line.get_ydata() + + logger.info('Selected data point ({0}): ({1}, {2})'.format(ind, x[ind], y[ind])) + self.__search_solution(solution_list, x[ind], y[ind]) diff --git a/jmetal/util/solution_list_output.py b/jmetal/util/solution_list_output.py index 5b0a8f95..9ded294b 100644 --- a/jmetal/util/solution_list_output.py +++ b/jmetal/util/solution_list_output.py @@ -12,35 +12,32 @@ class SolutionListOutput(Generic[S]): + @staticmethod - def plot_scatter_to_file(solution_list: List[S], file_name, output_format: str, dpi: int, - plot_title="Pareto frontier"): - """ Plot non-dominated solutions. For problems with TWO variables. - """ - sc = ScatterPlot(plot_title=plot_title) - sc.simple_plot(solution_list=solution_list, file_name=file_name, fmt=output_format, dpi=dpi) + def plot_frontier_to_file(solution_list: List[S], reference_solution_list: List[S], + file_name="output", output_format: str='eps', dpi: int=200): + """ Plot non-dominated solutions. For problems with TWO variables """ + sc = ScatterPlot("Pareto frontier") + sc.plot(solution_list, reference_solution_list, True, output_format, dpi, file_name) @staticmethod - def plot_scatter_to_screen(solution_list: List[S], - plot_title="Pareto frontier (interactive)"): - """ Plot non-dominated solutions. For problems with TWO variables. - """ - sc = ScatterPlot(plot_title=plot_title) - sc.interactive_plot(solution_list=solution_list) + def plot_frontier_to_screen(solution_list: List[S]): + """ Plot non-dominated solutions. For problems with TWO variables """ + sc = ScatterPlot("Pareto frontier") + sc.plot_interactive(solution_list) @staticmethod - def plot_scatter_real_time(solution_list: List[S], evaluations: int, computing_time: float, animation_speed: float, - plot_title="Pareto frontier (real-time)"): - """ Plot non-dominated solutions in real-time. For problems with TWO variables. - """ + def plot_frontier_interactive(solution_list: List[S], reference_solution_list: List[S], evaluations: int, + computing_time: float, animation_speed: float=1 * 10e-10): + """ Plot non-dominated solutions in real-time. For problems with TWO variables """ global sc if not plt.get_fignums(): # The first time, set up plot - sc = ScatterPlot(plot_title=plot_title, animation_speed=animation_speed) - sc.simple_plot(solution_list=solution_list, save=False) + sc = ScatterPlot("Pareto frontier", animation_speed) + sc.plot(solution_list, reference_solution_list, save=False) else: - sc.update(solution_list=solution_list, evaluations=evaluations, computing_time=computing_time) + sc.update(solution_list, evaluations, computing_time) @staticmethod def print_variables_to_screen(solution_list: List[S]): From 775d2b384fccb6ddd15c7f80548267c274dbbf42 Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 21 May 2018 13:45:04 +0200 Subject: [PATCH 44/90] Removed potentially troubled test --- jmetal/component/test/test_evaluator.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/jmetal/component/test/test_evaluator.py b/jmetal/component/test/test_evaluator.py index 053cc14f..1dcfeccd 100644 --- a/jmetal/component/test/test_evaluator.py +++ b/jmetal/component/test/test_evaluator.py @@ -39,8 +39,8 @@ def test_should_evaluate_a_list_of_problem_work_properly_with_a_solution(self): self.evaluator.evaluate(problem_list, self.problem) - self.assertEquals(1.2, problem_list[0].objectives[0]) - self.assertEquals(2.3, problem_list[0].objectives[1]) + self.assertEqual(1.2, problem_list[0].objectives[0]) + self.assertEqual(2.3, problem_list[0].objectives[1]) def test_should_evaluate_a_list_of_problem_work_properly(self): problem_list = [self.problem.create_solution() for _ in range(10)] @@ -48,10 +48,11 @@ def test_should_evaluate_a_list_of_problem_work_properly(self): self.evaluator.evaluate(problem_list, self.problem) for i in range(10): - self.assertEquals(1.2, problem_list[i].objectives[0]) - self.assertEquals(2.3, problem_list[i].objectives[1]) + self.assertEqual(1.2, problem_list[i].objectives[0]) + self.assertEqual(2.3, problem_list[i].objectives[1]) +""" class DaskMultithreadedEvaluatorTestCases(unittest.TestCase): def setUp(self): self.evaluator = DaskMultithreadedEvaluator() @@ -79,6 +80,7 @@ def test_should_evaluate_a_list_of_problem_work_properly(self): self.assertEquals(1.2, evaluated_list[i].objectives[0]) self.assertEquals(2.3, evaluated_list[i].objectives[1]) self.assertEquals(len(problem_list), len(evaluated_list)) +""" if __name__ == "__main__": From 1be57dfddb0f78f1ab2fcad0de9cdce3aeecd10a Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 21 May 2018 13:48:30 +0200 Subject: [PATCH 45/90] Updated --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 31f8e92f..b85bb9c4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,4 @@ PyHamcrest==1.9.0 mockito==1.0.11 matplotlib==2.0.2 numpy==1.13.1 -dask==0.17.4 \ No newline at end of file +dask[distributed]==0.17.4 \ No newline at end of file From 7387a735bd8bc202b903bcd852e49f84f8600c4a Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 21 May 2018 14:20:23 +0200 Subject: [PATCH 46/90] Save solution to file --- jmetal/util/graphic.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index 0652cb72..ff653a33 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -76,9 +76,16 @@ def plot_interactive(self, solution_list: List[S]) -> None: plt.show() - def retrieve_info(self, solution: Solution) -> None: + def retrieve_info(self, x_val: float, y_val: float, solution: Solution) -> None: """ Retrieve more information about a solution object. """ - pass + logger.info("Output file: " + '{0}-{1}'.format(x_val, y_val)) + with open('{0}-{1}'.format(x_val, y_val), 'w') as of: + for function_value in solution.objectives: + of.write(str(function_value) + " ") + of.write("\n \n") + for function_variable in solution.variables: + of.write(str(function_variable) + "\n") + of.write("\n") def update(self, solution_list: List[S], evaluations: int=0, computing_time: float=0) -> None: """ Update a plot(). Note that the plot must be initialized first. """ @@ -124,7 +131,7 @@ def __search_solution(self, solution_list: List[S], x_val: float, y_val: float) if solution.objectives[0] == x_val and solution.objectives[1]), None) if sol is not None: - self.retrieve_info(sol) + self.retrieve_info(x_val, y_val, sol) else: raise Exception("Solution is none.") From 5f26d544016920d19a68c34d4373b4c7d80ed49a Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 28 May 2018 22:08:13 +0200 Subject: [PATCH 47/90] Added 3D plot --- jmetal/component/observer.py | 7 +- jmetal/problem/multiobjective/dtlz.py | 3 +- .../nsgaii_standard_settings.py | 15 +-- jmetal/util/graphic.py | 99 +++++++++++-------- jmetal/util/solution_list_output.py | 25 ++--- 5 files changed, 83 insertions(+), 66 deletions(-) diff --git a/jmetal/component/observer.py b/jmetal/component/observer.py index 39f1afcf..5bdf3450 100644 --- a/jmetal/component/observer.py +++ b/jmetal/component/observer.py @@ -42,8 +42,7 @@ def update(self, *args, **kwargs): class VisualizerObserver(Observer): - def __init__(self, animation_speed: float, frequency: float = 1.0) -> None: - self.animation_speed = animation_speed + def __init__(self, frequency: float = 1.0) -> None: self.display_frequency = frequency def update(self, *args, **kwargs): @@ -53,5 +52,5 @@ def update(self, *args, **kwargs): reference_solution_list = kwargs.get("reference", None) if (evaluations % self.display_frequency) == 0: - SolutionListOutput.plot_frontier_interactive(solution_list, reference_solution_list, evaluations, - computing_time, self.animation_speed) + SolutionListOutput.plot_frontier_live( + solution_list, reference_solution_list, "Pareto frontier", evaluations, computing_time) diff --git a/jmetal/problem/multiobjective/dtlz.py b/jmetal/problem/multiobjective/dtlz.py index a1f915c5..2c7485a5 100644 --- a/jmetal/problem/multiobjective/dtlz.py +++ b/jmetal/problem/multiobjective/dtlz.py @@ -18,10 +18,11 @@ class DTLZ1(FloatProblem): .. note:: Continuous problem having a convex Pareto front """ - def __init__(self, number_of_variables: int = 30, number_of_objectives = 3): + def __init__(self, number_of_variables: int = 30, number_of_objectives=3): """Constructor :param number_of_variables: number of decision variables of the problem """ + super().__init__() self.number_of_variables = number_of_variables self.number_of_objectives = number_of_objectives self.number_of_constraints = 0 diff --git a/jmetal/runner/multiobjective/nsgaii_standard_settings.py b/jmetal/runner/multiobjective/nsgaii_standard_settings.py index 473c9e63..02ba4bdd 100644 --- a/jmetal/runner/multiobjective/nsgaii_standard_settings.py +++ b/jmetal/runner/multiobjective/nsgaii_standard_settings.py @@ -9,6 +9,7 @@ from jmetal.operator.crossover import SBX from jmetal.operator.mutation import Polynomial from jmetal.operator.selection import BinaryTournament2Selection +from jmetal.problem.multiobjective.dtlz import DTLZ1 from jmetal.problem.multiobjective.zdt import ZDT1 from jmetal.util.comparator import SolutionAttributeComparator from jmetal.util.solution_list_output import SolutionListOutput @@ -19,7 +20,7 @@ def main() -> None: - problem = ZDT1() + problem = DTLZ1() algorithm = NSGAII[FloatSolution, List[FloatSolution]]( problem=problem, population_size=100, @@ -31,16 +32,18 @@ def main() -> None: selection=BinaryTournament2Selection([SolutionAttributeComparator("dominance_ranking"), SolutionAttributeComparator("crowding_distance", lowest_is_best=False)])) - observer = VisualizerObserver(animation_speed=1 * 10e-8) + observer = VisualizerObserver() algorithm.observable.register(observer=observer) algorithm.run() result = algorithm.get_result() - SolutionListOutput[FloatSolution].plot_frontier_to_file(result, None, file_name="NSGAII." + problem.get_name(), - output_format='png', dpi=200) - SolutionListOutput[FloatSolution].plot_frontier_to_screen(result) - SolutionListOutput[FloatSolution].print_function_values_to_file("NSGAII." + problem.get_name(), result) + SolutionListOutput[FloatSolution].plot_frontier_to_file(result, None, + title=problem.get_name(), + file_name="NSGAII." + problem.get_name(), + output_format='png') + SolutionListOutput[FloatSolution].plot_frontier_to_screen(result, None, title=problem.get_name()) + #SolutionListOutput[FloatSolution].print_function_values_to_file(result, "NSGAII." + problem.get_name()) logger.info("Algorithm (continuous problem): " + algorithm.get_name()) logger.info("Problem: " + problem.get_name()) diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index 0652cb72..765707b7 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -1,10 +1,14 @@ import logging +import warnings from typing import TypeVar, List, Tuple import matplotlib.pyplot as plt +from mpl_toolkits.mplot3d import Axes3D from jmetal.core.solution import Solution +warnings.filterwarnings("ignore",".*GUI is implemented.*") + logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @@ -22,25 +26,27 @@ class ScatterPlot: - def __init__(self, plot_title: str, animation_speed: float=1 * 10e-10): - """ Creates a new :class:`ScatterPlot` instance. + def __init__(self, plot_title: str, number_of_objectives: int=2): + """ Creates a new :class:`Plot` instance. :param plot_title: Title of the scatter diagram. - :param animation_speed: TDelay (for live plot only). Allow time for the gui event loops to trigger and update the display. """ self.plot_title = plot_title - self.fig = plt.figure() - self.axis = self.fig.add_subplot(111) + self.number_of_objectives = number_of_objectives + # Initialize a plot + self.fig = plt.figure() self.sc = None - # Real-time plotting options - self.animation_speed = animation_speed + if number_of_objectives == 2: + self.axis = self.fig.add_subplot(111) + else: + self.axis = Axes3D(self.fig) + self.axis.autoscale(enable=True, axis='both') - # Initialize a plot - self.__init_plot() + self.__initialize() - def __init_plot(self, is_auto_scalable: bool = True) -> None: + def __initialize(self, is_auto_scalable: bool = True) -> None: """ Initialize the scatter plot the first time. """ if is_auto_scalable: self.axis.set_autoscale_on(True) @@ -52,48 +58,41 @@ def __init_plot(self, is_auto_scalable: bool = True) -> None: self.axis.grid(color='#f0f0f5', linestyle='-', linewidth=2, alpha=0.5) self.fig.suptitle(self.plot_title, fontsize=13) - def plot(self, solution_list: List[S], reference_solution_list: List[S], - save: bool = True, fmt: str='eps', dpi: int=200, file_name: str="OUT") -> None: - if reference_solution_list: - reference_x_values, reference_y_values = self.__get_data_points(reference_solution_list) - self.axis.plot(reference_x_values, reference_y_values, 'b', markersize=3, picker=10) - - x_values, y_values = self.__get_data_points(solution_list) - self.sc, = self.axis.plot(x_values, y_values, 'go', markersize=3, picker=10) - - if save: - if fmt not in SUPPORTED_FORMATS: - raise Exception("{0} is not a valid format! Use one of these instead: {0}".format(fmt, SUPPORTED_FORMATS)) - self.fig.savefig(file_name + '.' + fmt, format=fmt, dpi=dpi) - - def plot_interactive(self, solution_list: List[S]) -> None: - """ Create a plot to get to directly access the coords (x,y) of a point by a mouse click. """ - self.__init_plot() - x_values, y_values = self.__get_data_points(solution_list) + def __plot(self, x_values, y_values, z_values, solution_list, color: str='go'): + if self.number_of_objectives == 2: + self.sc, = self.axis.plot(x_values, y_values, color, markersize=3, picker=10) + self.fig.canvas.mpl_connect('pick_event', lambda event: self.__pick_handler(event, solution_list)) + else: + self.sc, = self.axis.plot(x_values, y_values, z_values, color, markersize=3, picker=10) - self.sc, = self.axis.plot(x_values, y_values, 'go', markersize=3, picker=10) - self.fig.canvas.mpl_connect('pick_event', lambda event: self.__pick_handler(event, solution_list)) + def plot(self, solution_list: List[S], reference_solution_list: List[S], show: bool=False) -> None: + if reference_solution_list: + ref_x_values, ref_y_values, ref_z_values = self.__get_objectives(reference_solution_list) + self.__plot(ref_x_values, ref_y_values, ref_z_values, None, 'b') - plt.show() + x_values, y_values, z_values = self.__get_objectives(solution_list) + self.__plot(x_values, y_values, z_values, solution_list) - def retrieve_info(self, solution: Solution) -> None: - """ Retrieve more information about a solution object. """ - pass + if show: + plt.show() def update(self, solution_list: List[S], evaluations: int=0, computing_time: float=0) -> None: """ Update a plot(). Note that the plot must be initialized first. """ if self.sc is None: raise Exception("Error while updating: Initialize plot first!") - x_values, y_values = self.__get_data_points(solution_list) + x_values, y_values, z_values = self.__get_objectives(solution_list) # Replace with new points self.sc.set_data(x_values, y_values) - # Also, we need to add (every time and on) the event handler + # Also, add event handler event_handler = \ self.fig.canvas.mpl_connect('pick_event', lambda event: self.__pick_handler(event, solution_list)) + if self.number_of_objectives == 3: + self.sc.set_3d_properties(z_values) + # Update title with new times and evaluations self.fig.suptitle('{0}, Eval: {1}, Time: {2}'.format(self.plot_title, evaluations, computing_time), fontsize=13) @@ -103,30 +102,44 @@ def update(self, solution_list: List[S], evaluations: int=0, computing_time: flo # Draw self.fig.canvas.draw() - plt.pause(self.animation_speed) + plt.pause(0.01) # Disconnect the pick event for the next update self.fig.canvas.mpl_disconnect(event_handler) - def __get_data_points(self, solution_list: List[S]) -> Tuple[list, list]: + def save(self, file_name: str, fmt: str='eps', dpi: int=200): + if fmt not in SUPPORTED_FORMATS: + raise Exception("{0} is not a valid format! Use one of these instead: {0}".format(fmt, SUPPORTED_FORMATS)) + self.fig.savefig(file_name + '.' + fmt, format=fmt, dpi=dpi) + + def retrieve_info(self, solution: Solution) -> None: + """ Retrieve more information about a solution object. """ + pass + + def __get_objectives(self, solution_list: List[S]) -> Tuple[list, list, list]: """ Get coords (x,y) from a solution_list. """ if solution_list is None: raise Exception("Solution list is none!") points = list(solution.objectives for solution in solution_list) + x_values, y_values = [point[0] for point in points], [point[1] for point in points] + z_values = [] + + if self.number_of_objectives == 3: + z_values = [point[2] for point in points] - return x_values, y_values + return x_values, y_values, z_values - def __search_solution(self, solution_list: List[S], x_val: float, y_val: float) -> None: + def __get_solution_from_list(self, solution_list: List[S], x_val: float, y_val: float) -> None: """ :return: A solution object associated with some values of (x,y) """ sol = next((solution for solution in solution_list - if solution.objectives[0] == x_val and solution.objectives[1]), None) + if solution.objectives[0] == x_val and solution.objectives[1] == y_val), None) if sol is not None: self.retrieve_info(sol) else: - raise Exception("Solution is none.") + logger.warning("Solution is none.") def __pick_handler(self, event, solution_list: List[S]): """ Handler for picking points from the plot. """ @@ -134,4 +147,4 @@ def __pick_handler(self, event, solution_list: List[S]): x, y = line.get_xdata(), line.get_ydata() logger.info('Selected data point ({0}): ({1}, {2})'.format(ind, x[ind], y[ind])) - self.__search_solution(solution_list, x[ind], y[ind]) + self.__get_solution_from_list(solution_list, x[ind], y[ind]) diff --git a/jmetal/util/solution_list_output.py b/jmetal/util/solution_list_output.py index 9ded294b..5f359201 100644 --- a/jmetal/util/solution_list_output.py +++ b/jmetal/util/solution_list_output.py @@ -14,28 +14,29 @@ class SolutionListOutput(Generic[S]): @staticmethod - def plot_frontier_to_file(solution_list: List[S], reference_solution_list: List[S], - file_name="output", output_format: str='eps', dpi: int=200): + def plot_frontier_to_file(solution_list: List[S], reference_solution_list: List[S], title: str, + file_name: str, output_format: str='eps'): """ Plot non-dominated solutions. For problems with TWO variables """ - sc = ScatterPlot("Pareto frontier") - sc.plot(solution_list, reference_solution_list, True, output_format, dpi, file_name) + sc = ScatterPlot(title, solution_list[0].number_of_objectives) + sc.plot(solution_list, reference_solution_list) + sc.save(file_name, output_format) @staticmethod - def plot_frontier_to_screen(solution_list: List[S]): + def plot_frontier_to_screen(solution_list: List[S], reference_solution_list: List[S], title: str): """ Plot non-dominated solutions. For problems with TWO variables """ - sc = ScatterPlot("Pareto frontier") - sc.plot_interactive(solution_list) + sc = ScatterPlot(title, solution_list[0].number_of_objectives) + sc.plot(solution_list, reference_solution_list, True) @staticmethod - def plot_frontier_interactive(solution_list: List[S], reference_solution_list: List[S], evaluations: int, - computing_time: float, animation_speed: float=1 * 10e-10): + def plot_frontier_live(solution_list: List[S], reference_solution_list: List[S], title: str, + evaluations: int, computing_time: float): """ Plot non-dominated solutions in real-time. For problems with TWO variables """ global sc if not plt.get_fignums(): # The first time, set up plot - sc = ScatterPlot("Pareto frontier", animation_speed) - sc.plot(solution_list, reference_solution_list, save=False) + sc = ScatterPlot(title, solution_list[0].number_of_objectives) + sc.plot(solution_list, reference_solution_list) else: sc.update(solution_list, evaluations, computing_time) @@ -52,7 +53,7 @@ def print_function_values_to_screen(solution_list: List[S]): print() @staticmethod - def print_function_values_to_file(file_name, solution_list: List[S]): + def print_function_values_to_file(solution_list: List[S], file_name): logger.info("Output file (function values): " + file_name) with open(file_name, 'w') as of: for solution in solution_list: From 2ced411c1ccf664e30f055de3caa9ed66cf06c09 Mon Sep 17 00:00:00 2001 From: benhid Date: Mon, 28 May 2018 22:08:25 +0200 Subject: [PATCH 48/90] New major version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index baca4b7b..7aedd71e 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages setup(name='jmetalpy', - version='0.5', + version='1.0.0', description='JMetalPy. Python version of the jMetal framework', author='Antonio J. Nebro', author_email='ajnebro@uma.es', From 71c557a33ec6d26acd3b5088a89fa257414bd3b4 Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 29 May 2018 10:33:36 +0200 Subject: [PATCH 49/90] Update requirements --- docs/requirements.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 5a154449..3d125899 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1,3 @@ -sphinx==1.6.3 \ No newline at end of file +sphinx==1.6.3 +matplotlib==2.0.2 +dask[distributed]==0.17.4 \ No newline at end of file From 5c22e5be1172005cb904a4346a8bf4027c01148b Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 29 May 2018 10:49:39 +0200 Subject: [PATCH 50/90] Update docs --- docs/requirements.txt | 4 +--- docs/source/conf.py | 4 ++-- docs/source/runner/nsgaii.rst | 8 ++++---- docs/source/runner/smpso.rst | 4 ++-- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 3d125899..5a154449 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1 @@ -sphinx==1.6.3 -matplotlib==2.0.2 -dask[distributed]==0.17.4 \ No newline at end of file +sphinx==1.6.3 \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index 1694ee45..61aab2ae 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -19,7 +19,7 @@ # http://blog.rtwilson.com/how-to-make-your-sphinx-documentation-compile-with-readthedocs-when-youre-using-numpy-and-scipy/ import mock -MOCK_MODULES = ['numpy', 'matplotlib', 'matplotlib.pyplot'] +MOCK_MODULES = ['numpy', 'dask', 'dask[distributed]', 'matplotlib', 'matplotlib.pyplot', 'matplotlib.axes'] for mod_name in MOCK_MODULES: sys.modules[mod_name] = mock.Mock() @@ -30,7 +30,7 @@ author = 'Antonio J. Nebro' # The short X.Y version -version = '' +version = '1.0.0' # The full version, including alpha/beta/rc tags release = '' diff --git a/docs/source/runner/nsgaii.rst b/docs/source/runner/nsgaii.rst index a44704ad..11172e8b 100644 --- a/docs/source/runner/nsgaii.rst +++ b/docs/source/runner/nsgaii.rst @@ -14,7 +14,7 @@ Common imports: from jmetal.util.comparator import RankingAndCrowdingDistanceComparator NSGA-II with standard settings ------------- +------------------------------------ .. code-block:: python @@ -31,7 +31,7 @@ NSGA-II with standard settings result = algorithm.get_result() NSGA-II with observer ------------- +------------------------------------ .. code-block:: python @@ -53,7 +53,7 @@ NSGA-II with observer result = algorithm.get_result() NSGA-II with plot in real-time ------------- +------------------------------------ .. code-block:: python @@ -75,7 +75,7 @@ NSGA-II with plot in real-time result = algorithm.get_result() NSGA-II stopping by time ------------- +------------------------------------ .. code-block:: python diff --git a/docs/source/runner/smpso.rst b/docs/source/runner/smpso.rst index c75e85e0..60c0048c 100644 --- a/docs/source/runner/smpso.rst +++ b/docs/source/runner/smpso.rst @@ -11,7 +11,7 @@ Common imports: from jmetal.component.archive import CrowdingDistanceArchive SMPSO with standard settings ------------- +------------------------------------ .. code-block:: python @@ -29,7 +29,7 @@ SMPSO with standard settings result = algorithm.get_result() SMPSO/RP with standard settings ------------- +------------------------------------ .. code-block:: python From 71c60cb5b9c539745ad7af6b895388a384c43e32 Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 29 May 2018 10:50:13 +0200 Subject: [PATCH 51/90] Added documentation --- jmetal/util/graphic.py | 29 ++++++++++++++++++++--------- jmetal/util/observable.py | 4 ++-- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index 00a8fe82..789d1d81 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -27,15 +27,17 @@ class ScatterPlot: def __init__(self, plot_title: str, number_of_objectives: int=2): - """ Creates a new :class:`Plot` instance. + """ Creates a new :class:`ScatterPlot` instance. Suitable for problems with 2 or 3 objectives. :param plot_title: Title of the scatter diagram. + :param number_of_objectives: Number of objectives to be used (2D/3D). """ self.plot_title = plot_title self.number_of_objectives = number_of_objectives # Initialize a plot self.fig = plt.figure() + self.fig.canvas.set_window_title('jMetalPy') self.sc = None if number_of_objectives == 2: @@ -46,14 +48,13 @@ def __init__(self, plot_title: str, number_of_objectives: int=2): self.__initialize() - def __initialize(self, is_auto_scalable: bool = True) -> None: + def __initialize(self) -> None: """ Initialize the scatter plot the first time. """ - if is_auto_scalable: - self.axis.set_autoscale_on(True) - self.axis.autoscale_view(True, True, True) - logger.info("Generating plot...") + self.axis.set_autoscale_on(True) + self.axis.autoscale_view(True, True, True) + # Style options self.axis.grid(color='#f0f0f5', linestyle='-', linewidth=2, alpha=0.5) self.fig.suptitle(self.plot_title, fontsize=13) @@ -73,8 +74,13 @@ def plot(self, solution_list: List[S], reference_solution_list: List[S], show: b x_values, y_values, z_values = self.__get_objectives(solution_list) self.__plot(x_values, y_values, z_values, solution_list) + if show: + plt.show() + def update(self, solution_list: List[S], evaluations: int=0, computing_time: float=0) -> None: - """ Update a plot(). Note that the plot must be initialized first. """ + """ Update a plot with new values. + + .. note:: The plot must be initialized first. """ if self.sc is None: raise Exception("Error while updating: Initialize plot first!") @@ -105,12 +111,15 @@ def update(self, solution_list: List[S], evaluations: int=0, computing_time: flo self.fig.canvas.mpl_disconnect(event_handler) def save(self, file_name: str, fmt: str='eps', dpi: int=200): + """ Save the plot in a file. """ + logger.info("Saving to file...") + if fmt not in SUPPORTED_FORMATS: raise Exception("{0} is not a valid format! Use one of these instead: {0}".format(fmt, SUPPORTED_FORMATS)) self.fig.savefig(file_name + '.' + fmt, format=fmt, dpi=dpi) def retrieve_info(self, x_val: float, y_val: float, solution: Solution) -> None: - """ Retrieve more information about a solution object. """ + """ Retrieve some information about a solution object. """ logger.info("Output file: " + '{0}-{1}'.format(x_val, y_val)) with open('{0}-{1}'.format(x_val, y_val), 'w') as of: for function_value in solution.objectives: @@ -121,7 +130,9 @@ def retrieve_info(self, x_val: float, y_val: float, solution: Solution) -> None: of.write("\n") def __get_objectives(self, solution_list: List[S]) -> Tuple[list, list, list]: - """ Get coords (x,y) from a solution_list. """ + """ Get coords (x,y,z) from a solution_list. + + :return: A tuple with (x,y,z) values. The third might be empty if working with a problem with 2 objectives.""" if solution_list is None: raise Exception("Solution list is none!") diff --git a/jmetal/util/observable.py b/jmetal/util/observable.py index 4240c09c..de4ca31e 100644 --- a/jmetal/util/observable.py +++ b/jmetal/util/observable.py @@ -20,8 +20,8 @@ class Observer(object): @abstractmethod def update(self, *args, **kwargs): - """ - Update method + """ Update method + :param args: :param kwargs: :return: From b65e109fe40112f418dab99282beb2699ebcdb90 Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 29 May 2018 11:43:11 +0200 Subject: [PATCH 52/90] Update mocked modules --- docs/source/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 61aab2ae..39b58d0c 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -19,7 +19,7 @@ # http://blog.rtwilson.com/how-to-make-your-sphinx-documentation-compile-with-readthedocs-when-youre-using-numpy-and-scipy/ import mock -MOCK_MODULES = ['numpy', 'dask', 'dask[distributed]', 'matplotlib', 'matplotlib.pyplot', 'matplotlib.axes'] +MOCK_MODULES = ['numpy', 'dask', 'dask.distributed', 'mpl_toolkits', 'matplotlib', 'matplotlib.pyplot', 'matplotlib.axes'] for mod_name in MOCK_MODULES: sys.modules[mod_name] = mock.Mock() From cb0436b66a2e8bb759ffc32843650cd7e7305ccb Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 31 May 2018 13:10:56 +0200 Subject: [PATCH 53/90] Populate docs --- README.md | 2 +- docs/source/examples.rst | 3 ++- docs/source/runner/nsgaii.rst | 48 ++------------------------------- docs/source/runner/observer.rst | 31 +++++++++++++++++++++ 4 files changed, 36 insertions(+), 48 deletions(-) create mode 100644 docs/source/runner/observer.rst diff --git a/README.md b/README.md index 5f0b7bdb..36d73a18 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ $ pip install -r requirements.txt ``` # Usage -Examples of configuring and running all the included algorithms are located in the [jmetalpy.runner](jmetal/runner) folder. +Examples of configuring and running all the included algorithms are located [in the docs](http://jmetalpy.readthedocs.io/en/develop/examples.html). # Contributing Please read [CONTRIBUTING](CONTRIBUTING.md) for details on how to contribute to the project. diff --git a/docs/source/examples.rst b/docs/source/examples.rst index 68f89264..e4fdb9ae 100644 --- a/docs/source/examples.rst +++ b/docs/source/examples.rst @@ -7,4 +7,5 @@ Examples :caption: Algorithms: runner/nsgaii - runner/smpso \ No newline at end of file + runner/smpso + runner/observer \ No newline at end of file diff --git a/docs/source/runner/nsgaii.rst b/docs/source/runner/nsgaii.rst index 11172e8b..1b11886a 100644 --- a/docs/source/runner/nsgaii.rst +++ b/docs/source/runner/nsgaii.rst @@ -1,7 +1,7 @@ NSGA-II ======================== -Common imports: +Common imports for these examples: .. code-block:: python @@ -30,50 +30,6 @@ NSGA-II with standard settings algorithm.run() result = algorithm.get_result() -NSGA-II with observer ------------------------------------- - -.. code-block:: python - - from jmetal.component.observer import WriteFrontToFileObserver - - algorithm = NSGAII[FloatSolution, List[FloatSolution]]( - problem, - population_size=100, - max_evaluations=25000, - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator()) - ) - - observer = WriteFrontToFileObserver("output_directory") - algorithm.observable.register(observer=observer) - - algorithm.run() - result = algorithm.get_result() - -NSGA-II with plot in real-time ------------------------------------- - -.. code-block:: python - - from jmetal.component.observer import AlgorithmObserver - - algorithm = NSGAII[FloatSolution, List[FloatSolution]]( - problem, - population_size=100, - max_evaluations=25000, - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator()) - ) - - observer = AlgorithmObserver(animation_speed=1*10e-8) - algorithm.observable.register(observer=observer) - - algorithm.run() - result = algorithm.get_result() - NSGA-II stopping by time ------------------------------------ @@ -105,4 +61,4 @@ NSGA-II stopping by time ) algorithm.run() - result = algorithm.get_result() \ No newline at end of file + result = algorithm.get_result() diff --git a/docs/source/runner/observer.rst b/docs/source/runner/observer.rst new file mode 100644 index 00000000..74b22490 --- /dev/null +++ b/docs/source/runner/observer.rst @@ -0,0 +1,31 @@ +Observers +======================== + +It is possible to attach any number of observers to a jMetalPy's algorithm to retrieve information from each iteration. +For example, a basic algorithm observer will print the number of evaluations, the objectives from the best individual in the population and the computing time: + + +.. code-block:: python + + observer = BasicAlgorithmObserver(frequency=1.0) + algorithm.observable.register(observer=observer) + +Write Front To File +------------------------------------ + +This observer will save each generation of individuals in files: + +.. code-block:: python + + observer = WriteFrontToFileObserver(output_directory="FUN") + algorithm.observable.register(observer=observer) + +Visualization +------------------------------------ + +This observer will plot in real-time the Pareto frontier (with a reference front, if any) in 2D or 3D depending on the number of objectives. + +.. code-block:: python + + observer = VisualizerObserver(frequency=1.0) + algorithm.observable.register(observer=observer) \ No newline at end of file From 7680638e84880c38441f556a428fd64d6aaab362 Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 31 May 2018 13:18:57 +0200 Subject: [PATCH 54/90] Fix import --- docs/source/conf.py | 3 ++- docs/source/jmetalpy.png | Bin 0 -> 5831 bytes 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 docs/source/jmetalpy.png diff --git a/docs/source/conf.py b/docs/source/conf.py index 39b58d0c..9509e34c 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -19,7 +19,7 @@ # http://blog.rtwilson.com/how-to-make-your-sphinx-documentation-compile-with-readthedocs-when-youre-using-numpy-and-scipy/ import mock -MOCK_MODULES = ['numpy', 'dask', 'dask.distributed', 'mpl_toolkits', 'matplotlib', 'matplotlib.pyplot', 'matplotlib.axes'] +MOCK_MODULES = ['numpy', 'dask', 'dask.distributed', 'mpl_toolkits', 'mpl_toolkits.mplot3d', 'matplotlib', 'matplotlib.pyplot', 'matplotlib.axes'] for mod_name in MOCK_MODULES: sys.modules[mod_name] = mock.Mock() @@ -82,6 +82,7 @@ # a list of builtin themes. # html_theme = 'sphinx_rtd_theme' +html_logo = 'jmetalpy.png' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the diff --git a/docs/source/jmetalpy.png b/docs/source/jmetalpy.png new file mode 100644 index 0000000000000000000000000000000000000000..a41ad1e1540faa39e0d44ce99e430a3e86121480 GIT binary patch literal 5831 zcmX|F2Q<~;`@bSH2}QD31J@pzQ3xSryTo;`eZQ`ZYwuC^D0??9GP3U14hh+cxO|Ol z;Ucn2fBpWy^Lx*E_j^8{^StkQKF@RBXaoKG^t9J#VK5lIwwC(ivz~NTZ&Fj9wM>qI z&tWjK2Tn$2o@RQw3MecfibP{=?L>V5x3hg1OzDn~8xrMW=gDJh=iub3%(vCl%E#k` zR^~I6(G%BmyJzRF4aa(8m`bi%sw{KG`rV!b?-`S`^C zk%;}5<;*;>|Jipo`QHuMxt?8%`ME(hr?mH`K4y?*y zn=mHoNhTVaHO)_s&B5)`G-P+3#mMg7wT(}@#7D%5kui}CokXbm_4x1!Ff|9mEQYvY zLvY5VIU1f^+_o96`+y_NAN#G`eM0mgkuCA|Yelb8OJh=F1vYT#V9EpAW4(P}sXF(Z zVFAO1kS6%aKuB!;7IE$p$9d%lu7t2Kt^}@xhpU~9Jhv%&Ee`LS_tix`EC%ywbty#8 zcU2{X`$Sb=IR6C1+?bt3Qpa@MRA+pYbM-veiuB8mhPONA6W7b14!*Y>VxV1NtypQ^DCRH>qn8J>C+_1)1X+h*?ojJfmfV&N-kEED&SjF!vS~G>Eagt*O+M` zX$SY_i63E4?s9*yc}Ct@Yt)uVdl-36C4T8eB}c&HZPJbNr4Hv`KcvME%{vTL@9gGp zo}RY;Odl_bM9oJCGd}sdZYoFay(K*3YWV%U8`nA@`}`z_Y`m?F`fu%T>o4`vV~5oj zE%Lg0gQay&we4ijRfI5q?{>nLa|a@~tL;vrB7v~ZFdBQtt}55H;WF1{{r;xR%#P*` z-Rt(7N@Ehj23|;OxVYD$o279x-AM+yuqsM|HJxc~j69HKpN92mq~uI}alizwkc6ZC z?SbiAX{+B&CgI4M<5sfoY+L%1CjWHYtbJy1g*AON`0)6ct@qpH;l3hjGc}g*(W1Tk z6;ghO)@9)nyI9N9Ir=QS{7eax1)x0X_Onc5jPOOqXJ(9>FbOx6 zsps?S7-8CF)~nu*&6i#~C;WSYY+2{Be1nF*ZY=Hdh;<{fTYSs<0x`JWG^y>9T zb?;phC~IN-9r!RfIYb-fQVHBlX%`N?ZvBk@(#7_?XCNysw6b&gsCW5D&{b+Q;x1nZ zJSe!PElJcPIhRt-;yhz}|8xn92cyOSuX9E{Z0$M}qroF=f01x58rDq_!038gcwVgB zW~gl@)F}WxGFUlHrpTk@m@PYxA_IN|n*EjlEWc*nB4+K(rRkV)^Io`w$Ig`%ZMUc* z`~5V7fvGE$8nC5G@gNgNA5ovV*t;3N$S3NF0olGNkuGx@vxR+!U@xgCocoah?yl#H zIu}G@qU#RXTgyg;6VbPM`~=rNWTWKjs)I=kuO)FToLj;H+qt2p`eVJt zg#hc5hUiJzAH)(leQ&2p>!TOz54fjotsA;JejQ1KvV3nqrZ*AFU-?`d2AOr@(d-B7 zftY*{PL`vZ^$Xxiipc`Mf?=91jSnC{_%Ytq)uLJ4WA_s%1FTDJTYLqF_}uK8@<@2# zB!b7b+O$mwF-y6+P%UYe&gD$y0x8Dz)m0v=&H0DJCvh9`kS>&0BB?(KI<@}l9xtLC zp|tt?YxeIkJ`T@K=eWxq$Taa(7&6&w!6?F-dR5Hd26Fd;11HBeAOQy&zsSY7tR36C zGbJj^Sr2Cdebq~^97UjZMNC;D&9rxqsIQso+Mf&>1~fuE?Pg6JFf=BSHT7J8p{2T) zxE~AXvS%Ku6DUaQe-E>>wLc71h2V0&4P9XWHi4`0L_~#9iW5~+d-RtTLJkhk_H_l+AJ|h-1mwR zSlN#a_6cUBIP<9(PqPU2h#5&&var z$S~Pk`9DzBFT0f`po=Bm-MS0zWK;G~;;e?OuLx*$NyY^You&mr(WWX0cDb3W*R8V4 z4#U?!)DhvA&CODO?qIQL1Mh=G3L?800OA{VD5`}W15s(3v$yi1!fRI^RhMHO5TrKH z1cf-bj8W`g!xlGn%0qdKeEr=nG?fevkf6yvbR7gF0b2C|W42QFxzxIMB7av7DyU%B zj-NhENibf@{(GuD4cEu%7FfZo9oC2F*=Jq=MNzqE?^%PYrU8x;6VU4FlqOHmsT-IY z2TTWn@fw6daCtfuv(A+bh*4)g?7_!B$bX!ucR}7>iYpd4aZ*Mhz)HA8ic$>5Z#jPA zpfy-|ziT%RiI|>8cT-qUPlCVa_@O+mVnD3NRWuxn;fGg*Vd~e25a6lO9Y%8$RT#?6X|QcNArho6ebd+psse>x1becxW(vTGC~-dVe9952!WO5 zG7}~`+a_%<%NXi%fk3Xx9Sz@#`}R;0jnRbgBo&o(Xh8EM7+|BE0f_DH5vn%Yz}H^X zlE5OL|H8MSU_U8npD=f*N~d-sRqa+sMH^+)1c(`sAZk#v z-I*`A?!Blc36jW)@$eF=%g-1bzZMa4?6!u$qMPaF0=|1J%bc~OT%mhFhH?>3@0frA}TB<1yeZ*-cgTsnXsHypko~ zv+-FwuOP>6U8=TUd)Y9O5RtMZuy8N4oOAZ}f<~{#epjX3^d`#~Eks>;n^@As&W2t)Ia7X}`*P{0@} zGaNXsVVjHC@K5t=>QxqRsy*N=rYXpl@2LXfL~a~iM#gOO^=UuhjY}>7YI4wi$;dNW z15*~E=IwKlZAE{5q_%dxC4N!Xm%Z*O46`8;D^=b~mODYouU4+z;a4wYO{KGJWj_;t zp130A*&?K(GsK)Urve}vT0WWpE}85(@kP_4V2Ts;QZTg^7<*RQ(tl;D5Qs;1H42w8 z!-~xRoG+x?tk>-!vWT~&JGAZC`RE;7Z~L` z-413|0q(K<&~e)bAyE{9rlR_Im5cR+2qwCvDks}(6;0g2tBc*5e2${i$&4MhtR~g5 zK{J#L9h(OD+fB|$D1c&E_@%ZA-zp4*TP;`MHVSf?A1~R4HMWRjcvh9@Awy5TRqeCD za*@;Blx)bNz0nHNF^`ok-muW zKhDXQAH4xRf|$A?9EidtzKDMwSoftQ*S_Ls+c0Y;7znJE{h(aAgz-QL%PIIOP}P2C z>ErLAsYT-Gitncw*51a8EhjH7o`RYwrJK3V;%bvD=^qqK**N!ZsixwKerSL|yueC9 zV0_i>0w=urpTnKxc->Z4^%T<#cBE@egYg4_Bl<4Ajn}#0{;b7{NQr)p*&=R3mu{{^ znKFpOgw$VIRls}?f9BP8he$N!?p}vZWwx9k!$8E=GY5?`Mk_1}q+{5xrlwf&LutC% zHRXLolbSQtA&!xd2yU!uxeF8nh%pXU7fsb-vRpBW{GS8{=Z}+6*Ld=$7GeObB$!)R z{XBV*?4unTlIMHy3GUtR`V|CwSdmNE_wH>1`Scpg7S61;*4a9<(+qPe@W2-a{DSGDVTVvv8g2s0eJ|Y*;i)X z!`EpX7FnyFBE{OYtVsoyH~FS~b4gxQ>Dt|Rg=c5|Rw0!o3zQ`uaQ*xs;+-hR-;-Jz z&?-`*09n*&xtl&H;B@~z644(`PWvt)heD4Nw9}CZouKS$Y+(R|_cGZLnx~GVB{Vr+ z0DB$jD`*lST95;H0Hyu}V6fW89QKYBT|2!=eJimi!676-uNC_ZoZ^45HZuv9?oo#X zYE$oDSiPg{;DPs^Ore@71iS0{K&&x?+L()VGUb>LeH z41kOM1o}o9l>j3JApy8<%(j|`xSAehLQbo5Fepa=urK3be)m2Xkxq&E)Al=zH>D)zET;Z%R5n&=d(IT0&!*e~r{`4$Ry%NGR7UGk1mp zUOv2_^R|w0anj@k2w$57Im`?~8t6uI(7>5!A!yATIzzvtV>Ki%!bGsGR%`_I&qC3Cx=p`J>?#Mebdr(#`Pnu9~ z{k=8c7@PE=6(mi{Hw-j7Bl;unC({Zsc{$&M-gWW@Tx`7$Me!IVlPO|KYs<-n^&d6$ z){=yEw%Y=%tKlLlNnp!5TR1`DkQ6+j zysccv6>5wviF!rfaK~|Xg5K2^%lQMq2(u@nPl}1MRU1Jdd_o3=kYNooP^l{4L_)U2 z=K>GO`;I?18p+vQ9Gk{uBeJR_rXBcIcpQ0Q>Gz^LL%hoVZr`-#_vOunPn(WlAdgMf zq&35Q-_w@(Ld=i4ftaB+h7qud!qRlT0x0DfH3708Dvk_;#-i2ezy^)C0Q@X08q8^) z>2!FbuS|~Ecp&_(|44wPlq^>XA(UnFfC7{Ey5aPbNqcFQl+d?v^J$BOce9aAd_BOy zMqx5~V9<;#;~Hcemb%s81?L%j-9Hf|c=Ih+{o`k1Ql&9#MDekGCJ%=*@wJR^h}S@f zIwQg{b!^>Nla4=&gzhJZ8>&}ZiAA{9+}isg)4Hs@lCfzIHFJCf)BgA?f#s)Te~4gO zZ+$yh{Q?M7gf5oS%*I@?=zllbrL>exdW#r&gN{WX!H(pO_l;Hx`v2bVvm1}V;HmEp z+YD}s<^)aMU=VMf3t!4GX$#~4rhwJB^w~x&o1+a+>Z)t!i|~FX?=0 z*NlWKx1OLHsb91?Q9MN>qLa~qrdz#^u>xCLlv$7StDdUXui!^p!24BVd#+K5 zfinztzyUGr`~C;#BTROno|fJ^Em84Z$R|<-Cj-GU6m*2%7M8C5o;gPkxR_Z=AJ#6b5fkaq7pZENkO= zCwjpLC}o2wv*9@w(5h=oHZ%p0V-n+P0||9Er^11BysY>Ql$2cUB3E|G5I-RiFcv{S zHkXj7`B0LbSzn^HQ55J0k_?rbH;bQi?_93fSS_7dhE`NePVT68C$jzYeR=rr|5;l@ LU%le4P1yedxE53B literal 0 HcmV?d00001 From 00b3661cabc882ad1b6f557e739105ab0b327dcd Mon Sep 17 00:00:00 2001 From: ajnebro Date: Tue, 5 Jun 2018 09:59:23 +0200 Subject: [PATCH 55/90] Updating runners --- jmetal/runner/multiobjective/smpso_standard_settings.py | 2 +- .../smpso_standard_settings_with_reference_point.py | 2 +- jmetal/runner/multiobjective/smpsorp_standard_settings.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/jmetal/runner/multiobjective/smpso_standard_settings.py b/jmetal/runner/multiobjective/smpso_standard_settings.py index de3508de..80266a49 100644 --- a/jmetal/runner/multiobjective/smpso_standard_settings.py +++ b/jmetal/runner/multiobjective/smpso_standard_settings.py @@ -22,7 +22,7 @@ def main() -> None: leaders=CrowdingDistanceArchive(100) ) - observer = VisualizerObserver(animation_speed=1 * 10e-8) + observer = VisualizerObserver() algorithm.observable.register(observer=observer) algorithm.run() diff --git a/jmetal/runner/multiobjective/smpso_standard_settings_with_reference_point.py b/jmetal/runner/multiobjective/smpso_standard_settings_with_reference_point.py index d28705b0..90830e77 100644 --- a/jmetal/runner/multiobjective/smpso_standard_settings_with_reference_point.py +++ b/jmetal/runner/multiobjective/smpso_standard_settings_with_reference_point.py @@ -22,7 +22,7 @@ def main() -> None: leaders=CrowdingDistanceArchiveWithReferencePoint(100, reference_point=[1.0, 1.0]) ) - observer = VisualizerObserver(animation_speed=1 * 10e-8) + observer = VisualizerObserver() algorithm.observable.register(observer=observer) algorithm.run() diff --git a/jmetal/runner/multiobjective/smpsorp_standard_settings.py b/jmetal/runner/multiobjective/smpsorp_standard_settings.py index ed53785c..9a109739 100644 --- a/jmetal/runner/multiobjective/smpsorp_standard_settings.py +++ b/jmetal/runner/multiobjective/smpsorp_standard_settings.py @@ -16,7 +16,7 @@ def main() -> None: problem = ZDT1() swarm_size = 100 - reference_points = [[0.8, 0.2], [0.4, 0.6]] + reference_points = [[0.0, 0.0]] archives_with_reference_points = [] for point in reference_points: @@ -33,7 +33,7 @@ def main() -> None: leaders=archives_with_reference_points ) - observer = VisualizerObserver(animation_speed=1 * 10e-8) + observer = VisualizerObserver() algorithm.observable.register(observer=observer) algorithm.run() From 5d08503d8c48978d8fa03872abc73e293c4a0e7a Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 12 Jun 2018 14:12:40 +0200 Subject: [PATCH 56/90] Deleted unused files --- CHANGELOG.md | 66 ------------------- TODO.md | 6 -- ...gaII_standard_settings_plot_interactive.py | 37 ----------- ...I_standard_settings_with_observer_basic.py | 40 ----------- .../nsgaii_standard_settings_with_observer.py | 40 ----------- ...rd_settings_with_observer_plot_realtime.py | 37 ----------- .../multiobjective/nsgaii_stopping_by_time.py | 49 -------------- ..._standard_settings_with_reference_point.py | 38 ----------- jmetal/util/{front_utils.py => front_file.py} | 0 9 files changed, 313 deletions(-) delete mode 100644 CHANGELOG.md delete mode 100644 TODO.md delete mode 100644 jmetal/runner/multiobjective/nsgaII_standard_settings_plot_interactive.py delete mode 100644 jmetal/runner/multiobjective/nsgaII_standard_settings_with_observer_basic.py delete mode 100644 jmetal/runner/multiobjective/nsgaii_standard_settings_with_observer.py delete mode 100644 jmetal/runner/multiobjective/nsgaii_standard_settings_with_observer_plot_realtime.py delete mode 100644 jmetal/runner/multiobjective/nsgaii_stopping_by_time.py delete mode 100644 jmetal/runner/multiobjective/smpso_standard_settings_with_reference_point.py rename jmetal/util/{front_utils.py => front_file.py} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 66125f47..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,66 +0,0 @@ -# History -## Last changes (April 26th 2018) -* Added [SMPSO](jmetal/algorithm/multiobjective/smpso.py). - -## Last changes (July 21th 2017) -* Added guide for using [cProfile](resources/pages/profiling.md). -* Starting to implement [SMPSO](jmetal/algorithm/multiobjective/smpso.py). -* Added [comparators](jmetal/util/comparator.py). - -## Last changes (July 12th 2017) -* The time of execution and evaluation number now are shown in the live plot. -* Several fixes regarding wrong imports and unused attributes. - -## Last changes (July 11th 2017) -* Now It's possible to get to directly access the coords (x,y) of a point in a live plot by a mouse click. ~~Note: This still needs some changes in order to work properly.~~ - -## Last changes (July 9th 2017) -* New class for [graphics](jmetal/util/graphic.py). -* New [observer](jmetal/component/observer.py) for graphical display of algorithm. -* Added [CHANGELOG](CHANGELOG.md) file. - -## Last changes (July 7th 2017) -* New methods for plotting the solution list (`plot_scatter` and `plot_scatter_real_time`). -* New decorator for computing execution time of any method. Usage: [`from jmetal.util.time import get_time_of_exectuion`](jmetal/util/time.py) and add `@get_time_of_execution` before any method or function. -* Several improvements regarding [PEP8](resources/pages/code_style.md) code style guide. -* Updated [TODO.md](TODO.md) and added [CONTRIBUTING.cmd](CONTRIBUTING.md) file. -* Updated requirements. - -## Last changes (July 4th 2017) -* The algorithm [NSGA-II](jmetal/algorithm/multiobjective/nsgaii.py) has been implemented -* Examples of configuring and running all the included algorithms are located in the [jmetal.runner](https://github.com/jMetal/jMetalPy/tree/master/jmetal/runner) package. - -## Last changes (June 1st 2017) -* The package organization has been simplified to make it more "Python-ish". The former oarganization was a clone of the original Java-based jMetal project. -* The [`EvolutionaryAlgorithm`](jmetal/core/algorithm.py) class interits from `threading.Thread`, so any evolutionary algorithm can run as a thread. This class also contains an `Observable` field, allowing observer entities to register to be notified with algorithm information. -* [Four examples](jmetal/runner) of configuring and running three different single-objective algorithms are provided. - -## Current status (as for July 4th 2017) -The current implementation contains the following features: -* Algorithms - * Multi-objective - * NSGA-II - * Single-objective - * (mu+lamba)Evolution Strategy - * (mu,lamba)Evolution Strategy - * Generational Genetic algorithm -* Problems (multi-objective) - * Kursawe - * Fonseca - * Schaffer - * Viennet2 -* Problems (single-objective) - * Sphere - * OneMax -* Encoding - * Float - * Binary -* Operators - * SBX Crossover - * Single Point Crossover - * Polynomial Mutation - * Bit Flip Mutation - * Simple Random Mutation - * Null Mutation - * Uniform Mutation - * Binary Tournament Selection \ No newline at end of file diff --git a/TODO.md b/TODO.md deleted file mode 100644 index a8c22c90..00000000 --- a/TODO.md +++ /dev/null @@ -1,6 +0,0 @@ -# ToDo list - -- [ ] Add _experiment_ class with options to export results in LaTeX. -- [ ] Support parallelism (see: [Dask](https://dask.pydata.org/en/latest/)). -- [ ] Auto-generate documentation (also: the documentation of the code is not complete!) -- [ ] Add _state-of-the-art_ visualization methods. \ No newline at end of file diff --git a/jmetal/runner/multiobjective/nsgaII_standard_settings_plot_interactive.py b/jmetal/runner/multiobjective/nsgaII_standard_settings_plot_interactive.py deleted file mode 100644 index 0c12a30a..00000000 --- a/jmetal/runner/multiobjective/nsgaII_standard_settings_plot_interactive.py +++ /dev/null @@ -1,37 +0,0 @@ -import logging -from typing import List - -from jmetal.algorithm.multiobjective.nsgaii import NSGAII -from jmetal.core.solution import FloatSolution -from jmetal.operator.crossover import SBX -from jmetal.operator.mutation import Polynomial -from jmetal.operator.selection import BinaryTournamentSelection -from jmetal.problem.multiobjective.unconstrained import Kursawe -from jmetal.util.solution_list_output import SolutionListOutput - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - - -def main() -> None: - problem = Kursawe() - algorithm = NSGAII[FloatSolution, List[FloatSolution]]( - problem, - population_size=100, - max_evaluations=25000, - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection()) - - algorithm.run() - result = algorithm.get_result() - - SolutionListOutput[FloatSolution].plot_frontier_to_file(result, file_name="FUN." + problem.get_name(), - output_format='eps', dpi=200) - SolutionListOutput[FloatSolution].plot_frontier_to_screen(result) - - logger.info("Algorithm (continuous problem): " + algorithm.get_name()) - logger.info("Problem: " + problem.get_name()) - -if __name__ == '__main__': - main() diff --git a/jmetal/runner/multiobjective/nsgaII_standard_settings_with_observer_basic.py b/jmetal/runner/multiobjective/nsgaII_standard_settings_with_observer_basic.py deleted file mode 100644 index c40c99bb..00000000 --- a/jmetal/runner/multiobjective/nsgaII_standard_settings_with_observer_basic.py +++ /dev/null @@ -1,40 +0,0 @@ -import logging -from typing import List - -from jmetal.algorithm.multiobjective.nsgaii import NSGAII -from jmetal.component.observer import BasicAlgorithmObserver -from jmetal.core.solution import FloatSolution -from jmetal.operator.crossover import SBX -from jmetal.operator.mutation import Polynomial -from jmetal.operator.selection import BinaryTournamentSelection -from jmetal.problem.multiobjective.zdt import ZDT1 -from jmetal.util.solution_list_output import SolutionListOutput - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - - -def main() -> None: - problem = ZDT1() - algorithm = NSGAII[FloatSolution, List[FloatSolution]]( - problem, - population_size=100, - max_evaluations=25000, - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection()) - - observer = BasicAlgorithmObserver(1000) - algorithm.observable.register(observer=observer) - - algorithm.run() - result = algorithm.get_result() - - SolutionListOutput[FloatSolution].print_function_values_to_file("FUN."+problem.get_name(), result) - - logger.info("Algorithm (continuous problem): " + algorithm.get_name()) - logger.info("Problem: " + problem.get_name()) - logger.info("Computing time: " + str(algorithm.total_computing_time)) - -if __name__ == '__main__': - main() diff --git a/jmetal/runner/multiobjective/nsgaii_standard_settings_with_observer.py b/jmetal/runner/multiobjective/nsgaii_standard_settings_with_observer.py deleted file mode 100644 index 9f7e2116..00000000 --- a/jmetal/runner/multiobjective/nsgaii_standard_settings_with_observer.py +++ /dev/null @@ -1,40 +0,0 @@ -import logging -from typing import List - -from jmetal.algorithm.multiobjective.nsgaii import NSGAII -from jmetal.component.observer import WriteFrontToFileObserver -from jmetal.core.solution import FloatSolution -from jmetal.operator.crossover import SBX -from jmetal.operator.mutation import Polynomial -from jmetal.operator.selection import BinaryTournamentSelection -from jmetal.problem.multiobjective.unconstrained import Kursawe -from jmetal.util.comparator import RankingAndCrowdingDistanceComparator -from jmetal.util.solution_list_output import SolutionListOutput - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - - -def main() -> None: - problem = Kursawe() - algorithm = NSGAII[FloatSolution, List[FloatSolution]]( - problem, - population_size=100, - max_evaluations=25000, - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) - - observer = WriteFrontToFileObserver("output_directory") - algorithm.observable.register(observer=observer) - - algorithm.run() - result = algorithm.get_result() - - SolutionListOutput[FloatSolution].print_function_values_to_file("FUN."+problem.get_name(), result) - - logger.info("Algorithm (continuous problem): " + algorithm.get_name()) - logger.info("Problem: " + problem.get_name()) - -if __name__ == '__main__': - main() diff --git a/jmetal/runner/multiobjective/nsgaii_standard_settings_with_observer_plot_realtime.py b/jmetal/runner/multiobjective/nsgaii_standard_settings_with_observer_plot_realtime.py deleted file mode 100644 index 87d7a102..00000000 --- a/jmetal/runner/multiobjective/nsgaii_standard_settings_with_observer_plot_realtime.py +++ /dev/null @@ -1,37 +0,0 @@ -import logging -from typing import List - -from jmetal.algorithm.multiobjective.nsgaii import NSGAII -from jmetal.component.observer import VisualizerObserver -from jmetal.core.solution import FloatSolution -from jmetal.operator.crossover import SBX -from jmetal.operator.mutation import Polynomial -from jmetal.operator.selection import BinaryTournament2Selection -from jmetal.problem.multiobjective.zdt import ZDT1, ZDT4 -from jmetal.util.comparator import SolutionAttributeComparator - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - - -def main() -> None: - problem = ZDT1() - algorithm = NSGAII[FloatSolution, List[FloatSolution]]( - problem, - population_size=100, - max_evaluations=25000, - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournament2Selection([SolutionAttributeComparator("dominance_ranking"), - SolutionAttributeComparator("crowding_distance", lowest_is_best=False)])) - - observer = VisualizerObserver(animation_speed=1 * 10e-8) - algorithm.observable.register(observer=observer) - - algorithm.run() - - logger.info("Algorithm (continuous problem): " + algorithm.get_name()) - logger.info("Problem: " + problem.get_name()) - -if __name__ == '__main__': - main() diff --git a/jmetal/runner/multiobjective/nsgaii_stopping_by_time.py b/jmetal/runner/multiobjective/nsgaii_stopping_by_time.py deleted file mode 100644 index 3070201e..00000000 --- a/jmetal/runner/multiobjective/nsgaii_stopping_by_time.py +++ /dev/null @@ -1,49 +0,0 @@ -import logging -from typing import List, TypeVar - -from jmetal.algorithm.multiobjective.nsgaii import NSGAII -from jmetal.core.solution import FloatSolution -from jmetal.operator.crossover import SBX -from jmetal.operator.mutation import Polynomial -from jmetal.operator.selection import BinaryTournamentSelection -from jmetal.problem.multiobjective.unconstrained import Fonseca -from jmetal.util.comparator import RankingAndCrowdingDistanceComparator -from jmetal.util.solution_list_output import SolutionListOutput - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - -S = TypeVar('S') -R = TypeVar(List[S]) - - -def main() -> None: - class NSGA2b(NSGAII[S, R]): - def is_stopping_condition_reached(self): - # Re-define the stopping condition - reached = [False, True][self.get_current_computing_time() > 4] - - if reached: - logger.info("Stopping condition reached!") - - return reached - - problem = Fonseca() - algorithm = NSGA2b[FloatSolution, List[FloatSolution]]( - problem, - population_size=100, - max_evaluations=25000, - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) - - algorithm.run() - result = algorithm.get_result() - - SolutionListOutput[FloatSolution].print_function_values_to_file("FUN."+problem.get_name(), result) - - logger.info("Algorithm (continuous problem): " + algorithm.get_name()) - logger.info("Problem: " + problem.get_name()) - -if __name__ == '__main__': - main() diff --git a/jmetal/runner/multiobjective/smpso_standard_settings_with_reference_point.py b/jmetal/runner/multiobjective/smpso_standard_settings_with_reference_point.py deleted file mode 100644 index d28705b0..00000000 --- a/jmetal/runner/multiobjective/smpso_standard_settings_with_reference_point.py +++ /dev/null @@ -1,38 +0,0 @@ -import logging - -from jmetal.algorithm.multiobjective.smpso import SMPSO -from jmetal.component.archive import CrowdingDistanceArchiveWithReferencePoint -from jmetal.component.observer import VisualizerObserver -from jmetal.core.solution import FloatSolution -from jmetal.operator.mutation import Polynomial -from jmetal.problem.multiobjective.zdt import ZDT1 -from jmetal.util.solution_list_output import SolutionListOutput - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - - -def main() -> None: - problem = ZDT1() - algorithm = SMPSO( - problem=problem, - swarm_size=100, - max_evaluations=25000, - mutation=Polynomial(probability=1.0/problem.number_of_variables, distribution_index=20), - leaders=CrowdingDistanceArchiveWithReferencePoint(100, reference_point=[1.0, 1.0]) - ) - - observer = VisualizerObserver(animation_speed=1 * 10e-8) - algorithm.observable.register(observer=observer) - - algorithm.run() - result = algorithm.get_result() - - SolutionListOutput[FloatSolution].plot_frontier_to_screen(result) - - logger.info("Algorithm (continuous problem): " + algorithm.get_name()) - logger.info("Problem: " + problem.get_name()) - - -if __name__ == '__main__': - main() diff --git a/jmetal/util/front_utils.py b/jmetal/util/front_file.py similarity index 100% rename from jmetal/util/front_utils.py rename to jmetal/util/front_file.py From 340bae9f6a0b3f1dcc9e5b8da9529aba6d94c801 Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 12 Jun 2018 14:12:50 +0200 Subject: [PATCH 57/90] Added LICENSE --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/LICENSE b/LICENSE index e69de29b..600736db 100644 --- a/LICENSE +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Antonio J. Nebro + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 649a28fcce567f69f34decfe31e1287f6495fcba Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 12 Jun 2018 14:13:44 +0200 Subject: [PATCH 58/90] Added logging mechanism --- docs/source/about.rst | 2 +- docs/source/examples.rst | 8 ++++- docs/source/runner/logger.rst | 15 ++++++++ jmetal/component/density_estimator.py | 7 ++-- jmetal/component/evaluator.py | 1 + jmetal/component/observer.py | 13 ++++--- jmetal/core/algorithm.py | 1 - jmetal/core/operator.py | 23 ++++++------ jmetal/core/problem.py | 5 ++- .../nsgaii_standard_settings.py | 32 ++++++++--------- .../multiobjective/smpso_standard_settings.py | 26 +++++++++----- .../smpsorp_standard_settings.py | 22 +++++++----- jmetal/util/graphic.py | 1 - jmetal/util/solution_list_output.py | 1 - jmetal/util/time.py | 3 +- setup.py | 35 ++++++++++--------- 16 files changed, 113 insertions(+), 82 deletions(-) create mode 100644 docs/source/runner/logger.rst diff --git a/docs/source/about.rst b/docs/source/about.rst index f98ea0d2..50c6671a 100644 --- a/docs/source/about.rst +++ b/docs/source/about.rst @@ -1,7 +1,7 @@ About ============== -jMetalPy is being developed by `Antonio J. Nebro `_, associate professor at the University of Málaga, and Antonio Benítez-Hidalgo. +jMetalPy is being developed by `Antonio J. Nebro `_, associate professor at the University of Málaga, and `Antonio Benítez-Hidalgo `_. References -------------------------------- diff --git a/docs/source/examples.rst b/docs/source/examples.rst index e4fdb9ae..4c2503c4 100644 --- a/docs/source/examples.rst +++ b/docs/source/examples.rst @@ -8,4 +8,10 @@ Examples runner/nsgaii runner/smpso - runner/observer \ No newline at end of file + +.. toctree:: + :maxdepth: 2 + :caption: Further configuration: + + runner/observer + runner/logger diff --git a/docs/source/runner/logger.rst b/docs/source/runner/logger.rst new file mode 100644 index 00000000..856b31b9 --- /dev/null +++ b/docs/source/runner/logger.rst @@ -0,0 +1,15 @@ +Set up logger +======================== + +jMetalPy support the default Python's logging mechanism. This code will record logging events in a file and print them on console: + +.. code-block:: python + + logging.basicConfig( + level=logging.INFO, + format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s", + handlers=[ + logging.FileHandler('jmetalpy.log'), + logging.StreamHandler() + ] + ) \ No newline at end of file diff --git a/jmetal/component/density_estimator.py b/jmetal/component/density_estimator.py index b8e842fc..57cb4fe0 100644 --- a/jmetal/component/density_estimator.py +++ b/jmetal/component/density_estimator.py @@ -1,6 +1,8 @@ import logging from typing import TypeVar, List +logger = logging.getLogger(__name__) + S = TypeVar('S') """ @@ -11,9 +13,6 @@ .. moduleauthor:: Álvaro Gómez Jáuregui """ -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - class DensityEstimator(List[S]): """This is the interface of any density estimator algorithm. @@ -67,7 +66,7 @@ def compute_density_estimator(self, solution_list: List[S]): # Check if minimum and maximum are the same (in which case do nothing) if objective_maxn - objective_minn == 0: - logger.info("Minimum and maximum are the same!") + logger.warning("Minimum and maximum are the same!") else: distance = distance / (objective_maxn - objective_minn) diff --git a/jmetal/component/evaluator.py b/jmetal/component/evaluator.py index c11073cb..0f4aba83 100644 --- a/jmetal/component/evaluator.py +++ b/jmetal/component/evaluator.py @@ -1,5 +1,6 @@ from multiprocessing.pool import ThreadPool from typing import TypeVar, List, Generic + from dask.distributed import Client, as_completed from jmetal.core.problem import Problem diff --git a/jmetal/component/observer.py b/jmetal/component/observer.py index 5bdf3450..8113a1d3 100644 --- a/jmetal/component/observer.py +++ b/jmetal/component/observer.py @@ -4,7 +4,6 @@ from jmetal.util.observable import Observer from jmetal.util.solution_list_output import SolutionListOutput -logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @@ -16,9 +15,9 @@ def update(self, *args, **kwargs): evaluations = kwargs["evaluations"] if (evaluations % self.display_frequency) == 0: - logger.info("Evaluations: " + str(evaluations) + - ". Best fitness: " + str(kwargs["population"][0].objectives) + - ". Computing time: " + str(kwargs["computing time"])) + logger.debug("Evaluations: " + str(evaluations) + + ". Best fitness: " + str(kwargs["population"][0].objectives) + + ". Computing time: " + str(kwargs["computing time"])) class WriteFrontToFileObserver(Observer): @@ -27,16 +26,16 @@ def __init__(self, output_directory) -> None: self.directory = output_directory if os.path.isdir(self.directory): - logger.info("Directory " + self.directory + " exists. Removing contents.") + logger.warning("Directory " + self.directory + " exists. Removing contents.") for file in os.listdir(self.directory): os.remove(self.directory + "/" + file) else: - logger.info("Directory " + self.directory + " does not exist. Creating it.") + logger.warning("Directory " + self.directory + " does not exist. Creating it.") os.mkdir(self.directory) def update(self, *args, **kwargs): SolutionListOutput.print_function_values_to_file( - self.directory + "/FUN." + str(self.counter), kwargs["population"]) + kwargs["population"], self.directory + "/FUN." + str(self.counter)) self.counter += 1 diff --git a/jmetal/core/algorithm.py b/jmetal/core/algorithm.py index 5f939e66..d7cf311d 100644 --- a/jmetal/core/algorithm.py +++ b/jmetal/core/algorithm.py @@ -6,7 +6,6 @@ from jmetal.component.evaluator import Evaluator, SequentialEvaluator from jmetal.core.solution import FloatSolution -logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) S = TypeVar('S') diff --git a/jmetal/core/operator.py b/jmetal/core/operator.py index e80fc945..c258f60f 100644 --- a/jmetal/core/operator.py +++ b/jmetal/core/operator.py @@ -2,21 +2,21 @@ __author__ = "Antonio J. Nebro" -Source = TypeVar('S') -Result = TypeVar('R') +S = TypeVar('S') +R = TypeVar('R') -class Operator(Generic[Source, Result]): +class Operator(Generic[S, R]): """ Class representing operators """ - def execute(self, source: Source) -> Result: + def execute(self, source: S) -> R: pass def get_name(self): pass -class Mutation(Operator[Source, Source]): +class Mutation(Operator[S, S]): """ Class representing mutation operators """ def __init__(self, probability: float): @@ -27,11 +27,11 @@ def __init__(self, probability: float): self.probability = probability - def execute(self, source: Source) -> Source: + def execute(self, source: S) -> S: pass -class Crossover(Operator[List[Source], List[Result]]): +class Crossover(Operator[List[S], List[R]]): def __init__(self, probability: float): if probability > 1.0: raise Exception("The probability is greater than one: " + str(probability)) @@ -40,13 +40,16 @@ def __init__(self, probability: float): self.probability = probability - def execute(self, source: Source) -> Result: + def execute(self, source: S) -> R: pass def get_number_of_parents(self) -> int: pass -class Selection(Operator[Source, Result]): - def execute(self, source: Source) -> Result: +class Selection(Operator[S, R]): + def __init__(self): + pass + + def execute(self, source: S) -> R: pass diff --git a/jmetal/core/problem.py b/jmetal/core/problem.py index 30f1b31f..4a155d95 100644 --- a/jmetal/core/problem.py +++ b/jmetal/core/problem.py @@ -3,9 +3,7 @@ import random from jmetal.core.solution import BinarySolution, FloatSolution, IntegerSolution -from jmetal.util.front_utils import walk_up_folder, read_front_from_file_as_solutions - -FILE_PATH = dirname(join(dirname(__file__))) +from jmetal.util.front_file import walk_up_folder, read_front_from_file_as_solutions S = TypeVar('S') @@ -30,6 +28,7 @@ def create_solution(self) -> S: def get_reference_front(self) -> list: front = [] + FILE_PATH = dirname(join(dirname(__file__))) if self.reference_front_path: computed_path = join(walk_up_folder(FILE_PATH, 2), self.reference_front_path) diff --git a/jmetal/runner/multiobjective/nsgaii_standard_settings.py b/jmetal/runner/multiobjective/nsgaii_standard_settings.py index 02ba4bdd..c15ad607 100644 --- a/jmetal/runner/multiobjective/nsgaii_standard_settings.py +++ b/jmetal/runner/multiobjective/nsgaii_standard_settings.py @@ -1,8 +1,6 @@ import logging from typing import List -from jmetal.component.evaluator import SequentialEvaluator, DaskMultithreadedEvaluator, ParallelEvaluator - from jmetal.algorithm.multiobjective.nsgaii import NSGAII from jmetal.component.observer import VisualizerObserver from jmetal.core.solution import FloatSolution @@ -10,25 +8,18 @@ from jmetal.operator.mutation import Polynomial from jmetal.operator.selection import BinaryTournament2Selection from jmetal.problem.multiobjective.dtlz import DTLZ1 -from jmetal.problem.multiobjective.zdt import ZDT1 from jmetal.util.comparator import SolutionAttributeComparator from jmetal.util.solution_list_output import SolutionListOutput -from jmetal.problem.multiobjective.unconstrained import Kursawe - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) -def main() -> None: +def main(): problem = DTLZ1() algorithm = NSGAII[FloatSolution, List[FloatSolution]]( problem=problem, population_size=100, max_evaluations=25000, - #evaluator=DaskMultithreadedEvaluator(), - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), + mutation=Polynomial(1.0 / problem.number_of_variables, distribution_index=20), crossover=SBX(1.0, distribution_index=20), - # selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) selection=BinaryTournament2Selection([SolutionAttributeComparator("dominance_ranking"), SolutionAttributeComparator("crowding_distance", lowest_is_best=False)])) @@ -43,12 +34,21 @@ def main() -> None: file_name="NSGAII." + problem.get_name(), output_format='png') SolutionListOutput[FloatSolution].plot_frontier_to_screen(result, None, title=problem.get_name()) - #SolutionListOutput[FloatSolution].print_function_values_to_file(result, "NSGAII." + problem.get_name()) + SolutionListOutput[FloatSolution].print_function_values_to_file(result, "NSGAII." + problem.get_name()) - logger.info("Algorithm (continuous problem): " + algorithm.get_name()) - logger.info("Problem: " + problem.get_name()) - logger.info("Computing time: " + str(algorithm.total_computing_time)) + print("Algorithm (continuous problem): " + algorithm.get_name()) + print("Problem: " + problem.get_name()) + print("Computing time: " + str(algorithm.total_computing_time)) if __name__ == '__main__': - main() + logging.basicConfig( + level=logging.INFO, + format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s", + handlers=[ + logging.FileHandler('jmetalpy.log'), + logging.StreamHandler() + ] + ) + + main() \ No newline at end of file diff --git a/jmetal/runner/multiobjective/smpso_standard_settings.py b/jmetal/runner/multiobjective/smpso_standard_settings.py index de3508de..3d5955e8 100644 --- a/jmetal/runner/multiobjective/smpso_standard_settings.py +++ b/jmetal/runner/multiobjective/smpso_standard_settings.py @@ -5,15 +5,13 @@ from jmetal.component.observer import VisualizerObserver from jmetal.core.solution import FloatSolution from jmetal.operator.mutation import Polynomial +from jmetal.problem.multiobjective.dtlz import DTLZ1 from jmetal.problem.multiobjective.zdt import ZDT1 from jmetal.util.solution_list_output import SolutionListOutput -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - def main() -> None: - problem = ZDT1() + problem = DTLZ1() algorithm = SMPSO( problem=problem, swarm_size=100, @@ -22,17 +20,27 @@ def main() -> None: leaders=CrowdingDistanceArchive(100) ) - observer = VisualizerObserver(animation_speed=1 * 10e-8) + observer = VisualizerObserver() algorithm.observable.register(observer=observer) algorithm.run() result = algorithm.get_result() - SolutionListOutput[FloatSolution].plot_frontier_to_screen(result) + SolutionListOutput[FloatSolution].plot_frontier_to_screen(result, None, title=problem.get_name()) + SolutionListOutput[FloatSolution].print_function_values_to_file(result, "SMPSO." + problem.get_name()) - logger.info("Algorithm (continuous problem): " + algorithm.get_name()) - logger.info("Problem: " + problem.get_name()) + print("Algorithm (continuous problem): " + algorithm.get_name()) + print("Problem: " + problem.get_name()) if __name__ == '__main__': - main() + logging.basicConfig( + level=logging.INFO, + format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s", + handlers=[ + logging.FileHandler('jmetalpy.log'), + logging.StreamHandler() + ] + ) + + main() \ No newline at end of file diff --git a/jmetal/runner/multiobjective/smpsorp_standard_settings.py b/jmetal/runner/multiobjective/smpsorp_standard_settings.py index ed53785c..888091e1 100644 --- a/jmetal/runner/multiobjective/smpsorp_standard_settings.py +++ b/jmetal/runner/multiobjective/smpsorp_standard_settings.py @@ -3,13 +3,8 @@ from jmetal.algorithm.multiobjective.smpso import SMPSORP from jmetal.component.archive import CrowdingDistanceArchiveWithReferencePoint from jmetal.component.observer import VisualizerObserver -from jmetal.core.solution import FloatSolution from jmetal.operator.mutation import Polynomial from jmetal.problem.multiobjective.zdt import ZDT1 -from jmetal.util.solution_list_output import SolutionListOutput - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) def main() -> None: @@ -33,15 +28,24 @@ def main() -> None: leaders=archives_with_reference_points ) - observer = VisualizerObserver(animation_speed=1 * 10e-8) + observer = VisualizerObserver() algorithm.observable.register(observer=observer) algorithm.run() result = algorithm.get_result() - logger.info("Algorithm (continuous problem): " + algorithm.get_name()) - logger.info("Problem: " + problem.get_name()) + print("Algorithm (continuous problem): " + algorithm.get_name()) + print("Problem: " + problem.get_name()) if __name__ == '__main__': - main() + logging.basicConfig( + level=logging.INFO, + format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s", + handlers=[ + logging.FileHandler('jmetalpy.log'), + logging.StreamHandler() + ] + ) + + main() \ No newline at end of file diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index 789d1d81..9c408fec 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -9,7 +9,6 @@ warnings.filterwarnings("ignore",".*GUI is implemented.*") -logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) S = TypeVar('S') diff --git a/jmetal/util/solution_list_output.py b/jmetal/util/solution_list_output.py index 5f359201..27fbd2c7 100644 --- a/jmetal/util/solution_list_output.py +++ b/jmetal/util/solution_list_output.py @@ -5,7 +5,6 @@ from jmetal.util.graphic import ScatterPlot -logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) S = TypeVar('S') diff --git a/jmetal/util/time.py b/jmetal/util/time.py index 0d623a7d..ea5a89c7 100644 --- a/jmetal/util/time.py +++ b/jmetal/util/time.py @@ -1,7 +1,6 @@ import logging import time -logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @@ -11,7 +10,7 @@ def get_time_of_execution(fn): def wrapped(*args, **kwargs): start_time = time.time() res = fn(*args, **kwargs) - logger.info("Computing time to " + fn.__name__ + " (in seconds): " + str(time.time() - start_time)) + logger.debug("Computing time to " + fn.__name__ + " (in seconds): " + str(time.time() - start_time)) return res diff --git a/setup.py b/setup.py index 7aedd71e..649051f1 100644 --- a/setup.py +++ b/setup.py @@ -1,24 +1,25 @@ from setuptools import setup, find_packages -setup(name='jmetalpy', - version='1.0.0', - description='JMetalPy. Python version of the jMetal framework', - author='Antonio J. Nebro', - author_email='ajnebro@uma.es', - maintainer='Antonio Nebro', - maintainer_email='ajnebro@uma.es', - license='MIT', - url='https://github.com/jMetal/jMetalPy', - classifiers=[ - 'Development Status :: 3 - Alpha', +setup( + name='jmetalpy', + version='1.0.0', + description='JMetalPy. Python version of the jMetal framework', + author='Antonio J. Nebro', + author_email='ajnebro@uma.es', + maintainer='Antonio Nebro', + maintainer_email='ajnebro@uma.es', + license='MIT', + url='https://github.com/jMetal/jMetalPy', + classifiers=[ + 'Development Status :: 3 - Alpha', - 'Intended Audience :: Science/Research', + 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: MIT License', + 'License :: OSI Approved :: MIT License', - 'Topic :: Scientific/Engineering :: Artificial Intelligence', + 'Topic :: Scientific/Engineering :: Artificial Intelligence', - 'Programming Language :: Python :: 3.6'], + 'Programming Language :: Python :: 3.6'], - packages=find_packages(exclude=['test_']), - ) + packages=find_packages(exclude=['test_']), +) From 9e58d954a984baec80b00d2f8a3218d63a9ddcdf Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 12 Jun 2018 14:18:02 +0200 Subject: [PATCH 59/90] Fix import statement --- jmetal/util/test/test_quality_indicator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jmetal/util/test/test_quality_indicator.py b/jmetal/util/test/test_quality_indicator.py index b91296d0..fad4d7f4 100644 --- a/jmetal/util/test/test_quality_indicator.py +++ b/jmetal/util/test/test_quality_indicator.py @@ -1,7 +1,7 @@ from os.path import dirname, join import unittest -from jmetal.util.front_utils import read_front_from_file, walk_up_folder +from jmetal.util.front_file import read_front_from_file, walk_up_folder from jmetal.util.quality_indicator import HyperVolume FILE_PATH = dirname(join(dirname(__file__))) From 3660052586fad847d0c3f41fd8e56d6ae6afbe44 Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 19 Jun 2018 14:48:53 +0200 Subject: [PATCH 60/90] New problem DTLZ2 --- jmetal/problem/multiobjective/dtlz.py | 61 +++++++++++++++++++++------ 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/jmetal/problem/multiobjective/dtlz.py b/jmetal/problem/multiobjective/dtlz.py index 2c7485a5..67f93a21 100644 --- a/jmetal/problem/multiobjective/dtlz.py +++ b/jmetal/problem/multiobjective/dtlz.py @@ -1,4 +1,4 @@ -from math import pi, cos +from math import pi, cos, sin from jmetal.core.problem import FloatProblem from jmetal.core.solution import FloatSolution @@ -13,12 +13,12 @@ class DTLZ1(FloatProblem): - """ Problem DTLZ1 + """ Problem DTLZ1. Continuous problem having a flat Pareto front + .. note:: Unconstrained problem. The default number of variables and objectives are, respectively, 7 and 3. - .. note:: Continuous problem having a convex Pareto front """ - def __init__(self, number_of_variables: int = 30, number_of_objectives=3): + def __init__(self, number_of_variables: int = 7, number_of_objectives=3): """Constructor :param number_of_variables: number of decision variables of the problem """ @@ -34,23 +34,60 @@ def __init__(self, number_of_variables: int = 30, number_of_objectives=3): FloatSolution.upper_bound = self.upper_bound def evaluate(self, solution: FloatSolution): - g = 0.0 k = self.number_of_variables - self.number_of_objectives + 1 - for i in range (self.number_of_variables - k, self.number_of_variables): - g += (solution.variables[i] - 0.5) * (solution.variables[i] - 0.5) - \ - cos(20.0 * pi * (solution.variables[i] - 0.5)) + + g = sum([(x - 0.5) * (x - 0.5) - cos(20.0 * pi * (x - 0.5)) + for x in solution.variables[self.number_of_variables - k:]]) g = 100 * (k + g) - for i in range(self.number_of_objectives): - solution.objectives[i] = (1.0 + g) * 0.5 + + solution.objectives = [(1.0 + g) * 0.5] * self.number_of_objectives for i in range(self.number_of_objectives): for j in range(self.number_of_objectives - (i + 1)): solution.objectives[i] *= solution.variables[j] if i != 0: - aux = self.number_of_objectives - (i + 1) - solution.objectives[i] *= 1 - solution.variables[aux] + solution.objectives[i] *= 1 - solution.variables[self.number_of_objectives - (i + 1)] def get_name(self): return "DTLZ1" + + +class DTLZ2(FloatProblem): + """ Problem DTLZ2. Continuous problem having a convex Pareto front + + .. note:: Unconstrained problem. The default number of variables and objectives are, respectively, 12 and 3. + """ + + def __init__(self, number_of_variables: int = 12, number_of_objectives=3): + """Constructor + :param number_of_variables: number of decision variables of the problem + """ + super().__init__() + self.number_of_variables = number_of_variables + self.number_of_objectives = number_of_objectives + self.number_of_constraints = 0 + + self.lower_bound = self.number_of_variables * [0.0] + self.upper_bound = self.number_of_variables * [1.0] + + FloatSolution.lower_bound = self.lower_bound + FloatSolution.upper_bound = self.upper_bound + + def evaluate(self, solution: FloatSolution): + k = self.number_of_variables - self.number_of_objectives + 1 + + g = sum([(x - 0.5) * (x - 0.5) for x in solution.variables[self.number_of_variables - k:]]) + + solution.objectives = [1.0 + g] * self.number_of_objectives + + for i in range(self.number_of_objectives): + for j in range(self.number_of_objectives - (i + 1)): + solution.objectives[i] *= cos(solution.variables[j] * 0.5 * pi) + + if i != 0: + solution.objectives[i] *= sin(0.5 * pi * solution.variables[self.number_of_objectives - (i + 1)]) + + def get_name(self): + return "DTLZ2" From 4b6dfa57aeb8316ab8daad623f1828cfa5e52519 Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 19 Jun 2018 14:49:23 +0200 Subject: [PATCH 61/90] New options for plotting --- jmetal/component/observer.py | 5 +- jmetal/core/solution.py | 10 +- .../nsgaii_standard_settings.py | 6 +- jmetal/util/graphic.py | 107 +++++++++++------- jmetal/util/solution_list_output.py | 23 ++-- 5 files changed, 90 insertions(+), 61 deletions(-) diff --git a/jmetal/component/observer.py b/jmetal/component/observer.py index 8113a1d3..3ff1bb36 100644 --- a/jmetal/component/observer.py +++ b/jmetal/component/observer.py @@ -41,8 +41,9 @@ def update(self, *args, **kwargs): class VisualizerObserver(Observer): - def __init__(self, frequency: float = 1.0) -> None: + def __init__(self, frequency: float = 1.0, replace: bool=True) -> None: self.display_frequency = frequency + self.replace = replace def update(self, *args, **kwargs): evaluations = kwargs["evaluations"] @@ -52,4 +53,4 @@ def update(self, *args, **kwargs): if (evaluations % self.display_frequency) == 0: SolutionListOutput.plot_frontier_live( - solution_list, reference_solution_list, "Pareto frontier", evaluations, computing_time) + solution_list, reference_solution_list, "Pareto frontier", evaluations, computing_time, self.replace) diff --git a/jmetal/core/solution.py b/jmetal/core/solution.py index 501cc705..7b5ae5c0 100644 --- a/jmetal/core/solution.py +++ b/jmetal/core/solution.py @@ -12,10 +12,18 @@ def __init__(self, number_of_variables: int, number_of_objectives: int, number_o self.number_of_variables: int = number_of_variables self.number_of_constraints: int = number_of_constraints self.objectives = [0.0 for _ in range(self.number_of_objectives)] - self.normalized_objectives = [0.0 for _ in range(self.number_of_objectives)] self.variables = [[] for _ in range(self.number_of_variables)] self.attributes = {} + def __str__(self) -> str: + solution = "number_of_objectives: {0} \nnumber_of_variables: {1} \nnumber_of_constraints: {2} \n".format( + self.number_of_objectives, self.number_of_variables, self.number_of_constraints + ) + solution += "objectives: \n {0} \n".format(self.objectives) + solution += "variables: \n {0}".format(self.variables) + + return solution + class BinarySolution(Solution[BitSet]): """ Class representing float solutions """ diff --git a/jmetal/runner/multiobjective/nsgaii_standard_settings.py b/jmetal/runner/multiobjective/nsgaii_standard_settings.py index c15ad607..980fcf6d 100644 --- a/jmetal/runner/multiobjective/nsgaii_standard_settings.py +++ b/jmetal/runner/multiobjective/nsgaii_standard_settings.py @@ -7,13 +7,13 @@ from jmetal.operator.crossover import SBX from jmetal.operator.mutation import Polynomial from jmetal.operator.selection import BinaryTournament2Selection -from jmetal.problem.multiobjective.dtlz import DTLZ1 +from jmetal.problem.multiobjective.zdt import ZDT1 from jmetal.util.comparator import SolutionAttributeComparator from jmetal.util.solution_list_output import SolutionListOutput def main(): - problem = DTLZ1() + problem = ZDT1() algorithm = NSGAII[FloatSolution, List[FloatSolution]]( problem=problem, population_size=100, @@ -23,7 +23,7 @@ def main(): selection=BinaryTournament2Selection([SolutionAttributeComparator("dominance_ranking"), SolutionAttributeComparator("crowding_distance", lowest_is_best=False)])) - observer = VisualizerObserver() + observer = VisualizerObserver(replace=True) algorithm.observable.register(observer=observer) algorithm.run() diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index 9c408fec..835e81de 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -2,7 +2,10 @@ import warnings from typing import TypeVar, List, Tuple +import itertools import matplotlib.pyplot as plt +from cycler import cycler +from matplotlib import rcParams from mpl_toolkits.mplot3d import Axes3D from jmetal.core.solution import Solution @@ -19,74 +22,93 @@ :platform: Unix, Windows :synopsis: Class for plotting solutions. -.. moduleauthor:: Antonio Benítez +.. moduleauthor:: Antonio Benítez-Hidalgo """ class ScatterPlot: - def __init__(self, plot_title: str, number_of_objectives: int=2): + def __init__(self, plot_title: str, number_of_objectives: int=2, reference_solution_list: List[S] = None): """ Creates a new :class:`ScatterPlot` instance. Suitable for problems with 2 or 3 objectives. :param plot_title: Title of the scatter diagram. :param number_of_objectives: Number of objectives to be used (2D/3D). + :param reference_solution_list: Reference solution list (if any). """ self.plot_title = plot_title self.number_of_objectives = number_of_objectives + self.reference_solution_list = reference_solution_list + + self.__initialize() + + def __initialize(self) -> None: + """ Initialize the scatter plot for the first time. """ + logger.info("Generating plot...") # Initialize a plot self.fig = plt.figure() self.fig.canvas.set_window_title('jMetalPy') self.sc = None - if number_of_objectives == 2: + if self.number_of_objectives == 2: self.axis = self.fig.add_subplot(111) + + # Stylize axis + self.axis.spines['top'].set_visible(False) + self.axis.spines['right'].set_visible(False) + self.axis.get_xaxis().tick_bottom() + self.axis.get_yaxis().tick_left() else: self.axis = Axes3D(self.fig) self.axis.autoscale(enable=True, axis='both') - self.__initialize() - - def __initialize(self) -> None: - """ Initialize the scatter plot the first time. """ - logger.info("Generating plot...") - self.axis.set_autoscale_on(True) self.axis.autoscale_view(True, True, True) # Style options - self.axis.grid(color='#f0f0f5', linestyle='-', linewidth=2, alpha=0.5) + self.axis.grid(color='#f0f0f5', linestyle='-', linewidth=1, alpha=0.5) self.fig.suptitle(self.plot_title, fontsize=13) - def __plot(self, x_values, y_values, z_values, solution_list, color: str='go'): + def __plot(self, x_values, y_values, z_values, color: str='#98FB98', marker: str='o', msize: int=3): if self.number_of_objectives == 2: - self.sc, = self.axis.plot(x_values, y_values, color, markersize=3, picker=10) - self.fig.canvas.mpl_connect('pick_event', lambda event: self.__pick_handler(event, solution_list)) + self.sc, = self.axis.plot(x_values, y_values, + color=color, marker=marker, markersize=msize, ls='None', picker=10) else: - self.sc, = self.axis.plot(x_values, y_values, z_values, color, markersize=3, picker=10) + self.sc, = self.axis.plot(x_values, y_values, z_values, + color=color, marker=marker, markersize=msize, ls='None', picker=10) - def plot(self, solution_list: List[S], reference_solution_list: List[S], show: bool=False) -> None: - if reference_solution_list: - ref_x_values, ref_y_values, ref_z_values = self.__get_objectives(reference_solution_list) - self.__plot(ref_x_values, ref_y_values, ref_z_values, None, 'b') + def plot(self, solution_list: List[S], show: bool=False) -> None: + """ Plot a solution list. If any reference solution list, plot it first with other color. """ + if self.reference_solution_list: + ref_x_values, ref_y_values, ref_z_values = self.__get_objectives(self.reference_solution_list) + self.__plot(ref_x_values, ref_y_values, ref_z_values, color='#323232', marker='*') x_values, y_values, z_values = self.__get_objectives(solution_list) - self.__plot(x_values, y_values, z_values, solution_list) + self.__plot(x_values, y_values, z_values) if show: + self.fig.canvas.mpl_connect('pick_event', lambda event: self.__pick_handler(event, solution_list)) plt.show() - def update(self, solution_list: List[S], evaluations: int=0, computing_time: float=0) -> None: + def update(self, solution_list: List[S], subtitle: str="", replace_strategy: bool=True) -> None: """ Update a plot with new values. - .. note:: The plot must be initialized first. """ + .. note:: The plot must be initialized first. + + :param solution_list: List of points. + :param subtitle: Plot subtitle. + :param replace_strategy: Keep old points instead of replacing them on real-time plots. """ if self.sc is None: raise Exception("Error while updating: Initialize plot first!") x_values, y_values, z_values = self.__get_objectives(solution_list) - # Replace with new points - self.sc.set_data(x_values, y_values) + if replace_strategy: + # Replace with new points + self.sc.set_data(x_values, y_values) + else: + # Add new points + self.__plot(x_values, y_values, z_values) # Also, add event handler event_handler = \ @@ -96,7 +118,7 @@ def update(self, solution_list: List[S], evaluations: int=0, computing_time: flo self.sc.set_3d_properties(z_values) # Update title with new times and evaluations - self.fig.suptitle('{0}, Eval: {1}, Time: {2}'.format(self.plot_title, evaluations, computing_time), fontsize=13) + self.fig.suptitle(subtitle, fontsize=13) # Re-align the axis self.axis.relim() @@ -110,23 +132,22 @@ def update(self, solution_list: List[S], evaluations: int=0, computing_time: flo self.fig.canvas.mpl_disconnect(event_handler) def save(self, file_name: str, fmt: str='eps', dpi: int=200): - """ Save the plot in a file. """ + """ Save the plot in a file. + + :param file_name: File name (without format). + :param fmt: Output format. + :param dpi: Pixels density. """ logger.info("Saving to file...") if fmt not in SUPPORTED_FORMATS: raise Exception("{0} is not a valid format! Use one of these instead: {0}".format(fmt, SUPPORTED_FORMATS)) self.fig.savefig(file_name + '.' + fmt, format=fmt, dpi=dpi) - def retrieve_info(self, x_val: float, y_val: float, solution: Solution) -> None: - """ Retrieve some information about a solution object. """ + def __retrieve_info(self, x_val: float, y_val: float, solution: Solution) -> None: + """ Retrieve information about a solution object. """ logger.info("Output file: " + '{0}-{1}'.format(x_val, y_val)) with open('{0}-{1}'.format(x_val, y_val), 'w') as of: - for function_value in solution.objectives: - of.write(str(function_value) + " ") - of.write("\n \n") - for function_variable in solution.variables: - of.write(str(function_variable) + "\n") - of.write("\n") + of.write(solution.__str__()) def __get_objectives(self, solution_list: List[S]) -> Tuple[list, list, list]: """ Get coords (x,y,z) from a solution_list. @@ -145,20 +166,18 @@ def __get_objectives(self, solution_list: List[S]) -> Tuple[list, list, list]: return x_values, y_values, z_values - def __get_solution_from_list(self, solution_list: List[S], x_val: float, y_val: float) -> None: - """ :return: A solution object associated with some values of (x,y) """ - sol = next((solution for solution in solution_list - if solution.objectives[0] == x_val and solution.objectives[1] == y_val), None) - - if sol is not None: - self.retrieve_info(x_val, y_val, sol) - else: - logger.warning("Solution is none.") - def __pick_handler(self, event, solution_list: List[S]): """ Handler for picking points from the plot. """ line, ind = event.artist, event.ind[0] x, y = line.get_xdata(), line.get_ydata() logger.info('Selected data point ({0}): ({1}, {2})'.format(ind, x[ind], y[ind])) - self.__get_solution_from_list(solution_list, x[ind], y[ind]) + + sol = next((solution for solution in solution_list + if solution.objectives[0] == x[ind] and solution.objectives[1] == y[ind]), None) + + if sol is not None: + self.__retrieve_info(x[ind], y[ind], sol) + else: + logger.warning("Solution is none.") + return True diff --git a/jmetal/util/solution_list_output.py b/jmetal/util/solution_list_output.py index 27fbd2c7..43a3f0c1 100644 --- a/jmetal/util/solution_list_output.py +++ b/jmetal/util/solution_list_output.py @@ -15,29 +15,30 @@ class SolutionListOutput(Generic[S]): @staticmethod def plot_frontier_to_file(solution_list: List[S], reference_solution_list: List[S], title: str, file_name: str, output_format: str='eps'): - """ Plot non-dominated solutions. For problems with TWO variables """ - sc = ScatterPlot(title, solution_list[0].number_of_objectives) - sc.plot(solution_list, reference_solution_list) + """ Save plot of non-dominated solutions to file. For problems with TWO or THREE variables """ + sc = ScatterPlot(title, solution_list[0].number_of_objectives, reference_solution_list) + sc.plot(solution_list, False) sc.save(file_name, output_format) @staticmethod def plot_frontier_to_screen(solution_list: List[S], reference_solution_list: List[S], title: str): - """ Plot non-dominated solutions. For problems with TWO variables """ - sc = ScatterPlot(title, solution_list[0].number_of_objectives) - sc.plot(solution_list, reference_solution_list, True) + """ Plot non-dominated solutions interactively. For problems with TWO or THREE variables """ + sc = ScatterPlot(title, solution_list[0].number_of_objectives, reference_solution_list) + sc.plot(solution_list, True) @staticmethod def plot_frontier_live(solution_list: List[S], reference_solution_list: List[S], title: str, - evaluations: int, computing_time: float): - """ Plot non-dominated solutions in real-time. For problems with TWO variables """ + evaluations: int, computing_time: float, replace: bool): + """ Plot non-dominated solutions in real-time. For problems with TWO or THREE variables """ global sc if not plt.get_fignums(): # The first time, set up plot - sc = ScatterPlot(title, solution_list[0].number_of_objectives) - sc.plot(solution_list, reference_solution_list) + sc = ScatterPlot(title, solution_list[0].number_of_objectives, reference_solution_list) + sc.plot(solution_list) else: - sc.update(solution_list, evaluations, computing_time) + subtitle = '{0}, Eval: {1}, Time: {2}'.format(title, evaluations, computing_time) + sc.update(solution_list, subtitle, replace) @staticmethod def print_variables_to_screen(solution_list: List[S]): From 49abd4e397b4087d463bf6a71113a5ca6e106ad9 Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 21 Jun 2018 16:45:26 +0200 Subject: [PATCH 62/90] WIP new Bokeh-based plotting options --- jmetal/algorithm/multiobjective/smpso.py | 3 - .../singleobjective/evolutionaryalgorithm.py | 3 - jmetal/component/observer.py | 15 +- .../nsgaii_standard_settings.py | 15 +- .../multiobjective/smpso_standard_settings.py | 4 +- jmetal/util/graphic.py | 185 ++++++++++++++---- jmetal/util/solution_list_output.py | 48 ++--- 7 files changed, 185 insertions(+), 88 deletions(-) diff --git a/jmetal/algorithm/multiobjective/smpso.py b/jmetal/algorithm/multiobjective/smpso.py index ad17b011..c2b30a3a 100644 --- a/jmetal/algorithm/multiobjective/smpso.py +++ b/jmetal/algorithm/multiobjective/smpso.py @@ -96,9 +96,6 @@ def update_progress(self) -> None: observable_data = {'evaluations': self.evaluations, 'computing time': self.get_current_computing_time(), 'population': self.leaders.solution_list} - if self.problem.reference_front_path: - observable_data['reference'] = self.problem.get_reference_front() - self.observable.notify_all(**observable_data) def is_stopping_condition_reached(self) -> bool: diff --git a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py index 5da3c301..b3d1e68f 100644 --- a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py +++ b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py @@ -137,9 +137,6 @@ def update_progress(self): observable_data = {'evaluations': self.evaluations, 'computing time': self.get_current_computing_time(), 'population': self.population} - if self.problem.reference_front_path: - observable_data['reference'] = self.problem.get_reference_front() - self.observable.notify_all(**observable_data) def is_stopping_condition_reached(self) -> bool: diff --git a/jmetal/component/observer.py b/jmetal/component/observer.py index 3ff1bb36..61cb13ba 100644 --- a/jmetal/component/observer.py +++ b/jmetal/component/observer.py @@ -2,7 +2,7 @@ import os from jmetal.util.observable import Observer -from jmetal.util.solution_list_output import SolutionListOutput +from jmetal.util.solution_list_output import PrintSolutionList, GraphicSolutionList logger = logging.getLogger(__name__) @@ -34,23 +34,24 @@ def __init__(self, output_directory) -> None: os.mkdir(self.directory) def update(self, *args, **kwargs): - SolutionListOutput.print_function_values_to_file( + PrintSolutionList.print_function_values_to_file( kwargs["population"], self.directory + "/FUN." + str(self.counter)) self.counter += 1 class VisualizerObserver(Observer): - def __init__(self, frequency: float = 1.0, replace: bool=True) -> None: - self.display_frequency = frequency + def __init__(self, ref: list=None, replace: bool=True) -> None: + self.display_frequency = 1.0 self.replace = replace + self.solution_list_output = GraphicSolutionList(title='JMETALPY', reference=ref) def update(self, *args, **kwargs): evaluations = kwargs["evaluations"] computing_time = kwargs["computing time"] solution_list = kwargs["population"] - reference_solution_list = kwargs.get("reference", None) + + title = '{0}, Eval: {1}, Time: {2}'.format("VisualizerObserver", evaluations, computing_time) if (evaluations % self.display_frequency) == 0: - SolutionListOutput.plot_frontier_live( - solution_list, reference_solution_list, "Pareto frontier", evaluations, computing_time, self.replace) + self.solution_list_output.plot_frontier_live(solution_list, title, self.replace) diff --git a/jmetal/runner/multiobjective/nsgaii_standard_settings.py b/jmetal/runner/multiobjective/nsgaii_standard_settings.py index 980fcf6d..63d88643 100644 --- a/jmetal/runner/multiobjective/nsgaii_standard_settings.py +++ b/jmetal/runner/multiobjective/nsgaii_standard_settings.py @@ -9,7 +9,7 @@ from jmetal.operator.selection import BinaryTournament2Selection from jmetal.problem.multiobjective.zdt import ZDT1 from jmetal.util.comparator import SolutionAttributeComparator -from jmetal.util.solution_list_output import SolutionListOutput +from jmetal.util.solution_list_output import PrintSolutionList, GraphicSolutionList def main(): @@ -23,18 +23,17 @@ def main(): selection=BinaryTournament2Selection([SolutionAttributeComparator("dominance_ranking"), SolutionAttributeComparator("crowding_distance", lowest_is_best=False)])) - observer = VisualizerObserver(replace=True) + observer = VisualizerObserver(problem.get_reference_front()) + dobserver = VisualizerObserver() algorithm.observable.register(observer=observer) algorithm.run() result = algorithm.get_result() - SolutionListOutput[FloatSolution].plot_frontier_to_file(result, None, - title=problem.get_name(), - file_name="NSGAII." + problem.get_name(), - output_format='png') - SolutionListOutput[FloatSolution].plot_frontier_to_screen(result, None, title=problem.get_name()) - SolutionListOutput[FloatSolution].print_function_values_to_file(result, "NSGAII." + problem.get_name()) + GraphicSolutionList(title="NSGAII").plot_frontier_to_file(result, 'output') + GraphicSolutionList(title="NSGAII", reference=problem.get_reference_front()).plot_frontier_to_screen(result) + + #SolutionList[FloatSolution].print_function_values_to_file(result, "NSGAII." + problem.get_name()) print("Algorithm (continuous problem): " + algorithm.get_name()) print("Problem: " + problem.get_name()) diff --git a/jmetal/runner/multiobjective/smpso_standard_settings.py b/jmetal/runner/multiobjective/smpso_standard_settings.py index 3d5955e8..393b86d0 100644 --- a/jmetal/runner/multiobjective/smpso_standard_settings.py +++ b/jmetal/runner/multiobjective/smpso_standard_settings.py @@ -11,7 +11,7 @@ def main() -> None: - problem = DTLZ1() + problem = ZDT1() algorithm = SMPSO( problem=problem, swarm_size=100, @@ -20,7 +20,7 @@ def main() -> None: leaders=CrowdingDistanceArchive(100) ) - observer = VisualizerObserver() + observer = VisualizerObserver(replace=True) algorithm.observable.register(observer=observer) algorithm.run() diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index 835e81de..725addc0 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -2,15 +2,20 @@ import warnings from typing import TypeVar, List, Tuple -import itertools -import matplotlib.pyplot as plt -from cycler import cycler -from matplotlib import rcParams +from bokeh.embed import file_html +from bokeh.events import DoubleTap +from bokeh.resources import CDN from mpl_toolkits.mplot3d import Axes3D +import matplotlib.pyplot as plt +from bokeh.client import ClientSession +from bokeh.io import curdoc, reset_output +from bokeh.layouts import column +from bokeh.models import HoverTool, ColumnDataSource, TapTool, CustomJS, WheelZoomTool, Title +from bokeh.plotting import Figure from jmetal.core.solution import Solution -warnings.filterwarnings("ignore",".*GUI is implemented.*") +warnings.filterwarnings("ignore", ".*GUI is implemented.*") logger = logging.getLogger(__name__) @@ -26,20 +31,59 @@ """ -class ScatterPlot: +class Plot: - def __init__(self, plot_title: str, number_of_objectives: int=2, reference_solution_list: List[S] = None): + def __init__(self, plot_title: str, reference_solution_list: List[S], number_of_objectives: int): """ Creates a new :class:`ScatterPlot` instance. Suitable for problems with 2 or 3 objectives. :param plot_title: Title of the scatter diagram. - :param number_of_objectives: Number of objectives to be used (2D/3D). :param reference_solution_list: Reference solution list (if any). + :param number_of_objectives: Number of objectives to be used (2D/3D). """ self.plot_title = plot_title self.number_of_objectives = number_of_objectives self.reference_solution_list = reference_solution_list - self.__initialize() + def __initialize(self) -> None: + pass + + def plot(self, solution_list: List[S], show: bool = False) -> None: + pass + + def update(self, solution_list: List[S], subtitle: str = "", persistence: bool = True) -> None: + pass + + def get_objectives(self, solution_list: List[S]) -> Tuple[list, list, list]: + """ Get coords (x,y,z) from a solution_list. + + :return: A tuple with (x,y,z) values. The third might be empty if working with a problem with 2 objectives.""" + if solution_list is None: + raise Exception("Solution list is none!") + + points = list(solution.objectives for solution in solution_list) + + x_values, y_values = [point[0] for point in points], [point[1] for point in points] + z_values = [] + + try: + z_values = [point[2] for point in points] + except IndexError: + pass + + return x_values, y_values, z_values + + +class Scatter(Plot): + + def __init__(self, plot_title: str, reference_solution_list: List[S] = None, number_of_objectives: int = 2): + """ Creates a new :class:`ScatterPlot` instance. Suitable for problems with 2 or 3 objectives. + + :param plot_title: Title of the scatter diagram. + :param number_of_objectives: Number of objectives to be used (2D/3D). + :param reference_solution_list: Reference solution list (if any). + """ + super().__init__(plot_title, reference_solution_list, number_of_objectives) + logger.warning("Scatter() will be deprecated in the future. Use ScatterBokeh() instead") def __initialize(self) -> None: """ Initialize the scatter plot for the first time. """ @@ -69,7 +113,7 @@ def __initialize(self) -> None: self.axis.grid(color='#f0f0f5', linestyle='-', linewidth=1, alpha=0.5) self.fig.suptitle(self.plot_title, fontsize=13) - def __plot(self, x_values, y_values, z_values, color: str='#98FB98', marker: str='o', msize: int=3): + def __plot(self, x_values, y_values, z_values, color: str = '#98FB98', marker: str = 'o', msize: int = 3): if self.number_of_objectives == 2: self.sc, = self.axis.plot(x_values, y_values, color=color, marker=marker, markersize=msize, ls='None', picker=10) @@ -77,33 +121,33 @@ def __plot(self, x_values, y_values, z_values, color: str='#98FB98', marker: str self.sc, = self.axis.plot(x_values, y_values, z_values, color=color, marker=marker, markersize=msize, ls='None', picker=10) - def plot(self, solution_list: List[S], show: bool=False) -> None: + def plot(self, solution_list: List[S], show: bool = False) -> None: """ Plot a solution list. If any reference solution list, plot it first with other color. """ if self.reference_solution_list: - ref_x_values, ref_y_values, ref_z_values = self.__get_objectives(self.reference_solution_list) + ref_x_values, ref_y_values, ref_z_values = self.get_objectives(self.reference_solution_list) self.__plot(ref_x_values, ref_y_values, ref_z_values, color='#323232', marker='*') - x_values, y_values, z_values = self.__get_objectives(solution_list) + x_values, y_values, z_values = self.get_objectives(solution_list) self.__plot(x_values, y_values, z_values) if show: self.fig.canvas.mpl_connect('pick_event', lambda event: self.__pick_handler(event, solution_list)) plt.show() - def update(self, solution_list: List[S], subtitle: str="", replace_strategy: bool=True) -> None: + def update(self, solution_list: List[S], subtitle: str = "", persistence: bool = True) -> None: """ Update a plot with new values. .. note:: The plot must be initialized first. :param solution_list: List of points. :param subtitle: Plot subtitle. - :param replace_strategy: Keep old points instead of replacing them on real-time plots. """ + :param persistence: Keep old points instead of replacing them on real-time plots. """ if self.sc is None: raise Exception("Error while updating: Initialize plot first!") - x_values, y_values, z_values = self.__get_objectives(solution_list) + x_values, y_values, z_values = self.get_objectives(solution_list) - if replace_strategy: + if persistence: # Replace with new points self.sc.set_data(x_values, y_values) else: @@ -131,7 +175,7 @@ def update(self, solution_list: List[S], subtitle: str="", replace_strategy: boo # Disconnect the pick event for the next update self.fig.canvas.mpl_disconnect(event_handler) - def save(self, file_name: str, fmt: str='eps', dpi: int=200): + def save(self, file_name: str, fmt: str = 'eps', dpi: int = 200): """ Save the plot in a file. :param file_name: File name (without format). @@ -149,23 +193,6 @@ def __retrieve_info(self, x_val: float, y_val: float, solution: Solution) -> Non with open('{0}-{1}'.format(x_val, y_val), 'w') as of: of.write(solution.__str__()) - def __get_objectives(self, solution_list: List[S]) -> Tuple[list, list, list]: - """ Get coords (x,y,z) from a solution_list. - - :return: A tuple with (x,y,z) values. The third might be empty if working with a problem with 2 objectives.""" - if solution_list is None: - raise Exception("Solution list is none!") - - points = list(solution.objectives for solution in solution_list) - - x_values, y_values = [point[0] for point in points], [point[1] for point in points] - z_values = [] - - if self.number_of_objectives == 3: - z_values = [point[2] for point in points] - - return x_values, y_values, z_values - def __pick_handler(self, event, solution_list: List[S]): """ Handler for picking points from the plot. """ line, ind = event.artist, event.ind[0] @@ -181,3 +208,91 @@ def __pick_handler(self, event, solution_list: List[S]): else: logger.warning("Solution is none.") return True + + +class ScatterBokeh(Plot): + + def __init__(self, plot_title: str, reference: List[S] = None, number_of_objectives: int = 2, + source: ColumnDataSource = None, port: int=5006, ws_url: str="localhost:5006"): + super().__init__(plot_title, reference, number_of_objectives) + + if source is None: + self.source = ColumnDataSource(data=dict(x=[], y=[], variables=[])) + + if number_of_objectives > 2: + raise Exception("ScatterBokeh() can only serve 2D charts. Use Scatter() instead.") + + self.figure = None + self.client = ClientSession(websocket_url="ws://{0}/ws".format(ws_url)) + self.port = port + self.doc = curdoc() + + self.__initialize() + + def __initialize(self) -> None: + """ Set-up tools for plot. """ + code = ''' + selected = source.selected['1d']['indices'][0] + console.log(source.selected['1d']['indices']) + console.log(source.data) + console.log(source.data.variables[selected]) + ''' + + callback = CustomJS(args=dict(source=self.source), code=code) + self.plot_tools = [TapTool(callback=callback), WheelZoomTool(), 'save', 'pan', + HoverTool(tooltips=[("index", "$index"), ("(x,y)", "($x, $y)")])] + + def plot(self, solution_list: List[S], show: bool=True) -> None: + logger.debug("Opening Bokeh application on http://localhost:{0}/".format(self.port)) + + # This is important to purge data (if any) between calls + reset_output() + + # Set-up figure + self.figure = Figure(output_backend="webgl", sizing_mode='scale_width', + title=self.plot_title, tools=self.plot_tools) + + # Plot reference solution list (if any) + if self.reference_solution_list: + ref_x_values, ref_y_values, ref_z_values = self.get_objectives(self.reference_solution_list) + self.figure.line(x=ref_x_values, y=ref_y_values, legend="reference", color="green") + + # Plot solution list + self.figure.scatter(x='x', y='y', legend="solutions", fill_alpha=0.7, source=self.source) + + x_values, y_values, z_values = self.get_objectives(solution_list) + self.source.stream({'x': x_values, 'y': y_values, 'variables': [solution.variables for solution in solution_list]}) + + # Add to curdoc + self.doc.add_root(column(self.figure)) + self.client.push(self.doc) + + if show: + self.client.show() + + def update(self, solution_list: List[S], new_title: str="", persistence: bool=True) -> None: + # Check if plot has not been initialized first + if self.figure is None: + self.plot(solution_list) + + self.figure.title.text = new_title + x_values, y_values, z_values = self.get_objectives(solution_list) + + if persistence: + self.source.stream({'x': x_values, 'y': y_values, + 'variables': [solution.variables for solution in solution_list]}, + rollover=len(solution_list)) + else: + self.source.stream({'x': x_values, 'y': y_values, + 'variables': [solution.variables for solution in solution_list]}) + + def save(self, file_name: str): + html = file_html(models=self.figure, resources=CDN) + # todo Save to file + + def disconnect(self): + if self.is_connected(): + self.client.close() + + def is_connected(self) -> bool: + return self.client.connected diff --git a/jmetal/util/solution_list_output.py b/jmetal/util/solution_list_output.py index 43a3f0c1..99741110 100644 --- a/jmetal/util/solution_list_output.py +++ b/jmetal/util/solution_list_output.py @@ -1,59 +1,47 @@ import logging -from typing import TypeVar, List, Generic +from typing import TypeVar, Generic -import matplotlib.pyplot as plt - -from jmetal.util.graphic import ScatterPlot +from jmetal.util.graphic import ScatterBokeh +S = TypeVar('S') logger = logging.getLogger(__name__) -S = TypeVar('S') +class GraphicSolutionList(Generic[S]): -class SolutionListOutput(Generic[S]): + def __init__(self, title: str, reference: list=None, number_of_objectives: int=2): + self.bokeh = ScatterBokeh(title, reference, number_of_objectives) - @staticmethod - def plot_frontier_to_file(solution_list: List[S], reference_solution_list: List[S], title: str, - file_name: str, output_format: str='eps'): + def plot_frontier_to_file(self, solution_list: list, file_name: str): """ Save plot of non-dominated solutions to file. For problems with TWO or THREE variables """ - sc = ScatterPlot(title, solution_list[0].number_of_objectives, reference_solution_list) - sc.plot(solution_list, False) - sc.save(file_name, output_format) + self.bokeh.plot(solution_list) + self.bokeh.save(file_name) - @staticmethod - def plot_frontier_to_screen(solution_list: List[S], reference_solution_list: List[S], title: str): + def plot_frontier_to_screen(self, solution_list: list): """ Plot non-dominated solutions interactively. For problems with TWO or THREE variables """ - sc = ScatterPlot(title, solution_list[0].number_of_objectives, reference_solution_list) - sc.plot(solution_list, True) + self.bokeh.plot(solution_list, show=True) - @staticmethod - def plot_frontier_live(solution_list: List[S], reference_solution_list: List[S], title: str, - evaluations: int, computing_time: float, replace: bool): + def plot_frontier_live(self, solution_list: list, new_title: str, replace: bool): """ Plot non-dominated solutions in real-time. For problems with TWO or THREE variables """ - global sc + self.bokeh.update(solution_list, new_title, replace) + - if not plt.get_fignums(): - # The first time, set up plot - sc = ScatterPlot(title, solution_list[0].number_of_objectives, reference_solution_list) - sc.plot(solution_list) - else: - subtitle = '{0}, Eval: {1}, Time: {2}'.format(title, evaluations, computing_time) - sc.update(solution_list, subtitle, replace) +class PrintSolutionList(Generic[S]): @staticmethod - def print_variables_to_screen(solution_list: List[S]): + def print_variables_to_screen(solution_list: list): for solution in solution_list: print(solution.variables[0]) @staticmethod - def print_function_values_to_screen(solution_list: List[S]): + def print_function_values_to_screen(solution_list: list): for solution in solution_list: print(str(solution_list.index(solution)) + ": ", sep=' ', end='', flush=True) print(solution.objectives, sep=' ', end='', flush=True) print() @staticmethod - def print_function_values_to_file(solution_list: List[S], file_name): + def print_function_values_to_file(solution_list: list, file_name): logger.info("Output file (function values): " + file_name) with open(file_name, 'w') as of: for solution in solution_list: From b6a9528350c33180d9c1c12e35f69857679d6679 Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 22 Jun 2018 01:27:40 +0200 Subject: [PATCH 63/90] WIP bokeh backend for plotting --- jmetal/component/observer.py | 16 +- .../nsgaii_standard_settings.py | 23 +- .../multiobjective/smpso_standard_settings.py | 7 +- jmetal/util/graphic.py | 201 +++++++++--------- jmetal/util/solution_list_output.py | 23 +- requirements.txt | 3 +- 6 files changed, 126 insertions(+), 147 deletions(-) diff --git a/jmetal/component/observer.py b/jmetal/component/observer.py index 61cb13ba..cf66e682 100644 --- a/jmetal/component/observer.py +++ b/jmetal/component/observer.py @@ -1,13 +1,16 @@ import logging import os +from jmetal.core.problem import Problem +from jmetal.util.graphic import ScatterBokeh, ScatterMatplotlib from jmetal.util.observable import Observer -from jmetal.util.solution_list_output import PrintSolutionList, GraphicSolutionList +from jmetal.util.solution_list_output import SolutionList logger = logging.getLogger(__name__) class BasicAlgorithmObserver(Observer): + def __init__(self, frequency: float = 1.0) -> None: self.display_frequency = frequency @@ -21,6 +24,7 @@ def update(self, *args, **kwargs): class WriteFrontToFileObserver(Observer): + def __init__(self, output_directory) -> None: self.counter = 0 self.directory = output_directory @@ -34,17 +38,19 @@ def __init__(self, output_directory) -> None: os.mkdir(self.directory) def update(self, *args, **kwargs): - PrintSolutionList.print_function_values_to_file( + SolutionList.print_function_values_to_file( kwargs["population"], self.directory + "/FUN." + str(self.counter)) self.counter += 1 class VisualizerObserver(Observer): - def __init__(self, ref: list=None, replace: bool=True) -> None: + + def __init__(self, problem: Problem, replace: bool=True) -> None: self.display_frequency = 1.0 self.replace = replace - self.solution_list_output = GraphicSolutionList(title='JMETALPY', reference=ref) + self.reference = problem.get_reference_front() + self.plot = ScatterMatplotlib(plot_title='VisualizerObserver', number_of_objectives=problem.number_of_objectives) def update(self, *args, **kwargs): evaluations = kwargs["evaluations"] @@ -54,4 +60,4 @@ def update(self, *args, **kwargs): title = '{0}, Eval: {1}, Time: {2}'.format("VisualizerObserver", evaluations, computing_time) if (evaluations % self.display_frequency) == 0: - self.solution_list_output.plot_frontier_live(solution_list, title, self.replace) + self.plot.update(solution_list=solution_list, reference=self.reference, new_title=title, persistence=self.replace) diff --git a/jmetal/runner/multiobjective/nsgaii_standard_settings.py b/jmetal/runner/multiobjective/nsgaii_standard_settings.py index 63d88643..c918e279 100644 --- a/jmetal/runner/multiobjective/nsgaii_standard_settings.py +++ b/jmetal/runner/multiobjective/nsgaii_standard_settings.py @@ -7,33 +7,38 @@ from jmetal.operator.crossover import SBX from jmetal.operator.mutation import Polynomial from jmetal.operator.selection import BinaryTournament2Selection -from jmetal.problem.multiobjective.zdt import ZDT1 +from jmetal.problem.multiobjective.dtlz import DTLZ1 from jmetal.util.comparator import SolutionAttributeComparator -from jmetal.util.solution_list_output import PrintSolutionList, GraphicSolutionList +from jmetal.util.graphic import ScatterBokeh, ScatterMatplotlib +from jmetal.util.solution_list_output import SolutionList def main(): - problem = ZDT1() + problem = DTLZ1() algorithm = NSGAII[FloatSolution, List[FloatSolution]]( problem=problem, population_size=100, - max_evaluations=25000, + max_evaluations=1000, mutation=Polynomial(1.0 / problem.number_of_variables, distribution_index=20), crossover=SBX(1.0, distribution_index=20), selection=BinaryTournament2Selection([SolutionAttributeComparator("dominance_ranking"), SolutionAttributeComparator("crowding_distance", lowest_is_best=False)])) - observer = VisualizerObserver(problem.get_reference_front()) - dobserver = VisualizerObserver() + observer = VisualizerObserver(problem) algorithm.observable.register(observer=observer) algorithm.run() result = algorithm.get_result() - GraphicSolutionList(title="NSGAII").plot_frontier_to_file(result, 'output') - GraphicSolutionList(title="NSGAII", reference=problem.get_reference_front()).plot_frontier_to_screen(result) + # Plot frontier + pareto_front = ScatterBokeh(plot_title='NSGAII', number_of_objectives=problem.number_of_objectives) + pareto_front.plot(result, reference=problem.get_reference_front(), output='output') - #SolutionList[FloatSolution].print_function_values_to_file(result, "NSGAII." + problem.get_name()) + pareto_front = ScatterMatplotlib(plot_title='NSGAII', number_of_objectives=problem.number_of_objectives) + pareto_front.plot(result, reference=problem.get_reference_front(), output='output2') + + # Save variables to file + SolutionList[FloatSolution].print_function_values_to_file(result, "NSGAII." + problem.get_name()) print("Algorithm (continuous problem): " + algorithm.get_name()) print("Problem: " + problem.get_name()) diff --git a/jmetal/runner/multiobjective/smpso_standard_settings.py b/jmetal/runner/multiobjective/smpso_standard_settings.py index 393b86d0..ef70d59b 100644 --- a/jmetal/runner/multiobjective/smpso_standard_settings.py +++ b/jmetal/runner/multiobjective/smpso_standard_settings.py @@ -7,7 +7,6 @@ from jmetal.operator.mutation import Polynomial from jmetal.problem.multiobjective.dtlz import DTLZ1 from jmetal.problem.multiobjective.zdt import ZDT1 -from jmetal.util.solution_list_output import SolutionListOutput def main() -> None: @@ -20,14 +19,10 @@ def main() -> None: leaders=CrowdingDistanceArchive(100) ) - observer = VisualizerObserver(replace=True) + observer = VisualizerObserver(problem) algorithm.observable.register(observer=observer) algorithm.run() - result = algorithm.get_result() - - SolutionListOutput[FloatSolution].plot_frontier_to_screen(result, None, title=problem.get_name()) - SolutionListOutput[FloatSolution].print_function_values_to_file(result, "SMPSO." + problem.get_name()) print("Algorithm (continuous problem): " + algorithm.get_name()) print("Problem: " + problem.get_name()) diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index 725addc0..42b5047a 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -3,24 +3,21 @@ from typing import TypeVar, List, Tuple from bokeh.embed import file_html -from bokeh.events import DoubleTap from bokeh.resources import CDN -from mpl_toolkits.mplot3d import Axes3D -import matplotlib.pyplot as plt from bokeh.client import ClientSession from bokeh.io import curdoc, reset_output -from bokeh.layouts import column +from bokeh.layouts import column, row from bokeh.models import HoverTool, ColumnDataSource, TapTool, CustomJS, WheelZoomTool, Title from bokeh.plotting import Figure +from mpl_toolkits.mplot3d import Axes3D +import matplotlib.pyplot as plt from jmetal.core.solution import Solution warnings.filterwarnings("ignore", ".*GUI is implemented.*") logger = logging.getLogger(__name__) - S = TypeVar('S') -SUPPORTED_FORMATS = ["eps", "jpeg", "jpg", "pdf", "pgf", "png", "ps", "raw", "rgba", "svg", "svgz", "tif", "tiff"] """ .. module:: graphics @@ -33,66 +30,49 @@ class Plot: - def __init__(self, plot_title: str, reference_solution_list: List[S], number_of_objectives: int): - """ Creates a new :class:`ScatterPlot` instance. Suitable for problems with 2 or 3 objectives. - - :param plot_title: Title of the scatter diagram. - :param reference_solution_list: Reference solution list (if any). - :param number_of_objectives: Number of objectives to be used (2D/3D). - """ + def __init__(self, plot_title: str, number_of_objectives: int): self.plot_title = plot_title self.number_of_objectives = number_of_objectives - self.reference_solution_list = reference_solution_list - - def __initialize(self) -> None: - pass - - def plot(self, solution_list: List[S], show: bool = False) -> None: - pass - - def update(self, solution_list: List[S], subtitle: str = "", persistence: bool = True) -> None: - pass def get_objectives(self, solution_list: List[S]) -> Tuple[list, list, list]: - """ Get coords (x,y,z) from a solution_list. - - :return: A tuple with (x,y,z) values. The third might be empty if working with a problem with 2 objectives.""" if solution_list is None: raise Exception("Solution list is none!") points = list(solution.objectives for solution in solution_list) x_values, y_values = [point[0] for point in points], [point[1] for point in points] - z_values = [] try: z_values = [point[2] for point in points] except IndexError: - pass + z_values = [0]*len(points) return x_values, y_values, z_values -class Scatter(Plot): +class ScatterMatplotlib(Plot): - def __init__(self, plot_title: str, reference_solution_list: List[S] = None, number_of_objectives: int = 2): + def __init__(self, plot_title: str, number_of_objectives: int): """ Creates a new :class:`ScatterPlot` instance. Suitable for problems with 2 or 3 objectives. :param plot_title: Title of the scatter diagram. :param number_of_objectives: Number of objectives to be used (2D/3D). - :param reference_solution_list: Reference solution list (if any). """ - super().__init__(plot_title, reference_solution_list, number_of_objectives) - logger.warning("Scatter() will be deprecated in the future. Use ScatterBokeh() instead") + super().__init__(plot_title, number_of_objectives) + + # Initialize a plot + self.fig = plt.figure() + self.sc = None + self.axis = None + + self.__initialize() def __initialize(self) -> None: """ Initialize the scatter plot for the first time. """ logger.info("Generating plot...") # Initialize a plot - self.fig = plt.figure() self.fig.canvas.set_window_title('jMetalPy') - self.sc = None if self.number_of_objectives == 2: self.axis = self.fig.add_subplot(111) @@ -121,35 +101,32 @@ def __plot(self, x_values, y_values, z_values, color: str = '#98FB98', marker: s self.sc, = self.axis.plot(x_values, y_values, z_values, color=color, marker=marker, markersize=msize, ls='None', picker=10) - def plot(self, solution_list: List[S], show: bool = False) -> None: - """ Plot a solution list. If any reference solution list, plot it first with other color. """ - if self.reference_solution_list: - ref_x_values, ref_y_values, ref_z_values = self.get_objectives(self.reference_solution_list) + def plot(self, solution_list: List[S], reference: List[S], output: str='', show: bool=True) -> None: + if reference: + ref_x_values, ref_y_values, ref_z_values = self.get_objectives(reference) self.__plot(ref_x_values, ref_y_values, ref_z_values, color='#323232', marker='*') x_values, y_values, z_values = self.get_objectives(solution_list) self.__plot(x_values, y_values, z_values) + if output: + self.__save(output) if show: self.fig.canvas.mpl_connect('pick_event', lambda event: self.__pick_handler(event, solution_list)) plt.show() - def update(self, solution_list: List[S], subtitle: str = "", persistence: bool = True) -> None: - """ Update a plot with new values. - - .. note:: The plot must be initialized first. - - :param solution_list: List of points. - :param subtitle: Plot subtitle. - :param persistence: Keep old points instead of replacing them on real-time plots. """ + def update(self, solution_list: List[S], reference: List[S], new_title: str='', persistence: bool=True) -> None: if self.sc is None: - raise Exception("Error while updating: Initialize plot first!") + self.plot(solution_list, reference, show=False) x_values, y_values, z_values = self.get_objectives(solution_list) if persistence: # Replace with new points self.sc.set_data(x_values, y_values) + + if self.number_of_objectives == 3: + self.sc.set_3d_properties(z_values) else: # Add new points self.__plot(x_values, y_values, z_values) @@ -158,11 +135,8 @@ def update(self, solution_list: List[S], subtitle: str = "", persistence: bool = event_handler = \ self.fig.canvas.mpl_connect('pick_event', lambda event: self.__pick_handler(event, solution_list)) - if self.number_of_objectives == 3: - self.sc.set_3d_properties(z_values) - # Update title with new times and evaluations - self.fig.suptitle(subtitle, fontsize=13) + self.fig.suptitle(new_title, fontsize=13) # Re-align the axis self.axis.relim() @@ -175,21 +149,18 @@ def update(self, solution_list: List[S], subtitle: str = "", persistence: bool = # Disconnect the pick event for the next update self.fig.canvas.mpl_disconnect(event_handler) - def save(self, file_name: str, fmt: str = 'eps', dpi: int = 200): - """ Save the plot in a file. + def __save(self, file_name: str, fmt: str = 'png', dpi: int = 200): + supported_formats = ["eps", "jpeg", "jpg", "pdf", "pgf", "png", "ps", + "raw", "rgba", "svg", "svgz", "tif", "tiff"] - :param file_name: File name (without format). - :param fmt: Output format. - :param dpi: Pixels density. """ - logger.info("Saving to file...") + if fmt not in supported_formats: + raise Exception("{0} is not a valid format! Use one of these instead: {0}".format(fmt, supported_formats)) - if fmt not in SUPPORTED_FORMATS: - raise Exception("{0} is not a valid format! Use one of these instead: {0}".format(fmt, SUPPORTED_FORMATS)) self.fig.savefig(file_name + '.' + fmt, format=fmt, dpi=dpi) def __retrieve_info(self, x_val: float, y_val: float, solution: Solution) -> None: - """ Retrieve information about a solution object. """ logger.info("Output file: " + '{0}-{1}'.format(x_val, y_val)) + with open('{0}-{1}'.format(x_val, y_val), 'w') as of: of.write(solution.__str__()) @@ -198,7 +169,7 @@ def __pick_handler(self, event, solution_list: List[S]): line, ind = event.artist, event.ind[0] x, y = line.get_xdata(), line.get_ydata() - logger.info('Selected data point ({0}): ({1}, {2})'.format(ind, x[ind], y[ind])) + logger.debug('Selected data point ({0}): ({1}, {2})'.format(ind, x[ind], y[ind])) sol = next((solution for solution in solution_list if solution.objectives[0] == x[ind] and solution.objectives[1] == y[ind]), None) @@ -212,20 +183,21 @@ def __pick_handler(self, event, solution_list: List[S]): class ScatterBokeh(Plot): - def __init__(self, plot_title: str, reference: List[S] = None, number_of_objectives: int = 2, - source: ColumnDataSource = None, port: int=5006, ws_url: str="localhost:5006"): - super().__init__(plot_title, reference, number_of_objectives) - - if source is None: - self.source = ColumnDataSource(data=dict(x=[], y=[], variables=[])) + def __init__(self, plot_title: str, number_of_objectives: int, ws_url: str='localhost:5006'): + super().__init__(plot_title, number_of_objectives) - if number_of_objectives > 2: - raise Exception("ScatterBokeh() can only serve 2D charts. Use Scatter() instead.") + if self.number_of_objectives == 2: + self.source = ColumnDataSource(data=dict(x=[], y=[], str=[])) + elif self.number_of_objectives == 3: + self.source = ColumnDataSource(data=dict(x=[], y=[], z=[], str=[])) + else: + raise Exception('Wrong number of objectives: {0}'.format(number_of_objectives)) - self.figure = None self.client = ClientSession(websocket_url="ws://{0}/ws".format(ws_url)) - self.port = port self.doc = curdoc() + self.figure_xy = None + self.figure_xz = None + self.figure_yz = None self.__initialize() @@ -233,62 +205,83 @@ def __initialize(self) -> None: """ Set-up tools for plot. """ code = ''' selected = source.selected['1d']['indices'][0] - console.log(source.selected['1d']['indices']) - console.log(source.data) - console.log(source.data.variables[selected]) + var str = source.data.str[selected] + alert(str) ''' callback = CustomJS(args=dict(source=self.source), code=code) self.plot_tools = [TapTool(callback=callback), WheelZoomTool(), 'save', 'pan', HoverTool(tooltips=[("index", "$index"), ("(x,y)", "($x, $y)")])] - def plot(self, solution_list: List[S], show: bool=True) -> None: - logger.debug("Opening Bokeh application on http://localhost:{0}/".format(self.port)) - + def plot(self, solution_list: List[S], reference: List[S], output: str='', show: bool=True) -> None: # This is important to purge data (if any) between calls reset_output() - # Set-up figure - self.figure = Figure(output_backend="webgl", sizing_mode='scale_width', - title=self.plot_title, tools=self.plot_tools) + # Set up figure + self.figure_xy = Figure(output_backend='webgl', sizing_mode='scale_width', title=self.plot_title, tools=self.plot_tools) + self.figure_xy.scatter(x='x', y='y', legend='solution', fill_alpha=0.7, source=self.source) - # Plot reference solution list (if any) - if self.reference_solution_list: - ref_x_values, ref_y_values, ref_z_values = self.get_objectives(self.reference_solution_list) - self.figure.line(x=ref_x_values, y=ref_y_values, legend="reference", color="green") + x_values, y_values, z_values = self.get_objectives(solution_list) - # Plot solution list - self.figure.scatter(x='x', y='y', legend="solutions", fill_alpha=0.7, source=self.source) + if self.number_of_objectives == 2: + # Plot reference solution list (if any) + if reference: + ref_x_values, ref_y_values, _ = self.get_objectives(reference) + self.figure_xy.line(x=ref_x_values, y=ref_y_values, legend='reference', color='green') + + # Push data to server + self.source.stream({'x': x_values, 'y': y_values, 'str': [s.__str__() for s in solution_list]}) + self.doc.add_root(column(self.figure_xy)) + else: + # Add new figures for each axis + self.figure_xz = Figure(title='xz', output_backend='webgl', sizing_mode='scale_width', tools=self.plot_tools) + self.figure_xz.scatter(x='x', y='z', legend='solution', fill_alpha=0.7, source=self.source) - x_values, y_values, z_values = self.get_objectives(solution_list) - self.source.stream({'x': x_values, 'y': y_values, 'variables': [solution.variables for solution in solution_list]}) + self.figure_yz = Figure(title='yz', output_backend='webgl', sizing_mode='scale_width', tools=self.plot_tools) + self.figure_yz.scatter(x='y', y='z', legend='solution', fill_alpha=0.7, source=self.source) + + # Plot reference solution list (if any) + if reference: + ref_x_values, ref_y_values, ref_z_values = self.get_objectives(reference) + self.figure_xy.line(x=ref_x_values, y=ref_y_values, legend='reference', color='green') + self.figure_xz.line(x=ref_x_values, y=ref_z_values, legend='reference', color='green') + self.figure_yz.line(x=ref_y_values, y=ref_z_values, legend='reference', color='green') + + # Push data to server + self.source.stream({'x': x_values, 'y': y_values, 'z': z_values, 'str': [s.__str__() for s in solution_list]}) + self.doc.add_root(row(self.figure_xy, self.figure_xz, self.figure_yz)) - # Add to curdoc - self.doc.add_root(column(self.figure)) self.client.push(self.doc) + if output: + self.__save(output) if show: self.client.show() - def update(self, solution_list: List[S], new_title: str="", persistence: bool=True) -> None: + def update(self, solution_list: List[S], reference: List[S], new_title: str='', persistence: bool=False) -> None: # Check if plot has not been initialized first - if self.figure is None: - self.plot(solution_list) + if self.figure_xy is None: + self.plot(solution_list, reference) + + if not persistence: + rollover = len(solution_list) + else: + rollover = None - self.figure.title.text = new_title + self.figure_xy.title.text = new_title x_values, y_values, z_values = self.get_objectives(solution_list) - if persistence: - self.source.stream({'x': x_values, 'y': y_values, - 'variables': [solution.variables for solution in solution_list]}, - rollover=len(solution_list)) + if self.number_of_objectives == 2: + self.source.stream({'x': x_values, 'y': y_values, 'str': [s.__str__() for s in solution_list]}, + rollover=rollover) else: - self.source.stream({'x': x_values, 'y': y_values, - 'variables': [solution.variables for solution in solution_list]}) + self.source.stream({'x': x_values, 'y': y_values, 'z': z_values, 'str': [s.__str__() for s in solution_list]}, + rollover=rollover) - def save(self, file_name: str): - html = file_html(models=self.figure, resources=CDN) - # todo Save to file + def __save(self, file_name: str): + html = file_html(models=self.doc, resources=CDN) + with open(file_name + '.html', 'w') as of: + of.write(html) def disconnect(self): if self.is_connected(): diff --git a/jmetal/util/solution_list_output.py b/jmetal/util/solution_list_output.py index 99741110..ad255580 100644 --- a/jmetal/util/solution_list_output.py +++ b/jmetal/util/solution_list_output.py @@ -1,32 +1,11 @@ import logging from typing import TypeVar, Generic -from jmetal.util.graphic import ScatterBokeh - S = TypeVar('S') logger = logging.getLogger(__name__) -class GraphicSolutionList(Generic[S]): - - def __init__(self, title: str, reference: list=None, number_of_objectives: int=2): - self.bokeh = ScatterBokeh(title, reference, number_of_objectives) - - def plot_frontier_to_file(self, solution_list: list, file_name: str): - """ Save plot of non-dominated solutions to file. For problems with TWO or THREE variables """ - self.bokeh.plot(solution_list) - self.bokeh.save(file_name) - - def plot_frontier_to_screen(self, solution_list: list): - """ Plot non-dominated solutions interactively. For problems with TWO or THREE variables """ - self.bokeh.plot(solution_list, show=True) - - def plot_frontier_live(self, solution_list: list, new_title: str, replace: bool): - """ Plot non-dominated solutions in real-time. For problems with TWO or THREE variables """ - self.bokeh.update(solution_list, new_title, replace) - - -class PrintSolutionList(Generic[S]): +class SolutionList(Generic[S]): @staticmethod def print_variables_to_screen(solution_list: list): diff --git a/requirements.txt b/requirements.txt index b85bb9c4..aa054361 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,7 @@ +bokeh==0.13.0 pytest==3.1.2 PyHamcrest==1.9.0 mockito==1.0.11 matplotlib==2.0.2 numpy==1.13.1 -dask[distributed]==0.17.4 \ No newline at end of file +dask[complete]==0.18.0 \ No newline at end of file From 29789c22b79311aa52376b3af186ee770564f29e Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 22 Jun 2018 13:12:58 +0200 Subject: [PATCH 64/90] Added labels --- jmetal/util/graphic.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index 42b5047a..208cdeb4 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -7,7 +7,7 @@ from bokeh.client import ClientSession from bokeh.io import curdoc, reset_output from bokeh.layouts import column, row -from bokeh.models import HoverTool, ColumnDataSource, TapTool, CustomJS, WheelZoomTool, Title +from bokeh.models import HoverTool, ColumnDataSource, TapTool, CustomJS, WheelZoomTool from bokeh.plotting import Figure from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt @@ -30,10 +30,15 @@ class Plot: - def __init__(self, plot_title: str, number_of_objectives: int): + def __init__(self, plot_title: str, number_of_objectives: int, + xaxis_label: str='', yaxis_label: str='', zaxis_label: str=''): self.plot_title = plot_title self.number_of_objectives = number_of_objectives + self.xaxis_label = xaxis_label + self.yaxis_label = yaxis_label + self.zaxis_label = zaxis_label + def get_objectives(self, solution_list: List[S]) -> Tuple[list, list, list]: if solution_list is None: raise Exception("Solution list is none!") @@ -195,6 +200,7 @@ def __init__(self, plot_title: str, number_of_objectives: int, ws_url: str='loca self.client = ClientSession(websocket_url="ws://{0}/ws".format(ws_url)) self.doc = curdoc() + self.doc.title = plot_title self.figure_xy = None self.figure_xz = None self.figure_yz = None @@ -213,13 +219,15 @@ def __initialize(self) -> None: self.plot_tools = [TapTool(callback=callback), WheelZoomTool(), 'save', 'pan', HoverTool(tooltips=[("index", "$index"), ("(x,y)", "($x, $y)")])] - def plot(self, solution_list: List[S], reference: List[S], output: str='', show: bool=True) -> None: + def plot(self, solution_list: List[S], reference: List[S]=None, output: str='', show: bool=True) -> None: # This is important to purge data (if any) between calls reset_output() # Set up figure self.figure_xy = Figure(output_backend='webgl', sizing_mode='scale_width', title=self.plot_title, tools=self.plot_tools) self.figure_xy.scatter(x='x', y='y', legend='solution', fill_alpha=0.7, source=self.source) + self.figure_xy.xaxis.axis_label = self.xaxis_label + self.figure_xy.yaxis.axis_label = self.yaxis_label x_values, y_values, z_values = self.get_objectives(solution_list) @@ -236,9 +244,13 @@ def plot(self, solution_list: List[S], reference: List[S], output: str='', show: # Add new figures for each axis self.figure_xz = Figure(title='xz', output_backend='webgl', sizing_mode='scale_width', tools=self.plot_tools) self.figure_xz.scatter(x='x', y='z', legend='solution', fill_alpha=0.7, source=self.source) + self.figure_xz.xaxis.axis_label = self.xaxis_label + self.figure_xz.yaxis.axis_label = self.zaxis_label self.figure_yz = Figure(title='yz', output_backend='webgl', sizing_mode='scale_width', tools=self.plot_tools) self.figure_yz.scatter(x='y', y='z', legend='solution', fill_alpha=0.7, source=self.source) + self.figure_yz.xaxis.axis_label = self.yaxis_label + self.figure_yz.yaxis.axis_label = self.zaxis_label # Plot reference solution list (if any) if reference: @@ -279,6 +291,9 @@ def update(self, solution_list: List[S], reference: List[S], new_title: str='', rollover=rollover) def __save(self, file_name: str): + # env = Environment(loader=FileSystemLoader(BASE_PATH + '/util/')) + # env.filters['json'] = lambda obj: Markup(json.dumps(obj)) + html = file_html(models=self.doc, resources=CDN) with open(file_name + '.html', 'w') as of: of.write(html) From 7f0ccc1d39fb3d90f21a6edaeea71080add4dedc Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 22 Jun 2018 13:13:22 +0200 Subject: [PATCH 65/90] Changed Bokeh version --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index aa054361..09cc7145 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -bokeh==0.13.0 +bokeh==0.12.16 pytest==3.1.2 PyHamcrest==1.9.0 mockito==1.0.11 From 0278d0c75cec917d6ff0a945c1e185773459de4a Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 26 Jun 2018 09:44:16 +0200 Subject: [PATCH 66/90] Syntax changes --- jmetal/algorithm/multiobjective/smpso.py | 2 + .../multiobjective/test/test_smpo.py | 6 +- .../singleobjective/evolutionaryalgorithm.py | 3 + jmetal/component/density_estimator.py | 5 +- jmetal/component/evaluator.py | 4 + jmetal/component/observer.py | 4 +- jmetal/component/test/test_archive.py | 37 +- .../component/test/test_density_estimator.py | 1 + jmetal/component/test/test_evaluator.py | 38 +- jmetal/core/operator.py | 4 +- jmetal/core/problem.py | 20 +- jmetal/operator/crossover.py | 2 +- jmetal/operator/mutation.py | 2 +- jmetal/operator/selection.py | 2 +- jmetal/problem/multiobjective/constrained.py | 8 +- jmetal/problem/multiobjective/dtlz.py | 6 +- .../multiobjective/test/test_constrained.py | 8 - .../multiobjective/test/test_unconstrained.py | 24 +- .../problem/multiobjective/test/test_zdt.py | 17 - .../problem/multiobjective/unconstrained.py | 17 +- jmetal/problem/multiobjective/zdt.py | 9 +- jmetal/problem/resources/DTLZ1.pf | 10000 ++++++++++++++++ .../data => jmetal/problem/resources}/ZDT1.pf | 0 jmetal/problem/resources/ZDT2.pf | 1000 ++ jmetal/problem/resources/ZDT3.pf | 1000 ++ jmetal/problem/resources/ZDT4.pf | 1000 ++ jmetal/problem/resources/ZDT6.pf | 1000 ++ .../nsgaii_standard_settings.py | 6 +- .../multiobjective/smpso_standard_settings.py | 12 +- jmetal/util/front_file.py | 16 +- jmetal/util/graphic.py | 14 +- jmetal/util/observable.py | 10 + jmetal/util/quality_indicator.py | 4 +- jmetal/util/ranking.py | 12 +- jmetal/util/test/test_comparator.py | 57 +- jmetal/util/test/test_observable.py | 9 +- jmetal/util/test/test_quality_indicator.py | 6 +- jmetal/util/test/test_ranking.py | 4 +- jmetal/util/time.py | 17 - 39 files changed, 14169 insertions(+), 217 deletions(-) create mode 100644 jmetal/problem/resources/DTLZ1.pf rename {resources/data => jmetal/problem/resources}/ZDT1.pf (100%) create mode 100644 jmetal/problem/resources/ZDT2.pf create mode 100644 jmetal/problem/resources/ZDT3.pf create mode 100644 jmetal/problem/resources/ZDT4.pf create mode 100644 jmetal/problem/resources/ZDT6.pf delete mode 100644 jmetal/util/time.py diff --git a/jmetal/algorithm/multiobjective/smpso.py b/jmetal/algorithm/multiobjective/smpso.py index c2b30a3a..0463b499 100644 --- a/jmetal/algorithm/multiobjective/smpso.py +++ b/jmetal/algorithm/multiobjective/smpso.py @@ -26,6 +26,7 @@ class SMPSO(ParticleSwarmOptimization): + def __init__(self, problem: FloatProblem, swarm_size: int, @@ -217,6 +218,7 @@ def __constriction_coefficient(self, c1: float, c2: float) -> float: class SMPSORP(SMPSO): + def __init__(self, problem: FloatProblem, swarm_size: int, max_evaluations: int, diff --git a/jmetal/algorithm/multiobjective/test/test_smpo.py b/jmetal/algorithm/multiobjective/test/test_smpo.py index fde77ddb..d7583835 100644 --- a/jmetal/algorithm/multiobjective/test/test_smpo.py +++ b/jmetal/algorithm/multiobjective/test/test_smpo.py @@ -10,8 +10,6 @@ class SMPSOTestCases(unittest.TestCase): - def setUp(self): - pass def test_should_constructor_create_a_valid_object(self): problem = self.__DummyFloatProblem() @@ -44,8 +42,8 @@ def __init__(self): self.number_of_objectives = 2 self.number_of_constraints = 0 - self.lower_bound = [-2.0 for i in range(self.number_of_variables)] - self.upper_bound = [2.0 for i in range(self.number_of_variables)] + self.lower_bound = [-2.0 for _ in range(self.number_of_variables)] + self.upper_bound = [2.0 for _ in range(self.number_of_variables)] FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound diff --git a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py index b3d1e68f..0fbe2b4a 100644 --- a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py +++ b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py @@ -20,6 +20,7 @@ class ElitistEvolutionStrategy(EvolutionaryAlgorithm[S, R]): + def __init__(self, problem: Problem[S], mu: int, @@ -86,6 +87,7 @@ def get_name(self): class NonElitistEvolutionStrategy(ElitistEvolutionStrategy[S, R]): + def __init__(self, problem: Problem[S], mu: int, lambdA: int, @@ -109,6 +111,7 @@ def get_name(self) -> str: class GenerationalGeneticAlgorithm(EvolutionaryAlgorithm[S, R]): + def __init__(self, problem: Problem[S], population_size: int, diff --git a/jmetal/component/density_estimator.py b/jmetal/component/density_estimator.py index 57cb4fe0..41651fb0 100644 --- a/jmetal/component/density_estimator.py +++ b/jmetal/component/density_estimator.py @@ -29,8 +29,9 @@ class CrowdingDistance(DensityEstimator[List[S]]): def compute_density_estimator(self, solution_list: List[S]): """This function performs the computation of the crowding density estimation over the solution list. - .. note:: - This method assign the distance in the inner elements of the solution list. + + .. note:: + This method assign the distance in the inner elements of the solution list. :param solution_list: The list of solutions. """ diff --git a/jmetal/component/evaluator.py b/jmetal/component/evaluator.py index 0f4aba83..280bb949 100644 --- a/jmetal/component/evaluator.py +++ b/jmetal/component/evaluator.py @@ -9,6 +9,7 @@ class Evaluator(Generic[S]): + def evaluate(self, solution_list: List[S], problem: Problem) -> List[S]: pass @@ -20,6 +21,7 @@ def evaluate_solution(solution: S, problem: Problem) -> None: class SequentialEvaluator(Evaluator[S]): + def evaluate(self, solution_list: List[S], problem: Problem) -> List[S]: for solution in solution_list: Evaluator.evaluate_solution(solution, problem) @@ -28,6 +30,7 @@ def evaluate(self, solution_list: List[S], problem: Problem) -> List[S]: class ParallelEvaluator(Evaluator[S]): + def __init__(self, processes=None): self.pool = ThreadPool(processes) @@ -38,6 +41,7 @@ def evaluate(self, solution_list: List[S], problem: Problem) -> List[S]: class DaskMultithreadedEvaluator(Evaluator[S]): + def __init__(self): self.client = Client() diff --git a/jmetal/component/observer.py b/jmetal/component/observer.py index cf66e682..581776fc 100644 --- a/jmetal/component/observer.py +++ b/jmetal/component/observer.py @@ -50,7 +50,7 @@ def __init__(self, problem: Problem, replace: bool=True) -> None: self.display_frequency = 1.0 self.replace = replace self.reference = problem.get_reference_front() - self.plot = ScatterMatplotlib(plot_title='VisualizerObserver', number_of_objectives=problem.number_of_objectives) + self.plot = ScatterMatplotlib('VisualizerObserver', problem.number_of_objectives) def update(self, *args, **kwargs): evaluations = kwargs["evaluations"] @@ -60,4 +60,4 @@ def update(self, *args, **kwargs): title = '{0}, Eval: {1}, Time: {2}'.format("VisualizerObserver", evaluations, computing_time) if (evaluations % self.display_frequency) == 0: - self.plot.update(solution_list=solution_list, reference=self.reference, new_title=title, persistence=self.replace) + self.plot.update(solution_list, self.reference, new_title=title, persistence=self.replace) diff --git a/jmetal/component/test/test_archive.py b/jmetal/component/test/test_archive.py index 59472af1..808ea35a 100644 --- a/jmetal/component/test/test_archive.py +++ b/jmetal/component/test/test_archive.py @@ -5,6 +5,7 @@ class ArchiveTestCases(unittest.TestCase): + def setUp(self): self.archive = Archive() @@ -16,6 +17,7 @@ def test_should_constructor_create_an_empty_list(self): class BoundedArchiveTestCases(unittest.TestCase): + def setUp(self): self.archive = BoundedArchive(5) @@ -27,6 +29,7 @@ def test_should_constructor_set_the_max_size(self): class NonDominatedSolutionListArchiveTestCases(unittest.TestCase): + def setUp(self): self.archive = NonDominatedSolutionListArchive() @@ -108,6 +111,7 @@ def test_should_adding_three_solutions_work_properly_if_two_of_them_are_equal(se class CrowdingDistanceArchiveTestCases(unittest.TestCase): + def setUp(self): self.archive = CrowdingDistanceArchive[Solution](5) @@ -128,8 +132,7 @@ def test_should_add_a_solution_when_the_archive_is_empty_work_properly(self): self.assertEqual(solution, self.archive.get(0)) def test_should_add_work_properly_case1(self) : - """ - Case 1: add a dominated solution when the archive size is 1 must not include the solution + """ Case 1: add a dominated solution when the archive size is 1 must not include the solution. """ solution1 = Solution(2, 2) solution1.objectives = [1, 2] @@ -143,8 +146,7 @@ def test_should_add_work_properly_case1(self) : self.assertEqual(solution1, self.archive.get(0)) def test_should_add_work_properly_case2(self) : - """ - Case 2: add a non-dominated solution when the archive size is 1 must include the solution + """ Case 2: add a non-dominated solution when the archive size is 1 must include the solution. """ solution1 = Solution(2, 2) solution1.objectives = [1, 2] @@ -159,8 +161,7 @@ def test_should_add_work_properly_case2(self) : self.assertTrue(solution2 in self.archive.get_solution_list()) def test_should_add_work_properly_case3(self) : - """ - Case 3: add a non-dominated solution when the archive size is 3 must include the solution + """ Case 3: add a non-dominated solution when the archive size is 3 must include the solution. """ solution1 = Solution(2, 2) solution1.objectives = [1.0, 2.0] @@ -183,8 +184,7 @@ def test_should_add_work_properly_case3(self) : self.assertTrue(solution4 in self.archive.get_solution_list()) def test_should_add_work_properly_case4(self) : - """ - Case 4: add a dominated solution when the archive size is 3 must not include the solution + """ Case 4: add a dominated solution when the archive size is 3 must not include the solution. """ solution1 = Solution(2, 2) solution1.objectives = [1.0, 2.0] @@ -206,8 +206,7 @@ def test_should_add_work_properly_case4(self) : self.assertTrue(solution3 in self.archive.get_solution_list()) def test_should_add_work_properly_case5(self) : - """ - Case 5: add a dominated solution when the archive is full should not include the solution + """ Case 5: add a dominated solution when the archive is full should not include the solution. """ solution1 = Solution(2, 2) solution1.objectives = [1.0, 2.0] @@ -229,9 +228,8 @@ def test_should_add_work_properly_case5(self) : self.assertTrue(solution3 in self.archive.get_solution_list()) def test_should_add_work_properly_case6(self) : - """ - Case 6: add a non-dominated solution when the archive is full should not include - the solution if it has the highest distance crowding value + """ Case 6: add a non-dominated solution when the archive is full should not include + the solution if it has the highest distance crowding value. """ archive = CrowdingDistanceArchive(4) @@ -257,9 +255,7 @@ def test_should_add_work_properly_case6(self) : self.assertTrue(new_solution not in archive.get_solution_list()) def test_should_add_work_properly_case7(self) : - """ - Case 7: add a non-dominated solution when the archive is full should remove all the - dominated solutions + """ Case 7: add a non-dominated solution when the archive is full should remove all the dominated solutions. """ archive = CrowdingDistanceArchive(4) @@ -285,8 +281,7 @@ def test_should_add_work_properly_case7(self) : self.assertTrue(new_solution in archive.get_solution_list()) def test_should_compute_density_estimator_work_properly_case1(self) : - """ - Case 1: The archive contains one solution + """ Case 1: The archive contains one solution. """ archive = CrowdingDistanceArchive(4) @@ -300,8 +295,7 @@ def test_should_compute_density_estimator_work_properly_case1(self) : self.assertEqual(float("inf"), solution1.attributes["crowding_distance"]) def test_should_compute_density_estimator_work_properly_case2(self) : - """ - Case 2: The archive contains two solutions + """ Case 2: The archive contains two solutions. """ archive = CrowdingDistanceArchive(4) @@ -320,8 +314,7 @@ def test_should_compute_density_estimator_work_properly_case2(self) : self.assertEqual(float("inf"), solution2.attributes["crowding_distance"]) def test_should_compute_density_estimator_work_properly_case3(self) : - """ - Case 3: The archive contains two solutions + """ Case 3: The archive contains two solutions. """ archive = CrowdingDistanceArchive(4) diff --git a/jmetal/component/test/test_density_estimator.py b/jmetal/component/test/test_density_estimator.py index 69251817..eb096372 100644 --- a/jmetal/component/test/test_density_estimator.py +++ b/jmetal/component/test/test_density_estimator.py @@ -5,6 +5,7 @@ class CrowdingDistanceTestCases(unittest.TestCase): + def setUp(self): self.crowding = CrowdingDistance() diff --git a/jmetal/component/test/test_evaluator.py b/jmetal/component/test/test_evaluator.py index 1dcfeccd..fb15c491 100644 --- a/jmetal/component/test/test_evaluator.py +++ b/jmetal/component/test/test_evaluator.py @@ -1,12 +1,12 @@ -import math import unittest -from jmetal.component.evaluator import SequentialEvaluator, DaskMultithreadedEvaluator -from jmetal.core.problem import Problem, FloatProblem +from jmetal.component.evaluator import SequentialEvaluator +from jmetal.core.problem import FloatProblem from jmetal.core.solution import FloatSolution class MockedProblem(FloatProblem): + def __init__(self, number_of_variables: int = 3): super().__init__() self.number_of_objectives = 2 @@ -27,6 +27,7 @@ def evaluate(self, solution: FloatSolution): class SequentialEvaluatorTestCases(unittest.TestCase): + def setUp(self): self.evaluator = SequentialEvaluator() self.problem = MockedProblem() @@ -52,36 +53,5 @@ def test_should_evaluate_a_list_of_problem_work_properly(self): self.assertEqual(2.3, problem_list[i].objectives[1]) -""" -class DaskMultithreadedEvaluatorTestCases(unittest.TestCase): - def setUp(self): - self.evaluator = DaskMultithreadedEvaluator() - self.problem = MockedProblem() - - def test_should_constructor_create_a_non_null_object(self): - self.assertIsNotNone(self.evaluator) - - def test_should_evaluate_a_list_of_problem_work_properly_with_a_solution(self): - problem_list = [self.problem.create_solution() for _ in range(1)] - - evaluated_list = self.evaluator.evaluate(problem_list, self.problem) - - self.assertEquals(1.2, evaluated_list[0].objectives[0]) - self.assertEquals(2.3, evaluated_list[0].objectives[1]) - - self.assertEquals(problem_list[0].variables[0], evaluated_list[0].variables[0]) - - def test_should_evaluate_a_list_of_problem_work_properly(self): - problem_list = [self.problem.create_solution() for _ in range(10)] - - evaluated_list = self.evaluator.evaluate(problem_list, self.problem) - - for i in range(10): - self.assertEquals(1.2, evaluated_list[i].objectives[0]) - self.assertEquals(2.3, evaluated_list[i].objectives[1]) - self.assertEquals(len(problem_list), len(evaluated_list)) -""" - - if __name__ == "__main__": unittest.main() diff --git a/jmetal/core/operator.py b/jmetal/core/operator.py index c258f60f..e3cf03c8 100644 --- a/jmetal/core/operator.py +++ b/jmetal/core/operator.py @@ -7,7 +7,7 @@ class Operator(Generic[S, R]): - """ Class representing operators """ + """ Class representing operator """ def execute(self, source: S) -> R: pass @@ -17,7 +17,7 @@ def get_name(self): class Mutation(Operator[S, S]): - """ Class representing mutation operators """ + """ Class representing mutation operator """ def __init__(self, probability: float): if probability > 1.0: diff --git a/jmetal/core/problem.py b/jmetal/core/problem.py index 4a155d95..1f98a704 100644 --- a/jmetal/core/problem.py +++ b/jmetal/core/problem.py @@ -1,4 +1,6 @@ +import os from os.path import dirname, join +from pathlib import Path from typing import Generic, TypeVar import random @@ -9,13 +11,13 @@ class Problem(Generic[S]): - """ Class representing problems """ + """ Class representing problems. """ def __init__(self): self.number_of_variables: int = None self.number_of_objectives: int = None self.number_of_constraints: int = None - self.reference_front_path: str = None + self.reference_front_path: str = 'problem/resources/{0}.pf'.format(self.get_name()) def evaluate(self, solution: S) -> S: raise NotImplemented @@ -28,20 +30,20 @@ def create_solution(self) -> S: def get_reference_front(self) -> list: front = [] - FILE_PATH = dirname(join(dirname(__file__))) + file_path = dirname(join(dirname(__file__))) + computed_path = join(file_path, self.reference_front_path) - if self.reference_front_path: - computed_path = join(walk_up_folder(FILE_PATH, 2), self.reference_front_path) + if Path(computed_path).is_file(): front = read_front_from_file_as_solutions(computed_path) return front def get_name(self) -> str: - raise NotImplemented + return self.__class__.__name__ class BinaryProblem(Problem[BinarySolution]): - """ Class representing binary problems """ + """ Class representing binary problems. """ def evaluate(self, solution: BinarySolution) -> None: pass @@ -51,7 +53,7 @@ def create_solution(self) -> BinarySolution: class FloatProblem(Problem[FloatSolution]): - """ Class representing float problems """ + """ Class representing float problems. """ def __init__(self): super().__init__() @@ -68,7 +70,7 @@ def create_solution(self) -> FloatSolution: class IntegerProblem(Problem[IntegerSolution]): - """ Class representing integer problems """ + """ Class representing integer problems. """ def __init__(self): super().__init__() diff --git a/jmetal/operator/crossover.py b/jmetal/operator/crossover.py index 71c722ed..c1d228f2 100644 --- a/jmetal/operator/crossover.py +++ b/jmetal/operator/crossover.py @@ -5,7 +5,7 @@ from jmetal.core.operator import Crossover from jmetal.core.solution import Solution, FloatSolution, BinarySolution -""" Class implementing the null crossover operators """ +""" Class implementing the null crossover operator """ class Null(Crossover[Solution, Solution]): diff --git a/jmetal/operator/mutation.py b/jmetal/operator/mutation.py index 54a8b83c..1a5bbc85 100644 --- a/jmetal/operator/mutation.py +++ b/jmetal/operator/mutation.py @@ -3,7 +3,7 @@ from jmetal.core.operator import Mutation from jmetal.core.solution import BinarySolution, Solution, FloatSolution, IntegerSolution -""" Class implementing the binary BitFlip mutation operators """ +""" Class implementing the binary BitFlip mutation operator """ __author__ = "Antonio J. Nebro" diff --git a/jmetal/operator/selection.py b/jmetal/operator/selection.py index 7308eb5f..e9e18a73 100644 --- a/jmetal/operator/selection.py +++ b/jmetal/operator/selection.py @@ -6,7 +6,7 @@ from jmetal.util.comparator import Comparator, DominanceComparator from jmetal.util.ranking import FastNonDominatedRanking -""" Class implementing a best solution selection operators """ +""" Class implementing a best solution selection operator """ S = TypeVar('S') diff --git a/jmetal/problem/multiobjective/constrained.py b/jmetal/problem/multiobjective/constrained.py index c7865f8c..e22e86d4 100644 --- a/jmetal/problem/multiobjective/constrained.py +++ b/jmetal/problem/multiobjective/constrained.py @@ -3,7 +3,13 @@ from jmetal.core.solution import FloatSolution from jmetal.core.problem import FloatProblem -""" Unconstrained Test problems for multi-objective optimization """ +""" +.. module:: constrained + :platform: Unix, Windows + :synopsis: Constrained test problems for multi-objective optimization + +.. moduleauthor:: Antonio J. Nebro +""" class Srinivas(FloatProblem): diff --git a/jmetal/problem/multiobjective/dtlz.py b/jmetal/problem/multiobjective/dtlz.py index 67f93a21..cacee429 100644 --- a/jmetal/problem/multiobjective/dtlz.py +++ b/jmetal/problem/multiobjective/dtlz.py @@ -19,8 +19,7 @@ class DTLZ1(FloatProblem): """ def __init__(self, number_of_variables: int = 7, number_of_objectives=3): - """Constructor - :param number_of_variables: number of decision variables of the problem + """ :param number_of_variables: number of decision variables of the problem """ super().__init__() self.number_of_variables = number_of_variables @@ -61,8 +60,7 @@ class DTLZ2(FloatProblem): """ def __init__(self, number_of_variables: int = 12, number_of_objectives=3): - """Constructor - :param number_of_variables: number of decision variables of the problem + """:param number_of_variables: number of decision variables of the problem """ super().__init__() self.number_of_variables = number_of_variables diff --git a/jmetal/problem/multiobjective/test/test_constrained.py b/jmetal/problem/multiobjective/test/test_constrained.py index 55af5e3d..7d0ac8e1 100644 --- a/jmetal/problem/multiobjective/test/test_constrained.py +++ b/jmetal/problem/multiobjective/test/test_constrained.py @@ -3,14 +3,9 @@ from jmetal.problem.multiobjective.constrained import Srinivas, Tanaka -__author__ = "Antonio J. Nebro" - class SrinivasTestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self) -> None: problem = Srinivas() self.assertIsNotNone(problem) @@ -41,9 +36,6 @@ def test_should_get_name_return_the_right_name(self): class TanakaTestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self) -> None: problem = Tanaka() self.assertIsNotNone(problem) diff --git a/jmetal/problem/multiobjective/test/test_unconstrained.py b/jmetal/problem/multiobjective/test/test_unconstrained.py index e8deda63..f3e95b8b 100644 --- a/jmetal/problem/multiobjective/test/test_unconstrained.py +++ b/jmetal/problem/multiobjective/test/test_unconstrained.py @@ -2,14 +2,10 @@ from jmetal.problem.multiobjective.unconstrained import Kursawe, Fonseca, Schaffer, Viennet2 -__author__ = "Antonio J. Nebro" class KursaweTestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self) -> None: problem = Kursawe(3) self.assertIsNotNone(problem) @@ -50,8 +46,6 @@ def test_should_get_name_return_the_right_name(self): class FonsecaTestCases(unittest.TestCase): - def setUp(self): - pass def test_should_constructor_create_a_non_null_object(self): problem = Fonseca() @@ -92,8 +86,8 @@ def test_should_create_solution_return_right_evaluation_values(self): problem.evaluate(solution1) - self.assertAlmostEqual(solution1.objectives[0], 0.991563628, 4); - self.assertAlmostEqual(solution1.objectives[1], 0.999663388, 4); + self.assertAlmostEqual(solution1.objectives[0], 0.991563628, 4) + self.assertAlmostEqual(solution1.objectives[1], 0.999663388, 4) def test_should_get_name_return_the_right_name(self): problem = Fonseca() @@ -102,9 +96,6 @@ def test_should_get_name_return_the_right_name(self): class SchafferTestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self): problem = Schaffer() self.assertIsNotNone(problem) @@ -145,11 +136,11 @@ def test_should_create_solution_return_right_evaluation_values(self): problem.evaluate(solution1) problem.evaluate(solution2) - self.assertAlmostEqual(solution1.objectives[0], 9); - self.assertAlmostEqual(solution1.objectives[1], 1); + self.assertAlmostEqual(solution1.objectives[0], 9) + self.assertAlmostEqual(solution1.objectives[1], 1) - self.assertAlmostEqual(solution2.objectives[0], 6.76); - self.assertAlmostEqual(solution2.objectives[1], 21.16); + self.assertAlmostEqual(solution2.objectives[0], 6.76) + self.assertAlmostEqual(solution2.objectives[1], 21.16) def test_should_get_name_return_the_right_name(self): problem = Schaffer() @@ -158,9 +149,6 @@ def test_should_get_name_return_the_right_name(self): class Viennet2TestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self): problem = Viennet2() self.assertIsNotNone(problem) diff --git a/jmetal/problem/multiobjective/test/test_zdt.py b/jmetal/problem/multiobjective/test/test_zdt.py index 929bc542..a87168ba 100644 --- a/jmetal/problem/multiobjective/test/test_zdt.py +++ b/jmetal/problem/multiobjective/test/test_zdt.py @@ -2,14 +2,9 @@ from jmetal.problem.multiobjective.zdt import ZDT1, ZDT2, ZDT3, ZDT4, ZDT6 -__author__ = "Antonio J. Nebro" - class ZDT1TestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self) -> None: problem = ZDT1() self.assertIsNotNone(problem) @@ -51,9 +46,6 @@ def test_should_get_name_return_the_right_name(self): class ZDT2TestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self) -> None: problem = ZDT2() self.assertIsNotNone(problem) @@ -95,9 +87,6 @@ def test_should_get_name_return_the_right_name(self): class ZDT3TestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self) -> None: problem = ZDT3() self.assertIsNotNone(problem) @@ -139,9 +128,6 @@ def test_should_get_name_return_the_right_name(self): class ZDT4TestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self) -> None: problem = ZDT4() self.assertIsNotNone(problem) @@ -191,9 +177,6 @@ def test_should_get_name_return_the_right_name(self): class ZDT6TestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self) -> None: problem = ZDT6() self.assertIsNotNone(problem) diff --git a/jmetal/problem/multiobjective/unconstrained.py b/jmetal/problem/multiobjective/unconstrained.py index e29bdc29..6da24312 100644 --- a/jmetal/problem/multiobjective/unconstrained.py +++ b/jmetal/problem/multiobjective/unconstrained.py @@ -3,11 +3,18 @@ from jmetal.core.problem import FloatProblem from jmetal.core.solution import FloatSolution -""" Unconstrained Test problems for multi-objective optimization """ +""" +.. module:: constrained + :platform: Unix, Windows + :synopsis: Unconstrained test problems for multi-objective optimization + +.. moduleauthor:: Antonio J. Nebro +""" class Kursawe(FloatProblem): - """ Class representing problem Kursawe """ + """ Class representing problem Kursawe. """ + def __init__(self, number_of_variables: int = 3): super().__init__() self.number_of_objectives = 2 @@ -37,7 +44,9 @@ def evaluate(self, solution: FloatSolution): class Fonseca(FloatProblem): + def __init__(self): + super().__init__() self.number_of_variables = 3 self.number_of_objectives = 2 self.number_of_constraints = 0 @@ -58,7 +67,9 @@ def evaluate(self, solution: FloatSolution): class Schaffer(FloatProblem): + def __init__(self): + super().__init__() self.number_of_variables = 1 self.number_of_objectives = 2 self.number_of_constraints = 0 @@ -80,7 +91,9 @@ def evaluate(self, solution: FloatSolution): class Viennet2(FloatProblem): + def __init__(self): + super().__init__() self.number_of_variables = 2 self.number_of_objectives = 3 self.number_of_constraints = 0 diff --git a/jmetal/problem/multiobjective/zdt.py b/jmetal/problem/multiobjective/zdt.py index e7f712fd..87f59f3d 100644 --- a/jmetal/problem/multiobjective/zdt.py +++ b/jmetal/problem/multiobjective/zdt.py @@ -13,7 +13,7 @@ class ZDT1(FloatProblem): - """ Problem ZDT1 + """ Problem ZDT1. .. note:: Bi-objective unconstrained problem. The default number of variables is 30. .. note:: Continuous problem having a convex Pareto front @@ -21,6 +21,7 @@ class ZDT1(FloatProblem): def __init__(self, number_of_variables: int = 30): """Constructor + :param number_of_variables: number of decision variables of the problem """ super().__init__() @@ -34,8 +35,6 @@ def __init__(self, number_of_variables: int = 30): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - self.reference_front_path = 'resources/data/ZDT1.pf' - def evaluate(self, solution: FloatSolution): g = self.__eval_g(solution) h = self.__eval_h(solution.variables[0], g) @@ -64,6 +63,7 @@ class ZDT2(FloatProblem): .. note:: Bi-objective unconstrained problem. The default number of variables is 30. .. note:: Continuous problem having a non-convex Pareto front """ + def __init__(self, number_of_variables: int = 30): super().__init__() self.number_of_variables = number_of_variables @@ -104,6 +104,7 @@ class ZDT3(FloatProblem): .. note:: Bi-objective unconstrained problem. The default number of variables is 30. .. note:: Continuous problem having a partitioned Pareto front """ + def __init__(self, number_of_variables: int = 30): super().__init__() self.number_of_variables = number_of_variables @@ -144,6 +145,7 @@ class ZDT4(FloatProblem): .. note:: Bi-objective unconstrained problem. The default number of variables is 10. .. note:: Continuous multi-modal problem having a convex Pareto front """ + def __init__(self, number_of_variables: int = 10): super().__init__() self.number_of_variables = number_of_variables @@ -188,6 +190,7 @@ class ZDT6(FloatProblem): .. note:: Bi-objective unconstrained problem. The default number of variables is 10. .. note:: Continuous problem having a non-convex Pareto front """ + def __init__(self, number_of_variables: int = 10): super().__init__() self.number_of_variables = number_of_variables diff --git a/jmetal/problem/resources/DTLZ1.pf b/jmetal/problem/resources/DTLZ1.pf new file mode 100644 index 00000000..48d5dbc8 --- /dev/null +++ b/jmetal/problem/resources/DTLZ1.pf @@ -0,0 +1,10000 @@ +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0 0.5 +0 0.005 0.495 +5e-005 0.00495 0.495 +0.0001 0.0049 0.495 +0.00015 0.00485 0.495 +0.0002 0.0048 0.495 +0.00025 0.00475 0.495 +0.0003 0.0047 0.495 +0.00035 0.00465 0.495 +0.0004 0.0046 0.495 +0.00045 0.00455 0.495 +0.0005 0.0045 0.495 +0.00055 0.00445 0.495 +0.0006 0.0044 0.495 +0.00065 0.00435 0.495 +0.0007 0.0043 0.495 +0.00075 0.00425 0.495 +0.0008 0.0042 0.495 +0.00085 0.00415 0.495 +0.0009 0.0041 0.495 +0.00095 0.00405 0.495 +0.001 0.004 0.495 +0.00105 0.00395 0.495 +0.0011 0.0039 0.495 +0.00115 0.00385 0.495 +0.0012 0.0038 0.495 +0.00125 0.00375 0.495 +0.0013 0.0037 0.495 +0.00135 0.00365 0.495 +0.0014 0.0036 0.495 +0.00145 0.00355 0.495 +0.0015 0.0035 0.495 +0.00155 0.00345 0.495 +0.0016 0.0034 0.495 +0.00165 0.00335 0.495 +0.0017 0.0033 0.495 +0.00175 0.00325 0.495 +0.0018 0.0032 0.495 +0.00185 0.00315 0.495 +0.0019 0.0031 0.495 +0.00195 0.00305 0.495 +0.002 0.003 0.495 +0.00205 0.00295 0.495 +0.0021 0.0029 0.495 +0.00215 0.00285 0.495 +0.0022 0.0028 0.495 +0.00225 0.00275 0.495 +0.0023 0.0027 0.495 +0.00235 0.00265 0.495 +0.0024 0.0026 0.495 +0.00245 0.00255 0.495 +0.0025 0.0025 0.495 +0.00255 0.00245 0.495 +0.0026 0.0024 0.495 +0.00265 0.00235 0.495 +0.0027 0.0023 0.495 +0.00275 0.00225 0.495 +0.0028 0.0022 0.495 +0.00285 0.00215 0.495 +0.0029 0.0021 0.495 +0.00295 0.00205 0.495 +0.003 0.002 0.495 +0.00305 0.00195 0.495 +0.0031 0.0019 0.495 +0.00315 0.00185 0.495 +0.0032 0.0018 0.495 +0.00325 0.00175 0.495 +0.0033 0.0017 0.495 +0.00335 0.00165 0.495 +0.0034 0.0016 0.495 +0.00345 0.00155 0.495 +0.0035 0.0015 0.495 +0.00355 0.00145 0.495 +0.0036 0.0014 0.495 +0.00365 0.00135 0.495 +0.0037 0.0013 0.495 +0.00375 0.00125 0.495 +0.0038 0.0012 0.495 +0.00385 0.00115 0.495 +0.0039 0.0011 0.495 +0.00395 0.00105 0.495 +0.004 0.001 0.495 +0.00405 0.00095 0.495 +0.0041 0.0009 0.495 +0.00415 0.00085 0.495 +0.0042 0.0008 0.495 +0.00425 0.00075 0.495 +0.0043 0.0007 0.495 +0.00435 0.00065 0.495 +0.0044 0.0006 0.495 +0.00445 0.00055 0.495 +0.0045 0.0005 0.495 +0.00455 0.00045 0.495 +0.0046 0.0004 0.495 +0.00465 0.00035 0.495 +0.0047 0.0003 0.495 +0.00475 0.00025 0.495 +0.0048 0.0002 0.495 +0.00485 0.00015 0.495 +0.0049 0.0001 0.495 +0.00495 5e-005 0.495 +0 0.01 0.49 +0.0001 0.0099 0.49 +0.0002 0.0098 0.49 +0.0003 0.0097 0.49 +0.0004 0.0096 0.49 +0.0005 0.0095 0.49 +0.0006 0.0094 0.49 +0.0007 0.0093 0.49 +0.0008 0.0092 0.49 +0.0009 0.0091 0.49 +0.001 0.009 0.49 +0.0011 0.0089 0.49 +0.0012 0.0088 0.49 +0.0013 0.0087 0.49 +0.0014 0.0086 0.49 +0.0015 0.0085 0.49 +0.0016 0.0084 0.49 +0.0017 0.0083 0.49 +0.0018 0.0082 0.49 +0.0019 0.0081 0.49 +0.002 0.008 0.49 +0.0021 0.0079 0.49 +0.0022 0.0078 0.49 +0.0023 0.0077 0.49 +0.0024 0.0076 0.49 +0.0025 0.0075 0.49 +0.0026 0.0074 0.49 +0.0027 0.0073 0.49 +0.0028 0.0072 0.49 +0.0029 0.0071 0.49 +0.003 0.007 0.49 +0.0031 0.0069 0.49 +0.0032 0.0068 0.49 +0.0033 0.0067 0.49 +0.0034 0.0066 0.49 +0.0035 0.0065 0.49 +0.0036 0.0064 0.49 +0.0037 0.0063 0.49 +0.0038 0.0062 0.49 +0.0039 0.0061 0.49 +0.004 0.006 0.49 +0.0041 0.0059 0.49 +0.0042 0.0058 0.49 +0.0043 0.0057 0.49 +0.0044 0.0056 0.49 +0.0045 0.0055 0.49 +0.0046 0.0054 0.49 +0.0047 0.0053 0.49 +0.0048 0.0052 0.49 +0.0049 0.0051 0.49 +0.005 0.005 0.49 +0.0051 0.0049 0.49 +0.0052 0.0048 0.49 +0.0053 0.0047 0.49 +0.0054 0.0046 0.49 +0.0055 0.0045 0.49 +0.0056 0.0044 0.49 +0.0057 0.0043 0.49 +0.0058 0.0042 0.49 +0.0059 0.0041 0.49 +0.006 0.004 0.49 +0.0061 0.0039 0.49 +0.0062 0.0038 0.49 +0.0063 0.0037 0.49 +0.0064 0.0036 0.49 +0.0065 0.0035 0.49 +0.0066 0.0034 0.49 +0.0067 0.0033 0.49 +0.0068 0.0032 0.49 +0.0069 0.0031 0.49 +0.007 0.003 0.49 +0.0071 0.0029 0.49 +0.0072 0.0028 0.49 +0.0073 0.0027 0.49 +0.0074 0.0026 0.49 +0.0075 0.0025 0.49 +0.0076 0.0024 0.49 +0.0077 0.0023 0.49 +0.0078 0.0022 0.49 +0.0079 0.0021 0.49 +0.008 0.002 0.49 +0.0081 0.0019 0.49 +0.0082 0.0018 0.49 +0.0083 0.0017 0.49 +0.0084 0.0016 0.49 +0.0085 0.0015 0.49 +0.0086 0.0014 0.49 +0.0087 0.0013 0.49 +0.0088 0.0012 0.49 +0.0089 0.0011 0.49 +0.009 0.001 0.49 +0.0091 0.0009 0.49 +0.0092 0.0008 0.49 +0.0093 0.0007 0.49 +0.0094 0.0006 0.49 +0.0095 0.0005 0.49 +0.0096 0.0004 0.49 +0.0097 0.0003 0.49 +0.0098 0.0002 0.49 +0.0099 0.0001 0.49 +0 0.015 0.485 +0.00015 0.01485 0.485 +0.0003 0.0147 0.485 +0.00045 0.01455 0.485 +0.0006 0.0144 0.485 +0.00075 0.01425 0.485 +0.0009 0.0141 0.485 +0.00105 0.01395 0.485 +0.0012 0.0138 0.485 +0.00135 0.01365 0.485 +0.0015 0.0135 0.485 +0.00165 0.01335 0.485 +0.0018 0.0132 0.485 +0.00195 0.01305 0.485 +0.0021 0.0129 0.485 +0.00225 0.01275 0.485 +0.0024 0.0126 0.485 +0.00255 0.01245 0.485 +0.0027 0.0123 0.485 +0.00285 0.01215 0.485 +0.003 0.012 0.485 +0.00315 0.01185 0.485 +0.0033 0.0117 0.485 +0.00345 0.01155 0.485 +0.0036 0.0114 0.485 +0.00375 0.01125 0.485 +0.0039 0.0111 0.485 +0.00405 0.01095 0.485 +0.0042 0.0108 0.485 +0.00435 0.01065 0.485 +0.0045 0.0105 0.485 +0.00465 0.01035 0.485 +0.0048 0.0102 0.485 +0.00495 0.01005 0.485 +0.0051 0.0099 0.485 +0.00525 0.00975 0.485 +0.0054 0.0096 0.485 +0.00555 0.00945 0.485 +0.0057 0.0093 0.485 +0.00585 0.00915 0.485 +0.006 0.009 0.485 +0.00615 0.00885 0.485 +0.0063 0.0087 0.485 +0.00645 0.00855 0.485 +0.0066 0.0084 0.485 +0.00675 0.00825 0.485 +0.0069 0.0081 0.485 +0.00705 0.00795 0.485 +0.0072 0.0078 0.485 +0.00735 0.00765 0.485 +0.0075 0.0075 0.485 +0.00765 0.00735 0.485 +0.0078 0.0072 0.485 +0.00795 0.00705 0.485 +0.0081 0.0069 0.485 +0.00825 0.00675 0.485 +0.0084 0.0066 0.485 +0.00855 0.00645 0.485 +0.0087 0.0063 0.485 +0.00885 0.00615 0.485 +0.009 0.006 0.485 +0.00915 0.00585 0.485 +0.0093 0.0057 0.485 +0.00945 0.00555 0.485 +0.0096 0.0054 0.485 +0.00975 0.00525 0.485 +0.0099 0.0051 0.485 +0.01005 0.00495 0.485 +0.0102 0.0048 0.485 +0.01035 0.00465 0.485 +0.0105 0.0045 0.485 +0.01065 0.00435 0.485 +0.0108 0.0042 0.485 +0.01095 0.00405 0.485 +0.0111 0.0039 0.485 +0.01125 0.00375 0.485 +0.0114 0.0036 0.485 +0.01155 0.00345 0.485 +0.0117 0.0033 0.485 +0.01185 0.00315 0.485 +0.012 0.003 0.485 +0.01215 0.00285 0.485 +0.0123 0.0027 0.485 +0.01245 0.00255 0.485 +0.0126 0.0024 0.485 +0.01275 0.00225 0.485 +0.0129 0.0021 0.485 +0.01305 0.00195 0.485 +0.0132 0.0018 0.485 +0.01335 0.00165 0.485 +0.0135 0.0015 0.485 +0.01365 0.00135 0.485 +0.0138 0.0012 0.485 +0.01395 0.00105 0.485 +0.0141 0.0009 0.485 +0.01425 0.00075 0.485 +0.0144 0.0006 0.485 +0.01455 0.00045 0.485 +0.0147 0.0003 0.485 +0.01485 0.00015 0.485 +0 0.02 0.48 +0.0002 0.0198 0.48 +0.0004 0.0196 0.48 +0.0006 0.0194 0.48 +0.0008 0.0192 0.48 +0.001 0.019 0.48 +0.0012 0.0188 0.48 +0.0014 0.0186 0.48 +0.0016 0.0184 0.48 +0.0018 0.0182 0.48 +0.002 0.018 0.48 +0.0022 0.0178 0.48 +0.0024 0.0176 0.48 +0.0026 0.0174 0.48 +0.0028 0.0172 0.48 +0.003 0.017 0.48 +0.0032 0.0168 0.48 +0.0034 0.0166 0.48 +0.0036 0.0164 0.48 +0.0038 0.0162 0.48 +0.004 0.016 0.48 +0.0042 0.0158 0.48 +0.0044 0.0156 0.48 +0.0046 0.0154 0.48 +0.0048 0.0152 0.48 +0.005 0.015 0.48 +0.0052 0.0148 0.48 +0.0054 0.0146 0.48 +0.0056 0.0144 0.48 +0.0058 0.0142 0.48 +0.006 0.014 0.48 +0.0062 0.0138 0.48 +0.0064 0.0136 0.48 +0.0066 0.0134 0.48 +0.0068 0.0132 0.48 +0.007 0.013 0.48 +0.0072 0.0128 0.48 +0.0074 0.0126 0.48 +0.0076 0.0124 0.48 +0.0078 0.0122 0.48 +0.008 0.012 0.48 +0.0082 0.0118 0.48 +0.0084 0.0116 0.48 +0.0086 0.0114 0.48 +0.0088 0.0112 0.48 +0.009 0.011 0.48 +0.0092 0.0108 0.48 +0.0094 0.0106 0.48 +0.0096 0.0104 0.48 +0.0098 0.0102 0.48 +0.01 0.01 0.48 +0.0102 0.0098 0.48 +0.0104 0.0096 0.48 +0.0106 0.0094 0.48 +0.0108 0.0092 0.48 +0.011 0.009 0.48 +0.0112 0.0088 0.48 +0.0114 0.0086 0.48 +0.0116 0.0084 0.48 +0.0118 0.0082 0.48 +0.012 0.008 0.48 +0.0122 0.0078 0.48 +0.0124 0.0076 0.48 +0.0126 0.0074 0.48 +0.0128 0.0072 0.48 +0.013 0.007 0.48 +0.0132 0.0068 0.48 +0.0134 0.0066 0.48 +0.0136 0.0064 0.48 +0.0138 0.0062 0.48 +0.014 0.006 0.48 +0.0142 0.0058 0.48 +0.0144 0.0056 0.48 +0.0146 0.0054 0.48 +0.0148 0.0052 0.48 +0.015 0.005 0.48 +0.0152 0.0048 0.48 +0.0154 0.0046 0.48 +0.0156 0.0044 0.48 +0.0158 0.0042 0.48 +0.016 0.004 0.48 +0.0162 0.0038 0.48 +0.0164 0.0036 0.48 +0.0166 0.0034 0.48 +0.0168 0.0032 0.48 +0.017 0.003 0.48 +0.0172 0.0028 0.48 +0.0174 0.0026 0.48 +0.0176 0.0024 0.48 +0.0178 0.0022 0.48 +0.018 0.002 0.48 +0.0182 0.0018 0.48 +0.0184 0.0016 0.48 +0.0186 0.0014 0.48 +0.0188 0.0012 0.48 +0.019 0.001 0.48 +0.0192 0.0008 0.48 +0.0194 0.0006 0.48 +0.0196 0.0004 0.48 +0.0198 0.0002 0.48 +0 0.025 0.475 +0.00025 0.02475 0.475 +0.0005 0.0245 0.475 +0.00075 0.02425 0.475 +0.001 0.024 0.475 +0.00125 0.02375 0.475 +0.0015 0.0235 0.475 +0.00175 0.02325 0.475 +0.002 0.023 0.475 +0.00225 0.02275 0.475 +0.0025 0.0225 0.475 +0.00275 0.02225 0.475 +0.003 0.022 0.475 +0.00325 0.02175 0.475 +0.0035 0.0215 0.475 +0.00375 0.02125 0.475 +0.004 0.021 0.475 +0.00425 0.02075 0.475 +0.0045 0.0205 0.475 +0.00475 0.02025 0.475 +0.005 0.02 0.475 +0.00525 0.01975 0.475 +0.0055 0.0195 0.475 +0.00575 0.01925 0.475 +0.006 0.019 0.475 +0.00625 0.01875 0.475 +0.0065 0.0185 0.475 +0.00675 0.01825 0.475 +0.007 0.018 0.475 +0.00725 0.01775 0.475 +0.0075 0.0175 0.475 +0.00775 0.01725 0.475 +0.008 0.017 0.475 +0.00825 0.01675 0.475 +0.0085 0.0165 0.475 +0.00875 0.01625 0.475 +0.009 0.016 0.475 +0.00925 0.01575 0.475 +0.0095 0.0155 0.475 +0.00975 0.01525 0.475 +0.01 0.015 0.475 +0.01025 0.01475 0.475 +0.0105 0.0145 0.475 +0.01075 0.01425 0.475 +0.011 0.014 0.475 +0.01125 0.01375 0.475 +0.0115 0.0135 0.475 +0.01175 0.01325 0.475 +0.012 0.013 0.475 +0.01225 0.01275 0.475 +0.0125 0.0125 0.475 +0.01275 0.01225 0.475 +0.013 0.012 0.475 +0.01325 0.01175 0.475 +0.0135 0.0115 0.475 +0.01375 0.01125 0.475 +0.014 0.011 0.475 +0.01425 0.01075 0.475 +0.0145 0.0105 0.475 +0.01475 0.01025 0.475 +0.015 0.01 0.475 +0.01525 0.00975 0.475 +0.0155 0.0095 0.475 +0.01575 0.00925 0.475 +0.016 0.009 0.475 +0.01625 0.00875 0.475 +0.0165 0.0085 0.475 +0.01675 0.00825 0.475 +0.017 0.008 0.475 +0.01725 0.00775 0.475 +0.0175 0.0075 0.475 +0.01775 0.00725 0.475 +0.018 0.007 0.475 +0.01825 0.00675 0.475 +0.0185 0.0065 0.475 +0.01875 0.00625 0.475 +0.019 0.006 0.475 +0.01925 0.00575 0.475 +0.0195 0.0055 0.475 +0.01975 0.00525 0.475 +0.02 0.005 0.475 +0.02025 0.00475 0.475 +0.0205 0.0045 0.475 +0.02075 0.00425 0.475 +0.021 0.004 0.475 +0.02125 0.00375 0.475 +0.0215 0.0035 0.475 +0.02175 0.00325 0.475 +0.022 0.003 0.475 +0.02225 0.00275 0.475 +0.0225 0.0025 0.475 +0.02275 0.00225 0.475 +0.023 0.002 0.475 +0.02325 0.00175 0.475 +0.0235 0.0015 0.475 +0.02375 0.00125 0.475 +0.024 0.001 0.475 +0.02425 0.00075 0.475 +0.0245 0.0005 0.475 +0.02475 0.00025 0.475 +0 0.03 0.47 +0.0003 0.0297 0.47 +0.0006 0.0294 0.47 +0.0009 0.0291 0.47 +0.0012 0.0288 0.47 +0.0015 0.0285 0.47 +0.0018 0.0282 0.47 +0.0021 0.0279 0.47 +0.0024 0.0276 0.47 +0.0027 0.0273 0.47 +0.003 0.027 0.47 +0.0033 0.0267 0.47 +0.0036 0.0264 0.47 +0.0039 0.0261 0.47 +0.0042 0.0258 0.47 +0.0045 0.0255 0.47 +0.0048 0.0252 0.47 +0.0051 0.0249 0.47 +0.0054 0.0246 0.47 +0.0057 0.0243 0.47 +0.006 0.024 0.47 +0.0063 0.0237 0.47 +0.0066 0.0234 0.47 +0.0069 0.0231 0.47 +0.0072 0.0228 0.47 +0.0075 0.0225 0.47 +0.0078 0.0222 0.47 +0.0081 0.0219 0.47 +0.0084 0.0216 0.47 +0.0087 0.0213 0.47 +0.009 0.021 0.47 +0.0093 0.0207 0.47 +0.0096 0.0204 0.47 +0.0099 0.0201 0.47 +0.0102 0.0198 0.47 +0.0105 0.0195 0.47 +0.0108 0.0192 0.47 +0.0111 0.0189 0.47 +0.0114 0.0186 0.47 +0.0117 0.0183 0.47 +0.012 0.018 0.47 +0.0123 0.0177 0.47 +0.0126 0.0174 0.47 +0.0129 0.0171 0.47 +0.0132 0.0168 0.47 +0.0135 0.0165 0.47 +0.0138 0.0162 0.47 +0.0141 0.0159 0.47 +0.0144 0.0156 0.47 +0.0147 0.0153 0.47 +0.015 0.015 0.47 +0.0153 0.0147 0.47 +0.0156 0.0144 0.47 +0.0159 0.0141 0.47 +0.0162 0.0138 0.47 +0.0165 0.0135 0.47 +0.0168 0.0132 0.47 +0.0171 0.0129 0.47 +0.0174 0.0126 0.47 +0.0177 0.0123 0.47 +0.018 0.012 0.47 +0.0183 0.0117 0.47 +0.0186 0.0114 0.47 +0.0189 0.0111 0.47 +0.0192 0.0108 0.47 +0.0195 0.0105 0.47 +0.0198 0.0102 0.47 +0.0201 0.0099 0.47 +0.0204 0.0096 0.47 +0.0207 0.0093 0.47 +0.021 0.009 0.47 +0.0213 0.0087 0.47 +0.0216 0.0084 0.47 +0.0219 0.0081 0.47 +0.0222 0.0078 0.47 +0.0225 0.0075 0.47 +0.0228 0.0072 0.47 +0.0231 0.0069 0.47 +0.0234 0.0066 0.47 +0.0237 0.0063 0.47 +0.024 0.006 0.47 +0.0243 0.0057 0.47 +0.0246 0.0054 0.47 +0.0249 0.0051 0.47 +0.0252 0.0048 0.47 +0.0255 0.0045 0.47 +0.0258 0.0042 0.47 +0.0261 0.0039 0.47 +0.0264 0.0036 0.47 +0.0267 0.0033 0.47 +0.027 0.003 0.47 +0.0273 0.0027 0.47 +0.0276 0.0024 0.47 +0.0279 0.0021 0.47 +0.0282 0.0018 0.47 +0.0285 0.0015 0.47 +0.0288 0.0012 0.47 +0.0291 0.0009 0.47 +0.0294 0.0006 0.47 +0.0297 0.0003 0.47 +0 0.035 0.465 +0.00035 0.03465 0.465 +0.0007 0.0343 0.465 +0.00105 0.03395 0.465 +0.0014 0.0336 0.465 +0.00175 0.03325 0.465 +0.0021 0.0329 0.465 +0.00245 0.03255 0.465 +0.0028 0.0322 0.465 +0.00315 0.03185 0.465 +0.0035 0.0315 0.465 +0.00385 0.03115 0.465 +0.0042 0.0308 0.465 +0.00455 0.03045 0.465 +0.0049 0.0301 0.465 +0.00525 0.02975 0.465 +0.0056 0.0294 0.465 +0.00595 0.02905 0.465 +0.0063 0.0287 0.465 +0.00665 0.02835 0.465 +0.007 0.028 0.465 +0.00735 0.02765 0.465 +0.0077 0.0273 0.465 +0.00805 0.02695 0.465 +0.0084 0.0266 0.465 +0.00875 0.02625 0.465 +0.0091 0.0259 0.465 +0.00945 0.02555 0.465 +0.0098 0.0252 0.465 +0.01015 0.02485 0.465 +0.0105 0.0245 0.465 +0.01085 0.02415 0.465 +0.0112 0.0238 0.465 +0.01155 0.02345 0.465 +0.0119 0.0231 0.465 +0.01225 0.02275 0.465 +0.0126 0.0224 0.465 +0.01295 0.02205 0.465 +0.0133 0.0217 0.465 +0.01365 0.02135 0.465 +0.014 0.021 0.465 +0.01435 0.02065 0.465 +0.0147 0.0203 0.465 +0.01505 0.01995 0.465 +0.0154 0.0196 0.465 +0.01575 0.01925 0.465 +0.0161 0.0189 0.465 +0.01645 0.01855 0.465 +0.0168 0.0182 0.465 +0.01715 0.01785 0.465 +0.0175 0.0175 0.465 +0.01785 0.01715 0.465 +0.0182 0.0168 0.465 +0.01855 0.01645 0.465 +0.0189 0.0161 0.465 +0.01925 0.01575 0.465 +0.0196 0.0154 0.465 +0.01995 0.01505 0.465 +0.0203 0.0147 0.465 +0.02065 0.01435 0.465 +0.021 0.014 0.465 +0.02135 0.01365 0.465 +0.0217 0.0133 0.465 +0.02205 0.01295 0.465 +0.0224 0.0126 0.465 +0.02275 0.01225 0.465 +0.0231 0.0119 0.465 +0.02345 0.01155 0.465 +0.0238 0.0112 0.465 +0.02415 0.01085 0.465 +0.0245 0.0105 0.465 +0.02485 0.01015 0.465 +0.0252 0.0098 0.465 +0.02555 0.00945 0.465 +0.0259 0.0091 0.465 +0.02625 0.00875 0.465 +0.0266 0.0084 0.465 +0.02695 0.00805 0.465 +0.0273 0.0077 0.465 +0.02765 0.00735 0.465 +0.028 0.007 0.465 +0.02835 0.00665 0.465 +0.0287 0.0063 0.465 +0.02905 0.00595 0.465 +0.0294 0.0056 0.465 +0.02975 0.00525 0.465 +0.0301 0.0049 0.465 +0.03045 0.00455 0.465 +0.0308 0.0042 0.465 +0.03115 0.00385 0.465 +0.0315 0.0035 0.465 +0.03185 0.00315 0.465 +0.0322 0.0028 0.465 +0.03255 0.00245 0.465 +0.0329 0.0021 0.465 +0.03325 0.00175 0.465 +0.0336 0.0014 0.465 +0.03395 0.00105 0.465 +0.0343 0.0007 0.465 +0.03465 0.00035 0.465 +0 0.04 0.46 +0.0004 0.0396 0.46 +0.0008 0.0392 0.46 +0.0012 0.0388 0.46 +0.0016 0.0384 0.46 +0.002 0.038 0.46 +0.0024 0.0376 0.46 +0.0028 0.0372 0.46 +0.0032 0.0368 0.46 +0.0036 0.0364 0.46 +0.004 0.036 0.46 +0.0044 0.0356 0.46 +0.0048 0.0352 0.46 +0.0052 0.0348 0.46 +0.0056 0.0344 0.46 +0.006 0.034 0.46 +0.0064 0.0336 0.46 +0.0068 0.0332 0.46 +0.0072 0.0328 0.46 +0.0076 0.0324 0.46 +0.008 0.032 0.46 +0.0084 0.0316 0.46 +0.0088 0.0312 0.46 +0.0092 0.0308 0.46 +0.0096 0.0304 0.46 +0.01 0.03 0.46 +0.0104 0.0296 0.46 +0.0108 0.0292 0.46 +0.0112 0.0288 0.46 +0.0116 0.0284 0.46 +0.012 0.028 0.46 +0.0124 0.0276 0.46 +0.0128 0.0272 0.46 +0.0132 0.0268 0.46 +0.0136 0.0264 0.46 +0.014 0.026 0.46 +0.0144 0.0256 0.46 +0.0148 0.0252 0.46 +0.0152 0.0248 0.46 +0.0156 0.0244 0.46 +0.016 0.024 0.46 +0.0164 0.0236 0.46 +0.0168 0.0232 0.46 +0.0172 0.0228 0.46 +0.0176 0.0224 0.46 +0.018 0.022 0.46 +0.0184 0.0216 0.46 +0.0188 0.0212 0.46 +0.0192 0.0208 0.46 +0.0196 0.0204 0.46 +0.02 0.02 0.46 +0.0204 0.0196 0.46 +0.0208 0.0192 0.46 +0.0212 0.0188 0.46 +0.0216 0.0184 0.46 +0.022 0.018 0.46 +0.0224 0.0176 0.46 +0.0228 0.0172 0.46 +0.0232 0.0168 0.46 +0.0236 0.0164 0.46 +0.024 0.016 0.46 +0.0244 0.0156 0.46 +0.0248 0.0152 0.46 +0.0252 0.0148 0.46 +0.0256 0.0144 0.46 +0.026 0.014 0.46 +0.0264 0.0136 0.46 +0.0268 0.0132 0.46 +0.0272 0.0128 0.46 +0.0276 0.0124 0.46 +0.028 0.012 0.46 +0.0284 0.0116 0.46 +0.0288 0.0112 0.46 +0.0292 0.0108 0.46 +0.0296 0.0104 0.46 +0.03 0.01 0.46 +0.0304 0.0096 0.46 +0.0308 0.0092 0.46 +0.0312 0.0088 0.46 +0.0316 0.0084 0.46 +0.032 0.008 0.46 +0.0324 0.0076 0.46 +0.0328 0.0072 0.46 +0.0332 0.0068 0.46 +0.0336 0.0064 0.46 +0.034 0.006 0.46 +0.0344 0.0056 0.46 +0.0348 0.0052 0.46 +0.0352 0.0048 0.46 +0.0356 0.0044 0.46 +0.036 0.004 0.46 +0.0364 0.0036 0.46 +0.0368 0.0032 0.46 +0.0372 0.0028 0.46 +0.0376 0.0024 0.46 +0.038 0.002 0.46 +0.0384 0.0016 0.46 +0.0388 0.0012 0.46 +0.0392 0.0008 0.46 +0.0396 0.0004 0.46 +0 0.045 0.455 +0.00045 0.04455 0.455 +0.0009 0.0441 0.455 +0.00135 0.04365 0.455 +0.0018 0.0432 0.455 +0.00225 0.04275 0.455 +0.0027 0.0423 0.455 +0.00315 0.04185 0.455 +0.0036 0.0414 0.455 +0.00405 0.04095 0.455 +0.0045 0.0405 0.455 +0.00495 0.04005 0.455 +0.0054 0.0396 0.455 +0.00585 0.03915 0.455 +0.0063 0.0387 0.455 +0.00675 0.03825 0.455 +0.0072 0.0378 0.455 +0.00765 0.03735 0.455 +0.0081 0.0369 0.455 +0.00855 0.03645 0.455 +0.009 0.036 0.455 +0.00945 0.03555 0.455 +0.0099 0.0351 0.455 +0.01035 0.03465 0.455 +0.0108 0.0342 0.455 +0.01125 0.03375 0.455 +0.0117 0.0333 0.455 +0.01215 0.03285 0.455 +0.0126 0.0324 0.455 +0.01305 0.03195 0.455 +0.0135 0.0315 0.455 +0.01395 0.03105 0.455 +0.0144 0.0306 0.455 +0.01485 0.03015 0.455 +0.0153 0.0297 0.455 +0.01575 0.02925 0.455 +0.0162 0.0288 0.455 +0.01665 0.02835 0.455 +0.0171 0.0279 0.455 +0.01755 0.02745 0.455 +0.018 0.027 0.455 +0.01845 0.02655 0.455 +0.0189 0.0261 0.455 +0.01935 0.02565 0.455 +0.0198 0.0252 0.455 +0.02025 0.02475 0.455 +0.0207 0.0243 0.455 +0.02115 0.02385 0.455 +0.0216 0.0234 0.455 +0.02205 0.02295 0.455 +0.0225 0.0225 0.455 +0.02295 0.02205 0.455 +0.0234 0.0216 0.455 +0.02385 0.02115 0.455 +0.0243 0.0207 0.455 +0.02475 0.02025 0.455 +0.0252 0.0198 0.455 +0.02565 0.01935 0.455 +0.0261 0.0189 0.455 +0.02655 0.01845 0.455 +0.027 0.018 0.455 +0.02745 0.01755 0.455 +0.0279 0.0171 0.455 +0.02835 0.01665 0.455 +0.0288 0.0162 0.455 +0.02925 0.01575 0.455 +0.0297 0.0153 0.455 +0.03015 0.01485 0.455 +0.0306 0.0144 0.455 +0.03105 0.01395 0.455 +0.0315 0.0135 0.455 +0.03195 0.01305 0.455 +0.0324 0.0126 0.455 +0.03285 0.01215 0.455 +0.0333 0.0117 0.455 +0.03375 0.01125 0.455 +0.0342 0.0108 0.455 +0.03465 0.01035 0.455 +0.0351 0.0099 0.455 +0.03555 0.00945 0.455 +0.036 0.009 0.455 +0.03645 0.00855 0.455 +0.0369 0.0081 0.455 +0.03735 0.00765 0.455 +0.0378 0.0072 0.455 +0.03825 0.00675 0.455 +0.0387 0.0063 0.455 +0.03915 0.00585 0.455 +0.0396 0.0054 0.455 +0.04005 0.00495 0.455 +0.0405 0.0045 0.455 +0.04095 0.00405 0.455 +0.0414 0.0036 0.455 +0.04185 0.00315 0.455 +0.0423 0.0027 0.455 +0.04275 0.00225 0.455 +0.0432 0.0018 0.455 +0.04365 0.00135 0.455 +0.0441 0.0009 0.455 +0.04455 0.00045 0.455 +0 0.05 0.45 +0.0005 0.0495 0.45 +0.001 0.049 0.45 +0.0015 0.0485 0.45 +0.002 0.048 0.45 +0.0025 0.0475 0.45 +0.003 0.047 0.45 +0.0035 0.0465 0.45 +0.004 0.046 0.45 +0.0045 0.0455 0.45 +0.005 0.045 0.45 +0.0055 0.0445 0.45 +0.006 0.044 0.45 +0.0065 0.0435 0.45 +0.007 0.043 0.45 +0.0075 0.0425 0.45 +0.008 0.042 0.45 +0.0085 0.0415 0.45 +0.009 0.041 0.45 +0.0095 0.0405 0.45 +0.01 0.04 0.45 +0.0105 0.0395 0.45 +0.011 0.039 0.45 +0.0115 0.0385 0.45 +0.012 0.038 0.45 +0.0125 0.0375 0.45 +0.013 0.037 0.45 +0.0135 0.0365 0.45 +0.014 0.036 0.45 +0.0145 0.0355 0.45 +0.015 0.035 0.45 +0.0155 0.0345 0.45 +0.016 0.034 0.45 +0.0165 0.0335 0.45 +0.017 0.033 0.45 +0.0175 0.0325 0.45 +0.018 0.032 0.45 +0.0185 0.0315 0.45 +0.019 0.031 0.45 +0.0195 0.0305 0.45 +0.02 0.03 0.45 +0.0205 0.0295 0.45 +0.021 0.029 0.45 +0.0215 0.0285 0.45 +0.022 0.028 0.45 +0.0225 0.0275 0.45 +0.023 0.027 0.45 +0.0235 0.0265 0.45 +0.024 0.026 0.45 +0.0245 0.0255 0.45 +0.025 0.025 0.45 +0.0255 0.0245 0.45 +0.026 0.024 0.45 +0.0265 0.0235 0.45 +0.027 0.023 0.45 +0.0275 0.0225 0.45 +0.028 0.022 0.45 +0.0285 0.0215 0.45 +0.029 0.021 0.45 +0.0295 0.0205 0.45 +0.03 0.02 0.45 +0.0305 0.0195 0.45 +0.031 0.019 0.45 +0.0315 0.0185 0.45 +0.032 0.018 0.45 +0.0325 0.0175 0.45 +0.033 0.017 0.45 +0.0335 0.0165 0.45 +0.034 0.016 0.45 +0.0345 0.0155 0.45 +0.035 0.015 0.45 +0.0355 0.0145 0.45 +0.036 0.014 0.45 +0.0365 0.0135 0.45 +0.037 0.013 0.45 +0.0375 0.0125 0.45 +0.038 0.012 0.45 +0.0385 0.0115 0.45 +0.039 0.011 0.45 +0.0395 0.0105 0.45 +0.04 0.01 0.45 +0.0405 0.0095 0.45 +0.041 0.009 0.45 +0.0415 0.0085 0.45 +0.042 0.008 0.45 +0.0425 0.0075 0.45 +0.043 0.007 0.45 +0.0435 0.0065 0.45 +0.044 0.006 0.45 +0.0445 0.0055 0.45 +0.045 0.005 0.45 +0.0455 0.0045 0.45 +0.046 0.004 0.45 +0.0465 0.0035 0.45 +0.047 0.003 0.45 +0.0475 0.0025 0.45 +0.048 0.002 0.45 +0.0485 0.0015 0.45 +0.049 0.001 0.45 +0.0495 0.0005 0.45 +0 0.055 0.445 +0.00055 0.05445 0.445 +0.0011 0.0539 0.445 +0.00165 0.05335 0.445 +0.0022 0.0528 0.445 +0.00275 0.05225 0.445 +0.0033 0.0517 0.445 +0.00385 0.05115 0.445 +0.0044 0.0506 0.445 +0.00495 0.05005 0.445 +0.0055 0.0495 0.445 +0.00605 0.04895 0.445 +0.0066 0.0484 0.445 +0.00715 0.04785 0.445 +0.0077 0.0473 0.445 +0.00825 0.04675 0.445 +0.0088 0.0462 0.445 +0.00935 0.04565 0.445 +0.0099 0.0451 0.445 +0.01045 0.04455 0.445 +0.011 0.044 0.445 +0.01155 0.04345 0.445 +0.0121 0.0429 0.445 +0.01265 0.04235 0.445 +0.0132 0.0418 0.445 +0.01375 0.04125 0.445 +0.0143 0.0407 0.445 +0.01485 0.04015 0.445 +0.0154 0.0396 0.445 +0.01595 0.03905 0.445 +0.0165 0.0385 0.445 +0.01705 0.03795 0.445 +0.0176 0.0374 0.445 +0.01815 0.03685 0.445 +0.0187 0.0363 0.445 +0.01925 0.03575 0.445 +0.0198 0.0352 0.445 +0.02035 0.03465 0.445 +0.0209 0.0341 0.445 +0.02145 0.03355 0.445 +0.022 0.033 0.445 +0.02255 0.03245 0.445 +0.0231 0.0319 0.445 +0.02365 0.03135 0.445 +0.0242 0.0308 0.445 +0.02475 0.03025 0.445 +0.0253 0.0297 0.445 +0.02585 0.02915 0.445 +0.0264 0.0286 0.445 +0.02695 0.02805 0.445 +0.0275 0.0275 0.445 +0.02805 0.02695 0.445 +0.0286 0.0264 0.445 +0.02915 0.02585 0.445 +0.0297 0.0253 0.445 +0.03025 0.02475 0.445 +0.0308 0.0242 0.445 +0.03135 0.02365 0.445 +0.0319 0.0231 0.445 +0.03245 0.02255 0.445 +0.033 0.022 0.445 +0.03355 0.02145 0.445 +0.0341 0.0209 0.445 +0.03465 0.02035 0.445 +0.0352 0.0198 0.445 +0.03575 0.01925 0.445 +0.0363 0.0187 0.445 +0.03685 0.01815 0.445 +0.0374 0.0176 0.445 +0.03795 0.01705 0.445 +0.0385 0.0165 0.445 +0.03905 0.01595 0.445 +0.0396 0.0154 0.445 +0.04015 0.01485 0.445 +0.0407 0.0143 0.445 +0.04125 0.01375 0.445 +0.0418 0.0132 0.445 +0.04235 0.01265 0.445 +0.0429 0.0121 0.445 +0.04345 0.01155 0.445 +0.044 0.011 0.445 +0.04455 0.01045 0.445 +0.0451 0.0099 0.445 +0.04565 0.00935 0.445 +0.0462 0.0088 0.445 +0.04675 0.00825 0.445 +0.0473 0.0077 0.445 +0.04785 0.00715 0.445 +0.0484 0.0066 0.445 +0.04895 0.00605 0.445 +0.0495 0.0055 0.445 +0.05005 0.00495 0.445 +0.0506 0.0044 0.445 +0.05115 0.00385 0.445 +0.0517 0.0033 0.445 +0.05225 0.00275 0.445 +0.0528 0.0022 0.445 +0.05335 0.00165 0.445 +0.0539 0.0011 0.445 +0.05445 0.00055 0.445 +0 0.06 0.44 +0.0006 0.0594 0.44 +0.0012 0.0588 0.44 +0.0018 0.0582 0.44 +0.0024 0.0576 0.44 +0.003 0.057 0.44 +0.0036 0.0564 0.44 +0.0042 0.0558 0.44 +0.0048 0.0552 0.44 +0.0054 0.0546 0.44 +0.006 0.054 0.44 +0.0066 0.0534 0.44 +0.0072 0.0528 0.44 +0.0078 0.0522 0.44 +0.0084 0.0516 0.44 +0.009 0.051 0.44 +0.0096 0.0504 0.44 +0.0102 0.0498 0.44 +0.0108 0.0492 0.44 +0.0114 0.0486 0.44 +0.012 0.048 0.44 +0.0126 0.0474 0.44 +0.0132 0.0468 0.44 +0.0138 0.0462 0.44 +0.0144 0.0456 0.44 +0.015 0.045 0.44 +0.0156 0.0444 0.44 +0.0162 0.0438 0.44 +0.0168 0.0432 0.44 +0.0174 0.0426 0.44 +0.018 0.042 0.44 +0.0186 0.0414 0.44 +0.0192 0.0408 0.44 +0.0198 0.0402 0.44 +0.0204 0.0396 0.44 +0.021 0.039 0.44 +0.0216 0.0384 0.44 +0.0222 0.0378 0.44 +0.0228 0.0372 0.44 +0.0234 0.0366 0.44 +0.024 0.036 0.44 +0.0246 0.0354 0.44 +0.0252 0.0348 0.44 +0.0258 0.0342 0.44 +0.0264 0.0336 0.44 +0.027 0.033 0.44 +0.0276 0.0324 0.44 +0.0282 0.0318 0.44 +0.0288 0.0312 0.44 +0.0294 0.0306 0.44 +0.03 0.03 0.44 +0.0306 0.0294 0.44 +0.0312 0.0288 0.44 +0.0318 0.0282 0.44 +0.0324 0.0276 0.44 +0.033 0.027 0.44 +0.0336 0.0264 0.44 +0.0342 0.0258 0.44 +0.0348 0.0252 0.44 +0.0354 0.0246 0.44 +0.036 0.024 0.44 +0.0366 0.0234 0.44 +0.0372 0.0228 0.44 +0.0378 0.0222 0.44 +0.0384 0.0216 0.44 +0.039 0.021 0.44 +0.0396 0.0204 0.44 +0.0402 0.0198 0.44 +0.0408 0.0192 0.44 +0.0414 0.0186 0.44 +0.042 0.018 0.44 +0.0426 0.0174 0.44 +0.0432 0.0168 0.44 +0.0438 0.0162 0.44 +0.0444 0.0156 0.44 +0.045 0.015 0.44 +0.0456 0.0144 0.44 +0.0462 0.0138 0.44 +0.0468 0.0132 0.44 +0.0474 0.0126 0.44 +0.048 0.012 0.44 +0.0486 0.0114 0.44 +0.0492 0.0108 0.44 +0.0498 0.0102 0.44 +0.0504 0.0096 0.44 +0.051 0.009 0.44 +0.0516 0.0084 0.44 +0.0522 0.0078 0.44 +0.0528 0.0072 0.44 +0.0534 0.0066 0.44 +0.054 0.006 0.44 +0.0546 0.0054 0.44 +0.0552 0.0048 0.44 +0.0558 0.0042 0.44 +0.0564 0.0036 0.44 +0.057 0.003 0.44 +0.0576 0.0024 0.44 +0.0582 0.0018 0.44 +0.0588 0.0012 0.44 +0.0594 0.0006 0.44 +0 0.065 0.435 +0.00065 0.06435 0.435 +0.0013 0.0637 0.435 +0.00195 0.06305 0.435 +0.0026 0.0624 0.435 +0.00325 0.06175 0.435 +0.0039 0.0611 0.435 +0.00455 0.06045 0.435 +0.0052 0.0598 0.435 +0.00585 0.05915 0.435 +0.0065 0.0585 0.435 +0.00715 0.05785 0.435 +0.0078 0.0572 0.435 +0.00845 0.05655 0.435 +0.0091 0.0559 0.435 +0.00975 0.05525 0.435 +0.0104 0.0546 0.435 +0.01105 0.05395 0.435 +0.0117 0.0533 0.435 +0.01235 0.05265 0.435 +0.013 0.052 0.435 +0.01365 0.05135 0.435 +0.0143 0.0507 0.435 +0.01495 0.05005 0.435 +0.0156 0.0494 0.435 +0.01625 0.04875 0.435 +0.0169 0.0481 0.435 +0.01755 0.04745 0.435 +0.0182 0.0468 0.435 +0.01885 0.04615 0.435 +0.0195 0.0455 0.435 +0.02015 0.04485 0.435 +0.0208 0.0442 0.435 +0.02145 0.04355 0.435 +0.0221 0.0429 0.435 +0.02275 0.04225 0.435 +0.0234 0.0416 0.435 +0.02405 0.04095 0.435 +0.0247 0.0403 0.435 +0.02535 0.03965 0.435 +0.026 0.039 0.435 +0.02665 0.03835 0.435 +0.0273 0.0377 0.435 +0.02795 0.03705 0.435 +0.0286 0.0364 0.435 +0.02925 0.03575 0.435 +0.0299 0.0351 0.435 +0.03055 0.03445 0.435 +0.0312 0.0338 0.435 +0.03185 0.03315 0.435 +0.0325 0.0325 0.435 +0.03315 0.03185 0.435 +0.0338 0.0312 0.435 +0.03445 0.03055 0.435 +0.0351 0.0299 0.435 +0.03575 0.02925 0.435 +0.0364 0.0286 0.435 +0.03705 0.02795 0.435 +0.0377 0.0273 0.435 +0.03835 0.02665 0.435 +0.039 0.026 0.435 +0.03965 0.02535 0.435 +0.0403 0.0247 0.435 +0.04095 0.02405 0.435 +0.0416 0.0234 0.435 +0.04225 0.02275 0.435 +0.0429 0.0221 0.435 +0.04355 0.02145 0.435 +0.0442 0.0208 0.435 +0.04485 0.02015 0.435 +0.0455 0.0195 0.435 +0.04615 0.01885 0.435 +0.0468 0.0182 0.435 +0.04745 0.01755 0.435 +0.0481 0.0169 0.435 +0.04875 0.01625 0.435 +0.0494 0.0156 0.435 +0.05005 0.01495 0.435 +0.0507 0.0143 0.435 +0.05135 0.01365 0.435 +0.052 0.013 0.435 +0.05265 0.01235 0.435 +0.0533 0.0117 0.435 +0.05395 0.01105 0.435 +0.0546 0.0104 0.435 +0.05525 0.00975 0.435 +0.0559 0.0091 0.435 +0.05655 0.00845 0.435 +0.0572 0.0078 0.435 +0.05785 0.00715 0.435 +0.0585 0.0065 0.435 +0.05915 0.00585 0.435 +0.0598 0.0052 0.435 +0.06045 0.00455 0.435 +0.0611 0.0039 0.435 +0.06175 0.00325 0.435 +0.0624 0.0026 0.435 +0.06305 0.00195 0.435 +0.0637 0.0013 0.435 +0.06435 0.00065 0.435 +0 0.07 0.43 +0.0007 0.0693 0.43 +0.0014 0.0686 0.43 +0.0021 0.0679 0.43 +0.0028 0.0672 0.43 +0.0035 0.0665 0.43 +0.0042 0.0658 0.43 +0.0049 0.0651 0.43 +0.0056 0.0644 0.43 +0.0063 0.0637 0.43 +0.007 0.063 0.43 +0.0077 0.0623 0.43 +0.0084 0.0616 0.43 +0.0091 0.0609 0.43 +0.0098 0.0602 0.43 +0.0105 0.0595 0.43 +0.0112 0.0588 0.43 +0.0119 0.0581 0.43 +0.0126 0.0574 0.43 +0.0133 0.0567 0.43 +0.014 0.056 0.43 +0.0147 0.0553 0.43 +0.0154 0.0546 0.43 +0.0161 0.0539 0.43 +0.0168 0.0532 0.43 +0.0175 0.0525 0.43 +0.0182 0.0518 0.43 +0.0189 0.0511 0.43 +0.0196 0.0504 0.43 +0.0203 0.0497 0.43 +0.021 0.049 0.43 +0.0217 0.0483 0.43 +0.0224 0.0476 0.43 +0.0231 0.0469 0.43 +0.0238 0.0462 0.43 +0.0245 0.0455 0.43 +0.0252 0.0448 0.43 +0.0259 0.0441 0.43 +0.0266 0.0434 0.43 +0.0273 0.0427 0.43 +0.028 0.042 0.43 +0.0287 0.0413 0.43 +0.0294 0.0406 0.43 +0.0301 0.0399 0.43 +0.0308 0.0392 0.43 +0.0315 0.0385 0.43 +0.0322 0.0378 0.43 +0.0329 0.0371 0.43 +0.0336 0.0364 0.43 +0.0343 0.0357 0.43 +0.035 0.035 0.43 +0.0357 0.0343 0.43 +0.0364 0.0336 0.43 +0.0371 0.0329 0.43 +0.0378 0.0322 0.43 +0.0385 0.0315 0.43 +0.0392 0.0308 0.43 +0.0399 0.0301 0.43 +0.0406 0.0294 0.43 +0.0413 0.0287 0.43 +0.042 0.028 0.43 +0.0427 0.0273 0.43 +0.0434 0.0266 0.43 +0.0441 0.0259 0.43 +0.0448 0.0252 0.43 +0.0455 0.0245 0.43 +0.0462 0.0238 0.43 +0.0469 0.0231 0.43 +0.0476 0.0224 0.43 +0.0483 0.0217 0.43 +0.049 0.021 0.43 +0.0497 0.0203 0.43 +0.0504 0.0196 0.43 +0.0511 0.0189 0.43 +0.0518 0.0182 0.43 +0.0525 0.0175 0.43 +0.0532 0.0168 0.43 +0.0539 0.0161 0.43 +0.0546 0.0154 0.43 +0.0553 0.0147 0.43 +0.056 0.014 0.43 +0.0567 0.0133 0.43 +0.0574 0.0126 0.43 +0.0581 0.0119 0.43 +0.0588 0.0112 0.43 +0.0595 0.0105 0.43 +0.0602 0.0098 0.43 +0.0609 0.0091 0.43 +0.0616 0.0084 0.43 +0.0623 0.0077 0.43 +0.063 0.007 0.43 +0.0637 0.0063 0.43 +0.0644 0.0056 0.43 +0.0651 0.0049 0.43 +0.0658 0.0042 0.43 +0.0665 0.0035 0.43 +0.0672 0.0028 0.43 +0.0679 0.0021 0.43 +0.0686 0.0014 0.43 +0.0693 0.0007 0.43 +0 0.075 0.425 +0.00075 0.07425 0.425 +0.0015 0.0735 0.425 +0.00225 0.07275 0.425 +0.003 0.072 0.425 +0.00375 0.07125 0.425 +0.0045 0.0705 0.425 +0.00525 0.06975 0.425 +0.006 0.069 0.425 +0.00675 0.06825 0.425 +0.0075 0.0675 0.425 +0.00825 0.06675 0.425 +0.009 0.066 0.425 +0.00975 0.06525 0.425 +0.0105 0.0645 0.425 +0.01125 0.06375 0.425 +0.012 0.063 0.425 +0.01275 0.06225 0.425 +0.0135 0.0615 0.425 +0.01425 0.06075 0.425 +0.015 0.06 0.425 +0.01575 0.05925 0.425 +0.0165 0.0585 0.425 +0.01725 0.05775 0.425 +0.018 0.057 0.425 +0.01875 0.05625 0.425 +0.0195 0.0555 0.425 +0.02025 0.05475 0.425 +0.021 0.054 0.425 +0.02175 0.05325 0.425 +0.0225 0.0525 0.425 +0.02325 0.05175 0.425 +0.024 0.051 0.425 +0.02475 0.05025 0.425 +0.0255 0.0495 0.425 +0.02625 0.04875 0.425 +0.027 0.048 0.425 +0.02775 0.04725 0.425 +0.0285 0.0465 0.425 +0.02925 0.04575 0.425 +0.03 0.045 0.425 +0.03075 0.04425 0.425 +0.0315 0.0435 0.425 +0.03225 0.04275 0.425 +0.033 0.042 0.425 +0.03375 0.04125 0.425 +0.0345 0.0405 0.425 +0.03525 0.03975 0.425 +0.036 0.039 0.425 +0.03675 0.03825 0.425 +0.0375 0.0375 0.425 +0.03825 0.03675 0.425 +0.039 0.036 0.425 +0.03975 0.03525 0.425 +0.0405 0.0345 0.425 +0.04125 0.03375 0.425 +0.042 0.033 0.425 +0.04275 0.03225 0.425 +0.0435 0.0315 0.425 +0.04425 0.03075 0.425 +0.045 0.03 0.425 +0.04575 0.02925 0.425 +0.0465 0.0285 0.425 +0.04725 0.02775 0.425 +0.048 0.027 0.425 +0.04875 0.02625 0.425 +0.0495 0.0255 0.425 +0.05025 0.02475 0.425 +0.051 0.024 0.425 +0.05175 0.02325 0.425 +0.0525 0.0225 0.425 +0.05325 0.02175 0.425 +0.054 0.021 0.425 +0.05475 0.02025 0.425 +0.0555 0.0195 0.425 +0.05625 0.01875 0.425 +0.057 0.018 0.425 +0.05775 0.01725 0.425 +0.0585 0.0165 0.425 +0.05925 0.01575 0.425 +0.06 0.015 0.425 +0.06075 0.01425 0.425 +0.0615 0.0135 0.425 +0.06225 0.01275 0.425 +0.063 0.012 0.425 +0.06375 0.01125 0.425 +0.0645 0.0105 0.425 +0.06525 0.00975 0.425 +0.066 0.009 0.425 +0.06675 0.00825 0.425 +0.0675 0.0075 0.425 +0.06825 0.00675 0.425 +0.069 0.006 0.425 +0.06975 0.00525 0.425 +0.0705 0.0045 0.425 +0.07125 0.00375 0.425 +0.072 0.003 0.425 +0.07275 0.00225 0.425 +0.0735 0.0015 0.425 +0.07425 0.00075 0.425 +0 0.08 0.42 +0.0008 0.0792 0.42 +0.0016 0.0784 0.42 +0.0024 0.0776 0.42 +0.0032 0.0768 0.42 +0.004 0.076 0.42 +0.0048 0.0752 0.42 +0.0056 0.0744 0.42 +0.0064 0.0736 0.42 +0.0072 0.0728 0.42 +0.008 0.072 0.42 +0.0088 0.0712 0.42 +0.0096 0.0704 0.42 +0.0104 0.0696 0.42 +0.0112 0.0688 0.42 +0.012 0.068 0.42 +0.0128 0.0672 0.42 +0.0136 0.0664 0.42 +0.0144 0.0656 0.42 +0.0152 0.0648 0.42 +0.016 0.064 0.42 +0.0168 0.0632 0.42 +0.0176 0.0624 0.42 +0.0184 0.0616 0.42 +0.0192 0.0608 0.42 +0.02 0.06 0.42 +0.0208 0.0592 0.42 +0.0216 0.0584 0.42 +0.0224 0.0576 0.42 +0.0232 0.0568 0.42 +0.024 0.056 0.42 +0.0248 0.0552 0.42 +0.0256 0.0544 0.42 +0.0264 0.0536 0.42 +0.0272 0.0528 0.42 +0.028 0.052 0.42 +0.0288 0.0512 0.42 +0.0296 0.0504 0.42 +0.0304 0.0496 0.42 +0.0312 0.0488 0.42 +0.032 0.048 0.42 +0.0328 0.0472 0.42 +0.0336 0.0464 0.42 +0.0344 0.0456 0.42 +0.0352 0.0448 0.42 +0.036 0.044 0.42 +0.0368 0.0432 0.42 +0.0376 0.0424 0.42 +0.0384 0.0416 0.42 +0.0392 0.0408 0.42 +0.04 0.04 0.42 +0.0408 0.0392 0.42 +0.0416 0.0384 0.42 +0.0424 0.0376 0.42 +0.0432 0.0368 0.42 +0.044 0.036 0.42 +0.0448 0.0352 0.42 +0.0456 0.0344 0.42 +0.0464 0.0336 0.42 +0.0472 0.0328 0.42 +0.048 0.032 0.42 +0.0488 0.0312 0.42 +0.0496 0.0304 0.42 +0.0504 0.0296 0.42 +0.0512 0.0288 0.42 +0.052 0.028 0.42 +0.0528 0.0272 0.42 +0.0536 0.0264 0.42 +0.0544 0.0256 0.42 +0.0552 0.0248 0.42 +0.056 0.024 0.42 +0.0568 0.0232 0.42 +0.0576 0.0224 0.42 +0.0584 0.0216 0.42 +0.0592 0.0208 0.42 +0.06 0.02 0.42 +0.0608 0.0192 0.42 +0.0616 0.0184 0.42 +0.0624 0.0176 0.42 +0.0632 0.0168 0.42 +0.064 0.016 0.42 +0.0648 0.0152 0.42 +0.0656 0.0144 0.42 +0.0664 0.0136 0.42 +0.0672 0.0128 0.42 +0.068 0.012 0.42 +0.0688 0.0112 0.42 +0.0696 0.0104 0.42 +0.0704 0.0096 0.42 +0.0712 0.0088 0.42 +0.072 0.008 0.42 +0.0728 0.0072 0.42 +0.0736 0.0064 0.42 +0.0744 0.0056 0.42 +0.0752 0.0048 0.42 +0.076 0.004 0.42 +0.0768 0.0032 0.42 +0.0776 0.0024 0.42 +0.0784 0.0016 0.42 +0.0792 0.0008 0.42 +0 0.085 0.415 +0.00085 0.08415 0.415 +0.0017 0.0833 0.415 +0.00255 0.08245 0.415 +0.0034 0.0816 0.415 +0.00425 0.08075 0.415 +0.0051 0.0799 0.415 +0.00595 0.07905 0.415 +0.0068 0.0782 0.415 +0.00765 0.07735 0.415 +0.0085 0.0765 0.415 +0.00935 0.07565 0.415 +0.0102 0.0748 0.415 +0.01105 0.07395 0.415 +0.0119 0.0731 0.415 +0.01275 0.07225 0.415 +0.0136 0.0714 0.415 +0.01445 0.07055 0.415 +0.0153 0.0697 0.415 +0.01615 0.06885 0.415 +0.017 0.068 0.415 +0.01785 0.06715 0.415 +0.0187 0.0663 0.415 +0.01955 0.06545 0.415 +0.0204 0.0646 0.415 +0.02125 0.06375 0.415 +0.0221 0.0629 0.415 +0.02295 0.06205 0.415 +0.0238 0.0612 0.415 +0.02465 0.06035 0.415 +0.0255 0.0595 0.415 +0.02635 0.05865 0.415 +0.0272 0.0578 0.415 +0.02805 0.05695 0.415 +0.0289 0.0561 0.415 +0.02975 0.05525 0.415 +0.0306 0.0544 0.415 +0.03145 0.05355 0.415 +0.0323 0.0527 0.415 +0.03315 0.05185 0.415 +0.034 0.051 0.415 +0.03485 0.05015 0.415 +0.0357 0.0493 0.415 +0.03655 0.04845 0.415 +0.0374 0.0476 0.415 +0.03825 0.04675 0.415 +0.0391 0.0459 0.415 +0.03995 0.04505 0.415 +0.0408 0.0442 0.415 +0.04165 0.04335 0.415 +0.0425 0.0425 0.415 +0.04335 0.04165 0.415 +0.0442 0.0408 0.415 +0.04505 0.03995 0.415 +0.0459 0.0391 0.415 +0.04675 0.03825 0.415 +0.0476 0.0374 0.415 +0.04845 0.03655 0.415 +0.0493 0.0357 0.415 +0.05015 0.03485 0.415 +0.051 0.034 0.415 +0.05185 0.03315 0.415 +0.0527 0.0323 0.415 +0.05355 0.03145 0.415 +0.0544 0.0306 0.415 +0.05525 0.02975 0.415 +0.0561 0.0289 0.415 +0.05695 0.02805 0.415 +0.0578 0.0272 0.415 +0.05865 0.02635 0.415 +0.0595 0.0255 0.415 +0.06035 0.02465 0.415 +0.0612 0.0238 0.415 +0.06205 0.02295 0.415 +0.0629 0.0221 0.415 +0.06375 0.02125 0.415 +0.0646 0.0204 0.415 +0.06545 0.01955 0.415 +0.0663 0.0187 0.415 +0.06715 0.01785 0.415 +0.068 0.017 0.415 +0.06885 0.01615 0.415 +0.0697 0.0153 0.415 +0.07055 0.01445 0.415 +0.0714 0.0136 0.415 +0.07225 0.01275 0.415 +0.0731 0.0119 0.415 +0.07395 0.01105 0.415 +0.0748 0.0102 0.415 +0.07565 0.00935 0.415 +0.0765 0.0085 0.415 +0.07735 0.00765 0.415 +0.0782 0.0068 0.415 +0.07905 0.00595 0.415 +0.0799 0.0051 0.415 +0.08075 0.00425 0.415 +0.0816 0.0034 0.415 +0.08245 0.00255 0.415 +0.0833 0.0017 0.415 +0.08415 0.00085 0.415 +0 0.09 0.41 +0.0009 0.0891 0.41 +0.0018 0.0882 0.41 +0.0027 0.0873 0.41 +0.0036 0.0864 0.41 +0.0045 0.0855 0.41 +0.0054 0.0846 0.41 +0.0063 0.0837 0.41 +0.0072 0.0828 0.41 +0.0081 0.0819 0.41 +0.009 0.081 0.41 +0.0099 0.0801 0.41 +0.0108 0.0792 0.41 +0.0117 0.0783 0.41 +0.0126 0.0774 0.41 +0.0135 0.0765 0.41 +0.0144 0.0756 0.41 +0.0153 0.0747 0.41 +0.0162 0.0738 0.41 +0.0171 0.0729 0.41 +0.018 0.072 0.41 +0.0189 0.0711 0.41 +0.0198 0.0702 0.41 +0.0207 0.0693 0.41 +0.0216 0.0684 0.41 +0.0225 0.0675 0.41 +0.0234 0.0666 0.41 +0.0243 0.0657 0.41 +0.0252 0.0648 0.41 +0.0261 0.0639 0.41 +0.027 0.063 0.41 +0.0279 0.0621 0.41 +0.0288 0.0612 0.41 +0.0297 0.0603 0.41 +0.0306 0.0594 0.41 +0.0315 0.0585 0.41 +0.0324 0.0576 0.41 +0.0333 0.0567 0.41 +0.0342 0.0558 0.41 +0.0351 0.0549 0.41 +0.036 0.054 0.41 +0.0369 0.0531 0.41 +0.0378 0.0522 0.41 +0.0387 0.0513 0.41 +0.0396 0.0504 0.41 +0.0405 0.0495 0.41 +0.0414 0.0486 0.41 +0.0423 0.0477 0.41 +0.0432 0.0468 0.41 +0.0441 0.0459 0.41 +0.045 0.045 0.41 +0.0459 0.0441 0.41 +0.0468 0.0432 0.41 +0.0477 0.0423 0.41 +0.0486 0.0414 0.41 +0.0495 0.0405 0.41 +0.0504 0.0396 0.41 +0.0513 0.0387 0.41 +0.0522 0.0378 0.41 +0.0531 0.0369 0.41 +0.054 0.036 0.41 +0.0549 0.0351 0.41 +0.0558 0.0342 0.41 +0.0567 0.0333 0.41 +0.0576 0.0324 0.41 +0.0585 0.0315 0.41 +0.0594 0.0306 0.41 +0.0603 0.0297 0.41 +0.0612 0.0288 0.41 +0.0621 0.0279 0.41 +0.063 0.027 0.41 +0.0639 0.0261 0.41 +0.0648 0.0252 0.41 +0.0657 0.0243 0.41 +0.0666 0.0234 0.41 +0.0675 0.0225 0.41 +0.0684 0.0216 0.41 +0.0693 0.0207 0.41 +0.0702 0.0198 0.41 +0.0711 0.0189 0.41 +0.072 0.018 0.41 +0.0729 0.0171 0.41 +0.0738 0.0162 0.41 +0.0747 0.0153 0.41 +0.0756 0.0144 0.41 +0.0765 0.0135 0.41 +0.0774 0.0126 0.41 +0.0783 0.0117 0.41 +0.0792 0.0108 0.41 +0.0801 0.0099 0.41 +0.081 0.009 0.41 +0.0819 0.0081 0.41 +0.0828 0.0072 0.41 +0.0837 0.0063 0.41 +0.0846 0.0054 0.41 +0.0855 0.0045 0.41 +0.0864 0.0036 0.41 +0.0873 0.0027 0.41 +0.0882 0.0018 0.41 +0.0891 0.0009 0.41 +0 0.095 0.405 +0.00095 0.09405 0.405 +0.0019 0.0931 0.405 +0.00285 0.09215 0.405 +0.0038 0.0912 0.405 +0.00475 0.09025 0.405 +0.0057 0.0893 0.405 +0.00665 0.08835 0.405 +0.0076 0.0874 0.405 +0.00855 0.08645 0.405 +0.0095 0.0855 0.405 +0.01045 0.08455 0.405 +0.0114 0.0836 0.405 +0.01235 0.08265 0.405 +0.0133 0.0817 0.405 +0.01425 0.08075 0.405 +0.0152 0.0798 0.405 +0.01615 0.07885 0.405 +0.0171 0.0779 0.405 +0.01805 0.07695 0.405 +0.019 0.076 0.405 +0.01995 0.07505 0.405 +0.0209 0.0741 0.405 +0.02185 0.07315 0.405 +0.0228 0.0722 0.405 +0.02375 0.07125 0.405 +0.0247 0.0703 0.405 +0.02565 0.06935 0.405 +0.0266 0.0684 0.405 +0.02755 0.06745 0.405 +0.0285 0.0665 0.405 +0.02945 0.06555 0.405 +0.0304 0.0646 0.405 +0.03135 0.06365 0.405 +0.0323 0.0627 0.405 +0.03325 0.06175 0.405 +0.0342 0.0608 0.405 +0.03515 0.05985 0.405 +0.0361 0.0589 0.405 +0.03705 0.05795 0.405 +0.038 0.057 0.405 +0.03895 0.05605 0.405 +0.0399 0.0551 0.405 +0.04085 0.05415 0.405 +0.0418 0.0532 0.405 +0.04275 0.05225 0.405 +0.0437 0.0513 0.405 +0.04465 0.05035 0.405 +0.0456 0.0494 0.405 +0.04655 0.04845 0.405 +0.0475 0.0475 0.405 +0.04845 0.04655 0.405 +0.0494 0.0456 0.405 +0.05035 0.04465 0.405 +0.0513 0.0437 0.405 +0.05225 0.04275 0.405 +0.0532 0.0418 0.405 +0.05415 0.04085 0.405 +0.0551 0.0399 0.405 +0.05605 0.03895 0.405 +0.057 0.038 0.405 +0.05795 0.03705 0.405 +0.0589 0.0361 0.405 +0.05985 0.03515 0.405 +0.0608 0.0342 0.405 +0.06175 0.03325 0.405 +0.0627 0.0323 0.405 +0.06365 0.03135 0.405 +0.0646 0.0304 0.405 +0.06555 0.02945 0.405 +0.0665 0.0285 0.405 +0.06745 0.02755 0.405 +0.0684 0.0266 0.405 +0.06935 0.02565 0.405 +0.0703 0.0247 0.405 +0.07125 0.02375 0.405 +0.0722 0.0228 0.405 +0.07315 0.02185 0.405 +0.0741 0.0209 0.405 +0.07505 0.01995 0.405 +0.076 0.019 0.405 +0.07695 0.01805 0.405 +0.0779 0.0171 0.405 +0.07885 0.01615 0.405 +0.0798 0.0152 0.405 +0.08075 0.01425 0.405 +0.0817 0.0133 0.405 +0.08265 0.01235 0.405 +0.0836 0.0114 0.405 +0.08455 0.01045 0.405 +0.0855 0.0095 0.405 +0.08645 0.00855 0.405 +0.0874 0.0076 0.405 +0.08835 0.00665 0.405 +0.0893 0.0057 0.405 +0.09025 0.00475 0.405 +0.0912 0.0038 0.405 +0.09215 0.00285 0.405 +0.0931 0.0019 0.405 +0.09405 0.00095 0.405 +0 0.1 0.4 +0.001 0.099 0.4 +0.002 0.098 0.4 +0.003 0.097 0.4 +0.004 0.096 0.4 +0.005 0.095 0.4 +0.006 0.094 0.4 +0.007 0.093 0.4 +0.008 0.092 0.4 +0.009 0.091 0.4 +0.01 0.09 0.4 +0.011 0.089 0.4 +0.012 0.088 0.4 +0.013 0.087 0.4 +0.014 0.086 0.4 +0.015 0.085 0.4 +0.016 0.084 0.4 +0.017 0.083 0.4 +0.018 0.082 0.4 +0.019 0.081 0.4 +0.02 0.08 0.4 +0.021 0.079 0.4 +0.022 0.078 0.4 +0.023 0.077 0.4 +0.024 0.076 0.4 +0.025 0.075 0.4 +0.026 0.074 0.4 +0.027 0.073 0.4 +0.028 0.072 0.4 +0.029 0.071 0.4 +0.03 0.07 0.4 +0.031 0.069 0.4 +0.032 0.068 0.4 +0.033 0.067 0.4 +0.034 0.066 0.4 +0.035 0.065 0.4 +0.036 0.064 0.4 +0.037 0.063 0.4 +0.038 0.062 0.4 +0.039 0.061 0.4 +0.04 0.06 0.4 +0.041 0.059 0.4 +0.042 0.058 0.4 +0.043 0.057 0.4 +0.044 0.056 0.4 +0.045 0.055 0.4 +0.046 0.054 0.4 +0.047 0.053 0.4 +0.048 0.052 0.4 +0.049 0.051 0.4 +0.05 0.05 0.4 +0.051 0.049 0.4 +0.052 0.048 0.4 +0.053 0.047 0.4 +0.054 0.046 0.4 +0.055 0.045 0.4 +0.056 0.044 0.4 +0.057 0.043 0.4 +0.058 0.042 0.4 +0.059 0.041 0.4 +0.06 0.04 0.4 +0.061 0.039 0.4 +0.062 0.038 0.4 +0.063 0.037 0.4 +0.064 0.036 0.4 +0.065 0.035 0.4 +0.066 0.034 0.4 +0.067 0.033 0.4 +0.068 0.032 0.4 +0.069 0.031 0.4 +0.07 0.03 0.4 +0.071 0.029 0.4 +0.072 0.028 0.4 +0.073 0.027 0.4 +0.074 0.026 0.4 +0.075 0.025 0.4 +0.076 0.024 0.4 +0.077 0.023 0.4 +0.078 0.022 0.4 +0.079 0.021 0.4 +0.08 0.02 0.4 +0.081 0.019 0.4 +0.082 0.018 0.4 +0.083 0.017 0.4 +0.084 0.016 0.4 +0.085 0.015 0.4 +0.086 0.014 0.4 +0.087 0.013 0.4 +0.088 0.012 0.4 +0.089 0.011 0.4 +0.09 0.01 0.4 +0.091 0.009 0.4 +0.092 0.008 0.4 +0.093 0.007 0.4 +0.094 0.006 0.4 +0.095 0.005 0.4 +0.096 0.004 0.4 +0.097 0.003 0.4 +0.098 0.002 0.4 +0.099 0.001 0.4 +0 0.105 0.395 +0.00105 0.10395 0.395 +0.0021 0.1029 0.395 +0.00315 0.10185 0.395 +0.0042 0.1008 0.395 +0.00525 0.09975 0.395 +0.0063 0.0987 0.395 +0.00735 0.09765 0.395 +0.0084 0.0966 0.395 +0.00945 0.09555 0.395 +0.0105 0.0945 0.395 +0.01155 0.09345 0.395 +0.0126 0.0924 0.395 +0.01365 0.09135 0.395 +0.0147 0.0903 0.395 +0.01575 0.08925 0.395 +0.0168 0.0882 0.395 +0.01785 0.08715 0.395 +0.0189 0.0861 0.395 +0.01995 0.08505 0.395 +0.021 0.084 0.395 +0.02205 0.08295 0.395 +0.0231 0.0819 0.395 +0.02415 0.08085 0.395 +0.0252 0.0798 0.395 +0.02625 0.07875 0.395 +0.0273 0.0777 0.395 +0.02835 0.07665 0.395 +0.0294 0.0756 0.395 +0.03045 0.07455 0.395 +0.0315 0.0735 0.395 +0.03255 0.07245 0.395 +0.0336 0.0714 0.395 +0.03465 0.07035 0.395 +0.0357 0.0693 0.395 +0.03675 0.06825 0.395 +0.0378 0.0672 0.395 +0.03885 0.06615 0.395 +0.0399 0.0651 0.395 +0.04095 0.06405 0.395 +0.042 0.063 0.395 +0.04305 0.06195 0.395 +0.0441 0.0609 0.395 +0.04515 0.05985 0.395 +0.0462 0.0588 0.395 +0.04725 0.05775 0.395 +0.0483 0.0567 0.395 +0.04935 0.05565 0.395 +0.0504 0.0546 0.395 +0.05145 0.05355 0.395 +0.0525 0.0525 0.395 +0.05355 0.05145 0.395 +0.0546 0.0504 0.395 +0.05565 0.04935 0.395 +0.0567 0.0483 0.395 +0.05775 0.04725 0.395 +0.0588 0.0462 0.395 +0.05985 0.04515 0.395 +0.0609 0.0441 0.395 +0.06195 0.04305 0.395 +0.063 0.042 0.395 +0.06405 0.04095 0.395 +0.0651 0.0399 0.395 +0.06615 0.03885 0.395 +0.0672 0.0378 0.395 +0.06825 0.03675 0.395 +0.0693 0.0357 0.395 +0.07035 0.03465 0.395 +0.0714 0.0336 0.395 +0.07245 0.03255 0.395 +0.0735 0.0315 0.395 +0.07455 0.03045 0.395 +0.0756 0.0294 0.395 +0.07665 0.02835 0.395 +0.0777 0.0273 0.395 +0.07875 0.02625 0.395 +0.0798 0.0252 0.395 +0.08085 0.02415 0.395 +0.0819 0.0231 0.395 +0.08295 0.02205 0.395 +0.084 0.021 0.395 +0.08505 0.01995 0.395 +0.0861 0.0189 0.395 +0.08715 0.01785 0.395 +0.0882 0.0168 0.395 +0.08925 0.01575 0.395 +0.0903 0.0147 0.395 +0.09135 0.01365 0.395 +0.0924 0.0126 0.395 +0.09345 0.01155 0.395 +0.0945 0.0105 0.395 +0.09555 0.00945 0.395 +0.0966 0.0084 0.395 +0.09765 0.00735 0.395 +0.0987 0.0063 0.395 +0.09975 0.00525 0.395 +0.1008 0.0042 0.395 +0.10185 0.00315 0.395 +0.1029 0.0021 0.395 +0.10395 0.00105 0.395 +0 0.11 0.39 +0.0011 0.1089 0.39 +0.0022 0.1078 0.39 +0.0033 0.1067 0.39 +0.0044 0.1056 0.39 +0.0055 0.1045 0.39 +0.0066 0.1034 0.39 +0.0077 0.1023 0.39 +0.0088 0.1012 0.39 +0.0099 0.1001 0.39 +0.011 0.099 0.39 +0.0121 0.0979 0.39 +0.0132 0.0968 0.39 +0.0143 0.0957 0.39 +0.0154 0.0946 0.39 +0.0165 0.0935 0.39 +0.0176 0.0924 0.39 +0.0187 0.0913 0.39 +0.0198 0.0902 0.39 +0.0209 0.0891 0.39 +0.022 0.088 0.39 +0.0231 0.0869 0.39 +0.0242 0.0858 0.39 +0.0253 0.0847 0.39 +0.0264 0.0836 0.39 +0.0275 0.0825 0.39 +0.0286 0.0814 0.39 +0.0297 0.0803 0.39 +0.0308 0.0792 0.39 +0.0319 0.0781 0.39 +0.033 0.077 0.39 +0.0341 0.0759 0.39 +0.0352 0.0748 0.39 +0.0363 0.0737 0.39 +0.0374 0.0726 0.39 +0.0385 0.0715 0.39 +0.0396 0.0704 0.39 +0.0407 0.0693 0.39 +0.0418 0.0682 0.39 +0.0429 0.0671 0.39 +0.044 0.066 0.39 +0.0451 0.0649 0.39 +0.0462 0.0638 0.39 +0.0473 0.0627 0.39 +0.0484 0.0616 0.39 +0.0495 0.0605 0.39 +0.0506 0.0594 0.39 +0.0517 0.0583 0.39 +0.0528 0.0572 0.39 +0.0539 0.0561 0.39 +0.055 0.055 0.39 +0.0561 0.0539 0.39 +0.0572 0.0528 0.39 +0.0583 0.0517 0.39 +0.0594 0.0506 0.39 +0.0605 0.0495 0.39 +0.0616 0.0484 0.39 +0.0627 0.0473 0.39 +0.0638 0.0462 0.39 +0.0649 0.0451 0.39 +0.066 0.044 0.39 +0.0671 0.0429 0.39 +0.0682 0.0418 0.39 +0.0693 0.0407 0.39 +0.0704 0.0396 0.39 +0.0715 0.0385 0.39 +0.0726 0.0374 0.39 +0.0737 0.0363 0.39 +0.0748 0.0352 0.39 +0.0759 0.0341 0.39 +0.077 0.033 0.39 +0.0781 0.0319 0.39 +0.0792 0.0308 0.39 +0.0803 0.0297 0.39 +0.0814 0.0286 0.39 +0.0825 0.0275 0.39 +0.0836 0.0264 0.39 +0.0847 0.0253 0.39 +0.0858 0.0242 0.39 +0.0869 0.0231 0.39 +0.088 0.022 0.39 +0.0891 0.0209 0.39 +0.0902 0.0198 0.39 +0.0913 0.0187 0.39 +0.0924 0.0176 0.39 +0.0935 0.0165 0.39 +0.0946 0.0154 0.39 +0.0957 0.0143 0.39 +0.0968 0.0132 0.39 +0.0979 0.0121 0.39 +0.099 0.011 0.39 +0.1001 0.0099 0.39 +0.1012 0.0088 0.39 +0.1023 0.0077 0.39 +0.1034 0.0066 0.39 +0.1045 0.0055 0.39 +0.1056 0.0044 0.39 +0.1067 0.0033 0.39 +0.1078 0.0022 0.39 +0.1089 0.0011 0.39 +0 0.115 0.385 +0.00115 0.11385 0.385 +0.0023 0.1127 0.385 +0.00345 0.11155 0.385 +0.0046 0.1104 0.385 +0.00575 0.10925 0.385 +0.0069 0.1081 0.385 +0.00805 0.10695 0.385 +0.0092 0.1058 0.385 +0.01035 0.10465 0.385 +0.0115 0.1035 0.385 +0.01265 0.10235 0.385 +0.0138 0.1012 0.385 +0.01495 0.10005 0.385 +0.0161 0.0989 0.385 +0.01725 0.09775 0.385 +0.0184 0.0966 0.385 +0.01955 0.09545 0.385 +0.0207 0.0943 0.385 +0.02185 0.09315 0.385 +0.023 0.092 0.385 +0.02415 0.09085 0.385 +0.0253 0.0897 0.385 +0.02645 0.08855 0.385 +0.0276 0.0874 0.385 +0.02875 0.08625 0.385 +0.0299 0.0851 0.385 +0.03105 0.08395 0.385 +0.0322 0.0828 0.385 +0.03335 0.08165 0.385 +0.0345 0.0805 0.385 +0.03565 0.07935 0.385 +0.0368 0.0782 0.385 +0.03795 0.07705 0.385 +0.0391 0.0759 0.385 +0.04025 0.07475 0.385 +0.0414 0.0736 0.385 +0.04255 0.07245 0.385 +0.0437 0.0713 0.385 +0.04485 0.07015 0.385 +0.046 0.069 0.385 +0.04715 0.06785 0.385 +0.0483 0.0667 0.385 +0.04945 0.06555 0.385 +0.0506 0.0644 0.385 +0.05175 0.06325 0.385 +0.0529 0.0621 0.385 +0.05405 0.06095 0.385 +0.0552 0.0598 0.385 +0.05635 0.05865 0.385 +0.0575 0.0575 0.385 +0.05865 0.05635 0.385 +0.0598 0.0552 0.385 +0.06095 0.05405 0.385 +0.0621 0.0529 0.385 +0.06325 0.05175 0.385 +0.0644 0.0506 0.385 +0.06555 0.04945 0.385 +0.0667 0.0483 0.385 +0.06785 0.04715 0.385 +0.069 0.046 0.385 +0.07015 0.04485 0.385 +0.0713 0.0437 0.385 +0.07245 0.04255 0.385 +0.0736 0.0414 0.385 +0.07475 0.04025 0.385 +0.0759 0.0391 0.385 +0.07705 0.03795 0.385 +0.0782 0.0368 0.385 +0.07935 0.03565 0.385 +0.0805 0.0345 0.385 +0.08165 0.03335 0.385 +0.0828 0.0322 0.385 +0.08395 0.03105 0.385 +0.0851 0.0299 0.385 +0.08625 0.02875 0.385 +0.0874 0.0276 0.385 +0.08855 0.02645 0.385 +0.0897 0.0253 0.385 +0.09085 0.02415 0.385 +0.092 0.023 0.385 +0.09315 0.02185 0.385 +0.0943 0.0207 0.385 +0.09545 0.01955 0.385 +0.0966 0.0184 0.385 +0.09775 0.01725 0.385 +0.0989 0.0161 0.385 +0.10005 0.01495 0.385 +0.1012 0.0138 0.385 +0.10235 0.01265 0.385 +0.1035 0.0115 0.385 +0.10465 0.01035 0.385 +0.1058 0.0092 0.385 +0.10695 0.00805 0.385 +0.1081 0.0069 0.385 +0.10925 0.00575 0.385 +0.1104 0.0046 0.385 +0.11155 0.00345 0.385 +0.1127 0.0023 0.385 +0.11385 0.00115 0.385 +0 0.12 0.38 +0.0012 0.1188 0.38 +0.0024 0.1176 0.38 +0.0036 0.1164 0.38 +0.0048 0.1152 0.38 +0.006 0.114 0.38 +0.0072 0.1128 0.38 +0.0084 0.1116 0.38 +0.0096 0.1104 0.38 +0.0108 0.1092 0.38 +0.012 0.108 0.38 +0.0132 0.1068 0.38 +0.0144 0.1056 0.38 +0.0156 0.1044 0.38 +0.0168 0.1032 0.38 +0.018 0.102 0.38 +0.0192 0.1008 0.38 +0.0204 0.0996 0.38 +0.0216 0.0984 0.38 +0.0228 0.0972 0.38 +0.024 0.096 0.38 +0.0252 0.0948 0.38 +0.0264 0.0936 0.38 +0.0276 0.0924 0.38 +0.0288 0.0912 0.38 +0.03 0.09 0.38 +0.0312 0.0888 0.38 +0.0324 0.0876 0.38 +0.0336 0.0864 0.38 +0.0348 0.0852 0.38 +0.036 0.084 0.38 +0.0372 0.0828 0.38 +0.0384 0.0816 0.38 +0.0396 0.0804 0.38 +0.0408 0.0792 0.38 +0.042 0.078 0.38 +0.0432 0.0768 0.38 +0.0444 0.0756 0.38 +0.0456 0.0744 0.38 +0.0468 0.0732 0.38 +0.048 0.072 0.38 +0.0492 0.0708 0.38 +0.0504 0.0696 0.38 +0.0516 0.0684 0.38 +0.0528 0.0672 0.38 +0.054 0.066 0.38 +0.0552 0.0648 0.38 +0.0564 0.0636 0.38 +0.0576 0.0624 0.38 +0.0588 0.0612 0.38 +0.06 0.06 0.38 +0.0612 0.0588 0.38 +0.0624 0.0576 0.38 +0.0636 0.0564 0.38 +0.0648 0.0552 0.38 +0.066 0.054 0.38 +0.0672 0.0528 0.38 +0.0684 0.0516 0.38 +0.0696 0.0504 0.38 +0.0708 0.0492 0.38 +0.072 0.048 0.38 +0.0732 0.0468 0.38 +0.0744 0.0456 0.38 +0.0756 0.0444 0.38 +0.0768 0.0432 0.38 +0.078 0.042 0.38 +0.0792 0.0408 0.38 +0.0804 0.0396 0.38 +0.0816 0.0384 0.38 +0.0828 0.0372 0.38 +0.084 0.036 0.38 +0.0852 0.0348 0.38 +0.0864 0.0336 0.38 +0.0876 0.0324 0.38 +0.0888 0.0312 0.38 +0.09 0.03 0.38 +0.0912 0.0288 0.38 +0.0924 0.0276 0.38 +0.0936 0.0264 0.38 +0.0948 0.0252 0.38 +0.096 0.024 0.38 +0.0972 0.0228 0.38 +0.0984 0.0216 0.38 +0.0996 0.0204 0.38 +0.1008 0.0192 0.38 +0.102 0.018 0.38 +0.1032 0.0168 0.38 +0.1044 0.0156 0.38 +0.1056 0.0144 0.38 +0.1068 0.0132 0.38 +0.108 0.012 0.38 +0.1092 0.0108 0.38 +0.1104 0.0096 0.38 +0.1116 0.0084 0.38 +0.1128 0.0072 0.38 +0.114 0.006 0.38 +0.1152 0.0048 0.38 +0.1164 0.0036 0.38 +0.1176 0.0024 0.38 +0.1188 0.0012 0.38 +0 0.125 0.375 +0.00125 0.12375 0.375 +0.0025 0.1225 0.375 +0.00375 0.12125 0.375 +0.005 0.12 0.375 +0.00625 0.11875 0.375 +0.0075 0.1175 0.375 +0.00875 0.11625 0.375 +0.01 0.115 0.375 +0.01125 0.11375 0.375 +0.0125 0.1125 0.375 +0.01375 0.11125 0.375 +0.015 0.11 0.375 +0.01625 0.10875 0.375 +0.0175 0.1075 0.375 +0.01875 0.10625 0.375 +0.02 0.105 0.375 +0.02125 0.10375 0.375 +0.0225 0.1025 0.375 +0.02375 0.10125 0.375 +0.025 0.1 0.375 +0.02625 0.09875 0.375 +0.0275 0.0975 0.375 +0.02875 0.09625 0.375 +0.03 0.095 0.375 +0.03125 0.09375 0.375 +0.0325 0.0925 0.375 +0.03375 0.09125 0.375 +0.035 0.09 0.375 +0.03625 0.08875 0.375 +0.0375 0.0875 0.375 +0.03875 0.08625 0.375 +0.04 0.085 0.375 +0.04125 0.08375 0.375 +0.0425 0.0825 0.375 +0.04375 0.08125 0.375 +0.045 0.08 0.375 +0.04625 0.07875 0.375 +0.0475 0.0775 0.375 +0.04875 0.07625 0.375 +0.05 0.075 0.375 +0.05125 0.07375 0.375 +0.0525 0.0725 0.375 +0.05375 0.07125 0.375 +0.055 0.07 0.375 +0.05625 0.06875 0.375 +0.0575 0.0675 0.375 +0.05875 0.06625 0.375 +0.06 0.065 0.375 +0.06125 0.06375 0.375 +0.0625 0.0625 0.375 +0.06375 0.06125 0.375 +0.065 0.06 0.375 +0.06625 0.05875 0.375 +0.0675 0.0575 0.375 +0.06875 0.05625 0.375 +0.07 0.055 0.375 +0.07125 0.05375 0.375 +0.0725 0.0525 0.375 +0.07375 0.05125 0.375 +0.075 0.05 0.375 +0.07625 0.04875 0.375 +0.0775 0.0475 0.375 +0.07875 0.04625 0.375 +0.08 0.045 0.375 +0.08125 0.04375 0.375 +0.0825 0.0425 0.375 +0.08375 0.04125 0.375 +0.085 0.04 0.375 +0.08625 0.03875 0.375 +0.0875 0.0375 0.375 +0.08875 0.03625 0.375 +0.09 0.035 0.375 +0.09125 0.03375 0.375 +0.0925 0.0325 0.375 +0.09375 0.03125 0.375 +0.095 0.03 0.375 +0.09625 0.02875 0.375 +0.0975 0.0275 0.375 +0.09875 0.02625 0.375 +0.1 0.025 0.375 +0.10125 0.02375 0.375 +0.1025 0.0225 0.375 +0.10375 0.02125 0.375 +0.105 0.02 0.375 +0.10625 0.01875 0.375 +0.1075 0.0175 0.375 +0.10875 0.01625 0.375 +0.11 0.015 0.375 +0.11125 0.01375 0.375 +0.1125 0.0125 0.375 +0.11375 0.01125 0.375 +0.115 0.01 0.375 +0.11625 0.00875 0.375 +0.1175 0.0075 0.375 +0.11875 0.00625 0.375 +0.12 0.005 0.375 +0.12125 0.00375 0.375 +0.1225 0.0025 0.375 +0.12375 0.00125 0.375 +0 0.13 0.37 +0.0013 0.1287 0.37 +0.0026 0.1274 0.37 +0.0039 0.1261 0.37 +0.0052 0.1248 0.37 +0.0065 0.1235 0.37 +0.0078 0.1222 0.37 +0.0091 0.1209 0.37 +0.0104 0.1196 0.37 +0.0117 0.1183 0.37 +0.013 0.117 0.37 +0.0143 0.1157 0.37 +0.0156 0.1144 0.37 +0.0169 0.1131 0.37 +0.0182 0.1118 0.37 +0.0195 0.1105 0.37 +0.0208 0.1092 0.37 +0.0221 0.1079 0.37 +0.0234 0.1066 0.37 +0.0247 0.1053 0.37 +0.026 0.104 0.37 +0.0273 0.1027 0.37 +0.0286 0.1014 0.37 +0.0299 0.1001 0.37 +0.0312 0.0988 0.37 +0.0325 0.0975 0.37 +0.0338 0.0962 0.37 +0.0351 0.0949 0.37 +0.0364 0.0936 0.37 +0.0377 0.0923 0.37 +0.039 0.091 0.37 +0.0403 0.0897 0.37 +0.0416 0.0884 0.37 +0.0429 0.0871 0.37 +0.0442 0.0858 0.37 +0.0455 0.0845 0.37 +0.0468 0.0832 0.37 +0.0481 0.0819 0.37 +0.0494 0.0806 0.37 +0.0507 0.0793 0.37 +0.052 0.078 0.37 +0.0533 0.0767 0.37 +0.0546 0.0754 0.37 +0.0559 0.0741 0.37 +0.0572 0.0728 0.37 +0.0585 0.0715 0.37 +0.0598 0.0702 0.37 +0.0611 0.0689 0.37 +0.0624 0.0676 0.37 +0.0637 0.0663 0.37 +0.065 0.065 0.37 +0.0663 0.0637 0.37 +0.0676 0.0624 0.37 +0.0689 0.0611 0.37 +0.0702 0.0598 0.37 +0.0715 0.0585 0.37 +0.0728 0.0572 0.37 +0.0741 0.0559 0.37 +0.0754 0.0546 0.37 +0.0767 0.0533 0.37 +0.078 0.052 0.37 +0.0793 0.0507 0.37 +0.0806 0.0494 0.37 +0.0819 0.0481 0.37 +0.0832 0.0468 0.37 +0.0845 0.0455 0.37 +0.0858 0.0442 0.37 +0.0871 0.0429 0.37 +0.0884 0.0416 0.37 +0.0897 0.0403 0.37 +0.091 0.039 0.37 +0.0923 0.0377 0.37 +0.0936 0.0364 0.37 +0.0949 0.0351 0.37 +0.0962 0.0338 0.37 +0.0975 0.0325 0.37 +0.0988 0.0312 0.37 +0.1001 0.0299 0.37 +0.1014 0.0286 0.37 +0.1027 0.0273 0.37 +0.104 0.026 0.37 +0.1053 0.0247 0.37 +0.1066 0.0234 0.37 +0.1079 0.0221 0.37 +0.1092 0.0208 0.37 +0.1105 0.0195 0.37 +0.1118 0.0182 0.37 +0.1131 0.0169 0.37 +0.1144 0.0156 0.37 +0.1157 0.0143 0.37 +0.117 0.013 0.37 +0.1183 0.0117 0.37 +0.1196 0.0104 0.37 +0.1209 0.0091 0.37 +0.1222 0.0078 0.37 +0.1235 0.0065 0.37 +0.1248 0.0052 0.37 +0.1261 0.0039 0.37 +0.1274 0.0026 0.37 +0.1287 0.0013 0.37 +0 0.135 0.365 +0.00135 0.13365 0.365 +0.0027 0.1323 0.365 +0.00405 0.13095 0.365 +0.0054 0.1296 0.365 +0.00675 0.12825 0.365 +0.0081 0.1269 0.365 +0.00945 0.12555 0.365 +0.0108 0.1242 0.365 +0.01215 0.12285 0.365 +0.0135 0.1215 0.365 +0.01485 0.12015 0.365 +0.0162 0.1188 0.365 +0.01755 0.11745 0.365 +0.0189 0.1161 0.365 +0.02025 0.11475 0.365 +0.0216 0.1134 0.365 +0.02295 0.11205 0.365 +0.0243 0.1107 0.365 +0.02565 0.10935 0.365 +0.027 0.108 0.365 +0.02835 0.10665 0.365 +0.0297 0.1053 0.365 +0.03105 0.10395 0.365 +0.0324 0.1026 0.365 +0.03375 0.10125 0.365 +0.0351 0.0999 0.365 +0.03645 0.09855 0.365 +0.0378 0.0972 0.365 +0.03915 0.09585 0.365 +0.0405 0.0945 0.365 +0.04185 0.09315 0.365 +0.0432 0.0918 0.365 +0.04455 0.09045 0.365 +0.0459 0.0891 0.365 +0.04725 0.08775 0.365 +0.0486 0.0864 0.365 +0.04995 0.08505 0.365 +0.0513 0.0837 0.365 +0.05265 0.08235 0.365 +0.054 0.081 0.365 +0.05535 0.07965 0.365 +0.0567 0.0783 0.365 +0.05805 0.07695 0.365 +0.0594 0.0756 0.365 +0.06075 0.07425 0.365 +0.0621 0.0729 0.365 +0.06345 0.07155 0.365 +0.0648 0.0702 0.365 +0.06615 0.06885 0.365 +0.0675 0.0675 0.365 +0.06885 0.06615 0.365 +0.0702 0.0648 0.365 +0.07155 0.06345 0.365 +0.0729 0.0621 0.365 +0.07425 0.06075 0.365 +0.0756 0.0594 0.365 +0.07695 0.05805 0.365 +0.0783 0.0567 0.365 +0.07965 0.05535 0.365 +0.081 0.054 0.365 +0.08235 0.05265 0.365 +0.0837 0.0513 0.365 +0.08505 0.04995 0.365 +0.0864 0.0486 0.365 +0.08775 0.04725 0.365 +0.0891 0.0459 0.365 +0.09045 0.04455 0.365 +0.0918 0.0432 0.365 +0.09315 0.04185 0.365 +0.0945 0.0405 0.365 +0.09585 0.03915 0.365 +0.0972 0.0378 0.365 +0.09855 0.03645 0.365 +0.0999 0.0351 0.365 +0.10125 0.03375 0.365 +0.1026 0.0324 0.365 +0.10395 0.03105 0.365 +0.1053 0.0297 0.365 +0.10665 0.02835 0.365 +0.108 0.027 0.365 +0.10935 0.02565 0.365 +0.1107 0.0243 0.365 +0.11205 0.02295 0.365 +0.1134 0.0216 0.365 +0.11475 0.02025 0.365 +0.1161 0.0189 0.365 +0.11745 0.01755 0.365 +0.1188 0.0162 0.365 +0.12015 0.01485 0.365 +0.1215 0.0135 0.365 +0.12285 0.01215 0.365 +0.1242 0.0108 0.365 +0.12555 0.00945 0.365 +0.1269 0.0081 0.365 +0.12825 0.00675 0.365 +0.1296 0.0054 0.365 +0.13095 0.00405 0.365 +0.1323 0.0027 0.365 +0.13365 0.00135 0.365 +0 0.14 0.36 +0.0014 0.1386 0.36 +0.0028 0.1372 0.36 +0.0042 0.1358 0.36 +0.0056 0.1344 0.36 +0.007 0.133 0.36 +0.0084 0.1316 0.36 +0.0098 0.1302 0.36 +0.0112 0.1288 0.36 +0.0126 0.1274 0.36 +0.014 0.126 0.36 +0.0154 0.1246 0.36 +0.0168 0.1232 0.36 +0.0182 0.1218 0.36 +0.0196 0.1204 0.36 +0.021 0.119 0.36 +0.0224 0.1176 0.36 +0.0238 0.1162 0.36 +0.0252 0.1148 0.36 +0.0266 0.1134 0.36 +0.028 0.112 0.36 +0.0294 0.1106 0.36 +0.0308 0.1092 0.36 +0.0322 0.1078 0.36 +0.0336 0.1064 0.36 +0.035 0.105 0.36 +0.0364 0.1036 0.36 +0.0378 0.1022 0.36 +0.0392 0.1008 0.36 +0.0406 0.0994 0.36 +0.042 0.098 0.36 +0.0434 0.0966 0.36 +0.0448 0.0952 0.36 +0.0462 0.0938 0.36 +0.0476 0.0924 0.36 +0.049 0.091 0.36 +0.0504 0.0896 0.36 +0.0518 0.0882 0.36 +0.0532 0.0868 0.36 +0.0546 0.0854 0.36 +0.056 0.084 0.36 +0.0574 0.0826 0.36 +0.0588 0.0812 0.36 +0.0602 0.0798 0.36 +0.0616 0.0784 0.36 +0.063 0.077 0.36 +0.0644 0.0756 0.36 +0.0658 0.0742 0.36 +0.0672 0.0728 0.36 +0.0686 0.0714 0.36 +0.07 0.07 0.36 +0.0714 0.0686 0.36 +0.0728 0.0672 0.36 +0.0742 0.0658 0.36 +0.0756 0.0644 0.36 +0.077 0.063 0.36 +0.0784 0.0616 0.36 +0.0798 0.0602 0.36 +0.0812 0.0588 0.36 +0.0826 0.0574 0.36 +0.084 0.056 0.36 +0.0854 0.0546 0.36 +0.0868 0.0532 0.36 +0.0882 0.0518 0.36 +0.0896 0.0504 0.36 +0.091 0.049 0.36 +0.0924 0.0476 0.36 +0.0938 0.0462 0.36 +0.0952 0.0448 0.36 +0.0966 0.0434 0.36 +0.098 0.042 0.36 +0.0994 0.0406 0.36 +0.1008 0.0392 0.36 +0.1022 0.0378 0.36 +0.1036 0.0364 0.36 +0.105 0.035 0.36 +0.1064 0.0336 0.36 +0.1078 0.0322 0.36 +0.1092 0.0308 0.36 +0.1106 0.0294 0.36 +0.112 0.028 0.36 +0.1134 0.0266 0.36 +0.1148 0.0252 0.36 +0.1162 0.0238 0.36 +0.1176 0.0224 0.36 +0.119 0.021 0.36 +0.1204 0.0196 0.36 +0.1218 0.0182 0.36 +0.1232 0.0168 0.36 +0.1246 0.0154 0.36 +0.126 0.014 0.36 +0.1274 0.0126 0.36 +0.1288 0.0112 0.36 +0.1302 0.0098 0.36 +0.1316 0.0084 0.36 +0.133 0.007 0.36 +0.1344 0.0056 0.36 +0.1358 0.0042 0.36 +0.1372 0.0028 0.36 +0.1386 0.0014 0.36 +0 0.145 0.355 +0.00145 0.14355 0.355 +0.0029 0.1421 0.355 +0.00435 0.14065 0.355 +0.0058 0.1392 0.355 +0.00725 0.13775 0.355 +0.0087 0.1363 0.355 +0.01015 0.13485 0.355 +0.0116 0.1334 0.355 +0.01305 0.13195 0.355 +0.0145 0.1305 0.355 +0.01595 0.12905 0.355 +0.0174 0.1276 0.355 +0.01885 0.12615 0.355 +0.0203 0.1247 0.355 +0.02175 0.12325 0.355 +0.0232 0.1218 0.355 +0.02465 0.12035 0.355 +0.0261 0.1189 0.355 +0.02755 0.11745 0.355 +0.029 0.116 0.355 +0.03045 0.11455 0.355 +0.0319 0.1131 0.355 +0.03335 0.11165 0.355 +0.0348 0.1102 0.355 +0.03625 0.10875 0.355 +0.0377 0.1073 0.355 +0.03915 0.10585 0.355 +0.0406 0.1044 0.355 +0.04205 0.10295 0.355 +0.0435 0.1015 0.355 +0.04495 0.10005 0.355 +0.0464 0.0986 0.355 +0.04785 0.09715 0.355 +0.0493 0.0957 0.355 +0.05075 0.09425 0.355 +0.0522 0.0928 0.355 +0.05365 0.09135 0.355 +0.0551 0.0899 0.355 +0.05655 0.08845 0.355 +0.058 0.087 0.355 +0.05945 0.08555 0.355 +0.0609 0.0841 0.355 +0.06235 0.08265 0.355 +0.0638 0.0812 0.355 +0.06525 0.07975 0.355 +0.0667 0.0783 0.355 +0.06815 0.07685 0.355 +0.0696 0.0754 0.355 +0.07105 0.07395 0.355 +0.0725 0.0725 0.355 +0.07395 0.07105 0.355 +0.0754 0.0696 0.355 +0.07685 0.06815 0.355 +0.0783 0.0667 0.355 +0.07975 0.06525 0.355 +0.0812 0.0638 0.355 +0.08265 0.06235 0.355 +0.0841 0.0609 0.355 +0.08555 0.05945 0.355 +0.087 0.058 0.355 +0.08845 0.05655 0.355 +0.0899 0.0551 0.355 +0.09135 0.05365 0.355 +0.0928 0.0522 0.355 +0.09425 0.05075 0.355 +0.0957 0.0493 0.355 +0.09715 0.04785 0.355 +0.0986 0.0464 0.355 +0.10005 0.04495 0.355 +0.1015 0.0435 0.355 +0.10295 0.04205 0.355 +0.1044 0.0406 0.355 +0.10585 0.03915 0.355 +0.1073 0.0377 0.355 +0.10875 0.03625 0.355 +0.1102 0.0348 0.355 +0.11165 0.03335 0.355 +0.1131 0.0319 0.355 +0.11455 0.03045 0.355 +0.116 0.029 0.355 +0.11745 0.02755 0.355 +0.1189 0.0261 0.355 +0.12035 0.02465 0.355 +0.1218 0.0232 0.355 +0.12325 0.02175 0.355 +0.1247 0.0203 0.355 +0.12615 0.01885 0.355 +0.1276 0.0174 0.355 +0.12905 0.01595 0.355 +0.1305 0.0145 0.355 +0.13195 0.01305 0.355 +0.1334 0.0116 0.355 +0.13485 0.01015 0.355 +0.1363 0.0087 0.355 +0.13775 0.00725 0.355 +0.1392 0.0058 0.355 +0.14065 0.00435 0.355 +0.1421 0.0029 0.355 +0.14355 0.00145 0.355 +0 0.15 0.35 +0.0015 0.1485 0.35 +0.003 0.147 0.35 +0.0045 0.1455 0.35 +0.006 0.144 0.35 +0.0075 0.1425 0.35 +0.009 0.141 0.35 +0.0105 0.1395 0.35 +0.012 0.138 0.35 +0.0135 0.1365 0.35 +0.015 0.135 0.35 +0.0165 0.1335 0.35 +0.018 0.132 0.35 +0.0195 0.1305 0.35 +0.021 0.129 0.35 +0.0225 0.1275 0.35 +0.024 0.126 0.35 +0.0255 0.1245 0.35 +0.027 0.123 0.35 +0.0285 0.1215 0.35 +0.03 0.12 0.35 +0.0315 0.1185 0.35 +0.033 0.117 0.35 +0.0345 0.1155 0.35 +0.036 0.114 0.35 +0.0375 0.1125 0.35 +0.039 0.111 0.35 +0.0405 0.1095 0.35 +0.042 0.108 0.35 +0.0435 0.1065 0.35 +0.045 0.105 0.35 +0.0465 0.1035 0.35 +0.048 0.102 0.35 +0.0495 0.1005 0.35 +0.051 0.099 0.35 +0.0525 0.0975 0.35 +0.054 0.096 0.35 +0.0555 0.0945 0.35 +0.057 0.093 0.35 +0.0585 0.0915 0.35 +0.06 0.09 0.35 +0.0615 0.0885 0.35 +0.063 0.087 0.35 +0.0645 0.0855 0.35 +0.066 0.084 0.35 +0.0675 0.0825 0.35 +0.069 0.081 0.35 +0.0705 0.0795 0.35 +0.072 0.078 0.35 +0.0735 0.0765 0.35 +0.075 0.075 0.35 +0.0765 0.0735 0.35 +0.078 0.072 0.35 +0.0795 0.0705 0.35 +0.081 0.069 0.35 +0.0825 0.0675 0.35 +0.084 0.066 0.35 +0.0855 0.0645 0.35 +0.087 0.063 0.35 +0.0885 0.0615 0.35 +0.09 0.06 0.35 +0.0915 0.0585 0.35 +0.093 0.057 0.35 +0.0945 0.0555 0.35 +0.096 0.054 0.35 +0.0975 0.0525 0.35 +0.099 0.051 0.35 +0.1005 0.0495 0.35 +0.102 0.048 0.35 +0.1035 0.0465 0.35 +0.105 0.045 0.35 +0.1065 0.0435 0.35 +0.108 0.042 0.35 +0.1095 0.0405 0.35 +0.111 0.039 0.35 +0.1125 0.0375 0.35 +0.114 0.036 0.35 +0.1155 0.0345 0.35 +0.117 0.033 0.35 +0.1185 0.0315 0.35 +0.12 0.03 0.35 +0.1215 0.0285 0.35 +0.123 0.027 0.35 +0.1245 0.0255 0.35 +0.126 0.024 0.35 +0.1275 0.0225 0.35 +0.129 0.021 0.35 +0.1305 0.0195 0.35 +0.132 0.018 0.35 +0.1335 0.0165 0.35 +0.135 0.015 0.35 +0.1365 0.0135 0.35 +0.138 0.012 0.35 +0.1395 0.0105 0.35 +0.141 0.009 0.35 +0.1425 0.0075 0.35 +0.144 0.006 0.35 +0.1455 0.0045 0.35 +0.147 0.003 0.35 +0.1485 0.0015 0.35 +0 0.155 0.345 +0.00155 0.15345 0.345 +0.0031 0.1519 0.345 +0.00465 0.15035 0.345 +0.0062 0.1488 0.345 +0.00775 0.14725 0.345 +0.0093 0.1457 0.345 +0.01085 0.14415 0.345 +0.0124 0.1426 0.345 +0.01395 0.14105 0.345 +0.0155 0.1395 0.345 +0.01705 0.13795 0.345 +0.0186 0.1364 0.345 +0.02015 0.13485 0.345 +0.0217 0.1333 0.345 +0.02325 0.13175 0.345 +0.0248 0.1302 0.345 +0.02635 0.12865 0.345 +0.0279 0.1271 0.345 +0.02945 0.12555 0.345 +0.031 0.124 0.345 +0.03255 0.12245 0.345 +0.0341 0.1209 0.345 +0.03565 0.11935 0.345 +0.0372 0.1178 0.345 +0.03875 0.11625 0.345 +0.0403 0.1147 0.345 +0.04185 0.11315 0.345 +0.0434 0.1116 0.345 +0.04495 0.11005 0.345 +0.0465 0.1085 0.345 +0.04805 0.10695 0.345 +0.0496 0.1054 0.345 +0.05115 0.10385 0.345 +0.0527 0.1023 0.345 +0.05425 0.10075 0.345 +0.0558 0.0992 0.345 +0.05735 0.09765 0.345 +0.0589 0.0961 0.345 +0.06045 0.09455 0.345 +0.062 0.093 0.345 +0.06355 0.09145 0.345 +0.0651 0.0899 0.345 +0.06665 0.08835 0.345 +0.0682 0.0868 0.345 +0.06975 0.08525 0.345 +0.0713 0.0837 0.345 +0.07285 0.08215 0.345 +0.0744 0.0806 0.345 +0.07595 0.07905 0.345 +0.0775 0.0775 0.345 +0.07905 0.07595 0.345 +0.0806 0.0744 0.345 +0.08215 0.07285 0.345 +0.0837 0.0713 0.345 +0.08525 0.06975 0.345 +0.0868 0.0682 0.345 +0.08835 0.06665 0.345 +0.0899 0.0651 0.345 +0.09145 0.06355 0.345 +0.093 0.062 0.345 +0.09455 0.06045 0.345 +0.0961 0.0589 0.345 +0.09765 0.05735 0.345 +0.0992 0.0558 0.345 +0.10075 0.05425 0.345 +0.1023 0.0527 0.345 +0.10385 0.05115 0.345 +0.1054 0.0496 0.345 +0.10695 0.04805 0.345 +0.1085 0.0465 0.345 +0.11005 0.04495 0.345 +0.1116 0.0434 0.345 +0.11315 0.04185 0.345 +0.1147 0.0403 0.345 +0.11625 0.03875 0.345 +0.1178 0.0372 0.345 +0.11935 0.03565 0.345 +0.1209 0.0341 0.345 +0.12245 0.03255 0.345 +0.124 0.031 0.345 +0.12555 0.02945 0.345 +0.1271 0.0279 0.345 +0.12865 0.02635 0.345 +0.1302 0.0248 0.345 +0.13175 0.02325 0.345 +0.1333 0.0217 0.345 +0.13485 0.02015 0.345 +0.1364 0.0186 0.345 +0.13795 0.01705 0.345 +0.1395 0.0155 0.345 +0.14105 0.01395 0.345 +0.1426 0.0124 0.345 +0.14415 0.01085 0.345 +0.1457 0.0093 0.345 +0.14725 0.00775 0.345 +0.1488 0.0062 0.345 +0.15035 0.00465 0.345 +0.1519 0.0031 0.345 +0.15345 0.00155 0.345 +0 0.16 0.34 +0.0016 0.1584 0.34 +0.0032 0.1568 0.34 +0.0048 0.1552 0.34 +0.0064 0.1536 0.34 +0.008 0.152 0.34 +0.0096 0.1504 0.34 +0.0112 0.1488 0.34 +0.0128 0.1472 0.34 +0.0144 0.1456 0.34 +0.016 0.144 0.34 +0.0176 0.1424 0.34 +0.0192 0.1408 0.34 +0.0208 0.1392 0.34 +0.0224 0.1376 0.34 +0.024 0.136 0.34 +0.0256 0.1344 0.34 +0.0272 0.1328 0.34 +0.0288 0.1312 0.34 +0.0304 0.1296 0.34 +0.032 0.128 0.34 +0.0336 0.1264 0.34 +0.0352 0.1248 0.34 +0.0368 0.1232 0.34 +0.0384 0.1216 0.34 +0.04 0.12 0.34 +0.0416 0.1184 0.34 +0.0432 0.1168 0.34 +0.0448 0.1152 0.34 +0.0464 0.1136 0.34 +0.048 0.112 0.34 +0.0496 0.1104 0.34 +0.0512 0.1088 0.34 +0.0528 0.1072 0.34 +0.0544 0.1056 0.34 +0.056 0.104 0.34 +0.0576 0.1024 0.34 +0.0592 0.1008 0.34 +0.0608 0.0992 0.34 +0.0624 0.0976 0.34 +0.064 0.096 0.34 +0.0656 0.0944 0.34 +0.0672 0.0928 0.34 +0.0688 0.0912 0.34 +0.0704 0.0896 0.34 +0.072 0.088 0.34 +0.0736 0.0864 0.34 +0.0752 0.0848 0.34 +0.0768 0.0832 0.34 +0.0784 0.0816 0.34 +0.08 0.08 0.34 +0.0816 0.0784 0.34 +0.0832 0.0768 0.34 +0.0848 0.0752 0.34 +0.0864 0.0736 0.34 +0.088 0.072 0.34 +0.0896 0.0704 0.34 +0.0912 0.0688 0.34 +0.0928 0.0672 0.34 +0.0944 0.0656 0.34 +0.096 0.064 0.34 +0.0976 0.0624 0.34 +0.0992 0.0608 0.34 +0.1008 0.0592 0.34 +0.1024 0.0576 0.34 +0.104 0.056 0.34 +0.1056 0.0544 0.34 +0.1072 0.0528 0.34 +0.1088 0.0512 0.34 +0.1104 0.0496 0.34 +0.112 0.048 0.34 +0.1136 0.0464 0.34 +0.1152 0.0448 0.34 +0.1168 0.0432 0.34 +0.1184 0.0416 0.34 +0.12 0.04 0.34 +0.1216 0.0384 0.34 +0.1232 0.0368 0.34 +0.1248 0.0352 0.34 +0.1264 0.0336 0.34 +0.128 0.032 0.34 +0.1296 0.0304 0.34 +0.1312 0.0288 0.34 +0.1328 0.0272 0.34 +0.1344 0.0256 0.34 +0.136 0.024 0.34 +0.1376 0.0224 0.34 +0.1392 0.0208 0.34 +0.1408 0.0192 0.34 +0.1424 0.0176 0.34 +0.144 0.016 0.34 +0.1456 0.0144 0.34 +0.1472 0.0128 0.34 +0.1488 0.0112 0.34 +0.1504 0.0096 0.34 +0.152 0.008 0.34 +0.1536 0.0064 0.34 +0.1552 0.0048 0.34 +0.1568 0.0032 0.34 +0.1584 0.0016 0.34 +0 0.165 0.335 +0.00165 0.16335 0.335 +0.0033 0.1617 0.335 +0.00495 0.16005 0.335 +0.0066 0.1584 0.335 +0.00825 0.15675 0.335 +0.0099 0.1551 0.335 +0.01155 0.15345 0.335 +0.0132 0.1518 0.335 +0.01485 0.15015 0.335 +0.0165 0.1485 0.335 +0.01815 0.14685 0.335 +0.0198 0.1452 0.335 +0.02145 0.14355 0.335 +0.0231 0.1419 0.335 +0.02475 0.14025 0.335 +0.0264 0.1386 0.335 +0.02805 0.13695 0.335 +0.0297 0.1353 0.335 +0.03135 0.13365 0.335 +0.033 0.132 0.335 +0.03465 0.13035 0.335 +0.0363 0.1287 0.335 +0.03795 0.12705 0.335 +0.0396 0.1254 0.335 +0.04125 0.12375 0.335 +0.0429 0.1221 0.335 +0.04455 0.12045 0.335 +0.0462 0.1188 0.335 +0.04785 0.11715 0.335 +0.0495 0.1155 0.335 +0.05115 0.11385 0.335 +0.0528 0.1122 0.335 +0.05445 0.11055 0.335 +0.0561 0.1089 0.335 +0.05775 0.10725 0.335 +0.0594 0.1056 0.335 +0.06105 0.10395 0.335 +0.0627 0.1023 0.335 +0.06435 0.10065 0.335 +0.066 0.099 0.335 +0.06765 0.09735 0.335 +0.0693 0.0957 0.335 +0.07095 0.09405 0.335 +0.0726 0.0924 0.335 +0.07425 0.09075 0.335 +0.0759 0.0891 0.335 +0.07755 0.08745 0.335 +0.0792 0.0858 0.335 +0.08085 0.08415 0.335 +0.0825 0.0825 0.335 +0.08415 0.08085 0.335 +0.0858 0.0792 0.335 +0.08745 0.07755 0.335 +0.0891 0.0759 0.335 +0.09075 0.07425 0.335 +0.0924 0.0726 0.335 +0.09405 0.07095 0.335 +0.0957 0.0693 0.335 +0.09735 0.06765 0.335 +0.099 0.066 0.335 +0.10065 0.06435 0.335 +0.1023 0.0627 0.335 +0.10395 0.06105 0.335 +0.1056 0.0594 0.335 +0.10725 0.05775 0.335 +0.1089 0.0561 0.335 +0.11055 0.05445 0.335 +0.1122 0.0528 0.335 +0.11385 0.05115 0.335 +0.1155 0.0495 0.335 +0.11715 0.04785 0.335 +0.1188 0.0462 0.335 +0.12045 0.04455 0.335 +0.1221 0.0429 0.335 +0.12375 0.04125 0.335 +0.1254 0.0396 0.335 +0.12705 0.03795 0.335 +0.1287 0.0363 0.335 +0.13035 0.03465 0.335 +0.132 0.033 0.335 +0.13365 0.03135 0.335 +0.1353 0.0297 0.335 +0.13695 0.02805 0.335 +0.1386 0.0264 0.335 +0.14025 0.02475 0.335 +0.1419 0.0231 0.335 +0.14355 0.02145 0.335 +0.1452 0.0198 0.335 +0.14685 0.01815 0.335 +0.1485 0.0165 0.335 +0.15015 0.01485 0.335 +0.1518 0.0132 0.335 +0.15345 0.01155 0.335 +0.1551 0.0099 0.335 +0.15675 0.00825 0.335 +0.1584 0.0066 0.335 +0.16005 0.00495 0.335 +0.1617 0.0033 0.335 +0.16335 0.00165 0.335 +0 0.17 0.33 +0.0017 0.1683 0.33 +0.0034 0.1666 0.33 +0.0051 0.1649 0.33 +0.0068 0.1632 0.33 +0.0085 0.1615 0.33 +0.0102 0.1598 0.33 +0.0119 0.1581 0.33 +0.0136 0.1564 0.33 +0.0153 0.1547 0.33 +0.017 0.153 0.33 +0.0187 0.1513 0.33 +0.0204 0.1496 0.33 +0.0221 0.1479 0.33 +0.0238 0.1462 0.33 +0.0255 0.1445 0.33 +0.0272 0.1428 0.33 +0.0289 0.1411 0.33 +0.0306 0.1394 0.33 +0.0323 0.1377 0.33 +0.034 0.136 0.33 +0.0357 0.1343 0.33 +0.0374 0.1326 0.33 +0.0391 0.1309 0.33 +0.0408 0.1292 0.33 +0.0425 0.1275 0.33 +0.0442 0.1258 0.33 +0.0459 0.1241 0.33 +0.0476 0.1224 0.33 +0.0493 0.1207 0.33 +0.051 0.119 0.33 +0.0527 0.1173 0.33 +0.0544 0.1156 0.33 +0.0561 0.1139 0.33 +0.0578 0.1122 0.33 +0.0595 0.1105 0.33 +0.0612 0.1088 0.33 +0.0629 0.1071 0.33 +0.0646 0.1054 0.33 +0.0663 0.1037 0.33 +0.068 0.102 0.33 +0.0697 0.1003 0.33 +0.0714 0.0986 0.33 +0.0731 0.0969 0.33 +0.0748 0.0952 0.33 +0.0765 0.0935 0.33 +0.0782 0.0918 0.33 +0.0799 0.0901 0.33 +0.0816 0.0884 0.33 +0.0833 0.0867 0.33 +0.085 0.085 0.33 +0.0867 0.0833 0.33 +0.0884 0.0816 0.33 +0.0901 0.0799 0.33 +0.0918 0.0782 0.33 +0.0935 0.0765 0.33 +0.0952 0.0748 0.33 +0.0969 0.0731 0.33 +0.0986 0.0714 0.33 +0.1003 0.0697 0.33 +0.102 0.068 0.33 +0.1037 0.0663 0.33 +0.1054 0.0646 0.33 +0.1071 0.0629 0.33 +0.1088 0.0612 0.33 +0.1105 0.0595 0.33 +0.1122 0.0578 0.33 +0.1139 0.0561 0.33 +0.1156 0.0544 0.33 +0.1173 0.0527 0.33 +0.119 0.051 0.33 +0.1207 0.0493 0.33 +0.1224 0.0476 0.33 +0.1241 0.0459 0.33 +0.1258 0.0442 0.33 +0.1275 0.0425 0.33 +0.1292 0.0408 0.33 +0.1309 0.0391 0.33 +0.1326 0.0374 0.33 +0.1343 0.0357 0.33 +0.136 0.034 0.33 +0.1377 0.0323 0.33 +0.1394 0.0306 0.33 +0.1411 0.0289 0.33 +0.1428 0.0272 0.33 +0.1445 0.0255 0.33 +0.1462 0.0238 0.33 +0.1479 0.0221 0.33 +0.1496 0.0204 0.33 +0.1513 0.0187 0.33 +0.153 0.017 0.33 +0.1547 0.0153 0.33 +0.1564 0.0136 0.33 +0.1581 0.0119 0.33 +0.1598 0.0102 0.33 +0.1615 0.0085 0.33 +0.1632 0.0068 0.33 +0.1649 0.0051 0.33 +0.1666 0.0034 0.33 +0.1683 0.0017 0.33 +0 0.175 0.325 +0.00175 0.17325 0.325 +0.0035 0.1715 0.325 +0.00525 0.16975 0.325 +0.007 0.168 0.325 +0.00875 0.16625 0.325 +0.0105 0.1645 0.325 +0.01225 0.16275 0.325 +0.014 0.161 0.325 +0.01575 0.15925 0.325 +0.0175 0.1575 0.325 +0.01925 0.15575 0.325 +0.021 0.154 0.325 +0.02275 0.15225 0.325 +0.0245 0.1505 0.325 +0.02625 0.14875 0.325 +0.028 0.147 0.325 +0.02975 0.14525 0.325 +0.0315 0.1435 0.325 +0.03325 0.14175 0.325 +0.035 0.14 0.325 +0.03675 0.13825 0.325 +0.0385 0.1365 0.325 +0.04025 0.13475 0.325 +0.042 0.133 0.325 +0.04375 0.13125 0.325 +0.0455 0.1295 0.325 +0.04725 0.12775 0.325 +0.049 0.126 0.325 +0.05075 0.12425 0.325 +0.0525 0.1225 0.325 +0.05425 0.12075 0.325 +0.056 0.119 0.325 +0.05775 0.11725 0.325 +0.0595 0.1155 0.325 +0.06125 0.11375 0.325 +0.063 0.112 0.325 +0.06475 0.11025 0.325 +0.0665 0.1085 0.325 +0.06825 0.10675 0.325 +0.07 0.105 0.325 +0.07175 0.10325 0.325 +0.0735 0.1015 0.325 +0.07525 0.09975 0.325 +0.077 0.098 0.325 +0.07875 0.09625 0.325 +0.0805 0.0945 0.325 +0.08225 0.09275 0.325 +0.084 0.091 0.325 +0.08575 0.08925 0.325 +0.0875 0.0875 0.325 +0.08925 0.08575 0.325 +0.091 0.084 0.325 +0.09275 0.08225 0.325 +0.0945 0.0805 0.325 +0.09625 0.07875 0.325 +0.098 0.077 0.325 +0.09975 0.07525 0.325 +0.1015 0.0735 0.325 +0.10325 0.07175 0.325 +0.105 0.07 0.325 +0.10675 0.06825 0.325 +0.1085 0.0665 0.325 +0.11025 0.06475 0.325 +0.112 0.063 0.325 +0.11375 0.06125 0.325 +0.1155 0.0595 0.325 +0.11725 0.05775 0.325 +0.119 0.056 0.325 +0.12075 0.05425 0.325 +0.1225 0.0525 0.325 +0.12425 0.05075 0.325 +0.126 0.049 0.325 +0.12775 0.04725 0.325 +0.1295 0.0455 0.325 +0.13125 0.04375 0.325 +0.133 0.042 0.325 +0.13475 0.04025 0.325 +0.1365 0.0385 0.325 +0.13825 0.03675 0.325 +0.14 0.035 0.325 +0.14175 0.03325 0.325 +0.1435 0.0315 0.325 +0.14525 0.02975 0.325 +0.147 0.028 0.325 +0.14875 0.02625 0.325 +0.1505 0.0245 0.325 +0.15225 0.02275 0.325 +0.154 0.021 0.325 +0.15575 0.01925 0.325 +0.1575 0.0175 0.325 +0.15925 0.01575 0.325 +0.161 0.014 0.325 +0.16275 0.01225 0.325 +0.1645 0.0105 0.325 +0.16625 0.00875 0.325 +0.168 0.007 0.325 +0.16975 0.00525 0.325 +0.1715 0.0035 0.325 +0.17325 0.00175 0.325 +0 0.18 0.32 +0.0018 0.1782 0.32 +0.0036 0.1764 0.32 +0.0054 0.1746 0.32 +0.0072 0.1728 0.32 +0.009 0.171 0.32 +0.0108 0.1692 0.32 +0.0126 0.1674 0.32 +0.0144 0.1656 0.32 +0.0162 0.1638 0.32 +0.018 0.162 0.32 +0.0198 0.1602 0.32 +0.0216 0.1584 0.32 +0.0234 0.1566 0.32 +0.0252 0.1548 0.32 +0.027 0.153 0.32 +0.0288 0.1512 0.32 +0.0306 0.1494 0.32 +0.0324 0.1476 0.32 +0.0342 0.1458 0.32 +0.036 0.144 0.32 +0.0378 0.1422 0.32 +0.0396 0.1404 0.32 +0.0414 0.1386 0.32 +0.0432 0.1368 0.32 +0.045 0.135 0.32 +0.0468 0.1332 0.32 +0.0486 0.1314 0.32 +0.0504 0.1296 0.32 +0.0522 0.1278 0.32 +0.054 0.126 0.32 +0.0558 0.1242 0.32 +0.0576 0.1224 0.32 +0.0594 0.1206 0.32 +0.0612 0.1188 0.32 +0.063 0.117 0.32 +0.0648 0.1152 0.32 +0.0666 0.1134 0.32 +0.0684 0.1116 0.32 +0.0702 0.1098 0.32 +0.072 0.108 0.32 +0.0738 0.1062 0.32 +0.0756 0.1044 0.32 +0.0774 0.1026 0.32 +0.0792 0.1008 0.32 +0.081 0.099 0.32 +0.0828 0.0972 0.32 +0.0846 0.0954 0.32 +0.0864 0.0936 0.32 +0.0882 0.0918 0.32 +0.09 0.09 0.32 +0.0918 0.0882 0.32 +0.0936 0.0864 0.32 +0.0954 0.0846 0.32 +0.0972 0.0828 0.32 +0.099 0.081 0.32 +0.1008 0.0792 0.32 +0.1026 0.0774 0.32 +0.1044 0.0756 0.32 +0.1062 0.0738 0.32 +0.108 0.072 0.32 +0.1098 0.0702 0.32 +0.1116 0.0684 0.32 +0.1134 0.0666 0.32 +0.1152 0.0648 0.32 +0.117 0.063 0.32 +0.1188 0.0612 0.32 +0.1206 0.0594 0.32 +0.1224 0.0576 0.32 +0.1242 0.0558 0.32 +0.126 0.054 0.32 +0.1278 0.0522 0.32 +0.1296 0.0504 0.32 +0.1314 0.0486 0.32 +0.1332 0.0468 0.32 +0.135 0.045 0.32 +0.1368 0.0432 0.32 +0.1386 0.0414 0.32 +0.1404 0.0396 0.32 +0.1422 0.0378 0.32 +0.144 0.036 0.32 +0.1458 0.0342 0.32 +0.1476 0.0324 0.32 +0.1494 0.0306 0.32 +0.1512 0.0288 0.32 +0.153 0.027 0.32 +0.1548 0.0252 0.32 +0.1566 0.0234 0.32 +0.1584 0.0216 0.32 +0.1602 0.0198 0.32 +0.162 0.018 0.32 +0.1638 0.0162 0.32 +0.1656 0.0144 0.32 +0.1674 0.0126 0.32 +0.1692 0.0108 0.32 +0.171 0.009 0.32 +0.1728 0.0072 0.32 +0.1746 0.0054 0.32 +0.1764 0.0036 0.32 +0.1782 0.0018 0.32 +0 0.185 0.315 +0.00185 0.18315 0.315 +0.0037 0.1813 0.315 +0.00555 0.17945 0.315 +0.0074 0.1776 0.315 +0.00925 0.17575 0.315 +0.0111 0.1739 0.315 +0.01295 0.17205 0.315 +0.0148 0.1702 0.315 +0.01665 0.16835 0.315 +0.0185 0.1665 0.315 +0.02035 0.16465 0.315 +0.0222 0.1628 0.315 +0.02405 0.16095 0.315 +0.0259 0.1591 0.315 +0.02775 0.15725 0.315 +0.0296 0.1554 0.315 +0.03145 0.15355 0.315 +0.0333 0.1517 0.315 +0.03515 0.14985 0.315 +0.037 0.148 0.315 +0.03885 0.14615 0.315 +0.0407 0.1443 0.315 +0.04255 0.14245 0.315 +0.0444 0.1406 0.315 +0.04625 0.13875 0.315 +0.0481 0.1369 0.315 +0.04995 0.13505 0.315 +0.0518 0.1332 0.315 +0.05365 0.13135 0.315 +0.0555 0.1295 0.315 +0.05735 0.12765 0.315 +0.0592 0.1258 0.315 +0.06105 0.12395 0.315 +0.0629 0.1221 0.315 +0.06475 0.12025 0.315 +0.0666 0.1184 0.315 +0.06845 0.11655 0.315 +0.0703 0.1147 0.315 +0.07215 0.11285 0.315 +0.074 0.111 0.315 +0.07585 0.10915 0.315 +0.0777 0.1073 0.315 +0.07955 0.10545 0.315 +0.0814 0.1036 0.315 +0.08325 0.10175 0.315 +0.0851 0.0999 0.315 +0.08695 0.09805 0.315 +0.0888 0.0962 0.315 +0.09065 0.09435 0.315 +0.0925 0.0925 0.315 +0.09435 0.09065 0.315 +0.0962 0.0888 0.315 +0.09805 0.08695 0.315 +0.0999 0.0851 0.315 +0.10175 0.08325 0.315 +0.1036 0.0814 0.315 +0.10545 0.07955 0.315 +0.1073 0.0777 0.315 +0.10915 0.07585 0.315 +0.111 0.074 0.315 +0.11285 0.07215 0.315 +0.1147 0.0703 0.315 +0.11655 0.06845 0.315 +0.1184 0.0666 0.315 +0.12025 0.06475 0.315 +0.1221 0.0629 0.315 +0.12395 0.06105 0.315 +0.1258 0.0592 0.315 +0.12765 0.05735 0.315 +0.1295 0.0555 0.315 +0.13135 0.05365 0.315 +0.1332 0.0518 0.315 +0.13505 0.04995 0.315 +0.1369 0.0481 0.315 +0.13875 0.04625 0.315 +0.1406 0.0444 0.315 +0.14245 0.04255 0.315 +0.1443 0.0407 0.315 +0.14615 0.03885 0.315 +0.148 0.037 0.315 +0.14985 0.03515 0.315 +0.1517 0.0333 0.315 +0.15355 0.03145 0.315 +0.1554 0.0296 0.315 +0.15725 0.02775 0.315 +0.1591 0.0259 0.315 +0.16095 0.02405 0.315 +0.1628 0.0222 0.315 +0.16465 0.02035 0.315 +0.1665 0.0185 0.315 +0.16835 0.01665 0.315 +0.1702 0.0148 0.315 +0.17205 0.01295 0.315 +0.1739 0.0111 0.315 +0.17575 0.00925 0.315 +0.1776 0.0074 0.315 +0.17945 0.00555 0.315 +0.1813 0.0037 0.315 +0.18315 0.00185 0.315 +0 0.19 0.31 +0.0019 0.1881 0.31 +0.0038 0.1862 0.31 +0.0057 0.1843 0.31 +0.0076 0.1824 0.31 +0.0095 0.1805 0.31 +0.0114 0.1786 0.31 +0.0133 0.1767 0.31 +0.0152 0.1748 0.31 +0.0171 0.1729 0.31 +0.019 0.171 0.31 +0.0209 0.1691 0.31 +0.0228 0.1672 0.31 +0.0247 0.1653 0.31 +0.0266 0.1634 0.31 +0.0285 0.1615 0.31 +0.0304 0.1596 0.31 +0.0323 0.1577 0.31 +0.0342 0.1558 0.31 +0.0361 0.1539 0.31 +0.038 0.152 0.31 +0.0399 0.1501 0.31 +0.0418 0.1482 0.31 +0.0437 0.1463 0.31 +0.0456 0.1444 0.31 +0.0475 0.1425 0.31 +0.0494 0.1406 0.31 +0.0513 0.1387 0.31 +0.0532 0.1368 0.31 +0.0551 0.1349 0.31 +0.057 0.133 0.31 +0.0589 0.1311 0.31 +0.0608 0.1292 0.31 +0.0627 0.1273 0.31 +0.0646 0.1254 0.31 +0.0665 0.1235 0.31 +0.0684 0.1216 0.31 +0.0703 0.1197 0.31 +0.0722 0.1178 0.31 +0.0741 0.1159 0.31 +0.076 0.114 0.31 +0.0779 0.1121 0.31 +0.0798 0.1102 0.31 +0.0817 0.1083 0.31 +0.0836 0.1064 0.31 +0.0855 0.1045 0.31 +0.0874 0.1026 0.31 +0.0893 0.1007 0.31 +0.0912 0.0988 0.31 +0.0931 0.0969 0.31 +0.095 0.095 0.31 +0.0969 0.0931 0.31 +0.0988 0.0912 0.31 +0.1007 0.0893 0.31 +0.1026 0.0874 0.31 +0.1045 0.0855 0.31 +0.1064 0.0836 0.31 +0.1083 0.0817 0.31 +0.1102 0.0798 0.31 +0.1121 0.0779 0.31 +0.114 0.076 0.31 +0.1159 0.0741 0.31 +0.1178 0.0722 0.31 +0.1197 0.0703 0.31 +0.1216 0.0684 0.31 +0.1235 0.0665 0.31 +0.1254 0.0646 0.31 +0.1273 0.0627 0.31 +0.1292 0.0608 0.31 +0.1311 0.0589 0.31 +0.133 0.057 0.31 +0.1349 0.0551 0.31 +0.1368 0.0532 0.31 +0.1387 0.0513 0.31 +0.1406 0.0494 0.31 +0.1425 0.0475 0.31 +0.1444 0.0456 0.31 +0.1463 0.0437 0.31 +0.1482 0.0418 0.31 +0.1501 0.0399 0.31 +0.152 0.038 0.31 +0.1539 0.0361 0.31 +0.1558 0.0342 0.31 +0.1577 0.0323 0.31 +0.1596 0.0304 0.31 +0.1615 0.0285 0.31 +0.1634 0.0266 0.31 +0.1653 0.0247 0.31 +0.1672 0.0228 0.31 +0.1691 0.0209 0.31 +0.171 0.019 0.31 +0.1729 0.0171 0.31 +0.1748 0.0152 0.31 +0.1767 0.0133 0.31 +0.1786 0.0114 0.31 +0.1805 0.0095 0.31 +0.1824 0.0076 0.31 +0.1843 0.0057 0.31 +0.1862 0.0038 0.31 +0.1881 0.0019 0.31 +0 0.195 0.305 +0.00195 0.19305 0.305 +0.0039 0.1911 0.305 +0.00585 0.18915 0.305 +0.0078 0.1872 0.305 +0.00975 0.18525 0.305 +0.0117 0.1833 0.305 +0.01365 0.18135 0.305 +0.0156 0.1794 0.305 +0.01755 0.17745 0.305 +0.0195 0.1755 0.305 +0.02145 0.17355 0.305 +0.0234 0.1716 0.305 +0.02535 0.16965 0.305 +0.0273 0.1677 0.305 +0.02925 0.16575 0.305 +0.0312 0.1638 0.305 +0.03315 0.16185 0.305 +0.0351 0.1599 0.305 +0.03705 0.15795 0.305 +0.039 0.156 0.305 +0.04095 0.15405 0.305 +0.0429 0.1521 0.305 +0.04485 0.15015 0.305 +0.0468 0.1482 0.305 +0.04875 0.14625 0.305 +0.0507 0.1443 0.305 +0.05265 0.14235 0.305 +0.0546 0.1404 0.305 +0.05655 0.13845 0.305 +0.0585 0.1365 0.305 +0.06045 0.13455 0.305 +0.0624 0.1326 0.305 +0.06435 0.13065 0.305 +0.0663 0.1287 0.305 +0.06825 0.12675 0.305 +0.0702 0.1248 0.305 +0.07215 0.12285 0.305 +0.0741 0.1209 0.305 +0.07605 0.11895 0.305 +0.078 0.117 0.305 +0.07995 0.11505 0.305 +0.0819 0.1131 0.305 +0.08385 0.11115 0.305 +0.0858 0.1092 0.305 +0.08775 0.10725 0.305 +0.0897 0.1053 0.305 +0.09165 0.10335 0.305 +0.0936 0.1014 0.305 +0.09555 0.09945 0.305 +0.0975 0.0975 0.305 +0.09945 0.09555 0.305 +0.1014 0.0936 0.305 +0.10335 0.09165 0.305 +0.1053 0.0897 0.305 +0.10725 0.08775 0.305 +0.1092 0.0858 0.305 +0.11115 0.08385 0.305 +0.1131 0.0819 0.305 +0.11505 0.07995 0.305 +0.117 0.078 0.305 +0.11895 0.07605 0.305 +0.1209 0.0741 0.305 +0.12285 0.07215 0.305 +0.1248 0.0702 0.305 +0.12675 0.06825 0.305 +0.1287 0.0663 0.305 +0.13065 0.06435 0.305 +0.1326 0.0624 0.305 +0.13455 0.06045 0.305 +0.1365 0.0585 0.305 +0.13845 0.05655 0.305 +0.1404 0.0546 0.305 +0.14235 0.05265 0.305 +0.1443 0.0507 0.305 +0.14625 0.04875 0.305 +0.1482 0.0468 0.305 +0.15015 0.04485 0.305 +0.1521 0.0429 0.305 +0.15405 0.04095 0.305 +0.156 0.039 0.305 +0.15795 0.03705 0.305 +0.1599 0.0351 0.305 +0.16185 0.03315 0.305 +0.1638 0.0312 0.305 +0.16575 0.02925 0.305 +0.1677 0.0273 0.305 +0.16965 0.02535 0.305 +0.1716 0.0234 0.305 +0.17355 0.02145 0.305 +0.1755 0.0195 0.305 +0.17745 0.01755 0.305 +0.1794 0.0156 0.305 +0.18135 0.01365 0.305 +0.1833 0.0117 0.305 +0.18525 0.00975 0.305 +0.1872 0.0078 0.305 +0.18915 0.00585 0.305 +0.1911 0.0039 0.305 +0.19305 0.00195 0.305 +0 0.2 0.3 +0.002 0.198 0.3 +0.004 0.196 0.3 +0.006 0.194 0.3 +0.008 0.192 0.3 +0.01 0.19 0.3 +0.012 0.188 0.3 +0.014 0.186 0.3 +0.016 0.184 0.3 +0.018 0.182 0.3 +0.02 0.18 0.3 +0.022 0.178 0.3 +0.024 0.176 0.3 +0.026 0.174 0.3 +0.028 0.172 0.3 +0.03 0.17 0.3 +0.032 0.168 0.3 +0.034 0.166 0.3 +0.036 0.164 0.3 +0.038 0.162 0.3 +0.04 0.16 0.3 +0.042 0.158 0.3 +0.044 0.156 0.3 +0.046 0.154 0.3 +0.048 0.152 0.3 +0.05 0.15 0.3 +0.052 0.148 0.3 +0.054 0.146 0.3 +0.056 0.144 0.3 +0.058 0.142 0.3 +0.06 0.14 0.3 +0.062 0.138 0.3 +0.064 0.136 0.3 +0.066 0.134 0.3 +0.068 0.132 0.3 +0.07 0.13 0.3 +0.072 0.128 0.3 +0.074 0.126 0.3 +0.076 0.124 0.3 +0.078 0.122 0.3 +0.08 0.12 0.3 +0.082 0.118 0.3 +0.084 0.116 0.3 +0.086 0.114 0.3 +0.088 0.112 0.3 +0.09 0.11 0.3 +0.092 0.108 0.3 +0.094 0.106 0.3 +0.096 0.104 0.3 +0.098 0.102 0.3 +0.1 0.1 0.3 +0.102 0.098 0.3 +0.104 0.096 0.3 +0.106 0.094 0.3 +0.108 0.092 0.3 +0.11 0.09 0.3 +0.112 0.088 0.3 +0.114 0.086 0.3 +0.116 0.084 0.3 +0.118 0.082 0.3 +0.12 0.08 0.3 +0.122 0.078 0.3 +0.124 0.076 0.3 +0.126 0.074 0.3 +0.128 0.072 0.3 +0.13 0.07 0.3 +0.132 0.068 0.3 +0.134 0.066 0.3 +0.136 0.064 0.3 +0.138 0.062 0.3 +0.14 0.06 0.3 +0.142 0.058 0.3 +0.144 0.056 0.3 +0.146 0.054 0.3 +0.148 0.052 0.3 +0.15 0.05 0.3 +0.152 0.048 0.3 +0.154 0.046 0.3 +0.156 0.044 0.3 +0.158 0.042 0.3 +0.16 0.04 0.3 +0.162 0.038 0.3 +0.164 0.036 0.3 +0.166 0.034 0.3 +0.168 0.032 0.3 +0.17 0.03 0.3 +0.172 0.028 0.3 +0.174 0.026 0.3 +0.176 0.024 0.3 +0.178 0.022 0.3 +0.18 0.02 0.3 +0.182 0.018 0.3 +0.184 0.016 0.3 +0.186 0.014 0.3 +0.188 0.012 0.3 +0.19 0.01 0.3 +0.192 0.008 0.3 +0.194 0.006 0.3 +0.196 0.004 0.3 +0.198 0.002 0.3 +0 0.205 0.295 +0.00205 0.20295 0.295 +0.0041 0.2009 0.295 +0.00615 0.19885 0.295 +0.0082 0.1968 0.295 +0.01025 0.19475 0.295 +0.0123 0.1927 0.295 +0.01435 0.19065 0.295 +0.0164 0.1886 0.295 +0.01845 0.18655 0.295 +0.0205 0.1845 0.295 +0.02255 0.18245 0.295 +0.0246 0.1804 0.295 +0.02665 0.17835 0.295 +0.0287 0.1763 0.295 +0.03075 0.17425 0.295 +0.0328 0.1722 0.295 +0.03485 0.17015 0.295 +0.0369 0.1681 0.295 +0.03895 0.16605 0.295 +0.041 0.164 0.295 +0.04305 0.16195 0.295 +0.0451 0.1599 0.295 +0.04715 0.15785 0.295 +0.0492 0.1558 0.295 +0.05125 0.15375 0.295 +0.0533 0.1517 0.295 +0.05535 0.14965 0.295 +0.0574 0.1476 0.295 +0.05945 0.14555 0.295 +0.0615 0.1435 0.295 +0.06355 0.14145 0.295 +0.0656 0.1394 0.295 +0.06765 0.13735 0.295 +0.0697 0.1353 0.295 +0.07175 0.13325 0.295 +0.0738 0.1312 0.295 +0.07585 0.12915 0.295 +0.0779 0.1271 0.295 +0.07995 0.12505 0.295 +0.082 0.123 0.295 +0.08405 0.12095 0.295 +0.0861 0.1189 0.295 +0.08815 0.11685 0.295 +0.0902 0.1148 0.295 +0.09225 0.11275 0.295 +0.0943 0.1107 0.295 +0.09635 0.10865 0.295 +0.0984 0.1066 0.295 +0.10045 0.10455 0.295 +0.1025 0.1025 0.295 +0.10455 0.10045 0.295 +0.1066 0.0984 0.295 +0.10865 0.09635 0.295 +0.1107 0.0943 0.295 +0.11275 0.09225 0.295 +0.1148 0.0902 0.295 +0.11685 0.08815 0.295 +0.1189 0.0861 0.295 +0.12095 0.08405 0.295 +0.123 0.082 0.295 +0.12505 0.07995 0.295 +0.1271 0.0779 0.295 +0.12915 0.07585 0.295 +0.1312 0.0738 0.295 +0.13325 0.07175 0.295 +0.1353 0.0697 0.295 +0.13735 0.06765 0.295 +0.1394 0.0656 0.295 +0.14145 0.06355 0.295 +0.1435 0.0615 0.295 +0.14555 0.05945 0.295 +0.1476 0.0574 0.295 +0.14965 0.05535 0.295 +0.1517 0.0533 0.295 +0.15375 0.05125 0.295 +0.1558 0.0492 0.295 +0.15785 0.04715 0.295 +0.1599 0.0451 0.295 +0.16195 0.04305 0.295 +0.164 0.041 0.295 +0.16605 0.03895 0.295 +0.1681 0.0369 0.295 +0.17015 0.03485 0.295 +0.1722 0.0328 0.295 +0.17425 0.03075 0.295 +0.1763 0.0287 0.295 +0.17835 0.02665 0.295 +0.1804 0.0246 0.295 +0.18245 0.02255 0.295 +0.1845 0.0205 0.295 +0.18655 0.01845 0.295 +0.1886 0.0164 0.295 +0.19065 0.01435 0.295 +0.1927 0.0123 0.295 +0.19475 0.01025 0.295 +0.1968 0.0082 0.295 +0.19885 0.00615 0.295 +0.2009 0.0041 0.295 +0.20295 0.00205 0.295 +0 0.21 0.29 +0.0021 0.2079 0.29 +0.0042 0.2058 0.29 +0.0063 0.2037 0.29 +0.0084 0.2016 0.29 +0.0105 0.1995 0.29 +0.0126 0.1974 0.29 +0.0147 0.1953 0.29 +0.0168 0.1932 0.29 +0.0189 0.1911 0.29 +0.021 0.189 0.29 +0.0231 0.1869 0.29 +0.0252 0.1848 0.29 +0.0273 0.1827 0.29 +0.0294 0.1806 0.29 +0.0315 0.1785 0.29 +0.0336 0.1764 0.29 +0.0357 0.1743 0.29 +0.0378 0.1722 0.29 +0.0399 0.1701 0.29 +0.042 0.168 0.29 +0.0441 0.1659 0.29 +0.0462 0.1638 0.29 +0.0483 0.1617 0.29 +0.0504 0.1596 0.29 +0.0525 0.1575 0.29 +0.0546 0.1554 0.29 +0.0567 0.1533 0.29 +0.0588 0.1512 0.29 +0.0609 0.1491 0.29 +0.063 0.147 0.29 +0.0651 0.1449 0.29 +0.0672 0.1428 0.29 +0.0693 0.1407 0.29 +0.0714 0.1386 0.29 +0.0735 0.1365 0.29 +0.0756 0.1344 0.29 +0.0777 0.1323 0.29 +0.0798 0.1302 0.29 +0.0819 0.1281 0.29 +0.084 0.126 0.29 +0.0861 0.1239 0.29 +0.0882 0.1218 0.29 +0.0903 0.1197 0.29 +0.0924 0.1176 0.29 +0.0945 0.1155 0.29 +0.0966 0.1134 0.29 +0.0987 0.1113 0.29 +0.1008 0.1092 0.29 +0.1029 0.1071 0.29 +0.105 0.105 0.29 +0.1071 0.1029 0.29 +0.1092 0.1008 0.29 +0.1113 0.0987 0.29 +0.1134 0.0966 0.29 +0.1155 0.0945 0.29 +0.1176 0.0924 0.29 +0.1197 0.0903 0.29 +0.1218 0.0882 0.29 +0.1239 0.0861 0.29 +0.126 0.084 0.29 +0.1281 0.0819 0.29 +0.1302 0.0798 0.29 +0.1323 0.0777 0.29 +0.1344 0.0756 0.29 +0.1365 0.0735 0.29 +0.1386 0.0714 0.29 +0.1407 0.0693 0.29 +0.1428 0.0672 0.29 +0.1449 0.0651 0.29 +0.147 0.063 0.29 +0.1491 0.0609 0.29 +0.1512 0.0588 0.29 +0.1533 0.0567 0.29 +0.1554 0.0546 0.29 +0.1575 0.0525 0.29 +0.1596 0.0504 0.29 +0.1617 0.0483 0.29 +0.1638 0.0462 0.29 +0.1659 0.0441 0.29 +0.168 0.042 0.29 +0.1701 0.0399 0.29 +0.1722 0.0378 0.29 +0.1743 0.0357 0.29 +0.1764 0.0336 0.29 +0.1785 0.0315 0.29 +0.1806 0.0294 0.29 +0.1827 0.0273 0.29 +0.1848 0.0252 0.29 +0.1869 0.0231 0.29 +0.189 0.021 0.29 +0.1911 0.0189 0.29 +0.1932 0.0168 0.29 +0.1953 0.0147 0.29 +0.1974 0.0126 0.29 +0.1995 0.0105 0.29 +0.2016 0.0084 0.29 +0.2037 0.0063 0.29 +0.2058 0.0042 0.29 +0.2079 0.0021 0.29 +0 0.215 0.285 +0.00215 0.21285 0.285 +0.0043 0.2107 0.285 +0.00645 0.20855 0.285 +0.0086 0.2064 0.285 +0.01075 0.20425 0.285 +0.0129 0.2021 0.285 +0.01505 0.19995 0.285 +0.0172 0.1978 0.285 +0.01935 0.19565 0.285 +0.0215 0.1935 0.285 +0.02365 0.19135 0.285 +0.0258 0.1892 0.285 +0.02795 0.18705 0.285 +0.0301 0.1849 0.285 +0.03225 0.18275 0.285 +0.0344 0.1806 0.285 +0.03655 0.17845 0.285 +0.0387 0.1763 0.285 +0.04085 0.17415 0.285 +0.043 0.172 0.285 +0.04515 0.16985 0.285 +0.0473 0.1677 0.285 +0.04945 0.16555 0.285 +0.0516 0.1634 0.285 +0.05375 0.16125 0.285 +0.0559 0.1591 0.285 +0.05805 0.15695 0.285 +0.0602 0.1548 0.285 +0.06235 0.15265 0.285 +0.0645 0.1505 0.285 +0.06665 0.14835 0.285 +0.0688 0.1462 0.285 +0.07095 0.14405 0.285 +0.0731 0.1419 0.285 +0.07525 0.13975 0.285 +0.0774 0.1376 0.285 +0.07955 0.13545 0.285 +0.0817 0.1333 0.285 +0.08385 0.13115 0.285 +0.086 0.129 0.285 +0.08815 0.12685 0.285 +0.0903 0.1247 0.285 +0.09245 0.12255 0.285 +0.0946 0.1204 0.285 +0.09675 0.11825 0.285 +0.0989 0.1161 0.285 +0.10105 0.11395 0.285 +0.1032 0.1118 0.285 +0.10535 0.10965 0.285 +0.1075 0.1075 0.285 +0.10965 0.10535 0.285 +0.1118 0.1032 0.285 +0.11395 0.10105 0.285 +0.1161 0.0989 0.285 +0.11825 0.09675 0.285 +0.1204 0.0946 0.285 +0.12255 0.09245 0.285 +0.1247 0.0903 0.285 +0.12685 0.08815 0.285 +0.129 0.086 0.285 +0.13115 0.08385 0.285 +0.1333 0.0817 0.285 +0.13545 0.07955 0.285 +0.1376 0.0774 0.285 +0.13975 0.07525 0.285 +0.1419 0.0731 0.285 +0.14405 0.07095 0.285 +0.1462 0.0688 0.285 +0.14835 0.06665 0.285 +0.1505 0.0645 0.285 +0.15265 0.06235 0.285 +0.1548 0.0602 0.285 +0.15695 0.05805 0.285 +0.1591 0.0559 0.285 +0.16125 0.05375 0.285 +0.1634 0.0516 0.285 +0.16555 0.04945 0.285 +0.1677 0.0473 0.285 +0.16985 0.04515 0.285 +0.172 0.043 0.285 +0.17415 0.04085 0.285 +0.1763 0.0387 0.285 +0.17845 0.03655 0.285 +0.1806 0.0344 0.285 +0.18275 0.03225 0.285 +0.1849 0.0301 0.285 +0.18705 0.02795 0.285 +0.1892 0.0258 0.285 +0.19135 0.02365 0.285 +0.1935 0.0215 0.285 +0.19565 0.01935 0.285 +0.1978 0.0172 0.285 +0.19995 0.01505 0.285 +0.2021 0.0129 0.285 +0.20425 0.01075 0.285 +0.2064 0.0086 0.285 +0.20855 0.00645 0.285 +0.2107 0.0043 0.285 +0.21285 0.00215 0.285 +0 0.22 0.28 +0.0022 0.2178 0.28 +0.0044 0.2156 0.28 +0.0066 0.2134 0.28 +0.0088 0.2112 0.28 +0.011 0.209 0.28 +0.0132 0.2068 0.28 +0.0154 0.2046 0.28 +0.0176 0.2024 0.28 +0.0198 0.2002 0.28 +0.022 0.198 0.28 +0.0242 0.1958 0.28 +0.0264 0.1936 0.28 +0.0286 0.1914 0.28 +0.0308 0.1892 0.28 +0.033 0.187 0.28 +0.0352 0.1848 0.28 +0.0374 0.1826 0.28 +0.0396 0.1804 0.28 +0.0418 0.1782 0.28 +0.044 0.176 0.28 +0.0462 0.1738 0.28 +0.0484 0.1716 0.28 +0.0506 0.1694 0.28 +0.0528 0.1672 0.28 +0.055 0.165 0.28 +0.0572 0.1628 0.28 +0.0594 0.1606 0.28 +0.0616 0.1584 0.28 +0.0638 0.1562 0.28 +0.066 0.154 0.28 +0.0682 0.1518 0.28 +0.0704 0.1496 0.28 +0.0726 0.1474 0.28 +0.0748 0.1452 0.28 +0.077 0.143 0.28 +0.0792 0.1408 0.28 +0.0814 0.1386 0.28 +0.0836 0.1364 0.28 +0.0858 0.1342 0.28 +0.088 0.132 0.28 +0.0902 0.1298 0.28 +0.0924 0.1276 0.28 +0.0946 0.1254 0.28 +0.0968 0.1232 0.28 +0.099 0.121 0.28 +0.1012 0.1188 0.28 +0.1034 0.1166 0.28 +0.1056 0.1144 0.28 +0.1078 0.1122 0.28 +0.11 0.11 0.28 +0.1122 0.1078 0.28 +0.1144 0.1056 0.28 +0.1166 0.1034 0.28 +0.1188 0.1012 0.28 +0.121 0.099 0.28 +0.1232 0.0968 0.28 +0.1254 0.0946 0.28 +0.1276 0.0924 0.28 +0.1298 0.0902 0.28 +0.132 0.088 0.28 +0.1342 0.0858 0.28 +0.1364 0.0836 0.28 +0.1386 0.0814 0.28 +0.1408 0.0792 0.28 +0.143 0.077 0.28 +0.1452 0.0748 0.28 +0.1474 0.0726 0.28 +0.1496 0.0704 0.28 +0.1518 0.0682 0.28 +0.154 0.066 0.28 +0.1562 0.0638 0.28 +0.1584 0.0616 0.28 +0.1606 0.0594 0.28 +0.1628 0.0572 0.28 +0.165 0.055 0.28 +0.1672 0.0528 0.28 +0.1694 0.0506 0.28 +0.1716 0.0484 0.28 +0.1738 0.0462 0.28 +0.176 0.044 0.28 +0.1782 0.0418 0.28 +0.1804 0.0396 0.28 +0.1826 0.0374 0.28 +0.1848 0.0352 0.28 +0.187 0.033 0.28 +0.1892 0.0308 0.28 +0.1914 0.0286 0.28 +0.1936 0.0264 0.28 +0.1958 0.0242 0.28 +0.198 0.022 0.28 +0.2002 0.0198 0.28 +0.2024 0.0176 0.28 +0.2046 0.0154 0.28 +0.2068 0.0132 0.28 +0.209 0.011 0.28 +0.2112 0.0088 0.28 +0.2134 0.0066 0.28 +0.2156 0.0044 0.28 +0.2178 0.0022 0.28 +0 0.225 0.275 +0.00225 0.22275 0.275 +0.0045 0.2205 0.275 +0.00675 0.21825 0.275 +0.009 0.216 0.275 +0.01125 0.21375 0.275 +0.0135 0.2115 0.275 +0.01575 0.20925 0.275 +0.018 0.207 0.275 +0.02025 0.20475 0.275 +0.0225 0.2025 0.275 +0.02475 0.20025 0.275 +0.027 0.198 0.275 +0.02925 0.19575 0.275 +0.0315 0.1935 0.275 +0.03375 0.19125 0.275 +0.036 0.189 0.275 +0.03825 0.18675 0.275 +0.0405 0.1845 0.275 +0.04275 0.18225 0.275 +0.045 0.18 0.275 +0.04725 0.17775 0.275 +0.0495 0.1755 0.275 +0.05175 0.17325 0.275 +0.054 0.171 0.275 +0.05625 0.16875 0.275 +0.0585 0.1665 0.275 +0.06075 0.16425 0.275 +0.063 0.162 0.275 +0.06525 0.15975 0.275 +0.0675 0.1575 0.275 +0.06975 0.15525 0.275 +0.072 0.153 0.275 +0.07425 0.15075 0.275 +0.0765 0.1485 0.275 +0.07875 0.14625 0.275 +0.081 0.144 0.275 +0.08325 0.14175 0.275 +0.0855 0.1395 0.275 +0.08775 0.13725 0.275 +0.09 0.135 0.275 +0.09225 0.13275 0.275 +0.0945 0.1305 0.275 +0.09675 0.12825 0.275 +0.099 0.126 0.275 +0.10125 0.12375 0.275 +0.1035 0.1215 0.275 +0.10575 0.11925 0.275 +0.108 0.117 0.275 +0.11025 0.11475 0.275 +0.1125 0.1125 0.275 +0.11475 0.11025 0.275 +0.117 0.108 0.275 +0.11925 0.10575 0.275 +0.1215 0.1035 0.275 +0.12375 0.10125 0.275 +0.126 0.099 0.275 +0.12825 0.09675 0.275 +0.1305 0.0945 0.275 +0.13275 0.09225 0.275 +0.135 0.09 0.275 +0.13725 0.08775 0.275 +0.1395 0.0855 0.275 +0.14175 0.08325 0.275 +0.144 0.081 0.275 +0.14625 0.07875 0.275 +0.1485 0.0765 0.275 +0.15075 0.07425 0.275 +0.153 0.072 0.275 +0.15525 0.06975 0.275 +0.1575 0.0675 0.275 +0.15975 0.06525 0.275 +0.162 0.063 0.275 +0.16425 0.06075 0.275 +0.1665 0.0585 0.275 +0.16875 0.05625 0.275 +0.171 0.054 0.275 +0.17325 0.05175 0.275 +0.1755 0.0495 0.275 +0.17775 0.04725 0.275 +0.18 0.045 0.275 +0.18225 0.04275 0.275 +0.1845 0.0405 0.275 +0.18675 0.03825 0.275 +0.189 0.036 0.275 +0.19125 0.03375 0.275 +0.1935 0.0315 0.275 +0.19575 0.02925 0.275 +0.198 0.027 0.275 +0.20025 0.02475 0.275 +0.2025 0.0225 0.275 +0.20475 0.02025 0.275 +0.207 0.018 0.275 +0.20925 0.01575 0.275 +0.2115 0.0135 0.275 +0.21375 0.01125 0.275 +0.216 0.009 0.275 +0.21825 0.00675 0.275 +0.2205 0.0045 0.275 +0.22275 0.00225 0.275 +0 0.23 0.27 +0.0023 0.2277 0.27 +0.0046 0.2254 0.27 +0.0069 0.2231 0.27 +0.0092 0.2208 0.27 +0.0115 0.2185 0.27 +0.0138 0.2162 0.27 +0.0161 0.2139 0.27 +0.0184 0.2116 0.27 +0.0207 0.2093 0.27 +0.023 0.207 0.27 +0.0253 0.2047 0.27 +0.0276 0.2024 0.27 +0.0299 0.2001 0.27 +0.0322 0.1978 0.27 +0.0345 0.1955 0.27 +0.0368 0.1932 0.27 +0.0391 0.1909 0.27 +0.0414 0.1886 0.27 +0.0437 0.1863 0.27 +0.046 0.184 0.27 +0.0483 0.1817 0.27 +0.0506 0.1794 0.27 +0.0529 0.1771 0.27 +0.0552 0.1748 0.27 +0.0575 0.1725 0.27 +0.0598 0.1702 0.27 +0.0621 0.1679 0.27 +0.0644 0.1656 0.27 +0.0667 0.1633 0.27 +0.069 0.161 0.27 +0.0713 0.1587 0.27 +0.0736 0.1564 0.27 +0.0759 0.1541 0.27 +0.0782 0.1518 0.27 +0.0805 0.1495 0.27 +0.0828 0.1472 0.27 +0.0851 0.1449 0.27 +0.0874 0.1426 0.27 +0.0897 0.1403 0.27 +0.092 0.138 0.27 +0.0943 0.1357 0.27 +0.0966 0.1334 0.27 +0.0989 0.1311 0.27 +0.1012 0.1288 0.27 +0.1035 0.1265 0.27 +0.1058 0.1242 0.27 +0.1081 0.1219 0.27 +0.1104 0.1196 0.27 +0.1127 0.1173 0.27 +0.115 0.115 0.27 +0.1173 0.1127 0.27 +0.1196 0.1104 0.27 +0.1219 0.1081 0.27 +0.1242 0.1058 0.27 +0.1265 0.1035 0.27 +0.1288 0.1012 0.27 +0.1311 0.0989 0.27 +0.1334 0.0966 0.27 +0.1357 0.0943 0.27 +0.138 0.092 0.27 +0.1403 0.0897 0.27 +0.1426 0.0874 0.27 +0.1449 0.0851 0.27 +0.1472 0.0828 0.27 +0.1495 0.0805 0.27 +0.1518 0.0782 0.27 +0.1541 0.0759 0.27 +0.1564 0.0736 0.27 +0.1587 0.0713 0.27 +0.161 0.069 0.27 +0.1633 0.0667 0.27 +0.1656 0.0644 0.27 +0.1679 0.0621 0.27 +0.1702 0.0598 0.27 +0.1725 0.0575 0.27 +0.1748 0.0552 0.27 +0.1771 0.0529 0.27 +0.1794 0.0506 0.27 +0.1817 0.0483 0.27 +0.184 0.046 0.27 +0.1863 0.0437 0.27 +0.1886 0.0414 0.27 +0.1909 0.0391 0.27 +0.1932 0.0368 0.27 +0.1955 0.0345 0.27 +0.1978 0.0322 0.27 +0.2001 0.0299 0.27 +0.2024 0.0276 0.27 +0.2047 0.0253 0.27 +0.207 0.023 0.27 +0.2093 0.0207 0.27 +0.2116 0.0184 0.27 +0.2139 0.0161 0.27 +0.2162 0.0138 0.27 +0.2185 0.0115 0.27 +0.2208 0.0092 0.27 +0.2231 0.0069 0.27 +0.2254 0.0046 0.27 +0.2277 0.0023 0.27 +0 0.235 0.265 +0.00235 0.23265 0.265 +0.0047 0.2303 0.265 +0.00705 0.22795 0.265 +0.0094 0.2256 0.265 +0.01175 0.22325 0.265 +0.0141 0.2209 0.265 +0.01645 0.21855 0.265 +0.0188 0.2162 0.265 +0.02115 0.21385 0.265 +0.0235 0.2115 0.265 +0.02585 0.20915 0.265 +0.0282 0.2068 0.265 +0.03055 0.20445 0.265 +0.0329 0.2021 0.265 +0.03525 0.19975 0.265 +0.0376 0.1974 0.265 +0.03995 0.19505 0.265 +0.0423 0.1927 0.265 +0.04465 0.19035 0.265 +0.047 0.188 0.265 +0.04935 0.18565 0.265 +0.0517 0.1833 0.265 +0.05405 0.18095 0.265 +0.0564 0.1786 0.265 +0.05875 0.17625 0.265 +0.0611 0.1739 0.265 +0.06345 0.17155 0.265 +0.0658 0.1692 0.265 +0.06815 0.16685 0.265 +0.0705 0.1645 0.265 +0.07285 0.16215 0.265 +0.0752 0.1598 0.265 +0.07755 0.15745 0.265 +0.0799 0.1551 0.265 +0.08225 0.15275 0.265 +0.0846 0.1504 0.265 +0.08695 0.14805 0.265 +0.0893 0.1457 0.265 +0.09165 0.14335 0.265 +0.094 0.141 0.265 +0.09635 0.13865 0.265 +0.0987 0.1363 0.265 +0.10105 0.13395 0.265 +0.1034 0.1316 0.265 +0.10575 0.12925 0.265 +0.1081 0.1269 0.265 +0.11045 0.12455 0.265 +0.1128 0.1222 0.265 +0.11515 0.11985 0.265 +0.1175 0.1175 0.265 +0.11985 0.11515 0.265 +0.1222 0.1128 0.265 +0.12455 0.11045 0.265 +0.1269 0.1081 0.265 +0.12925 0.10575 0.265 +0.1316 0.1034 0.265 +0.13395 0.10105 0.265 +0.1363 0.0987 0.265 +0.13865 0.09635 0.265 +0.141 0.094 0.265 +0.14335 0.09165 0.265 +0.1457 0.0893 0.265 +0.14805 0.08695 0.265 +0.1504 0.0846 0.265 +0.15275 0.08225 0.265 +0.1551 0.0799 0.265 +0.15745 0.07755 0.265 +0.1598 0.0752 0.265 +0.16215 0.07285 0.265 +0.1645 0.0705 0.265 +0.16685 0.06815 0.265 +0.1692 0.0658 0.265 +0.17155 0.06345 0.265 +0.1739 0.0611 0.265 +0.17625 0.05875 0.265 +0.1786 0.0564 0.265 +0.18095 0.05405 0.265 +0.1833 0.0517 0.265 +0.18565 0.04935 0.265 +0.188 0.047 0.265 +0.19035 0.04465 0.265 +0.1927 0.0423 0.265 +0.19505 0.03995 0.265 +0.1974 0.0376 0.265 +0.19975 0.03525 0.265 +0.2021 0.0329 0.265 +0.20445 0.03055 0.265 +0.2068 0.0282 0.265 +0.20915 0.02585 0.265 +0.2115 0.0235 0.265 +0.21385 0.02115 0.265 +0.2162 0.0188 0.265 +0.21855 0.01645 0.265 +0.2209 0.0141 0.265 +0.22325 0.01175 0.265 +0.2256 0.0094 0.265 +0.22795 0.00705 0.265 +0.2303 0.0047 0.265 +0.23265 0.00235 0.265 +0 0.24 0.26 +0.0024 0.2376 0.26 +0.0048 0.2352 0.26 +0.0072 0.2328 0.26 +0.0096 0.2304 0.26 +0.012 0.228 0.26 +0.0144 0.2256 0.26 +0.0168 0.2232 0.26 +0.0192 0.2208 0.26 +0.0216 0.2184 0.26 +0.024 0.216 0.26 +0.0264 0.2136 0.26 +0.0288 0.2112 0.26 +0.0312 0.2088 0.26 +0.0336 0.2064 0.26 +0.036 0.204 0.26 +0.0384 0.2016 0.26 +0.0408 0.1992 0.26 +0.0432 0.1968 0.26 +0.0456 0.1944 0.26 +0.048 0.192 0.26 +0.0504 0.1896 0.26 +0.0528 0.1872 0.26 +0.0552 0.1848 0.26 +0.0576 0.1824 0.26 +0.06 0.18 0.26 +0.0624 0.1776 0.26 +0.0648 0.1752 0.26 +0.0672 0.1728 0.26 +0.0696 0.1704 0.26 +0.072 0.168 0.26 +0.0744 0.1656 0.26 +0.0768 0.1632 0.26 +0.0792 0.1608 0.26 +0.0816 0.1584 0.26 +0.084 0.156 0.26 +0.0864 0.1536 0.26 +0.0888 0.1512 0.26 +0.0912 0.1488 0.26 +0.0936 0.1464 0.26 +0.096 0.144 0.26 +0.0984 0.1416 0.26 +0.1008 0.1392 0.26 +0.1032 0.1368 0.26 +0.1056 0.1344 0.26 +0.108 0.132 0.26 +0.1104 0.1296 0.26 +0.1128 0.1272 0.26 +0.1152 0.1248 0.26 +0.1176 0.1224 0.26 +0.12 0.12 0.26 +0.1224 0.1176 0.26 +0.1248 0.1152 0.26 +0.1272 0.1128 0.26 +0.1296 0.1104 0.26 +0.132 0.108 0.26 +0.1344 0.1056 0.26 +0.1368 0.1032 0.26 +0.1392 0.1008 0.26 +0.1416 0.0984 0.26 +0.144 0.096 0.26 +0.1464 0.0936 0.26 +0.1488 0.0912 0.26 +0.1512 0.0888 0.26 +0.1536 0.0864 0.26 +0.156 0.084 0.26 +0.1584 0.0816 0.26 +0.1608 0.0792 0.26 +0.1632 0.0768 0.26 +0.1656 0.0744 0.26 +0.168 0.072 0.26 +0.1704 0.0696 0.26 +0.1728 0.0672 0.26 +0.1752 0.0648 0.26 +0.1776 0.0624 0.26 +0.18 0.06 0.26 +0.1824 0.0576 0.26 +0.1848 0.0552 0.26 +0.1872 0.0528 0.26 +0.1896 0.0504 0.26 +0.192 0.048 0.26 +0.1944 0.0456 0.26 +0.1968 0.0432 0.26 +0.1992 0.0408 0.26 +0.2016 0.0384 0.26 +0.204 0.036 0.26 +0.2064 0.0336 0.26 +0.2088 0.0312 0.26 +0.2112 0.0288 0.26 +0.2136 0.0264 0.26 +0.216 0.024 0.26 +0.2184 0.0216 0.26 +0.2208 0.0192 0.26 +0.2232 0.0168 0.26 +0.2256 0.0144 0.26 +0.228 0.012 0.26 +0.2304 0.0096 0.26 +0.2328 0.0072 0.26 +0.2352 0.0048 0.26 +0.2376 0.0024 0.26 +0 0.245 0.255 +0.00245 0.24255 0.255 +0.0049 0.2401 0.255 +0.00735 0.23765 0.255 +0.0098 0.2352 0.255 +0.01225 0.23275 0.255 +0.0147 0.2303 0.255 +0.01715 0.22785 0.255 +0.0196 0.2254 0.255 +0.02205 0.22295 0.255 +0.0245 0.2205 0.255 +0.02695 0.21805 0.255 +0.0294 0.2156 0.255 +0.03185 0.21315 0.255 +0.0343 0.2107 0.255 +0.03675 0.20825 0.255 +0.0392 0.2058 0.255 +0.04165 0.20335 0.255 +0.0441 0.2009 0.255 +0.04655 0.19845 0.255 +0.049 0.196 0.255 +0.05145 0.19355 0.255 +0.0539 0.1911 0.255 +0.05635 0.18865 0.255 +0.0588 0.1862 0.255 +0.06125 0.18375 0.255 +0.0637 0.1813 0.255 +0.06615 0.17885 0.255 +0.0686 0.1764 0.255 +0.07105 0.17395 0.255 +0.0735 0.1715 0.255 +0.07595 0.16905 0.255 +0.0784 0.1666 0.255 +0.08085 0.16415 0.255 +0.0833 0.1617 0.255 +0.08575 0.15925 0.255 +0.0882 0.1568 0.255 +0.09065 0.15435 0.255 +0.0931 0.1519 0.255 +0.09555 0.14945 0.255 +0.098 0.147 0.255 +0.10045 0.14455 0.255 +0.1029 0.1421 0.255 +0.10535 0.13965 0.255 +0.1078 0.1372 0.255 +0.11025 0.13475 0.255 +0.1127 0.1323 0.255 +0.11515 0.12985 0.255 +0.1176 0.1274 0.255 +0.12005 0.12495 0.255 +0.1225 0.1225 0.255 +0.12495 0.12005 0.255 +0.1274 0.1176 0.255 +0.12985 0.11515 0.255 +0.1323 0.1127 0.255 +0.13475 0.11025 0.255 +0.1372 0.1078 0.255 +0.13965 0.10535 0.255 +0.1421 0.1029 0.255 +0.14455 0.10045 0.255 +0.147 0.098 0.255 +0.14945 0.09555 0.255 +0.1519 0.0931 0.255 +0.15435 0.09065 0.255 +0.1568 0.0882 0.255 +0.15925 0.08575 0.255 +0.1617 0.0833 0.255 +0.16415 0.08085 0.255 +0.1666 0.0784 0.255 +0.16905 0.07595 0.255 +0.1715 0.0735 0.255 +0.17395 0.07105 0.255 +0.1764 0.0686 0.255 +0.17885 0.06615 0.255 +0.1813 0.0637 0.255 +0.18375 0.06125 0.255 +0.1862 0.0588 0.255 +0.18865 0.05635 0.255 +0.1911 0.0539 0.255 +0.19355 0.05145 0.255 +0.196 0.049 0.255 +0.19845 0.04655 0.255 +0.2009 0.0441 0.255 +0.20335 0.04165 0.255 +0.2058 0.0392 0.255 +0.20825 0.03675 0.255 +0.2107 0.0343 0.255 +0.21315 0.03185 0.255 +0.2156 0.0294 0.255 +0.21805 0.02695 0.255 +0.2205 0.0245 0.255 +0.22295 0.02205 0.255 +0.2254 0.0196 0.255 +0.22785 0.01715 0.255 +0.2303 0.0147 0.255 +0.23275 0.01225 0.255 +0.2352 0.0098 0.255 +0.23765 0.00735 0.255 +0.2401 0.0049 0.255 +0.24255 0.00245 0.255 +0 0.25 0.25 +0.0025 0.2475 0.25 +0.005 0.245 0.25 +0.0075 0.2425 0.25 +0.01 0.24 0.25 +0.0125 0.2375 0.25 +0.015 0.235 0.25 +0.0175 0.2325 0.25 +0.02 0.23 0.25 +0.0225 0.2275 0.25 +0.025 0.225 0.25 +0.0275 0.2225 0.25 +0.03 0.22 0.25 +0.0325 0.2175 0.25 +0.035 0.215 0.25 +0.0375 0.2125 0.25 +0.04 0.21 0.25 +0.0425 0.2075 0.25 +0.045 0.205 0.25 +0.0475 0.2025 0.25 +0.05 0.2 0.25 +0.0525 0.1975 0.25 +0.055 0.195 0.25 +0.0575 0.1925 0.25 +0.06 0.19 0.25 +0.0625 0.1875 0.25 +0.065 0.185 0.25 +0.0675 0.1825 0.25 +0.07 0.18 0.25 +0.0725 0.1775 0.25 +0.075 0.175 0.25 +0.0775 0.1725 0.25 +0.08 0.17 0.25 +0.0825 0.1675 0.25 +0.085 0.165 0.25 +0.0875 0.1625 0.25 +0.09 0.16 0.25 +0.0925 0.1575 0.25 +0.095 0.155 0.25 +0.0975 0.1525 0.25 +0.1 0.15 0.25 +0.1025 0.1475 0.25 +0.105 0.145 0.25 +0.1075 0.1425 0.25 +0.11 0.14 0.25 +0.1125 0.1375 0.25 +0.115 0.135 0.25 +0.1175 0.1325 0.25 +0.12 0.13 0.25 +0.1225 0.1275 0.25 +0.125 0.125 0.25 +0.1275 0.1225 0.25 +0.13 0.12 0.25 +0.1325 0.1175 0.25 +0.135 0.115 0.25 +0.1375 0.1125 0.25 +0.14 0.11 0.25 +0.1425 0.1075 0.25 +0.145 0.105 0.25 +0.1475 0.1025 0.25 +0.15 0.1 0.25 +0.1525 0.0975 0.25 +0.155 0.095 0.25 +0.1575 0.0925 0.25 +0.16 0.09 0.25 +0.1625 0.0875 0.25 +0.165 0.085 0.25 +0.1675 0.0825 0.25 +0.17 0.08 0.25 +0.1725 0.0775 0.25 +0.175 0.075 0.25 +0.1775 0.0725 0.25 +0.18 0.07 0.25 +0.1825 0.0675 0.25 +0.185 0.065 0.25 +0.1875 0.0625 0.25 +0.19 0.06 0.25 +0.1925 0.0575 0.25 +0.195 0.055 0.25 +0.1975 0.0525 0.25 +0.2 0.05 0.25 +0.2025 0.0475 0.25 +0.205 0.045 0.25 +0.2075 0.0425 0.25 +0.21 0.04 0.25 +0.2125 0.0375 0.25 +0.215 0.035 0.25 +0.2175 0.0325 0.25 +0.22 0.03 0.25 +0.2225 0.0275 0.25 +0.225 0.025 0.25 +0.2275 0.0225 0.25 +0.23 0.02 0.25 +0.2325 0.0175 0.25 +0.235 0.015 0.25 +0.2375 0.0125 0.25 +0.24 0.01 0.25 +0.2425 0.0075 0.25 +0.245 0.005 0.25 +0.2475 0.0025 0.25 +0 0.255 0.245 +0.00255 0.25245 0.245 +0.0051 0.2499 0.245 +0.00765 0.24735 0.245 +0.0102 0.2448 0.245 +0.01275 0.24225 0.245 +0.0153 0.2397 0.245 +0.01785 0.23715 0.245 +0.0204 0.2346 0.245 +0.02295 0.23205 0.245 +0.0255 0.2295 0.245 +0.02805 0.22695 0.245 +0.0306 0.2244 0.245 +0.03315 0.22185 0.245 +0.0357 0.2193 0.245 +0.03825 0.21675 0.245 +0.0408 0.2142 0.245 +0.04335 0.21165 0.245 +0.0459 0.2091 0.245 +0.04845 0.20655 0.245 +0.051 0.204 0.245 +0.05355 0.20145 0.245 +0.0561 0.1989 0.245 +0.05865 0.19635 0.245 +0.0612 0.1938 0.245 +0.06375 0.19125 0.245 +0.0663 0.1887 0.245 +0.06885 0.18615 0.245 +0.0714 0.1836 0.245 +0.07395 0.18105 0.245 +0.0765 0.1785 0.245 +0.07905 0.17595 0.245 +0.0816 0.1734 0.245 +0.08415 0.17085 0.245 +0.0867 0.1683 0.245 +0.08925 0.16575 0.245 +0.0918 0.1632 0.245 +0.09435 0.16065 0.245 +0.0969 0.1581 0.245 +0.09945 0.15555 0.245 +0.102 0.153 0.245 +0.10455 0.15045 0.245 +0.1071 0.1479 0.245 +0.10965 0.14535 0.245 +0.1122 0.1428 0.245 +0.11475 0.14025 0.245 +0.1173 0.1377 0.245 +0.11985 0.13515 0.245 +0.1224 0.1326 0.245 +0.12495 0.13005 0.245 +0.1275 0.1275 0.245 +0.13005 0.12495 0.245 +0.1326 0.1224 0.245 +0.13515 0.11985 0.245 +0.1377 0.1173 0.245 +0.14025 0.11475 0.245 +0.1428 0.1122 0.245 +0.14535 0.10965 0.245 +0.1479 0.1071 0.245 +0.15045 0.10455 0.245 +0.153 0.102 0.245 +0.15555 0.09945 0.245 +0.1581 0.0969 0.245 +0.16065 0.09435 0.245 +0.1632 0.0918 0.245 +0.16575 0.08925 0.245 +0.1683 0.0867 0.245 +0.17085 0.08415 0.245 +0.1734 0.0816 0.245 +0.17595 0.07905 0.245 +0.1785 0.0765 0.245 +0.18105 0.07395 0.245 +0.1836 0.0714 0.245 +0.18615 0.06885 0.245 +0.1887 0.0663 0.245 +0.19125 0.06375 0.245 +0.1938 0.0612 0.245 +0.19635 0.05865 0.245 +0.1989 0.0561 0.245 +0.20145 0.05355 0.245 +0.204 0.051 0.245 +0.20655 0.04845 0.245 +0.2091 0.0459 0.245 +0.21165 0.04335 0.245 +0.2142 0.0408 0.245 +0.21675 0.03825 0.245 +0.2193 0.0357 0.245 +0.22185 0.03315 0.245 +0.2244 0.0306 0.245 +0.22695 0.02805 0.245 +0.2295 0.0255 0.245 +0.23205 0.02295 0.245 +0.2346 0.0204 0.245 +0.23715 0.01785 0.245 +0.2397 0.0153 0.245 +0.24225 0.01275 0.245 +0.2448 0.0102 0.245 +0.24735 0.00765 0.245 +0.2499 0.0051 0.245 +0.25245 0.00255 0.245 +0 0.26 0.24 +0.0026 0.2574 0.24 +0.0052 0.2548 0.24 +0.0078 0.2522 0.24 +0.0104 0.2496 0.24 +0.013 0.247 0.24 +0.0156 0.2444 0.24 +0.0182 0.2418 0.24 +0.0208 0.2392 0.24 +0.0234 0.2366 0.24 +0.026 0.234 0.24 +0.0286 0.2314 0.24 +0.0312 0.2288 0.24 +0.0338 0.2262 0.24 +0.0364 0.2236 0.24 +0.039 0.221 0.24 +0.0416 0.2184 0.24 +0.0442 0.2158 0.24 +0.0468 0.2132 0.24 +0.0494 0.2106 0.24 +0.052 0.208 0.24 +0.0546 0.2054 0.24 +0.0572 0.2028 0.24 +0.0598 0.2002 0.24 +0.0624 0.1976 0.24 +0.065 0.195 0.24 +0.0676 0.1924 0.24 +0.0702 0.1898 0.24 +0.0728 0.1872 0.24 +0.0754 0.1846 0.24 +0.078 0.182 0.24 +0.0806 0.1794 0.24 +0.0832 0.1768 0.24 +0.0858 0.1742 0.24 +0.0884 0.1716 0.24 +0.091 0.169 0.24 +0.0936 0.1664 0.24 +0.0962 0.1638 0.24 +0.0988 0.1612 0.24 +0.1014 0.1586 0.24 +0.104 0.156 0.24 +0.1066 0.1534 0.24 +0.1092 0.1508 0.24 +0.1118 0.1482 0.24 +0.1144 0.1456 0.24 +0.117 0.143 0.24 +0.1196 0.1404 0.24 +0.1222 0.1378 0.24 +0.1248 0.1352 0.24 +0.1274 0.1326 0.24 +0.13 0.13 0.24 +0.1326 0.1274 0.24 +0.1352 0.1248 0.24 +0.1378 0.1222 0.24 +0.1404 0.1196 0.24 +0.143 0.117 0.24 +0.1456 0.1144 0.24 +0.1482 0.1118 0.24 +0.1508 0.1092 0.24 +0.1534 0.1066 0.24 +0.156 0.104 0.24 +0.1586 0.1014 0.24 +0.1612 0.0988 0.24 +0.1638 0.0962 0.24 +0.1664 0.0936 0.24 +0.169 0.091 0.24 +0.1716 0.0884 0.24 +0.1742 0.0858 0.24 +0.1768 0.0832 0.24 +0.1794 0.0806 0.24 +0.182 0.078 0.24 +0.1846 0.0754 0.24 +0.1872 0.0728 0.24 +0.1898 0.0702 0.24 +0.1924 0.0676 0.24 +0.195 0.065 0.24 +0.1976 0.0624 0.24 +0.2002 0.0598 0.24 +0.2028 0.0572 0.24 +0.2054 0.0546 0.24 +0.208 0.052 0.24 +0.2106 0.0494 0.24 +0.2132 0.0468 0.24 +0.2158 0.0442 0.24 +0.2184 0.0416 0.24 +0.221 0.039 0.24 +0.2236 0.0364 0.24 +0.2262 0.0338 0.24 +0.2288 0.0312 0.24 +0.2314 0.0286 0.24 +0.234 0.026 0.24 +0.2366 0.0234 0.24 +0.2392 0.0208 0.24 +0.2418 0.0182 0.24 +0.2444 0.0156 0.24 +0.247 0.013 0.24 +0.2496 0.0104 0.24 +0.2522 0.0078 0.24 +0.2548 0.0052 0.24 +0.2574 0.0026 0.24 +0 0.265 0.235 +0.00265 0.26235 0.235 +0.0053 0.2597 0.235 +0.00795 0.25705 0.235 +0.0106 0.2544 0.235 +0.01325 0.25175 0.235 +0.0159 0.2491 0.235 +0.01855 0.24645 0.235 +0.0212 0.2438 0.235 +0.02385 0.24115 0.235 +0.0265 0.2385 0.235 +0.02915 0.23585 0.235 +0.0318 0.2332 0.235 +0.03445 0.23055 0.235 +0.0371 0.2279 0.235 +0.03975 0.22525 0.235 +0.0424 0.2226 0.235 +0.04505 0.21995 0.235 +0.0477 0.2173 0.235 +0.05035 0.21465 0.235 +0.053 0.212 0.235 +0.05565 0.20935 0.235 +0.0583 0.2067 0.235 +0.06095 0.20405 0.235 +0.0636 0.2014 0.235 +0.06625 0.19875 0.235 +0.0689 0.1961 0.235 +0.07155 0.19345 0.235 +0.0742 0.1908 0.235 +0.07685 0.18815 0.235 +0.0795 0.1855 0.235 +0.08215 0.18285 0.235 +0.0848 0.1802 0.235 +0.08745 0.17755 0.235 +0.0901 0.1749 0.235 +0.09275 0.17225 0.235 +0.0954 0.1696 0.235 +0.09805 0.16695 0.235 +0.1007 0.1643 0.235 +0.10335 0.16165 0.235 +0.106 0.159 0.235 +0.10865 0.15635 0.235 +0.1113 0.1537 0.235 +0.11395 0.15105 0.235 +0.1166 0.1484 0.235 +0.11925 0.14575 0.235 +0.1219 0.1431 0.235 +0.12455 0.14045 0.235 +0.1272 0.1378 0.235 +0.12985 0.13515 0.235 +0.1325 0.1325 0.235 +0.13515 0.12985 0.235 +0.1378 0.1272 0.235 +0.14045 0.12455 0.235 +0.1431 0.1219 0.235 +0.14575 0.11925 0.235 +0.1484 0.1166 0.235 +0.15105 0.11395 0.235 +0.1537 0.1113 0.235 +0.15635 0.10865 0.235 +0.159 0.106 0.235 +0.16165 0.10335 0.235 +0.1643 0.1007 0.235 +0.16695 0.09805 0.235 +0.1696 0.0954 0.235 +0.17225 0.09275 0.235 +0.1749 0.0901 0.235 +0.17755 0.08745 0.235 +0.1802 0.0848 0.235 +0.18285 0.08215 0.235 +0.1855 0.0795 0.235 +0.18815 0.07685 0.235 +0.1908 0.0742 0.235 +0.19345 0.07155 0.235 +0.1961 0.0689 0.235 +0.19875 0.06625 0.235 +0.2014 0.0636 0.235 +0.20405 0.06095 0.235 +0.2067 0.0583 0.235 +0.20935 0.05565 0.235 +0.212 0.053 0.235 +0.21465 0.05035 0.235 +0.2173 0.0477 0.235 +0.21995 0.04505 0.235 +0.2226 0.0424 0.235 +0.22525 0.03975 0.235 +0.2279 0.0371 0.235 +0.23055 0.03445 0.235 +0.2332 0.0318 0.235 +0.23585 0.02915 0.235 +0.2385 0.0265 0.235 +0.24115 0.02385 0.235 +0.2438 0.0212 0.235 +0.24645 0.01855 0.235 +0.2491 0.0159 0.235 +0.25175 0.01325 0.235 +0.2544 0.0106 0.235 +0.25705 0.00795 0.235 +0.2597 0.0053 0.235 +0.26235 0.00265 0.235 +0 0.27 0.23 +0.0027 0.2673 0.23 +0.0054 0.2646 0.23 +0.0081 0.2619 0.23 +0.0108 0.2592 0.23 +0.0135 0.2565 0.23 +0.0162 0.2538 0.23 +0.0189 0.2511 0.23 +0.0216 0.2484 0.23 +0.0243 0.2457 0.23 +0.027 0.243 0.23 +0.0297 0.2403 0.23 +0.0324 0.2376 0.23 +0.0351 0.2349 0.23 +0.0378 0.2322 0.23 +0.0405 0.2295 0.23 +0.0432 0.2268 0.23 +0.0459 0.2241 0.23 +0.0486 0.2214 0.23 +0.0513 0.2187 0.23 +0.054 0.216 0.23 +0.0567 0.2133 0.23 +0.0594 0.2106 0.23 +0.0621 0.2079 0.23 +0.0648 0.2052 0.23 +0.0675 0.2025 0.23 +0.0702 0.1998 0.23 +0.0729 0.1971 0.23 +0.0756 0.1944 0.23 +0.0783 0.1917 0.23 +0.081 0.189 0.23 +0.0837 0.1863 0.23 +0.0864 0.1836 0.23 +0.0891 0.1809 0.23 +0.0918 0.1782 0.23 +0.0945 0.1755 0.23 +0.0972 0.1728 0.23 +0.0999 0.1701 0.23 +0.1026 0.1674 0.23 +0.1053 0.1647 0.23 +0.108 0.162 0.23 +0.1107 0.1593 0.23 +0.1134 0.1566 0.23 +0.1161 0.1539 0.23 +0.1188 0.1512 0.23 +0.1215 0.1485 0.23 +0.1242 0.1458 0.23 +0.1269 0.1431 0.23 +0.1296 0.1404 0.23 +0.1323 0.1377 0.23 +0.135 0.135 0.23 +0.1377 0.1323 0.23 +0.1404 0.1296 0.23 +0.1431 0.1269 0.23 +0.1458 0.1242 0.23 +0.1485 0.1215 0.23 +0.1512 0.1188 0.23 +0.1539 0.1161 0.23 +0.1566 0.1134 0.23 +0.1593 0.1107 0.23 +0.162 0.108 0.23 +0.1647 0.1053 0.23 +0.1674 0.1026 0.23 +0.1701 0.0999 0.23 +0.1728 0.0972 0.23 +0.1755 0.0945 0.23 +0.1782 0.0918 0.23 +0.1809 0.0891 0.23 +0.1836 0.0864 0.23 +0.1863 0.0837 0.23 +0.189 0.081 0.23 +0.1917 0.0783 0.23 +0.1944 0.0756 0.23 +0.1971 0.0729 0.23 +0.1998 0.0702 0.23 +0.2025 0.0675 0.23 +0.2052 0.0648 0.23 +0.2079 0.0621 0.23 +0.2106 0.0594 0.23 +0.2133 0.0567 0.23 +0.216 0.054 0.23 +0.2187 0.0513 0.23 +0.2214 0.0486 0.23 +0.2241 0.0459 0.23 +0.2268 0.0432 0.23 +0.2295 0.0405 0.23 +0.2322 0.0378 0.23 +0.2349 0.0351 0.23 +0.2376 0.0324 0.23 +0.2403 0.0297 0.23 +0.243 0.027 0.23 +0.2457 0.0243 0.23 +0.2484 0.0216 0.23 +0.2511 0.0189 0.23 +0.2538 0.0162 0.23 +0.2565 0.0135 0.23 +0.2592 0.0108 0.23 +0.2619 0.0081 0.23 +0.2646 0.0054 0.23 +0.2673 0.0027 0.23 +0 0.275 0.225 +0.00275 0.27225 0.225 +0.0055 0.2695 0.225 +0.00825 0.26675 0.225 +0.011 0.264 0.225 +0.01375 0.26125 0.225 +0.0165 0.2585 0.225 +0.01925 0.25575 0.225 +0.022 0.253 0.225 +0.02475 0.25025 0.225 +0.0275 0.2475 0.225 +0.03025 0.24475 0.225 +0.033 0.242 0.225 +0.03575 0.23925 0.225 +0.0385 0.2365 0.225 +0.04125 0.23375 0.225 +0.044 0.231 0.225 +0.04675 0.22825 0.225 +0.0495 0.2255 0.225 +0.05225 0.22275 0.225 +0.055 0.22 0.225 +0.05775 0.21725 0.225 +0.0605 0.2145 0.225 +0.06325 0.21175 0.225 +0.066 0.209 0.225 +0.06875 0.20625 0.225 +0.0715 0.2035 0.225 +0.07425 0.20075 0.225 +0.077 0.198 0.225 +0.07975 0.19525 0.225 +0.0825 0.1925 0.225 +0.08525 0.18975 0.225 +0.088 0.187 0.225 +0.09075 0.18425 0.225 +0.0935 0.1815 0.225 +0.09625 0.17875 0.225 +0.099 0.176 0.225 +0.10175 0.17325 0.225 +0.1045 0.1705 0.225 +0.10725 0.16775 0.225 +0.11 0.165 0.225 +0.11275 0.16225 0.225 +0.1155 0.1595 0.225 +0.11825 0.15675 0.225 +0.121 0.154 0.225 +0.12375 0.15125 0.225 +0.1265 0.1485 0.225 +0.12925 0.14575 0.225 +0.132 0.143 0.225 +0.13475 0.14025 0.225 +0.1375 0.1375 0.225 +0.14025 0.13475 0.225 +0.143 0.132 0.225 +0.14575 0.12925 0.225 +0.1485 0.1265 0.225 +0.15125 0.12375 0.225 +0.154 0.121 0.225 +0.15675 0.11825 0.225 +0.1595 0.1155 0.225 +0.16225 0.11275 0.225 +0.165 0.11 0.225 +0.16775 0.10725 0.225 +0.1705 0.1045 0.225 +0.17325 0.10175 0.225 +0.176 0.099 0.225 +0.17875 0.09625 0.225 +0.1815 0.0935 0.225 +0.18425 0.09075 0.225 +0.187 0.088 0.225 +0.18975 0.08525 0.225 +0.1925 0.0825 0.225 +0.19525 0.07975 0.225 +0.198 0.077 0.225 +0.20075 0.07425 0.225 +0.2035 0.0715 0.225 +0.20625 0.06875 0.225 +0.209 0.066 0.225 +0.21175 0.06325 0.225 +0.2145 0.0605 0.225 +0.21725 0.05775 0.225 +0.22 0.055 0.225 +0.22275 0.05225 0.225 +0.2255 0.0495 0.225 +0.22825 0.04675 0.225 +0.231 0.044 0.225 +0.23375 0.04125 0.225 +0.2365 0.0385 0.225 +0.23925 0.03575 0.225 +0.242 0.033 0.225 +0.24475 0.03025 0.225 +0.2475 0.0275 0.225 +0.25025 0.02475 0.225 +0.253 0.022 0.225 +0.25575 0.01925 0.225 +0.2585 0.0165 0.225 +0.26125 0.01375 0.225 +0.264 0.011 0.225 +0.26675 0.00825 0.225 +0.2695 0.0055 0.225 +0.27225 0.00275 0.225 +0 0.28 0.22 +0.0028 0.2772 0.22 +0.0056 0.2744 0.22 +0.0084 0.2716 0.22 +0.0112 0.2688 0.22 +0.014 0.266 0.22 +0.0168 0.2632 0.22 +0.0196 0.2604 0.22 +0.0224 0.2576 0.22 +0.0252 0.2548 0.22 +0.028 0.252 0.22 +0.0308 0.2492 0.22 +0.0336 0.2464 0.22 +0.0364 0.2436 0.22 +0.0392 0.2408 0.22 +0.042 0.238 0.22 +0.0448 0.2352 0.22 +0.0476 0.2324 0.22 +0.0504 0.2296 0.22 +0.0532 0.2268 0.22 +0.056 0.224 0.22 +0.0588 0.2212 0.22 +0.0616 0.2184 0.22 +0.0644 0.2156 0.22 +0.0672 0.2128 0.22 +0.07 0.21 0.22 +0.0728 0.2072 0.22 +0.0756 0.2044 0.22 +0.0784 0.2016 0.22 +0.0812 0.1988 0.22 +0.084 0.196 0.22 +0.0868 0.1932 0.22 +0.0896 0.1904 0.22 +0.0924 0.1876 0.22 +0.0952 0.1848 0.22 +0.098 0.182 0.22 +0.1008 0.1792 0.22 +0.1036 0.1764 0.22 +0.1064 0.1736 0.22 +0.1092 0.1708 0.22 +0.112 0.168 0.22 +0.1148 0.1652 0.22 +0.1176 0.1624 0.22 +0.1204 0.1596 0.22 +0.1232 0.1568 0.22 +0.126 0.154 0.22 +0.1288 0.1512 0.22 +0.1316 0.1484 0.22 +0.1344 0.1456 0.22 +0.1372 0.1428 0.22 +0.14 0.14 0.22 +0.1428 0.1372 0.22 +0.1456 0.1344 0.22 +0.1484 0.1316 0.22 +0.1512 0.1288 0.22 +0.154 0.126 0.22 +0.1568 0.1232 0.22 +0.1596 0.1204 0.22 +0.1624 0.1176 0.22 +0.1652 0.1148 0.22 +0.168 0.112 0.22 +0.1708 0.1092 0.22 +0.1736 0.1064 0.22 +0.1764 0.1036 0.22 +0.1792 0.1008 0.22 +0.182 0.098 0.22 +0.1848 0.0952 0.22 +0.1876 0.0924 0.22 +0.1904 0.0896 0.22 +0.1932 0.0868 0.22 +0.196 0.084 0.22 +0.1988 0.0812 0.22 +0.2016 0.0784 0.22 +0.2044 0.0756 0.22 +0.2072 0.0728 0.22 +0.21 0.07 0.22 +0.2128 0.0672 0.22 +0.2156 0.0644 0.22 +0.2184 0.0616 0.22 +0.2212 0.0588 0.22 +0.224 0.056 0.22 +0.2268 0.0532 0.22 +0.2296 0.0504 0.22 +0.2324 0.0476 0.22 +0.2352 0.0448 0.22 +0.238 0.042 0.22 +0.2408 0.0392 0.22 +0.2436 0.0364 0.22 +0.2464 0.0336 0.22 +0.2492 0.0308 0.22 +0.252 0.028 0.22 +0.2548 0.0252 0.22 +0.2576 0.0224 0.22 +0.2604 0.0196 0.22 +0.2632 0.0168 0.22 +0.266 0.014 0.22 +0.2688 0.0112 0.22 +0.2716 0.0084 0.22 +0.2744 0.0056 0.22 +0.2772 0.0028 0.22 +0 0.285 0.215 +0.00285 0.28215 0.215 +0.0057 0.2793 0.215 +0.00855 0.27645 0.215 +0.0114 0.2736 0.215 +0.01425 0.27075 0.215 +0.0171 0.2679 0.215 +0.01995 0.26505 0.215 +0.0228 0.2622 0.215 +0.02565 0.25935 0.215 +0.0285 0.2565 0.215 +0.03135 0.25365 0.215 +0.0342 0.2508 0.215 +0.03705 0.24795 0.215 +0.0399 0.2451 0.215 +0.04275 0.24225 0.215 +0.0456 0.2394 0.215 +0.04845 0.23655 0.215 +0.0513 0.2337 0.215 +0.05415 0.23085 0.215 +0.057 0.228 0.215 +0.05985 0.22515 0.215 +0.0627 0.2223 0.215 +0.06555 0.21945 0.215 +0.0684 0.2166 0.215 +0.07125 0.21375 0.215 +0.0741 0.2109 0.215 +0.07695 0.20805 0.215 +0.0798 0.2052 0.215 +0.08265 0.20235 0.215 +0.0855 0.1995 0.215 +0.08835 0.19665 0.215 +0.0912 0.1938 0.215 +0.09405 0.19095 0.215 +0.0969 0.1881 0.215 +0.09975 0.18525 0.215 +0.1026 0.1824 0.215 +0.10545 0.17955 0.215 +0.1083 0.1767 0.215 +0.11115 0.17385 0.215 +0.114 0.171 0.215 +0.11685 0.16815 0.215 +0.1197 0.1653 0.215 +0.12255 0.16245 0.215 +0.1254 0.1596 0.215 +0.12825 0.15675 0.215 +0.1311 0.1539 0.215 +0.13395 0.15105 0.215 +0.1368 0.1482 0.215 +0.13965 0.14535 0.215 +0.1425 0.1425 0.215 +0.14535 0.13965 0.215 +0.1482 0.1368 0.215 +0.15105 0.13395 0.215 +0.1539 0.1311 0.215 +0.15675 0.12825 0.215 +0.1596 0.1254 0.215 +0.16245 0.12255 0.215 +0.1653 0.1197 0.215 +0.16815 0.11685 0.215 +0.171 0.114 0.215 +0.17385 0.11115 0.215 +0.1767 0.1083 0.215 +0.17955 0.10545 0.215 +0.1824 0.1026 0.215 +0.18525 0.09975 0.215 +0.1881 0.0969 0.215 +0.19095 0.09405 0.215 +0.1938 0.0912 0.215 +0.19665 0.08835 0.215 +0.1995 0.0855 0.215 +0.20235 0.08265 0.215 +0.2052 0.0798 0.215 +0.20805 0.07695 0.215 +0.2109 0.0741 0.215 +0.21375 0.07125 0.215 +0.2166 0.0684 0.215 +0.21945 0.06555 0.215 +0.2223 0.0627 0.215 +0.22515 0.05985 0.215 +0.228 0.057 0.215 +0.23085 0.05415 0.215 +0.2337 0.0513 0.215 +0.23655 0.04845 0.215 +0.2394 0.0456 0.215 +0.24225 0.04275 0.215 +0.2451 0.0399 0.215 +0.24795 0.03705 0.215 +0.2508 0.0342 0.215 +0.25365 0.03135 0.215 +0.2565 0.0285 0.215 +0.25935 0.02565 0.215 +0.2622 0.0228 0.215 +0.26505 0.01995 0.215 +0.2679 0.0171 0.215 +0.27075 0.01425 0.215 +0.2736 0.0114 0.215 +0.27645 0.00855 0.215 +0.2793 0.0057 0.215 +0.28215 0.00285 0.215 +0 0.29 0.21 +0.0029 0.2871 0.21 +0.0058 0.2842 0.21 +0.0087 0.2813 0.21 +0.0116 0.2784 0.21 +0.0145 0.2755 0.21 +0.0174 0.2726 0.21 +0.0203 0.2697 0.21 +0.0232 0.2668 0.21 +0.0261 0.2639 0.21 +0.029 0.261 0.21 +0.0319 0.2581 0.21 +0.0348 0.2552 0.21 +0.0377 0.2523 0.21 +0.0406 0.2494 0.21 +0.0435 0.2465 0.21 +0.0464 0.2436 0.21 +0.0493 0.2407 0.21 +0.0522 0.2378 0.21 +0.0551 0.2349 0.21 +0.058 0.232 0.21 +0.0609 0.2291 0.21 +0.0638 0.2262 0.21 +0.0667 0.2233 0.21 +0.0696 0.2204 0.21 +0.0725 0.2175 0.21 +0.0754 0.2146 0.21 +0.0783 0.2117 0.21 +0.0812 0.2088 0.21 +0.0841 0.2059 0.21 +0.087 0.203 0.21 +0.0899 0.2001 0.21 +0.0928 0.1972 0.21 +0.0957 0.1943 0.21 +0.0986 0.1914 0.21 +0.1015 0.1885 0.21 +0.1044 0.1856 0.21 +0.1073 0.1827 0.21 +0.1102 0.1798 0.21 +0.1131 0.1769 0.21 +0.116 0.174 0.21 +0.1189 0.1711 0.21 +0.1218 0.1682 0.21 +0.1247 0.1653 0.21 +0.1276 0.1624 0.21 +0.1305 0.1595 0.21 +0.1334 0.1566 0.21 +0.1363 0.1537 0.21 +0.1392 0.1508 0.21 +0.1421 0.1479 0.21 +0.145 0.145 0.21 +0.1479 0.1421 0.21 +0.1508 0.1392 0.21 +0.1537 0.1363 0.21 +0.1566 0.1334 0.21 +0.1595 0.1305 0.21 +0.1624 0.1276 0.21 +0.1653 0.1247 0.21 +0.1682 0.1218 0.21 +0.1711 0.1189 0.21 +0.174 0.116 0.21 +0.1769 0.1131 0.21 +0.1798 0.1102 0.21 +0.1827 0.1073 0.21 +0.1856 0.1044 0.21 +0.1885 0.1015 0.21 +0.1914 0.0986 0.21 +0.1943 0.0957 0.21 +0.1972 0.0928 0.21 +0.2001 0.0899 0.21 +0.203 0.087 0.21 +0.2059 0.0841 0.21 +0.2088 0.0812 0.21 +0.2117 0.0783 0.21 +0.2146 0.0754 0.21 +0.2175 0.0725 0.21 +0.2204 0.0696 0.21 +0.2233 0.0667 0.21 +0.2262 0.0638 0.21 +0.2291 0.0609 0.21 +0.232 0.058 0.21 +0.2349 0.0551 0.21 +0.2378 0.0522 0.21 +0.2407 0.0493 0.21 +0.2436 0.0464 0.21 +0.2465 0.0435 0.21 +0.2494 0.0406 0.21 +0.2523 0.0377 0.21 +0.2552 0.0348 0.21 +0.2581 0.0319 0.21 +0.261 0.029 0.21 +0.2639 0.0261 0.21 +0.2668 0.0232 0.21 +0.2697 0.0203 0.21 +0.2726 0.0174 0.21 +0.2755 0.0145 0.21 +0.2784 0.0116 0.21 +0.2813 0.0087 0.21 +0.2842 0.0058 0.21 +0.2871 0.0029 0.21 +0 0.295 0.205 +0.00295 0.29205 0.205 +0.0059 0.2891 0.205 +0.00885 0.28615 0.205 +0.0118 0.2832 0.205 +0.01475 0.28025 0.205 +0.0177 0.2773 0.205 +0.02065 0.27435 0.205 +0.0236 0.2714 0.205 +0.02655 0.26845 0.205 +0.0295 0.2655 0.205 +0.03245 0.26255 0.205 +0.0354 0.2596 0.205 +0.03835 0.25665 0.205 +0.0413 0.2537 0.205 +0.04425 0.25075 0.205 +0.0472 0.2478 0.205 +0.05015 0.24485 0.205 +0.0531 0.2419 0.205 +0.05605 0.23895 0.205 +0.059 0.236 0.205 +0.06195 0.23305 0.205 +0.0649 0.2301 0.205 +0.06785 0.22715 0.205 +0.0708 0.2242 0.205 +0.07375 0.22125 0.205 +0.0767 0.2183 0.205 +0.07965 0.21535 0.205 +0.0826 0.2124 0.205 +0.08555 0.20945 0.205 +0.0885 0.2065 0.205 +0.09145 0.20355 0.205 +0.0944 0.2006 0.205 +0.09735 0.19765 0.205 +0.1003 0.1947 0.205 +0.10325 0.19175 0.205 +0.1062 0.1888 0.205 +0.10915 0.18585 0.205 +0.1121 0.1829 0.205 +0.11505 0.17995 0.205 +0.118 0.177 0.205 +0.12095 0.17405 0.205 +0.1239 0.1711 0.205 +0.12685 0.16815 0.205 +0.1298 0.1652 0.205 +0.13275 0.16225 0.205 +0.1357 0.1593 0.205 +0.13865 0.15635 0.205 +0.1416 0.1534 0.205 +0.14455 0.15045 0.205 +0.1475 0.1475 0.205 +0.15045 0.14455 0.205 +0.1534 0.1416 0.205 +0.15635 0.13865 0.205 +0.1593 0.1357 0.205 +0.16225 0.13275 0.205 +0.1652 0.1298 0.205 +0.16815 0.12685 0.205 +0.1711 0.1239 0.205 +0.17405 0.12095 0.205 +0.177 0.118 0.205 +0.17995 0.11505 0.205 +0.1829 0.1121 0.205 +0.18585 0.10915 0.205 +0.1888 0.1062 0.205 +0.19175 0.10325 0.205 +0.1947 0.1003 0.205 +0.19765 0.09735 0.205 +0.2006 0.0944 0.205 +0.20355 0.09145 0.205 +0.2065 0.0885 0.205 +0.20945 0.08555 0.205 +0.2124 0.0826 0.205 +0.21535 0.07965 0.205 +0.2183 0.0767 0.205 +0.22125 0.07375 0.205 +0.2242 0.0708 0.205 +0.22715 0.06785 0.205 +0.2301 0.0649 0.205 +0.23305 0.06195 0.205 +0.236 0.059 0.205 +0.23895 0.05605 0.205 +0.2419 0.0531 0.205 +0.24485 0.05015 0.205 +0.2478 0.0472 0.205 +0.25075 0.04425 0.205 +0.2537 0.0413 0.205 +0.25665 0.03835 0.205 +0.2596 0.0354 0.205 +0.26255 0.03245 0.205 +0.2655 0.0295 0.205 +0.26845 0.02655 0.205 +0.2714 0.0236 0.205 +0.27435 0.02065 0.205 +0.2773 0.0177 0.205 +0.28025 0.01475 0.205 +0.2832 0.0118 0.205 +0.28615 0.00885 0.205 +0.2891 0.0059 0.205 +0.29205 0.00295 0.205 +0 0.3 0.2 +0.003 0.297 0.2 +0.006 0.294 0.2 +0.009 0.291 0.2 +0.012 0.288 0.2 +0.015 0.285 0.2 +0.018 0.282 0.2 +0.021 0.279 0.2 +0.024 0.276 0.2 +0.027 0.273 0.2 +0.03 0.27 0.2 +0.033 0.267 0.2 +0.036 0.264 0.2 +0.039 0.261 0.2 +0.042 0.258 0.2 +0.045 0.255 0.2 +0.048 0.252 0.2 +0.051 0.249 0.2 +0.054 0.246 0.2 +0.057 0.243 0.2 +0.06 0.24 0.2 +0.063 0.237 0.2 +0.066 0.234 0.2 +0.069 0.231 0.2 +0.072 0.228 0.2 +0.075 0.225 0.2 +0.078 0.222 0.2 +0.081 0.219 0.2 +0.084 0.216 0.2 +0.087 0.213 0.2 +0.09 0.21 0.2 +0.093 0.207 0.2 +0.096 0.204 0.2 +0.099 0.201 0.2 +0.102 0.198 0.2 +0.105 0.195 0.2 +0.108 0.192 0.2 +0.111 0.189 0.2 +0.114 0.186 0.2 +0.117 0.183 0.2 +0.12 0.18 0.2 +0.123 0.177 0.2 +0.126 0.174 0.2 +0.129 0.171 0.2 +0.132 0.168 0.2 +0.135 0.165 0.2 +0.138 0.162 0.2 +0.141 0.159 0.2 +0.144 0.156 0.2 +0.147 0.153 0.2 +0.15 0.15 0.2 +0.153 0.147 0.2 +0.156 0.144 0.2 +0.159 0.141 0.2 +0.162 0.138 0.2 +0.165 0.135 0.2 +0.168 0.132 0.2 +0.171 0.129 0.2 +0.174 0.126 0.2 +0.177 0.123 0.2 +0.18 0.12 0.2 +0.183 0.117 0.2 +0.186 0.114 0.2 +0.189 0.111 0.2 +0.192 0.108 0.2 +0.195 0.105 0.2 +0.198 0.102 0.2 +0.201 0.099 0.2 +0.204 0.096 0.2 +0.207 0.093 0.2 +0.21 0.09 0.2 +0.213 0.087 0.2 +0.216 0.084 0.2 +0.219 0.081 0.2 +0.222 0.078 0.2 +0.225 0.075 0.2 +0.228 0.072 0.2 +0.231 0.069 0.2 +0.234 0.066 0.2 +0.237 0.063 0.2 +0.24 0.06 0.2 +0.243 0.057 0.2 +0.246 0.054 0.2 +0.249 0.051 0.2 +0.252 0.048 0.2 +0.255 0.045 0.2 +0.258 0.042 0.2 +0.261 0.039 0.2 +0.264 0.036 0.2 +0.267 0.033 0.2 +0.27 0.03 0.2 +0.273 0.027 0.2 +0.276 0.024 0.2 +0.279 0.021 0.2 +0.282 0.018 0.2 +0.285 0.015 0.2 +0.288 0.012 0.2 +0.291 0.009 0.2 +0.294 0.006 0.2 +0.297 0.003 0.2 +0 0.305 0.195 +0.00305 0.30195 0.195 +0.0061 0.2989 0.195 +0.00915 0.29585 0.195 +0.0122 0.2928 0.195 +0.01525 0.28975 0.195 +0.0183 0.2867 0.195 +0.02135 0.28365 0.195 +0.0244 0.2806 0.195 +0.02745 0.27755 0.195 +0.0305 0.2745 0.195 +0.03355 0.27145 0.195 +0.0366 0.2684 0.195 +0.03965 0.26535 0.195 +0.0427 0.2623 0.195 +0.04575 0.25925 0.195 +0.0488 0.2562 0.195 +0.05185 0.25315 0.195 +0.0549 0.2501 0.195 +0.05795 0.24705 0.195 +0.061 0.244 0.195 +0.06405 0.24095 0.195 +0.0671 0.2379 0.195 +0.07015 0.23485 0.195 +0.0732 0.2318 0.195 +0.07625 0.22875 0.195 +0.0793 0.2257 0.195 +0.08235 0.22265 0.195 +0.0854 0.2196 0.195 +0.08845 0.21655 0.195 +0.0915 0.2135 0.195 +0.09455 0.21045 0.195 +0.0976 0.2074 0.195 +0.10065 0.20435 0.195 +0.1037 0.2013 0.195 +0.10675 0.19825 0.195 +0.1098 0.1952 0.195 +0.11285 0.19215 0.195 +0.1159 0.1891 0.195 +0.11895 0.18605 0.195 +0.122 0.183 0.195 +0.12505 0.17995 0.195 +0.1281 0.1769 0.195 +0.13115 0.17385 0.195 +0.1342 0.1708 0.195 +0.13725 0.16775 0.195 +0.1403 0.1647 0.195 +0.14335 0.16165 0.195 +0.1464 0.1586 0.195 +0.14945 0.15555 0.195 +0.1525 0.1525 0.195 +0.15555 0.14945 0.195 +0.1586 0.1464 0.195 +0.16165 0.14335 0.195 +0.1647 0.1403 0.195 +0.16775 0.13725 0.195 +0.1708 0.1342 0.195 +0.17385 0.13115 0.195 +0.1769 0.1281 0.195 +0.17995 0.12505 0.195 +0.183 0.122 0.195 +0.18605 0.11895 0.195 +0.1891 0.1159 0.195 +0.19215 0.11285 0.195 +0.1952 0.1098 0.195 +0.19825 0.10675 0.195 +0.2013 0.1037 0.195 +0.20435 0.10065 0.195 +0.2074 0.0976 0.195 +0.21045 0.09455 0.195 +0.2135 0.0915 0.195 +0.21655 0.08845 0.195 +0.2196 0.0854 0.195 +0.22265 0.08235 0.195 +0.2257 0.0793 0.195 +0.22875 0.07625 0.195 +0.2318 0.0732 0.195 +0.23485 0.07015 0.195 +0.2379 0.0671 0.195 +0.24095 0.06405 0.195 +0.244 0.061 0.195 +0.24705 0.05795 0.195 +0.2501 0.0549 0.195 +0.25315 0.05185 0.195 +0.2562 0.0488 0.195 +0.25925 0.04575 0.195 +0.2623 0.0427 0.195 +0.26535 0.03965 0.195 +0.2684 0.0366 0.195 +0.27145 0.03355 0.195 +0.2745 0.0305 0.195 +0.27755 0.02745 0.195 +0.2806 0.0244 0.195 +0.28365 0.02135 0.195 +0.2867 0.0183 0.195 +0.28975 0.01525 0.195 +0.2928 0.0122 0.195 +0.29585 0.00915 0.195 +0.2989 0.0061 0.195 +0.30195 0.00305 0.195 +0 0.31 0.19 +0.0031 0.3069 0.19 +0.0062 0.3038 0.19 +0.0093 0.3007 0.19 +0.0124 0.2976 0.19 +0.0155 0.2945 0.19 +0.0186 0.2914 0.19 +0.0217 0.2883 0.19 +0.0248 0.2852 0.19 +0.0279 0.2821 0.19 +0.031 0.279 0.19 +0.0341 0.2759 0.19 +0.0372 0.2728 0.19 +0.0403 0.2697 0.19 +0.0434 0.2666 0.19 +0.0465 0.2635 0.19 +0.0496 0.2604 0.19 +0.0527 0.2573 0.19 +0.0558 0.2542 0.19 +0.0589 0.2511 0.19 +0.062 0.248 0.19 +0.0651 0.2449 0.19 +0.0682 0.2418 0.19 +0.0713 0.2387 0.19 +0.0744 0.2356 0.19 +0.0775 0.2325 0.19 +0.0806 0.2294 0.19 +0.0837 0.2263 0.19 +0.0868 0.2232 0.19 +0.0899 0.2201 0.19 +0.093 0.217 0.19 +0.0961 0.2139 0.19 +0.0992 0.2108 0.19 +0.1023 0.2077 0.19 +0.1054 0.2046 0.19 +0.1085 0.2015 0.19 +0.1116 0.1984 0.19 +0.1147 0.1953 0.19 +0.1178 0.1922 0.19 +0.1209 0.1891 0.19 +0.124 0.186 0.19 +0.1271 0.1829 0.19 +0.1302 0.1798 0.19 +0.1333 0.1767 0.19 +0.1364 0.1736 0.19 +0.1395 0.1705 0.19 +0.1426 0.1674 0.19 +0.1457 0.1643 0.19 +0.1488 0.1612 0.19 +0.1519 0.1581 0.19 +0.155 0.155 0.19 +0.1581 0.1519 0.19 +0.1612 0.1488 0.19 +0.1643 0.1457 0.19 +0.1674 0.1426 0.19 +0.1705 0.1395 0.19 +0.1736 0.1364 0.19 +0.1767 0.1333 0.19 +0.1798 0.1302 0.19 +0.1829 0.1271 0.19 +0.186 0.124 0.19 +0.1891 0.1209 0.19 +0.1922 0.1178 0.19 +0.1953 0.1147 0.19 +0.1984 0.1116 0.19 +0.2015 0.1085 0.19 +0.2046 0.1054 0.19 +0.2077 0.1023 0.19 +0.2108 0.0992 0.19 +0.2139 0.0961 0.19 +0.217 0.093 0.19 +0.2201 0.0899 0.19 +0.2232 0.0868 0.19 +0.2263 0.0837 0.19 +0.2294 0.0806 0.19 +0.2325 0.0775 0.19 +0.2356 0.0744 0.19 +0.2387 0.0713 0.19 +0.2418 0.0682 0.19 +0.2449 0.0651 0.19 +0.248 0.062 0.19 +0.2511 0.0589 0.19 +0.2542 0.0558 0.19 +0.2573 0.0527 0.19 +0.2604 0.0496 0.19 +0.2635 0.0465 0.19 +0.2666 0.0434 0.19 +0.2697 0.0403 0.19 +0.2728 0.0372 0.19 +0.2759 0.0341 0.19 +0.279 0.031 0.19 +0.2821 0.0279 0.19 +0.2852 0.0248 0.19 +0.2883 0.0217 0.19 +0.2914 0.0186 0.19 +0.2945 0.0155 0.19 +0.2976 0.0124 0.19 +0.3007 0.0093 0.19 +0.3038 0.0062 0.19 +0.3069 0.0031 0.19 +0 0.315 0.185 +0.00315 0.31185 0.185 +0.0063 0.3087 0.185 +0.00945 0.30555 0.185 +0.0126 0.3024 0.185 +0.01575 0.29925 0.185 +0.0189 0.2961 0.185 +0.02205 0.29295 0.185 +0.0252 0.2898 0.185 +0.02835 0.28665 0.185 +0.0315 0.2835 0.185 +0.03465 0.28035 0.185 +0.0378 0.2772 0.185 +0.04095 0.27405 0.185 +0.0441 0.2709 0.185 +0.04725 0.26775 0.185 +0.0504 0.2646 0.185 +0.05355 0.26145 0.185 +0.0567 0.2583 0.185 +0.05985 0.25515 0.185 +0.063 0.252 0.185 +0.06615 0.24885 0.185 +0.0693 0.2457 0.185 +0.07245 0.24255 0.185 +0.0756 0.2394 0.185 +0.07875 0.23625 0.185 +0.0819 0.2331 0.185 +0.08505 0.22995 0.185 +0.0882 0.2268 0.185 +0.09135 0.22365 0.185 +0.0945 0.2205 0.185 +0.09765 0.21735 0.185 +0.1008 0.2142 0.185 +0.10395 0.21105 0.185 +0.1071 0.2079 0.185 +0.11025 0.20475 0.185 +0.1134 0.2016 0.185 +0.11655 0.19845 0.185 +0.1197 0.1953 0.185 +0.12285 0.19215 0.185 +0.126 0.189 0.185 +0.12915 0.18585 0.185 +0.1323 0.1827 0.185 +0.13545 0.17955 0.185 +0.1386 0.1764 0.185 +0.14175 0.17325 0.185 +0.1449 0.1701 0.185 +0.14805 0.16695 0.185 +0.1512 0.1638 0.185 +0.15435 0.16065 0.185 +0.1575 0.1575 0.185 +0.16065 0.15435 0.185 +0.1638 0.1512 0.185 +0.16695 0.14805 0.185 +0.1701 0.1449 0.185 +0.17325 0.14175 0.185 +0.1764 0.1386 0.185 +0.17955 0.13545 0.185 +0.1827 0.1323 0.185 +0.18585 0.12915 0.185 +0.189 0.126 0.185 +0.19215 0.12285 0.185 +0.1953 0.1197 0.185 +0.19845 0.11655 0.185 +0.2016 0.1134 0.185 +0.20475 0.11025 0.185 +0.2079 0.1071 0.185 +0.21105 0.10395 0.185 +0.2142 0.1008 0.185 +0.21735 0.09765 0.185 +0.2205 0.0945 0.185 +0.22365 0.09135 0.185 +0.2268 0.0882 0.185 +0.22995 0.08505 0.185 +0.2331 0.0819 0.185 +0.23625 0.07875 0.185 +0.2394 0.0756 0.185 +0.24255 0.07245 0.185 +0.2457 0.0693 0.185 +0.24885 0.06615 0.185 +0.252 0.063 0.185 +0.25515 0.05985 0.185 +0.2583 0.0567 0.185 +0.26145 0.05355 0.185 +0.2646 0.0504 0.185 +0.26775 0.04725 0.185 +0.2709 0.0441 0.185 +0.27405 0.04095 0.185 +0.2772 0.0378 0.185 +0.28035 0.03465 0.185 +0.2835 0.0315 0.185 +0.28665 0.02835 0.185 +0.2898 0.0252 0.185 +0.29295 0.02205 0.185 +0.2961 0.0189 0.185 +0.29925 0.01575 0.185 +0.3024 0.0126 0.185 +0.30555 0.00945 0.185 +0.3087 0.0063 0.185 +0.31185 0.00315 0.185 +0 0.32 0.18 +0.0032 0.3168 0.18 +0.0064 0.3136 0.18 +0.0096 0.3104 0.18 +0.0128 0.3072 0.18 +0.016 0.304 0.18 +0.0192 0.3008 0.18 +0.0224 0.2976 0.18 +0.0256 0.2944 0.18 +0.0288 0.2912 0.18 +0.032 0.288 0.18 +0.0352 0.2848 0.18 +0.0384 0.2816 0.18 +0.0416 0.2784 0.18 +0.0448 0.2752 0.18 +0.048 0.272 0.18 +0.0512 0.2688 0.18 +0.0544 0.2656 0.18 +0.0576 0.2624 0.18 +0.0608 0.2592 0.18 +0.064 0.256 0.18 +0.0672 0.2528 0.18 +0.0704 0.2496 0.18 +0.0736 0.2464 0.18 +0.0768 0.2432 0.18 +0.08 0.24 0.18 +0.0832 0.2368 0.18 +0.0864 0.2336 0.18 +0.0896 0.2304 0.18 +0.0928 0.2272 0.18 +0.096 0.224 0.18 +0.0992 0.2208 0.18 +0.1024 0.2176 0.18 +0.1056 0.2144 0.18 +0.1088 0.2112 0.18 +0.112 0.208 0.18 +0.1152 0.2048 0.18 +0.1184 0.2016 0.18 +0.1216 0.1984 0.18 +0.1248 0.1952 0.18 +0.128 0.192 0.18 +0.1312 0.1888 0.18 +0.1344 0.1856 0.18 +0.1376 0.1824 0.18 +0.1408 0.1792 0.18 +0.144 0.176 0.18 +0.1472 0.1728 0.18 +0.1504 0.1696 0.18 +0.1536 0.1664 0.18 +0.1568 0.1632 0.18 +0.16 0.16 0.18 +0.1632 0.1568 0.18 +0.1664 0.1536 0.18 +0.1696 0.1504 0.18 +0.1728 0.1472 0.18 +0.176 0.144 0.18 +0.1792 0.1408 0.18 +0.1824 0.1376 0.18 +0.1856 0.1344 0.18 +0.1888 0.1312 0.18 +0.192 0.128 0.18 +0.1952 0.1248 0.18 +0.1984 0.1216 0.18 +0.2016 0.1184 0.18 +0.2048 0.1152 0.18 +0.208 0.112 0.18 +0.2112 0.1088 0.18 +0.2144 0.1056 0.18 +0.2176 0.1024 0.18 +0.2208 0.0992 0.18 +0.224 0.096 0.18 +0.2272 0.0928 0.18 +0.2304 0.0896 0.18 +0.2336 0.0864 0.18 +0.2368 0.0832 0.18 +0.24 0.08 0.18 +0.2432 0.0768 0.18 +0.2464 0.0736 0.18 +0.2496 0.0704 0.18 +0.2528 0.0672 0.18 +0.256 0.064 0.18 +0.2592 0.0608 0.18 +0.2624 0.0576 0.18 +0.2656 0.0544 0.18 +0.2688 0.0512 0.18 +0.272 0.048 0.18 +0.2752 0.0448 0.18 +0.2784 0.0416 0.18 +0.2816 0.0384 0.18 +0.2848 0.0352 0.18 +0.288 0.032 0.18 +0.2912 0.0288 0.18 +0.2944 0.0256 0.18 +0.2976 0.0224 0.18 +0.3008 0.0192 0.18 +0.304 0.016 0.18 +0.3072 0.0128 0.18 +0.3104 0.0096 0.18 +0.3136 0.0064 0.18 +0.3168 0.0032 0.18 +0 0.325 0.175 +0.00325 0.32175 0.175 +0.0065 0.3185 0.175 +0.00975 0.31525 0.175 +0.013 0.312 0.175 +0.01625 0.30875 0.175 +0.0195 0.3055 0.175 +0.02275 0.30225 0.175 +0.026 0.299 0.175 +0.02925 0.29575 0.175 +0.0325 0.2925 0.175 +0.03575 0.28925 0.175 +0.039 0.286 0.175 +0.04225 0.28275 0.175 +0.0455 0.2795 0.175 +0.04875 0.27625 0.175 +0.052 0.273 0.175 +0.05525 0.26975 0.175 +0.0585 0.2665 0.175 +0.06175 0.26325 0.175 +0.065 0.26 0.175 +0.06825 0.25675 0.175 +0.0715 0.2535 0.175 +0.07475 0.25025 0.175 +0.078 0.247 0.175 +0.08125 0.24375 0.175 +0.0845 0.2405 0.175 +0.08775 0.23725 0.175 +0.091 0.234 0.175 +0.09425 0.23075 0.175 +0.0975 0.2275 0.175 +0.10075 0.22425 0.175 +0.104 0.221 0.175 +0.10725 0.21775 0.175 +0.1105 0.2145 0.175 +0.11375 0.21125 0.175 +0.117 0.208 0.175 +0.12025 0.20475 0.175 +0.1235 0.2015 0.175 +0.12675 0.19825 0.175 +0.13 0.195 0.175 +0.13325 0.19175 0.175 +0.1365 0.1885 0.175 +0.13975 0.18525 0.175 +0.143 0.182 0.175 +0.14625 0.17875 0.175 +0.1495 0.1755 0.175 +0.15275 0.17225 0.175 +0.156 0.169 0.175 +0.15925 0.16575 0.175 +0.1625 0.1625 0.175 +0.16575 0.15925 0.175 +0.169 0.156 0.175 +0.17225 0.15275 0.175 +0.1755 0.1495 0.175 +0.17875 0.14625 0.175 +0.182 0.143 0.175 +0.18525 0.13975 0.175 +0.1885 0.1365 0.175 +0.19175 0.13325 0.175 +0.195 0.13 0.175 +0.19825 0.12675 0.175 +0.2015 0.1235 0.175 +0.20475 0.12025 0.175 +0.208 0.117 0.175 +0.21125 0.11375 0.175 +0.2145 0.1105 0.175 +0.21775 0.10725 0.175 +0.221 0.104 0.175 +0.22425 0.10075 0.175 +0.2275 0.0975 0.175 +0.23075 0.09425 0.175 +0.234 0.091 0.175 +0.23725 0.08775 0.175 +0.2405 0.0845 0.175 +0.24375 0.08125 0.175 +0.247 0.078 0.175 +0.25025 0.07475 0.175 +0.2535 0.0715 0.175 +0.25675 0.06825 0.175 +0.26 0.065 0.175 +0.26325 0.06175 0.175 +0.2665 0.0585 0.175 +0.26975 0.05525 0.175 +0.273 0.052 0.175 +0.27625 0.04875 0.175 +0.2795 0.0455 0.175 +0.28275 0.04225 0.175 +0.286 0.039 0.175 +0.28925 0.03575 0.175 +0.2925 0.0325 0.175 +0.29575 0.02925 0.175 +0.299 0.026 0.175 +0.30225 0.02275 0.175 +0.3055 0.0195 0.175 +0.30875 0.01625 0.175 +0.312 0.013 0.175 +0.31525 0.00975 0.175 +0.3185 0.0065 0.175 +0.32175 0.00325 0.175 +0 0.33 0.17 +0.0033 0.3267 0.17 +0.0066 0.3234 0.17 +0.0099 0.3201 0.17 +0.0132 0.3168 0.17 +0.0165 0.3135 0.17 +0.0198 0.3102 0.17 +0.0231 0.3069 0.17 +0.0264 0.3036 0.17 +0.0297 0.3003 0.17 +0.033 0.297 0.17 +0.0363 0.2937 0.17 +0.0396 0.2904 0.17 +0.0429 0.2871 0.17 +0.0462 0.2838 0.17 +0.0495 0.2805 0.17 +0.0528 0.2772 0.17 +0.0561 0.2739 0.17 +0.0594 0.2706 0.17 +0.0627 0.2673 0.17 +0.066 0.264 0.17 +0.0693 0.2607 0.17 +0.0726 0.2574 0.17 +0.0759 0.2541 0.17 +0.0792 0.2508 0.17 +0.0825 0.2475 0.17 +0.0858 0.2442 0.17 +0.0891 0.2409 0.17 +0.0924 0.2376 0.17 +0.0957 0.2343 0.17 +0.099 0.231 0.17 +0.1023 0.2277 0.17 +0.1056 0.2244 0.17 +0.1089 0.2211 0.17 +0.1122 0.2178 0.17 +0.1155 0.2145 0.17 +0.1188 0.2112 0.17 +0.1221 0.2079 0.17 +0.1254 0.2046 0.17 +0.1287 0.2013 0.17 +0.132 0.198 0.17 +0.1353 0.1947 0.17 +0.1386 0.1914 0.17 +0.1419 0.1881 0.17 +0.1452 0.1848 0.17 +0.1485 0.1815 0.17 +0.1518 0.1782 0.17 +0.1551 0.1749 0.17 +0.1584 0.1716 0.17 +0.1617 0.1683 0.17 +0.165 0.165 0.17 +0.1683 0.1617 0.17 +0.1716 0.1584 0.17 +0.1749 0.1551 0.17 +0.1782 0.1518 0.17 +0.1815 0.1485 0.17 +0.1848 0.1452 0.17 +0.1881 0.1419 0.17 +0.1914 0.1386 0.17 +0.1947 0.1353 0.17 +0.198 0.132 0.17 +0.2013 0.1287 0.17 +0.2046 0.1254 0.17 +0.2079 0.1221 0.17 +0.2112 0.1188 0.17 +0.2145 0.1155 0.17 +0.2178 0.1122 0.17 +0.2211 0.1089 0.17 +0.2244 0.1056 0.17 +0.2277 0.1023 0.17 +0.231 0.099 0.17 +0.2343 0.0957 0.17 +0.2376 0.0924 0.17 +0.2409 0.0891 0.17 +0.2442 0.0858 0.17 +0.2475 0.0825 0.17 +0.2508 0.0792 0.17 +0.2541 0.0759 0.17 +0.2574 0.0726 0.17 +0.2607 0.0693 0.17 +0.264 0.066 0.17 +0.2673 0.0627 0.17 +0.2706 0.0594 0.17 +0.2739 0.0561 0.17 +0.2772 0.0528 0.17 +0.2805 0.0495 0.17 +0.2838 0.0462 0.17 +0.2871 0.0429 0.17 +0.2904 0.0396 0.17 +0.2937 0.0363 0.17 +0.297 0.033 0.17 +0.3003 0.0297 0.17 +0.3036 0.0264 0.17 +0.3069 0.0231 0.17 +0.3102 0.0198 0.17 +0.3135 0.0165 0.17 +0.3168 0.0132 0.17 +0.3201 0.0099 0.17 +0.3234 0.0066 0.17 +0.3267 0.0033 0.17 +0 0.335 0.165 +0.00335 0.33165 0.165 +0.0067 0.3283 0.165 +0.01005 0.32495 0.165 +0.0134 0.3216 0.165 +0.01675 0.31825 0.165 +0.0201 0.3149 0.165 +0.02345 0.31155 0.165 +0.0268 0.3082 0.165 +0.03015 0.30485 0.165 +0.0335 0.3015 0.165 +0.03685 0.29815 0.165 +0.0402 0.2948 0.165 +0.04355 0.29145 0.165 +0.0469 0.2881 0.165 +0.05025 0.28475 0.165 +0.0536 0.2814 0.165 +0.05695 0.27805 0.165 +0.0603 0.2747 0.165 +0.06365 0.27135 0.165 +0.067 0.268 0.165 +0.07035 0.26465 0.165 +0.0737 0.2613 0.165 +0.07705 0.25795 0.165 +0.0804 0.2546 0.165 +0.08375 0.25125 0.165 +0.0871 0.2479 0.165 +0.09045 0.24455 0.165 +0.0938 0.2412 0.165 +0.09715 0.23785 0.165 +0.1005 0.2345 0.165 +0.10385 0.23115 0.165 +0.1072 0.2278 0.165 +0.11055 0.22445 0.165 +0.1139 0.2211 0.165 +0.11725 0.21775 0.165 +0.1206 0.2144 0.165 +0.12395 0.21105 0.165 +0.1273 0.2077 0.165 +0.13065 0.20435 0.165 +0.134 0.201 0.165 +0.13735 0.19765 0.165 +0.1407 0.1943 0.165 +0.14405 0.19095 0.165 +0.1474 0.1876 0.165 +0.15075 0.18425 0.165 +0.1541 0.1809 0.165 +0.15745 0.17755 0.165 +0.1608 0.1742 0.165 +0.16415 0.17085 0.165 +0.1675 0.1675 0.165 +0.17085 0.16415 0.165 +0.1742 0.1608 0.165 +0.17755 0.15745 0.165 +0.1809 0.1541 0.165 +0.18425 0.15075 0.165 +0.1876 0.1474 0.165 +0.19095 0.14405 0.165 +0.1943 0.1407 0.165 +0.19765 0.13735 0.165 +0.201 0.134 0.165 +0.20435 0.13065 0.165 +0.2077 0.1273 0.165 +0.21105 0.12395 0.165 +0.2144 0.1206 0.165 +0.21775 0.11725 0.165 +0.2211 0.1139 0.165 +0.22445 0.11055 0.165 +0.2278 0.1072 0.165 +0.23115 0.10385 0.165 +0.2345 0.1005 0.165 +0.23785 0.09715 0.165 +0.2412 0.0938 0.165 +0.24455 0.09045 0.165 +0.2479 0.0871 0.165 +0.25125 0.08375 0.165 +0.2546 0.0804 0.165 +0.25795 0.07705 0.165 +0.2613 0.0737 0.165 +0.26465 0.07035 0.165 +0.268 0.067 0.165 +0.27135 0.06365 0.165 +0.2747 0.0603 0.165 +0.27805 0.05695 0.165 +0.2814 0.0536 0.165 +0.28475 0.05025 0.165 +0.2881 0.0469 0.165 +0.29145 0.04355 0.165 +0.2948 0.0402 0.165 +0.29815 0.03685 0.165 +0.3015 0.0335 0.165 +0.30485 0.03015 0.165 +0.3082 0.0268 0.165 +0.31155 0.02345 0.165 +0.3149 0.0201 0.165 +0.31825 0.01675 0.165 +0.3216 0.0134 0.165 +0.32495 0.01005 0.165 +0.3283 0.0067 0.165 +0.33165 0.00335 0.165 +0 0.34 0.16 +0.0034 0.3366 0.16 +0.0068 0.3332 0.16 +0.0102 0.3298 0.16 +0.0136 0.3264 0.16 +0.017 0.323 0.16 +0.0204 0.3196 0.16 +0.0238 0.3162 0.16 +0.0272 0.3128 0.16 +0.0306 0.3094 0.16 +0.034 0.306 0.16 +0.0374 0.3026 0.16 +0.0408 0.2992 0.16 +0.0442 0.2958 0.16 +0.0476 0.2924 0.16 +0.051 0.289 0.16 +0.0544 0.2856 0.16 +0.0578 0.2822 0.16 +0.0612 0.2788 0.16 +0.0646 0.2754 0.16 +0.068 0.272 0.16 +0.0714 0.2686 0.16 +0.0748 0.2652 0.16 +0.0782 0.2618 0.16 +0.0816 0.2584 0.16 +0.085 0.255 0.16 +0.0884 0.2516 0.16 +0.0918 0.2482 0.16 +0.0952 0.2448 0.16 +0.0986 0.2414 0.16 +0.102 0.238 0.16 +0.1054 0.2346 0.16 +0.1088 0.2312 0.16 +0.1122 0.2278 0.16 +0.1156 0.2244 0.16 +0.119 0.221 0.16 +0.1224 0.2176 0.16 +0.1258 0.2142 0.16 +0.1292 0.2108 0.16 +0.1326 0.2074 0.16 +0.136 0.204 0.16 +0.1394 0.2006 0.16 +0.1428 0.1972 0.16 +0.1462 0.1938 0.16 +0.1496 0.1904 0.16 +0.153 0.187 0.16 +0.1564 0.1836 0.16 +0.1598 0.1802 0.16 +0.1632 0.1768 0.16 +0.1666 0.1734 0.16 +0.17 0.17 0.16 +0.1734 0.1666 0.16 +0.1768 0.1632 0.16 +0.1802 0.1598 0.16 +0.1836 0.1564 0.16 +0.187 0.153 0.16 +0.1904 0.1496 0.16 +0.1938 0.1462 0.16 +0.1972 0.1428 0.16 +0.2006 0.1394 0.16 +0.204 0.136 0.16 +0.2074 0.1326 0.16 +0.2108 0.1292 0.16 +0.2142 0.1258 0.16 +0.2176 0.1224 0.16 +0.221 0.119 0.16 +0.2244 0.1156 0.16 +0.2278 0.1122 0.16 +0.2312 0.1088 0.16 +0.2346 0.1054 0.16 +0.238 0.102 0.16 +0.2414 0.0986 0.16 +0.2448 0.0952 0.16 +0.2482 0.0918 0.16 +0.2516 0.0884 0.16 +0.255 0.085 0.16 +0.2584 0.0816 0.16 +0.2618 0.0782 0.16 +0.2652 0.0748 0.16 +0.2686 0.0714 0.16 +0.272 0.068 0.16 +0.2754 0.0646 0.16 +0.2788 0.0612 0.16 +0.2822 0.0578 0.16 +0.2856 0.0544 0.16 +0.289 0.051 0.16 +0.2924 0.0476 0.16 +0.2958 0.0442 0.16 +0.2992 0.0408 0.16 +0.3026 0.0374 0.16 +0.306 0.034 0.16 +0.3094 0.0306 0.16 +0.3128 0.0272 0.16 +0.3162 0.0238 0.16 +0.3196 0.0204 0.16 +0.323 0.017 0.16 +0.3264 0.0136 0.16 +0.3298 0.0102 0.16 +0.3332 0.0068 0.16 +0.3366 0.0034 0.16 +0 0.345 0.155 +0.00345 0.34155 0.155 +0.0069 0.3381 0.155 +0.01035 0.33465 0.155 +0.0138 0.3312 0.155 +0.01725 0.32775 0.155 +0.0207 0.3243 0.155 +0.02415 0.32085 0.155 +0.0276 0.3174 0.155 +0.03105 0.31395 0.155 +0.0345 0.3105 0.155 +0.03795 0.30705 0.155 +0.0414 0.3036 0.155 +0.04485 0.30015 0.155 +0.0483 0.2967 0.155 +0.05175 0.29325 0.155 +0.0552 0.2898 0.155 +0.05865 0.28635 0.155 +0.0621 0.2829 0.155 +0.06555 0.27945 0.155 +0.069 0.276 0.155 +0.07245 0.27255 0.155 +0.0759 0.2691 0.155 +0.07935 0.26565 0.155 +0.0828 0.2622 0.155 +0.08625 0.25875 0.155 +0.0897 0.2553 0.155 +0.09315 0.25185 0.155 +0.0966 0.2484 0.155 +0.10005 0.24495 0.155 +0.1035 0.2415 0.155 +0.10695 0.23805 0.155 +0.1104 0.2346 0.155 +0.11385 0.23115 0.155 +0.1173 0.2277 0.155 +0.12075 0.22425 0.155 +0.1242 0.2208 0.155 +0.12765 0.21735 0.155 +0.1311 0.2139 0.155 +0.13455 0.21045 0.155 +0.138 0.207 0.155 +0.14145 0.20355 0.155 +0.1449 0.2001 0.155 +0.14835 0.19665 0.155 +0.1518 0.1932 0.155 +0.15525 0.18975 0.155 +0.1587 0.1863 0.155 +0.16215 0.18285 0.155 +0.1656 0.1794 0.155 +0.16905 0.17595 0.155 +0.1725 0.1725 0.155 +0.17595 0.16905 0.155 +0.1794 0.1656 0.155 +0.18285 0.16215 0.155 +0.1863 0.1587 0.155 +0.18975 0.15525 0.155 +0.1932 0.1518 0.155 +0.19665 0.14835 0.155 +0.2001 0.1449 0.155 +0.20355 0.14145 0.155 +0.207 0.138 0.155 +0.21045 0.13455 0.155 +0.2139 0.1311 0.155 +0.21735 0.12765 0.155 +0.2208 0.1242 0.155 +0.22425 0.12075 0.155 +0.2277 0.1173 0.155 +0.23115 0.11385 0.155 +0.2346 0.1104 0.155 +0.23805 0.10695 0.155 +0.2415 0.1035 0.155 +0.24495 0.10005 0.155 +0.2484 0.0966 0.155 +0.25185 0.09315 0.155 +0.2553 0.0897 0.155 +0.25875 0.08625 0.155 +0.2622 0.0828 0.155 +0.26565 0.07935 0.155 +0.2691 0.0759 0.155 +0.27255 0.07245 0.155 +0.276 0.069 0.155 +0.27945 0.06555 0.155 +0.2829 0.0621 0.155 +0.28635 0.05865 0.155 +0.2898 0.0552 0.155 +0.29325 0.05175 0.155 +0.2967 0.0483 0.155 +0.30015 0.04485 0.155 +0.3036 0.0414 0.155 +0.30705 0.03795 0.155 +0.3105 0.0345 0.155 +0.31395 0.03105 0.155 +0.3174 0.0276 0.155 +0.32085 0.02415 0.155 +0.3243 0.0207 0.155 +0.32775 0.01725 0.155 +0.3312 0.0138 0.155 +0.33465 0.01035 0.155 +0.3381 0.0069 0.155 +0.34155 0.00345 0.155 +0 0.35 0.15 +0.0035 0.3465 0.15 +0.007 0.343 0.15 +0.0105 0.3395 0.15 +0.014 0.336 0.15 +0.0175 0.3325 0.15 +0.021 0.329 0.15 +0.0245 0.3255 0.15 +0.028 0.322 0.15 +0.0315 0.3185 0.15 +0.035 0.315 0.15 +0.0385 0.3115 0.15 +0.042 0.308 0.15 +0.0455 0.3045 0.15 +0.049 0.301 0.15 +0.0525 0.2975 0.15 +0.056 0.294 0.15 +0.0595 0.2905 0.15 +0.063 0.287 0.15 +0.0665 0.2835 0.15 +0.07 0.28 0.15 +0.0735 0.2765 0.15 +0.077 0.273 0.15 +0.0805 0.2695 0.15 +0.084 0.266 0.15 +0.0875 0.2625 0.15 +0.091 0.259 0.15 +0.0945 0.2555 0.15 +0.098 0.252 0.15 +0.1015 0.2485 0.15 +0.105 0.245 0.15 +0.1085 0.2415 0.15 +0.112 0.238 0.15 +0.1155 0.2345 0.15 +0.119 0.231 0.15 +0.1225 0.2275 0.15 +0.126 0.224 0.15 +0.1295 0.2205 0.15 +0.133 0.217 0.15 +0.1365 0.2135 0.15 +0.14 0.21 0.15 +0.1435 0.2065 0.15 +0.147 0.203 0.15 +0.1505 0.1995 0.15 +0.154 0.196 0.15 +0.1575 0.1925 0.15 +0.161 0.189 0.15 +0.1645 0.1855 0.15 +0.168 0.182 0.15 +0.1715 0.1785 0.15 +0.175 0.175 0.15 +0.1785 0.1715 0.15 +0.182 0.168 0.15 +0.1855 0.1645 0.15 +0.189 0.161 0.15 +0.1925 0.1575 0.15 +0.196 0.154 0.15 +0.1995 0.1505 0.15 +0.203 0.147 0.15 +0.2065 0.1435 0.15 +0.21 0.14 0.15 +0.2135 0.1365 0.15 +0.217 0.133 0.15 +0.2205 0.1295 0.15 +0.224 0.126 0.15 +0.2275 0.1225 0.15 +0.231 0.119 0.15 +0.2345 0.1155 0.15 +0.238 0.112 0.15 +0.2415 0.1085 0.15 +0.245 0.105 0.15 +0.2485 0.1015 0.15 +0.252 0.098 0.15 +0.2555 0.0945 0.15 +0.259 0.091 0.15 +0.2625 0.0875 0.15 +0.266 0.084 0.15 +0.2695 0.0805 0.15 +0.273 0.077 0.15 +0.2765 0.0735 0.15 +0.28 0.07 0.15 +0.2835 0.0665 0.15 +0.287 0.063 0.15 +0.2905 0.0595 0.15 +0.294 0.056 0.15 +0.2975 0.0525 0.15 +0.301 0.049 0.15 +0.3045 0.0455 0.15 +0.308 0.042 0.15 +0.3115 0.0385 0.15 +0.315 0.035 0.15 +0.3185 0.0315 0.15 +0.322 0.028 0.15 +0.3255 0.0245 0.15 +0.329 0.021 0.15 +0.3325 0.0175 0.15 +0.336 0.014 0.15 +0.3395 0.0105 0.15 +0.343 0.007 0.15 +0.3465 0.0035 0.15 +0 0.355 0.145 +0.00355 0.35145 0.145 +0.0071 0.3479 0.145 +0.01065 0.34435 0.145 +0.0142 0.3408 0.145 +0.01775 0.33725 0.145 +0.0213 0.3337 0.145 +0.02485 0.33015 0.145 +0.0284 0.3266 0.145 +0.03195 0.32305 0.145 +0.0355 0.3195 0.145 +0.03905 0.31595 0.145 +0.0426 0.3124 0.145 +0.04615 0.30885 0.145 +0.0497 0.3053 0.145 +0.05325 0.30175 0.145 +0.0568 0.2982 0.145 +0.06035 0.29465 0.145 +0.0639 0.2911 0.145 +0.06745 0.28755 0.145 +0.071 0.284 0.145 +0.07455 0.28045 0.145 +0.0781 0.2769 0.145 +0.08165 0.27335 0.145 +0.0852 0.2698 0.145 +0.08875 0.26625 0.145 +0.0923 0.2627 0.145 +0.09585 0.25915 0.145 +0.0994 0.2556 0.145 +0.10295 0.25205 0.145 +0.1065 0.2485 0.145 +0.11005 0.24495 0.145 +0.1136 0.2414 0.145 +0.11715 0.23785 0.145 +0.1207 0.2343 0.145 +0.12425 0.23075 0.145 +0.1278 0.2272 0.145 +0.13135 0.22365 0.145 +0.1349 0.2201 0.145 +0.13845 0.21655 0.145 +0.142 0.213 0.145 +0.14555 0.20945 0.145 +0.1491 0.2059 0.145 +0.15265 0.20235 0.145 +0.1562 0.1988 0.145 +0.15975 0.19525 0.145 +0.1633 0.1917 0.145 +0.16685 0.18815 0.145 +0.1704 0.1846 0.145 +0.17395 0.18105 0.145 +0.1775 0.1775 0.145 +0.18105 0.17395 0.145 +0.1846 0.1704 0.145 +0.18815 0.16685 0.145 +0.1917 0.1633 0.145 +0.19525 0.15975 0.145 +0.1988 0.1562 0.145 +0.20235 0.15265 0.145 +0.2059 0.1491 0.145 +0.20945 0.14555 0.145 +0.213 0.142 0.145 +0.21655 0.13845 0.145 +0.2201 0.1349 0.145 +0.22365 0.13135 0.145 +0.2272 0.1278 0.145 +0.23075 0.12425 0.145 +0.2343 0.1207 0.145 +0.23785 0.11715 0.145 +0.2414 0.1136 0.145 +0.24495 0.11005 0.145 +0.2485 0.1065 0.145 +0.25205 0.10295 0.145 +0.2556 0.0994 0.145 +0.25915 0.09585 0.145 +0.2627 0.0923 0.145 +0.26625 0.08875 0.145 +0.2698 0.0852 0.145 +0.27335 0.08165 0.145 +0.2769 0.0781 0.145 +0.28045 0.07455 0.145 +0.284 0.071 0.145 +0.28755 0.06745 0.145 +0.2911 0.0639 0.145 +0.29465 0.06035 0.145 +0.2982 0.0568 0.145 +0.30175 0.05325 0.145 +0.3053 0.0497 0.145 +0.30885 0.04615 0.145 +0.3124 0.0426 0.145 +0.31595 0.03905 0.145 +0.3195 0.0355 0.145 +0.32305 0.03195 0.145 +0.3266 0.0284 0.145 +0.33015 0.02485 0.145 +0.3337 0.0213 0.145 +0.33725 0.01775 0.145 +0.3408 0.0142 0.145 +0.34435 0.01065 0.145 +0.3479 0.0071 0.145 +0.35145 0.00355 0.145 +0 0.36 0.14 +0.0036 0.3564 0.14 +0.0072 0.3528 0.14 +0.0108 0.3492 0.14 +0.0144 0.3456 0.14 +0.018 0.342 0.14 +0.0216 0.3384 0.14 +0.0252 0.3348 0.14 +0.0288 0.3312 0.14 +0.0324 0.3276 0.14 +0.036 0.324 0.14 +0.0396 0.3204 0.14 +0.0432 0.3168 0.14 +0.0468 0.3132 0.14 +0.0504 0.3096 0.14 +0.054 0.306 0.14 +0.0576 0.3024 0.14 +0.0612 0.2988 0.14 +0.0648 0.2952 0.14 +0.0684 0.2916 0.14 +0.072 0.288 0.14 +0.0756 0.2844 0.14 +0.0792 0.2808 0.14 +0.0828 0.2772 0.14 +0.0864 0.2736 0.14 +0.09 0.27 0.14 +0.0936 0.2664 0.14 +0.0972 0.2628 0.14 +0.1008 0.2592 0.14 +0.1044 0.2556 0.14 +0.108 0.252 0.14 +0.1116 0.2484 0.14 +0.1152 0.2448 0.14 +0.1188 0.2412 0.14 +0.1224 0.2376 0.14 +0.126 0.234 0.14 +0.1296 0.2304 0.14 +0.1332 0.2268 0.14 +0.1368 0.2232 0.14 +0.1404 0.2196 0.14 +0.144 0.216 0.14 +0.1476 0.2124 0.14 +0.1512 0.2088 0.14 +0.1548 0.2052 0.14 +0.1584 0.2016 0.14 +0.162 0.198 0.14 +0.1656 0.1944 0.14 +0.1692 0.1908 0.14 +0.1728 0.1872 0.14 +0.1764 0.1836 0.14 +0.18 0.18 0.14 +0.1836 0.1764 0.14 +0.1872 0.1728 0.14 +0.1908 0.1692 0.14 +0.1944 0.1656 0.14 +0.198 0.162 0.14 +0.2016 0.1584 0.14 +0.2052 0.1548 0.14 +0.2088 0.1512 0.14 +0.2124 0.1476 0.14 +0.216 0.144 0.14 +0.2196 0.1404 0.14 +0.2232 0.1368 0.14 +0.2268 0.1332 0.14 +0.2304 0.1296 0.14 +0.234 0.126 0.14 +0.2376 0.1224 0.14 +0.2412 0.1188 0.14 +0.2448 0.1152 0.14 +0.2484 0.1116 0.14 +0.252 0.108 0.14 +0.2556 0.1044 0.14 +0.2592 0.1008 0.14 +0.2628 0.0972 0.14 +0.2664 0.0936 0.14 +0.27 0.09 0.14 +0.2736 0.0864 0.14 +0.2772 0.0828 0.14 +0.2808 0.0792 0.14 +0.2844 0.0756 0.14 +0.288 0.072 0.14 +0.2916 0.0684 0.14 +0.2952 0.0648 0.14 +0.2988 0.0612 0.14 +0.3024 0.0576 0.14 +0.306 0.054 0.14 +0.3096 0.0504 0.14 +0.3132 0.0468 0.14 +0.3168 0.0432 0.14 +0.3204 0.0396 0.14 +0.324 0.036 0.14 +0.3276 0.0324 0.14 +0.3312 0.0288 0.14 +0.3348 0.0252 0.14 +0.3384 0.0216 0.14 +0.342 0.018 0.14 +0.3456 0.0144 0.14 +0.3492 0.0108 0.14 +0.3528 0.0072 0.14 +0.3564 0.0036 0.14 +0 0.365 0.135 +0.00365 0.36135 0.135 +0.0073 0.3577 0.135 +0.01095 0.35405 0.135 +0.0146 0.3504 0.135 +0.01825 0.34675 0.135 +0.0219 0.3431 0.135 +0.02555 0.33945 0.135 +0.0292 0.3358 0.135 +0.03285 0.33215 0.135 +0.0365 0.3285 0.135 +0.04015 0.32485 0.135 +0.0438 0.3212 0.135 +0.04745 0.31755 0.135 +0.0511 0.3139 0.135 +0.05475 0.31025 0.135 +0.0584 0.3066 0.135 +0.06205 0.30295 0.135 +0.0657 0.2993 0.135 +0.06935 0.29565 0.135 +0.073 0.292 0.135 +0.07665 0.28835 0.135 +0.0803 0.2847 0.135 +0.08395 0.28105 0.135 +0.0876 0.2774 0.135 +0.09125 0.27375 0.135 +0.0949 0.2701 0.135 +0.09855 0.26645 0.135 +0.1022 0.2628 0.135 +0.10585 0.25915 0.135 +0.1095 0.2555 0.135 +0.11315 0.25185 0.135 +0.1168 0.2482 0.135 +0.12045 0.24455 0.135 +0.1241 0.2409 0.135 +0.12775 0.23725 0.135 +0.1314 0.2336 0.135 +0.13505 0.22995 0.135 +0.1387 0.2263 0.135 +0.14235 0.22265 0.135 +0.146 0.219 0.135 +0.14965 0.21535 0.135 +0.1533 0.2117 0.135 +0.15695 0.20805 0.135 +0.1606 0.2044 0.135 +0.16425 0.20075 0.135 +0.1679 0.1971 0.135 +0.17155 0.19345 0.135 +0.1752 0.1898 0.135 +0.17885 0.18615 0.135 +0.1825 0.1825 0.135 +0.18615 0.17885 0.135 +0.1898 0.1752 0.135 +0.19345 0.17155 0.135 +0.1971 0.1679 0.135 +0.20075 0.16425 0.135 +0.2044 0.1606 0.135 +0.20805 0.15695 0.135 +0.2117 0.1533 0.135 +0.21535 0.14965 0.135 +0.219 0.146 0.135 +0.22265 0.14235 0.135 +0.2263 0.1387 0.135 +0.22995 0.13505 0.135 +0.2336 0.1314 0.135 +0.23725 0.12775 0.135 +0.2409 0.1241 0.135 +0.24455 0.12045 0.135 +0.2482 0.1168 0.135 +0.25185 0.11315 0.135 +0.2555 0.1095 0.135 +0.25915 0.10585 0.135 +0.2628 0.1022 0.135 +0.26645 0.09855 0.135 +0.2701 0.0949 0.135 +0.27375 0.09125 0.135 +0.2774 0.0876 0.135 +0.28105 0.08395 0.135 +0.2847 0.0803 0.135 +0.28835 0.07665 0.135 +0.292 0.073 0.135 +0.29565 0.06935 0.135 +0.2993 0.0657 0.135 +0.30295 0.06205 0.135 +0.3066 0.0584 0.135 +0.31025 0.05475 0.135 +0.3139 0.0511 0.135 +0.31755 0.04745 0.135 +0.3212 0.0438 0.135 +0.32485 0.04015 0.135 +0.3285 0.0365 0.135 +0.33215 0.03285 0.135 +0.3358 0.0292 0.135 +0.33945 0.02555 0.135 +0.3431 0.0219 0.135 +0.34675 0.01825 0.135 +0.3504 0.0146 0.135 +0.35405 0.01095 0.135 +0.3577 0.0073 0.135 +0.36135 0.00365 0.135 +0 0.37 0.13 +0.0037 0.3663 0.13 +0.0074 0.3626 0.13 +0.0111 0.3589 0.13 +0.0148 0.3552 0.13 +0.0185 0.3515 0.13 +0.0222 0.3478 0.13 +0.0259 0.3441 0.13 +0.0296 0.3404 0.13 +0.0333 0.3367 0.13 +0.037 0.333 0.13 +0.0407 0.3293 0.13 +0.0444 0.3256 0.13 +0.0481 0.3219 0.13 +0.0518 0.3182 0.13 +0.0555 0.3145 0.13 +0.0592 0.3108 0.13 +0.0629 0.3071 0.13 +0.0666 0.3034 0.13 +0.0703 0.2997 0.13 +0.074 0.296 0.13 +0.0777 0.2923 0.13 +0.0814 0.2886 0.13 +0.0851 0.2849 0.13 +0.0888 0.2812 0.13 +0.0925 0.2775 0.13 +0.0962 0.2738 0.13 +0.0999 0.2701 0.13 +0.1036 0.2664 0.13 +0.1073 0.2627 0.13 +0.111 0.259 0.13 +0.1147 0.2553 0.13 +0.1184 0.2516 0.13 +0.1221 0.2479 0.13 +0.1258 0.2442 0.13 +0.1295 0.2405 0.13 +0.1332 0.2368 0.13 +0.1369 0.2331 0.13 +0.1406 0.2294 0.13 +0.1443 0.2257 0.13 +0.148 0.222 0.13 +0.1517 0.2183 0.13 +0.1554 0.2146 0.13 +0.1591 0.2109 0.13 +0.1628 0.2072 0.13 +0.1665 0.2035 0.13 +0.1702 0.1998 0.13 +0.1739 0.1961 0.13 +0.1776 0.1924 0.13 +0.1813 0.1887 0.13 +0.185 0.185 0.13 +0.1887 0.1813 0.13 +0.1924 0.1776 0.13 +0.1961 0.1739 0.13 +0.1998 0.1702 0.13 +0.2035 0.1665 0.13 +0.2072 0.1628 0.13 +0.2109 0.1591 0.13 +0.2146 0.1554 0.13 +0.2183 0.1517 0.13 +0.222 0.148 0.13 +0.2257 0.1443 0.13 +0.2294 0.1406 0.13 +0.2331 0.1369 0.13 +0.2368 0.1332 0.13 +0.2405 0.1295 0.13 +0.2442 0.1258 0.13 +0.2479 0.1221 0.13 +0.2516 0.1184 0.13 +0.2553 0.1147 0.13 +0.259 0.111 0.13 +0.2627 0.1073 0.13 +0.2664 0.1036 0.13 +0.2701 0.0999 0.13 +0.2738 0.0962 0.13 +0.2775 0.0925 0.13 +0.2812 0.0888 0.13 +0.2849 0.0851 0.13 +0.2886 0.0814 0.13 +0.2923 0.0777 0.13 +0.296 0.074 0.13 +0.2997 0.0703 0.13 +0.3034 0.0666 0.13 +0.3071 0.0629 0.13 +0.3108 0.0592 0.13 +0.3145 0.0555 0.13 +0.3182 0.0518 0.13 +0.3219 0.0481 0.13 +0.3256 0.0444 0.13 +0.3293 0.0407 0.13 +0.333 0.037 0.13 +0.3367 0.0333 0.13 +0.3404 0.0296 0.13 +0.3441 0.0259 0.13 +0.3478 0.0222 0.13 +0.3515 0.0185 0.13 +0.3552 0.0148 0.13 +0.3589 0.0111 0.13 +0.3626 0.0074 0.13 +0.3663 0.0037 0.13 +0 0.375 0.125 +0.00375 0.37125 0.125 +0.0075 0.3675 0.125 +0.01125 0.36375 0.125 +0.015 0.36 0.125 +0.01875 0.35625 0.125 +0.0225 0.3525 0.125 +0.02625 0.34875 0.125 +0.03 0.345 0.125 +0.03375 0.34125 0.125 +0.0375 0.3375 0.125 +0.04125 0.33375 0.125 +0.045 0.33 0.125 +0.04875 0.32625 0.125 +0.0525 0.3225 0.125 +0.05625 0.31875 0.125 +0.06 0.315 0.125 +0.06375 0.31125 0.125 +0.0675 0.3075 0.125 +0.07125 0.30375 0.125 +0.075 0.3 0.125 +0.07875 0.29625 0.125 +0.0825 0.2925 0.125 +0.08625 0.28875 0.125 +0.09 0.285 0.125 +0.09375 0.28125 0.125 +0.0975 0.2775 0.125 +0.10125 0.27375 0.125 +0.105 0.27 0.125 +0.10875 0.26625 0.125 +0.1125 0.2625 0.125 +0.11625 0.25875 0.125 +0.12 0.255 0.125 +0.12375 0.25125 0.125 +0.1275 0.2475 0.125 +0.13125 0.24375 0.125 +0.135 0.24 0.125 +0.13875 0.23625 0.125 +0.1425 0.2325 0.125 +0.14625 0.22875 0.125 +0.15 0.225 0.125 +0.15375 0.22125 0.125 +0.1575 0.2175 0.125 +0.16125 0.21375 0.125 +0.165 0.21 0.125 +0.16875 0.20625 0.125 +0.1725 0.2025 0.125 +0.17625 0.19875 0.125 +0.18 0.195 0.125 +0.18375 0.19125 0.125 +0.1875 0.1875 0.125 +0.19125 0.18375 0.125 +0.195 0.18 0.125 +0.19875 0.17625 0.125 +0.2025 0.1725 0.125 +0.20625 0.16875 0.125 +0.21 0.165 0.125 +0.21375 0.16125 0.125 +0.2175 0.1575 0.125 +0.22125 0.15375 0.125 +0.225 0.15 0.125 +0.22875 0.14625 0.125 +0.2325 0.1425 0.125 +0.23625 0.13875 0.125 +0.24 0.135 0.125 +0.24375 0.13125 0.125 +0.2475 0.1275 0.125 +0.25125 0.12375 0.125 +0.255 0.12 0.125 +0.25875 0.11625 0.125 +0.2625 0.1125 0.125 +0.26625 0.10875 0.125 +0.27 0.105 0.125 +0.27375 0.10125 0.125 +0.2775 0.0975 0.125 +0.28125 0.09375 0.125 +0.285 0.09 0.125 +0.28875 0.08625 0.125 +0.2925 0.0825 0.125 +0.29625 0.07875 0.125 +0.3 0.075 0.125 +0.30375 0.07125 0.125 +0.3075 0.0675 0.125 +0.31125 0.06375 0.125 +0.315 0.06 0.125 +0.31875 0.05625 0.125 +0.3225 0.0525 0.125 +0.32625 0.04875 0.125 +0.33 0.045 0.125 +0.33375 0.04125 0.125 +0.3375 0.0375 0.125 +0.34125 0.03375 0.125 +0.345 0.03 0.125 +0.34875 0.02625 0.125 +0.3525 0.0225 0.125 +0.35625 0.01875 0.125 +0.36 0.015 0.125 +0.36375 0.01125 0.125 +0.3675 0.0075 0.125 +0.37125 0.00375 0.125 +0 0.38 0.12 +0.0038 0.3762 0.12 +0.0076 0.3724 0.12 +0.0114 0.3686 0.12 +0.0152 0.3648 0.12 +0.019 0.361 0.12 +0.0228 0.3572 0.12 +0.0266 0.3534 0.12 +0.0304 0.3496 0.12 +0.0342 0.3458 0.12 +0.038 0.342 0.12 +0.0418 0.3382 0.12 +0.0456 0.3344 0.12 +0.0494 0.3306 0.12 +0.0532 0.3268 0.12 +0.057 0.323 0.12 +0.0608 0.3192 0.12 +0.0646 0.3154 0.12 +0.0684 0.3116 0.12 +0.0722 0.3078 0.12 +0.076 0.304 0.12 +0.0798 0.3002 0.12 +0.0836 0.2964 0.12 +0.0874 0.2926 0.12 +0.0912 0.2888 0.12 +0.095 0.285 0.12 +0.0988 0.2812 0.12 +0.1026 0.2774 0.12 +0.1064 0.2736 0.12 +0.1102 0.2698 0.12 +0.114 0.266 0.12 +0.1178 0.2622 0.12 +0.1216 0.2584 0.12 +0.1254 0.2546 0.12 +0.1292 0.2508 0.12 +0.133 0.247 0.12 +0.1368 0.2432 0.12 +0.1406 0.2394 0.12 +0.1444 0.2356 0.12 +0.1482 0.2318 0.12 +0.152 0.228 0.12 +0.1558 0.2242 0.12 +0.1596 0.2204 0.12 +0.1634 0.2166 0.12 +0.1672 0.2128 0.12 +0.171 0.209 0.12 +0.1748 0.2052 0.12 +0.1786 0.2014 0.12 +0.1824 0.1976 0.12 +0.1862 0.1938 0.12 +0.19 0.19 0.12 +0.1938 0.1862 0.12 +0.1976 0.1824 0.12 +0.2014 0.1786 0.12 +0.2052 0.1748 0.12 +0.209 0.171 0.12 +0.2128 0.1672 0.12 +0.2166 0.1634 0.12 +0.2204 0.1596 0.12 +0.2242 0.1558 0.12 +0.228 0.152 0.12 +0.2318 0.1482 0.12 +0.2356 0.1444 0.12 +0.2394 0.1406 0.12 +0.2432 0.1368 0.12 +0.247 0.133 0.12 +0.2508 0.1292 0.12 +0.2546 0.1254 0.12 +0.2584 0.1216 0.12 +0.2622 0.1178 0.12 +0.266 0.114 0.12 +0.2698 0.1102 0.12 +0.2736 0.1064 0.12 +0.2774 0.1026 0.12 +0.2812 0.0988 0.12 +0.285 0.095 0.12 +0.2888 0.0912 0.12 +0.2926 0.0874 0.12 +0.2964 0.0836 0.12 +0.3002 0.0798 0.12 +0.304 0.076 0.12 +0.3078 0.0722 0.12 +0.3116 0.0684 0.12 +0.3154 0.0646 0.12 +0.3192 0.0608 0.12 +0.323 0.057 0.12 +0.3268 0.0532 0.12 +0.3306 0.0494 0.12 +0.3344 0.0456 0.12 +0.3382 0.0418 0.12 +0.342 0.038 0.12 +0.3458 0.0342 0.12 +0.3496 0.0304 0.12 +0.3534 0.0266 0.12 +0.3572 0.0228 0.12 +0.361 0.019 0.12 +0.3648 0.0152 0.12 +0.3686 0.0114 0.12 +0.3724 0.0076 0.12 +0.3762 0.0038 0.12 +0 0.385 0.115 +0.00385 0.38115 0.115 +0.0077 0.3773 0.115 +0.01155 0.37345 0.115 +0.0154 0.3696 0.115 +0.01925 0.36575 0.115 +0.0231 0.3619 0.115 +0.02695 0.35805 0.115 +0.0308 0.3542 0.115 +0.03465 0.35035 0.115 +0.0385 0.3465 0.115 +0.04235 0.34265 0.115 +0.0462 0.3388 0.115 +0.05005 0.33495 0.115 +0.0539 0.3311 0.115 +0.05775 0.32725 0.115 +0.0616 0.3234 0.115 +0.06545 0.31955 0.115 +0.0693 0.3157 0.115 +0.07315 0.31185 0.115 +0.077 0.308 0.115 +0.08085 0.30415 0.115 +0.0847 0.3003 0.115 +0.08855 0.29645 0.115 +0.0924 0.2926 0.115 +0.09625 0.28875 0.115 +0.1001 0.2849 0.115 +0.10395 0.28105 0.115 +0.1078 0.2772 0.115 +0.11165 0.27335 0.115 +0.1155 0.2695 0.115 +0.11935 0.26565 0.115 +0.1232 0.2618 0.115 +0.12705 0.25795 0.115 +0.1309 0.2541 0.115 +0.13475 0.25025 0.115 +0.1386 0.2464 0.115 +0.14245 0.24255 0.115 +0.1463 0.2387 0.115 +0.15015 0.23485 0.115 +0.154 0.231 0.115 +0.15785 0.22715 0.115 +0.1617 0.2233 0.115 +0.16555 0.21945 0.115 +0.1694 0.2156 0.115 +0.17325 0.21175 0.115 +0.1771 0.2079 0.115 +0.18095 0.20405 0.115 +0.1848 0.2002 0.115 +0.18865 0.19635 0.115 +0.1925 0.1925 0.115 +0.19635 0.18865 0.115 +0.2002 0.1848 0.115 +0.20405 0.18095 0.115 +0.2079 0.1771 0.115 +0.21175 0.17325 0.115 +0.2156 0.1694 0.115 +0.21945 0.16555 0.115 +0.2233 0.1617 0.115 +0.22715 0.15785 0.115 +0.231 0.154 0.115 +0.23485 0.15015 0.115 +0.2387 0.1463 0.115 +0.24255 0.14245 0.115 +0.2464 0.1386 0.115 +0.25025 0.13475 0.115 +0.2541 0.1309 0.115 +0.25795 0.12705 0.115 +0.2618 0.1232 0.115 +0.26565 0.11935 0.115 +0.2695 0.1155 0.115 +0.27335 0.11165 0.115 +0.2772 0.1078 0.115 +0.28105 0.10395 0.115 +0.2849 0.1001 0.115 +0.28875 0.09625 0.115 +0.2926 0.0924 0.115 +0.29645 0.08855 0.115 +0.3003 0.0847 0.115 +0.30415 0.08085 0.115 +0.308 0.077 0.115 +0.31185 0.07315 0.115 +0.3157 0.0693 0.115 +0.31955 0.06545 0.115 +0.3234 0.0616 0.115 +0.32725 0.05775 0.115 +0.3311 0.0539 0.115 +0.33495 0.05005 0.115 +0.3388 0.0462 0.115 +0.34265 0.04235 0.115 +0.3465 0.0385 0.115 +0.35035 0.03465 0.115 +0.3542 0.0308 0.115 +0.35805 0.02695 0.115 +0.3619 0.0231 0.115 +0.36575 0.01925 0.115 +0.3696 0.0154 0.115 +0.37345 0.01155 0.115 +0.3773 0.0077 0.115 +0.38115 0.00385 0.115 +0 0.39 0.11 +0.0039 0.3861 0.11 +0.0078 0.3822 0.11 +0.0117 0.3783 0.11 +0.0156 0.3744 0.11 +0.0195 0.3705 0.11 +0.0234 0.3666 0.11 +0.0273 0.3627 0.11 +0.0312 0.3588 0.11 +0.0351 0.3549 0.11 +0.039 0.351 0.11 +0.0429 0.3471 0.11 +0.0468 0.3432 0.11 +0.0507 0.3393 0.11 +0.0546 0.3354 0.11 +0.0585 0.3315 0.11 +0.0624 0.3276 0.11 +0.0663 0.3237 0.11 +0.0702 0.3198 0.11 +0.0741 0.3159 0.11 +0.078 0.312 0.11 +0.0819 0.3081 0.11 +0.0858 0.3042 0.11 +0.0897 0.3003 0.11 +0.0936 0.2964 0.11 +0.0975 0.2925 0.11 +0.1014 0.2886 0.11 +0.1053 0.2847 0.11 +0.1092 0.2808 0.11 +0.1131 0.2769 0.11 +0.117 0.273 0.11 +0.1209 0.2691 0.11 +0.1248 0.2652 0.11 +0.1287 0.2613 0.11 +0.1326 0.2574 0.11 +0.1365 0.2535 0.11 +0.1404 0.2496 0.11 +0.1443 0.2457 0.11 +0.1482 0.2418 0.11 +0.1521 0.2379 0.11 +0.156 0.234 0.11 +0.1599 0.2301 0.11 +0.1638 0.2262 0.11 +0.1677 0.2223 0.11 +0.1716 0.2184 0.11 +0.1755 0.2145 0.11 +0.1794 0.2106 0.11 +0.1833 0.2067 0.11 +0.1872 0.2028 0.11 +0.1911 0.1989 0.11 +0.195 0.195 0.11 +0.1989 0.1911 0.11 +0.2028 0.1872 0.11 +0.2067 0.1833 0.11 +0.2106 0.1794 0.11 +0.2145 0.1755 0.11 +0.2184 0.1716 0.11 +0.2223 0.1677 0.11 +0.2262 0.1638 0.11 +0.2301 0.1599 0.11 +0.234 0.156 0.11 +0.2379 0.1521 0.11 +0.2418 0.1482 0.11 +0.2457 0.1443 0.11 +0.2496 0.1404 0.11 +0.2535 0.1365 0.11 +0.2574 0.1326 0.11 +0.2613 0.1287 0.11 +0.2652 0.1248 0.11 +0.2691 0.1209 0.11 +0.273 0.117 0.11 +0.2769 0.1131 0.11 +0.2808 0.1092 0.11 +0.2847 0.1053 0.11 +0.2886 0.1014 0.11 +0.2925 0.0975 0.11 +0.2964 0.0936 0.11 +0.3003 0.0897 0.11 +0.3042 0.0858 0.11 +0.3081 0.0819 0.11 +0.312 0.078 0.11 +0.3159 0.0741 0.11 +0.3198 0.0702 0.11 +0.3237 0.0663 0.11 +0.3276 0.0624 0.11 +0.3315 0.0585 0.11 +0.3354 0.0546 0.11 +0.3393 0.0507 0.11 +0.3432 0.0468 0.11 +0.3471 0.0429 0.11 +0.351 0.039 0.11 +0.3549 0.0351 0.11 +0.3588 0.0312 0.11 +0.3627 0.0273 0.11 +0.3666 0.0234 0.11 +0.3705 0.0195 0.11 +0.3744 0.0156 0.11 +0.3783 0.0117 0.11 +0.3822 0.0078 0.11 +0.3861 0.0039 0.11 +0 0.395 0.105 +0.00395 0.39105 0.105 +0.0079 0.3871 0.105 +0.01185 0.38315 0.105 +0.0158 0.3792 0.105 +0.01975 0.37525 0.105 +0.0237 0.3713 0.105 +0.02765 0.36735 0.105 +0.0316 0.3634 0.105 +0.03555 0.35945 0.105 +0.0395 0.3555 0.105 +0.04345 0.35155 0.105 +0.0474 0.3476 0.105 +0.05135 0.34365 0.105 +0.0553 0.3397 0.105 +0.05925 0.33575 0.105 +0.0632 0.3318 0.105 +0.06715 0.32785 0.105 +0.0711 0.3239 0.105 +0.07505 0.31995 0.105 +0.079 0.316 0.105 +0.08295 0.31205 0.105 +0.0869 0.3081 0.105 +0.09085 0.30415 0.105 +0.0948 0.3002 0.105 +0.09875 0.29625 0.105 +0.1027 0.2923 0.105 +0.10665 0.28835 0.105 +0.1106 0.2844 0.105 +0.11455 0.28045 0.105 +0.1185 0.2765 0.105 +0.12245 0.27255 0.105 +0.1264 0.2686 0.105 +0.13035 0.26465 0.105 +0.1343 0.2607 0.105 +0.13825 0.25675 0.105 +0.1422 0.2528 0.105 +0.14615 0.24885 0.105 +0.1501 0.2449 0.105 +0.15405 0.24095 0.105 +0.158 0.237 0.105 +0.16195 0.23305 0.105 +0.1659 0.2291 0.105 +0.16985 0.22515 0.105 +0.1738 0.2212 0.105 +0.17775 0.21725 0.105 +0.1817 0.2133 0.105 +0.18565 0.20935 0.105 +0.1896 0.2054 0.105 +0.19355 0.20145 0.105 +0.1975 0.1975 0.105 +0.20145 0.19355 0.105 +0.2054 0.1896 0.105 +0.20935 0.18565 0.105 +0.2133 0.1817 0.105 +0.21725 0.17775 0.105 +0.2212 0.1738 0.105 +0.22515 0.16985 0.105 +0.2291 0.1659 0.105 +0.23305 0.16195 0.105 +0.237 0.158 0.105 +0.24095 0.15405 0.105 +0.2449 0.1501 0.105 +0.24885 0.14615 0.105 +0.2528 0.1422 0.105 +0.25675 0.13825 0.105 +0.2607 0.1343 0.105 +0.26465 0.13035 0.105 +0.2686 0.1264 0.105 +0.27255 0.12245 0.105 +0.2765 0.1185 0.105 +0.28045 0.11455 0.105 +0.2844 0.1106 0.105 +0.28835 0.10665 0.105 +0.2923 0.1027 0.105 +0.29625 0.09875 0.105 +0.3002 0.0948 0.105 +0.30415 0.09085 0.105 +0.3081 0.0869 0.105 +0.31205 0.08295 0.105 +0.316 0.079 0.105 +0.31995 0.07505 0.105 +0.3239 0.0711 0.105 +0.32785 0.06715 0.105 +0.3318 0.0632 0.105 +0.33575 0.05925 0.105 +0.3397 0.0553 0.105 +0.34365 0.05135 0.105 +0.3476 0.0474 0.105 +0.35155 0.04345 0.105 +0.3555 0.0395 0.105 +0.35945 0.03555 0.105 +0.3634 0.0316 0.105 +0.36735 0.02765 0.105 +0.3713 0.0237 0.105 +0.37525 0.01975 0.105 +0.3792 0.0158 0.105 +0.38315 0.01185 0.105 +0.3871 0.0079 0.105 +0.39105 0.00395 0.105 +0 0.4 0.1 +0.004 0.396 0.1 +0.008 0.392 0.1 +0.012 0.388 0.1 +0.016 0.384 0.1 +0.02 0.38 0.1 +0.024 0.376 0.1 +0.028 0.372 0.1 +0.032 0.368 0.1 +0.036 0.364 0.1 +0.04 0.36 0.1 +0.044 0.356 0.1 +0.048 0.352 0.1 +0.052 0.348 0.1 +0.056 0.344 0.1 +0.06 0.34 0.1 +0.064 0.336 0.1 +0.068 0.332 0.1 +0.072 0.328 0.1 +0.076 0.324 0.1 +0.08 0.32 0.1 +0.084 0.316 0.1 +0.088 0.312 0.1 +0.092 0.308 0.1 +0.096 0.304 0.1 +0.1 0.3 0.1 +0.104 0.296 0.1 +0.108 0.292 0.1 +0.112 0.288 0.1 +0.116 0.284 0.1 +0.12 0.28 0.1 +0.124 0.276 0.1 +0.128 0.272 0.1 +0.132 0.268 0.1 +0.136 0.264 0.1 +0.14 0.26 0.1 +0.144 0.256 0.1 +0.148 0.252 0.1 +0.152 0.248 0.1 +0.156 0.244 0.1 +0.16 0.24 0.1 +0.164 0.236 0.1 +0.168 0.232 0.1 +0.172 0.228 0.1 +0.176 0.224 0.1 +0.18 0.22 0.1 +0.184 0.216 0.1 +0.188 0.212 0.1 +0.192 0.208 0.1 +0.196 0.204 0.1 +0.2 0.2 0.1 +0.204 0.196 0.1 +0.208 0.192 0.1 +0.212 0.188 0.1 +0.216 0.184 0.1 +0.22 0.18 0.1 +0.224 0.176 0.1 +0.228 0.172 0.1 +0.232 0.168 0.1 +0.236 0.164 0.1 +0.24 0.16 0.1 +0.244 0.156 0.1 +0.248 0.152 0.1 +0.252 0.148 0.1 +0.256 0.144 0.1 +0.26 0.14 0.1 +0.264 0.136 0.1 +0.268 0.132 0.1 +0.272 0.128 0.1 +0.276 0.124 0.1 +0.28 0.12 0.1 +0.284 0.116 0.1 +0.288 0.112 0.1 +0.292 0.108 0.1 +0.296 0.104 0.1 +0.3 0.1 0.1 +0.304 0.096 0.1 +0.308 0.092 0.1 +0.312 0.088 0.1 +0.316 0.084 0.1 +0.32 0.08 0.1 +0.324 0.076 0.1 +0.328 0.072 0.1 +0.332 0.068 0.1 +0.336 0.064 0.1 +0.34 0.06 0.1 +0.344 0.056 0.1 +0.348 0.052 0.1 +0.352 0.048 0.1 +0.356 0.044 0.1 +0.36 0.04 0.1 +0.364 0.036 0.1 +0.368 0.032 0.1 +0.372 0.028 0.1 +0.376 0.024 0.1 +0.38 0.02 0.1 +0.384 0.016 0.1 +0.388 0.012 0.1 +0.392 0.008 0.1 +0.396 0.004 0.1 +0 0.405 0.095 +0.00405 0.40095 0.095 +0.0081 0.3969 0.095 +0.01215 0.39285 0.095 +0.0162 0.3888 0.095 +0.02025 0.38475 0.095 +0.0243 0.3807 0.095 +0.02835 0.37665 0.095 +0.0324 0.3726 0.095 +0.03645 0.36855 0.095 +0.0405 0.3645 0.095 +0.04455 0.36045 0.095 +0.0486 0.3564 0.095 +0.05265 0.35235 0.095 +0.0567 0.3483 0.095 +0.06075 0.34425 0.095 +0.0648 0.3402 0.095 +0.06885 0.33615 0.095 +0.0729 0.3321 0.095 +0.07695 0.32805 0.095 +0.081 0.324 0.095 +0.08505 0.31995 0.095 +0.0891 0.3159 0.095 +0.09315 0.31185 0.095 +0.0972 0.3078 0.095 +0.10125 0.30375 0.095 +0.1053 0.2997 0.095 +0.10935 0.29565 0.095 +0.1134 0.2916 0.095 +0.11745 0.28755 0.095 +0.1215 0.2835 0.095 +0.12555 0.27945 0.095 +0.1296 0.2754 0.095 +0.13365 0.27135 0.095 +0.1377 0.2673 0.095 +0.14175 0.26325 0.095 +0.1458 0.2592 0.095 +0.14985 0.25515 0.095 +0.1539 0.2511 0.095 +0.15795 0.24705 0.095 +0.162 0.243 0.095 +0.16605 0.23895 0.095 +0.1701 0.2349 0.095 +0.17415 0.23085 0.095 +0.1782 0.2268 0.095 +0.18225 0.22275 0.095 +0.1863 0.2187 0.095 +0.19035 0.21465 0.095 +0.1944 0.2106 0.095 +0.19845 0.20655 0.095 +0.2025 0.2025 0.095 +0.20655 0.19845 0.095 +0.2106 0.1944 0.095 +0.21465 0.19035 0.095 +0.2187 0.1863 0.095 +0.22275 0.18225 0.095 +0.2268 0.1782 0.095 +0.23085 0.17415 0.095 +0.2349 0.1701 0.095 +0.23895 0.16605 0.095 +0.243 0.162 0.095 +0.24705 0.15795 0.095 +0.2511 0.1539 0.095 +0.25515 0.14985 0.095 +0.2592 0.1458 0.095 +0.26325 0.14175 0.095 +0.2673 0.1377 0.095 +0.27135 0.13365 0.095 +0.2754 0.1296 0.095 +0.27945 0.12555 0.095 +0.2835 0.1215 0.095 +0.28755 0.11745 0.095 +0.2916 0.1134 0.095 +0.29565 0.10935 0.095 +0.2997 0.1053 0.095 +0.30375 0.10125 0.095 +0.3078 0.0972 0.095 +0.31185 0.09315 0.095 +0.3159 0.0891 0.095 +0.31995 0.08505 0.095 +0.324 0.081 0.095 +0.32805 0.07695 0.095 +0.3321 0.0729 0.095 +0.33615 0.06885 0.095 +0.3402 0.0648 0.095 +0.34425 0.06075 0.095 +0.3483 0.0567 0.095 +0.35235 0.05265 0.095 +0.3564 0.0486 0.095 +0.36045 0.04455 0.095 +0.3645 0.0405 0.095 +0.36855 0.03645 0.095 +0.3726 0.0324 0.095 +0.37665 0.02835 0.095 +0.3807 0.0243 0.095 +0.38475 0.02025 0.095 +0.3888 0.0162 0.095 +0.39285 0.01215 0.095 +0.3969 0.0081 0.095 +0.40095 0.00405 0.095 +0 0.41 0.09 +0.0041 0.4059 0.09 +0.0082 0.4018 0.09 +0.0123 0.3977 0.09 +0.0164 0.3936 0.09 +0.0205 0.3895 0.09 +0.0246 0.3854 0.09 +0.0287 0.3813 0.09 +0.0328 0.3772 0.09 +0.0369 0.3731 0.09 +0.041 0.369 0.09 +0.0451 0.3649 0.09 +0.0492 0.3608 0.09 +0.0533 0.3567 0.09 +0.0574 0.3526 0.09 +0.0615 0.3485 0.09 +0.0656 0.3444 0.09 +0.0697 0.3403 0.09 +0.0738 0.3362 0.09 +0.0779 0.3321 0.09 +0.082 0.328 0.09 +0.0861 0.3239 0.09 +0.0902 0.3198 0.09 +0.0943 0.3157 0.09 +0.0984 0.3116 0.09 +0.1025 0.3075 0.09 +0.1066 0.3034 0.09 +0.1107 0.2993 0.09 +0.1148 0.2952 0.09 +0.1189 0.2911 0.09 +0.123 0.287 0.09 +0.1271 0.2829 0.09 +0.1312 0.2788 0.09 +0.1353 0.2747 0.09 +0.1394 0.2706 0.09 +0.1435 0.2665 0.09 +0.1476 0.2624 0.09 +0.1517 0.2583 0.09 +0.1558 0.2542 0.09 +0.1599 0.2501 0.09 +0.164 0.246 0.09 +0.1681 0.2419 0.09 +0.1722 0.2378 0.09 +0.1763 0.2337 0.09 +0.1804 0.2296 0.09 +0.1845 0.2255 0.09 +0.1886 0.2214 0.09 +0.1927 0.2173 0.09 +0.1968 0.2132 0.09 +0.2009 0.2091 0.09 +0.205 0.205 0.09 +0.2091 0.2009 0.09 +0.2132 0.1968 0.09 +0.2173 0.1927 0.09 +0.2214 0.1886 0.09 +0.2255 0.1845 0.09 +0.2296 0.1804 0.09 +0.2337 0.1763 0.09 +0.2378 0.1722 0.09 +0.2419 0.1681 0.09 +0.246 0.164 0.09 +0.2501 0.1599 0.09 +0.2542 0.1558 0.09 +0.2583 0.1517 0.09 +0.2624 0.1476 0.09 +0.2665 0.1435 0.09 +0.2706 0.1394 0.09 +0.2747 0.1353 0.09 +0.2788 0.1312 0.09 +0.2829 0.1271 0.09 +0.287 0.123 0.09 +0.2911 0.1189 0.09 +0.2952 0.1148 0.09 +0.2993 0.1107 0.09 +0.3034 0.1066 0.09 +0.3075 0.1025 0.09 +0.3116 0.0984 0.09 +0.3157 0.0943 0.09 +0.3198 0.0902 0.09 +0.3239 0.0861 0.09 +0.328 0.082 0.09 +0.3321 0.0779 0.09 +0.3362 0.0738 0.09 +0.3403 0.0697 0.09 +0.3444 0.0656 0.09 +0.3485 0.0615 0.09 +0.3526 0.0574 0.09 +0.3567 0.0533 0.09 +0.3608 0.0492 0.09 +0.3649 0.0451 0.09 +0.369 0.041 0.09 +0.3731 0.0369 0.09 +0.3772 0.0328 0.09 +0.3813 0.0287 0.09 +0.3854 0.0246 0.09 +0.3895 0.0205 0.09 +0.3936 0.0164 0.09 +0.3977 0.0123 0.09 +0.4018 0.0082 0.09 +0.4059 0.0041 0.09 +0 0.415 0.085 +0.00415 0.41085 0.085 +0.0083 0.4067 0.085 +0.01245 0.40255 0.085 +0.0166 0.3984 0.085 +0.02075 0.39425 0.085 +0.0249 0.3901 0.085 +0.02905 0.38595 0.085 +0.0332 0.3818 0.085 +0.03735 0.37765 0.085 +0.0415 0.3735 0.085 +0.04565 0.36935 0.085 +0.0498 0.3652 0.085 +0.05395 0.36105 0.085 +0.0581 0.3569 0.085 +0.06225 0.35275 0.085 +0.0664 0.3486 0.085 +0.07055 0.34445 0.085 +0.0747 0.3403 0.085 +0.07885 0.33615 0.085 +0.083 0.332 0.085 +0.08715 0.32785 0.085 +0.0913 0.3237 0.085 +0.09545 0.31955 0.085 +0.0996 0.3154 0.085 +0.10375 0.31125 0.085 +0.1079 0.3071 0.085 +0.11205 0.30295 0.085 +0.1162 0.2988 0.085 +0.12035 0.29465 0.085 +0.1245 0.2905 0.085 +0.12865 0.28635 0.085 +0.1328 0.2822 0.085 +0.13695 0.27805 0.085 +0.1411 0.2739 0.085 +0.14525 0.26975 0.085 +0.1494 0.2656 0.085 +0.15355 0.26145 0.085 +0.1577 0.2573 0.085 +0.16185 0.25315 0.085 +0.166 0.249 0.085 +0.17015 0.24485 0.085 +0.1743 0.2407 0.085 +0.17845 0.23655 0.085 +0.1826 0.2324 0.085 +0.18675 0.22825 0.085 +0.1909 0.2241 0.085 +0.19505 0.21995 0.085 +0.1992 0.2158 0.085 +0.20335 0.21165 0.085 +0.2075 0.2075 0.085 +0.21165 0.20335 0.085 +0.2158 0.1992 0.085 +0.21995 0.19505 0.085 +0.2241 0.1909 0.085 +0.22825 0.18675 0.085 +0.2324 0.1826 0.085 +0.23655 0.17845 0.085 +0.2407 0.1743 0.085 +0.24485 0.17015 0.085 +0.249 0.166 0.085 +0.25315 0.16185 0.085 +0.2573 0.1577 0.085 +0.26145 0.15355 0.085 +0.2656 0.1494 0.085 +0.26975 0.14525 0.085 +0.2739 0.1411 0.085 +0.27805 0.13695 0.085 +0.2822 0.1328 0.085 +0.28635 0.12865 0.085 +0.2905 0.1245 0.085 +0.29465 0.12035 0.085 +0.2988 0.1162 0.085 +0.30295 0.11205 0.085 +0.3071 0.1079 0.085 +0.31125 0.10375 0.085 +0.3154 0.0996 0.085 +0.31955 0.09545 0.085 +0.3237 0.0913 0.085 +0.32785 0.08715 0.085 +0.332 0.083 0.085 +0.33615 0.07885 0.085 +0.3403 0.0747 0.085 +0.34445 0.07055 0.085 +0.3486 0.0664 0.085 +0.35275 0.06225 0.085 +0.3569 0.0581 0.085 +0.36105 0.05395 0.085 +0.3652 0.0498 0.085 +0.36935 0.04565 0.085 +0.3735 0.0415 0.085 +0.37765 0.03735 0.085 +0.3818 0.0332 0.085 +0.38595 0.02905 0.085 +0.3901 0.0249 0.085 +0.39425 0.02075 0.085 +0.3984 0.0166 0.085 +0.40255 0.01245 0.085 +0.4067 0.0083 0.085 +0.41085 0.00415 0.085 +0 0.42 0.08 +0.0042 0.4158 0.08 +0.0084 0.4116 0.08 +0.0126 0.4074 0.08 +0.0168 0.4032 0.08 +0.021 0.399 0.08 +0.0252 0.3948 0.08 +0.0294 0.3906 0.08 +0.0336 0.3864 0.08 +0.0378 0.3822 0.08 +0.042 0.378 0.08 +0.0462 0.3738 0.08 +0.0504 0.3696 0.08 +0.0546 0.3654 0.08 +0.0588 0.3612 0.08 +0.063 0.357 0.08 +0.0672 0.3528 0.08 +0.0714 0.3486 0.08 +0.0756 0.3444 0.08 +0.0798 0.3402 0.08 +0.084 0.336 0.08 +0.0882 0.3318 0.08 +0.0924 0.3276 0.08 +0.0966 0.3234 0.08 +0.1008 0.3192 0.08 +0.105 0.315 0.08 +0.1092 0.3108 0.08 +0.1134 0.3066 0.08 +0.1176 0.3024 0.08 +0.1218 0.2982 0.08 +0.126 0.294 0.08 +0.1302 0.2898 0.08 +0.1344 0.2856 0.08 +0.1386 0.2814 0.08 +0.1428 0.2772 0.08 +0.147 0.273 0.08 +0.1512 0.2688 0.08 +0.1554 0.2646 0.08 +0.1596 0.2604 0.08 +0.1638 0.2562 0.08 +0.168 0.252 0.08 +0.1722 0.2478 0.08 +0.1764 0.2436 0.08 +0.1806 0.2394 0.08 +0.1848 0.2352 0.08 +0.189 0.231 0.08 +0.1932 0.2268 0.08 +0.1974 0.2226 0.08 +0.2016 0.2184 0.08 +0.2058 0.2142 0.08 +0.21 0.21 0.08 +0.2142 0.2058 0.08 +0.2184 0.2016 0.08 +0.2226 0.1974 0.08 +0.2268 0.1932 0.08 +0.231 0.189 0.08 +0.2352 0.1848 0.08 +0.2394 0.1806 0.08 +0.2436 0.1764 0.08 +0.2478 0.1722 0.08 +0.252 0.168 0.08 +0.2562 0.1638 0.08 +0.2604 0.1596 0.08 +0.2646 0.1554 0.08 +0.2688 0.1512 0.08 +0.273 0.147 0.08 +0.2772 0.1428 0.08 +0.2814 0.1386 0.08 +0.2856 0.1344 0.08 +0.2898 0.1302 0.08 +0.294 0.126 0.08 +0.2982 0.1218 0.08 +0.3024 0.1176 0.08 +0.3066 0.1134 0.08 +0.3108 0.1092 0.08 +0.315 0.105 0.08 +0.3192 0.1008 0.08 +0.3234 0.0966 0.08 +0.3276 0.0924 0.08 +0.3318 0.0882 0.08 +0.336 0.084 0.08 +0.3402 0.0798 0.08 +0.3444 0.0756 0.08 +0.3486 0.0714 0.08 +0.3528 0.0672 0.08 +0.357 0.063 0.08 +0.3612 0.0588 0.08 +0.3654 0.0546 0.08 +0.3696 0.0504 0.08 +0.3738 0.0462 0.08 +0.378 0.042 0.08 +0.3822 0.0378 0.08 +0.3864 0.0336 0.08 +0.3906 0.0294 0.08 +0.3948 0.0252 0.08 +0.399 0.021 0.08 +0.4032 0.0168 0.08 +0.4074 0.0126 0.08 +0.4116 0.0084 0.08 +0.4158 0.0042 0.08 +0 0.425 0.075 +0.00425 0.42075 0.075 +0.0085 0.4165 0.075 +0.01275 0.41225 0.075 +0.017 0.408 0.075 +0.02125 0.40375 0.075 +0.0255 0.3995 0.075 +0.02975 0.39525 0.075 +0.034 0.391 0.075 +0.03825 0.38675 0.075 +0.0425 0.3825 0.075 +0.04675 0.37825 0.075 +0.051 0.374 0.075 +0.05525 0.36975 0.075 +0.0595 0.3655 0.075 +0.06375 0.36125 0.075 +0.068 0.357 0.075 +0.07225 0.35275 0.075 +0.0765 0.3485 0.075 +0.08075 0.34425 0.075 +0.085 0.34 0.075 +0.08925 0.33575 0.075 +0.0935 0.3315 0.075 +0.09775 0.32725 0.075 +0.102 0.323 0.075 +0.10625 0.31875 0.075 +0.1105 0.3145 0.075 +0.11475 0.31025 0.075 +0.119 0.306 0.075 +0.12325 0.30175 0.075 +0.1275 0.2975 0.075 +0.13175 0.29325 0.075 +0.136 0.289 0.075 +0.14025 0.28475 0.075 +0.1445 0.2805 0.075 +0.14875 0.27625 0.075 +0.153 0.272 0.075 +0.15725 0.26775 0.075 +0.1615 0.2635 0.075 +0.16575 0.25925 0.075 +0.17 0.255 0.075 +0.17425 0.25075 0.075 +0.1785 0.2465 0.075 +0.18275 0.24225 0.075 +0.187 0.238 0.075 +0.19125 0.23375 0.075 +0.1955 0.2295 0.075 +0.19975 0.22525 0.075 +0.204 0.221 0.075 +0.20825 0.21675 0.075 +0.2125 0.2125 0.075 +0.21675 0.20825 0.075 +0.221 0.204 0.075 +0.22525 0.19975 0.075 +0.2295 0.1955 0.075 +0.23375 0.19125 0.075 +0.238 0.187 0.075 +0.24225 0.18275 0.075 +0.2465 0.1785 0.075 +0.25075 0.17425 0.075 +0.255 0.17 0.075 +0.25925 0.16575 0.075 +0.2635 0.1615 0.075 +0.26775 0.15725 0.075 +0.272 0.153 0.075 +0.27625 0.14875 0.075 +0.2805 0.1445 0.075 +0.28475 0.14025 0.075 +0.289 0.136 0.075 +0.29325 0.13175 0.075 +0.2975 0.1275 0.075 +0.30175 0.12325 0.075 +0.306 0.119 0.075 +0.31025 0.11475 0.075 +0.3145 0.1105 0.075 +0.31875 0.10625 0.075 +0.323 0.102 0.075 +0.32725 0.09775 0.075 +0.3315 0.0935 0.075 +0.33575 0.08925 0.075 +0.34 0.085 0.075 +0.34425 0.08075 0.075 +0.3485 0.0765 0.075 +0.35275 0.07225 0.075 +0.357 0.068 0.075 +0.36125 0.06375 0.075 +0.3655 0.0595 0.075 +0.36975 0.05525 0.075 +0.374 0.051 0.075 +0.37825 0.04675 0.075 +0.3825 0.0425 0.075 +0.38675 0.03825 0.075 +0.391 0.034 0.075 +0.39525 0.02975 0.075 +0.3995 0.0255 0.075 +0.40375 0.02125 0.075 +0.408 0.017 0.075 +0.41225 0.01275 0.075 +0.4165 0.0085 0.075 +0.42075 0.00425 0.075 +0 0.43 0.07 +0.0043 0.4257 0.07 +0.0086 0.4214 0.07 +0.0129 0.4171 0.07 +0.0172 0.4128 0.07 +0.0215 0.4085 0.07 +0.0258 0.4042 0.07 +0.0301 0.3999 0.07 +0.0344 0.3956 0.07 +0.0387 0.3913 0.07 +0.043 0.387 0.07 +0.0473 0.3827 0.07 +0.0516 0.3784 0.07 +0.0559 0.3741 0.07 +0.0602 0.3698 0.07 +0.0645 0.3655 0.07 +0.0688 0.3612 0.07 +0.0731 0.3569 0.07 +0.0774 0.3526 0.07 +0.0817 0.3483 0.07 +0.086 0.344 0.07 +0.0903 0.3397 0.07 +0.0946 0.3354 0.07 +0.0989 0.3311 0.07 +0.1032 0.3268 0.07 +0.1075 0.3225 0.07 +0.1118 0.3182 0.07 +0.1161 0.3139 0.07 +0.1204 0.3096 0.07 +0.1247 0.3053 0.07 +0.129 0.301 0.07 +0.1333 0.2967 0.07 +0.1376 0.2924 0.07 +0.1419 0.2881 0.07 +0.1462 0.2838 0.07 +0.1505 0.2795 0.07 +0.1548 0.2752 0.07 +0.1591 0.2709 0.07 +0.1634 0.2666 0.07 +0.1677 0.2623 0.07 +0.172 0.258 0.07 +0.1763 0.2537 0.07 +0.1806 0.2494 0.07 +0.1849 0.2451 0.07 +0.1892 0.2408 0.07 +0.1935 0.2365 0.07 +0.1978 0.2322 0.07 +0.2021 0.2279 0.07 +0.2064 0.2236 0.07 +0.2107 0.2193 0.07 +0.215 0.215 0.07 +0.2193 0.2107 0.07 +0.2236 0.2064 0.07 +0.2279 0.2021 0.07 +0.2322 0.1978 0.07 +0.2365 0.1935 0.07 +0.2408 0.1892 0.07 +0.2451 0.1849 0.07 +0.2494 0.1806 0.07 +0.2537 0.1763 0.07 +0.258 0.172 0.07 +0.2623 0.1677 0.07 +0.2666 0.1634 0.07 +0.2709 0.1591 0.07 +0.2752 0.1548 0.07 +0.2795 0.1505 0.07 +0.2838 0.1462 0.07 +0.2881 0.1419 0.07 +0.2924 0.1376 0.07 +0.2967 0.1333 0.07 +0.301 0.129 0.07 +0.3053 0.1247 0.07 +0.3096 0.1204 0.07 +0.3139 0.1161 0.07 +0.3182 0.1118 0.07 +0.3225 0.1075 0.07 +0.3268 0.1032 0.07 +0.3311 0.0989 0.07 +0.3354 0.0946 0.07 +0.3397 0.0903 0.07 +0.344 0.086 0.07 +0.3483 0.0817 0.07 +0.3526 0.0774 0.07 +0.3569 0.0731 0.07 +0.3612 0.0688 0.07 +0.3655 0.0645 0.07 +0.3698 0.0602 0.07 +0.3741 0.0559 0.07 +0.3784 0.0516 0.07 +0.3827 0.0473 0.07 +0.387 0.043 0.07 +0.3913 0.0387 0.07 +0.3956 0.0344 0.07 +0.3999 0.0301 0.07 +0.4042 0.0258 0.07 +0.4085 0.0215 0.07 +0.4128 0.0172 0.07 +0.4171 0.0129 0.07 +0.4214 0.0086 0.07 +0.4257 0.0043 0.07 +0 0.435 0.065 +0.00435 0.43065 0.065 +0.0087 0.4263 0.065 +0.01305 0.42195 0.065 +0.0174 0.4176 0.065 +0.02175 0.41325 0.065 +0.0261 0.4089 0.065 +0.03045 0.40455 0.065 +0.0348 0.4002 0.065 +0.03915 0.39585 0.065 +0.0435 0.3915 0.065 +0.04785 0.38715 0.065 +0.0522 0.3828 0.065 +0.05655 0.37845 0.065 +0.0609 0.3741 0.065 +0.06525 0.36975 0.065 +0.0696 0.3654 0.065 +0.07395 0.36105 0.065 +0.0783 0.3567 0.065 +0.08265 0.35235 0.065 +0.087 0.348 0.065 +0.09135 0.34365 0.065 +0.0957 0.3393 0.065 +0.10005 0.33495 0.065 +0.1044 0.3306 0.065 +0.10875 0.32625 0.065 +0.1131 0.3219 0.065 +0.11745 0.31755 0.065 +0.1218 0.3132 0.065 +0.12615 0.30885 0.065 +0.1305 0.3045 0.065 +0.13485 0.30015 0.065 +0.1392 0.2958 0.065 +0.14355 0.29145 0.065 +0.1479 0.2871 0.065 +0.15225 0.28275 0.065 +0.1566 0.2784 0.065 +0.16095 0.27405 0.065 +0.1653 0.2697 0.065 +0.16965 0.26535 0.065 +0.174 0.261 0.065 +0.17835 0.25665 0.065 +0.1827 0.2523 0.065 +0.18705 0.24795 0.065 +0.1914 0.2436 0.065 +0.19575 0.23925 0.065 +0.2001 0.2349 0.065 +0.20445 0.23055 0.065 +0.2088 0.2262 0.065 +0.21315 0.22185 0.065 +0.2175 0.2175 0.065 +0.22185 0.21315 0.065 +0.2262 0.2088 0.065 +0.23055 0.20445 0.065 +0.2349 0.2001 0.065 +0.23925 0.19575 0.065 +0.2436 0.1914 0.065 +0.24795 0.18705 0.065 +0.2523 0.1827 0.065 +0.25665 0.17835 0.065 +0.261 0.174 0.065 +0.26535 0.16965 0.065 +0.2697 0.1653 0.065 +0.27405 0.16095 0.065 +0.2784 0.1566 0.065 +0.28275 0.15225 0.065 +0.2871 0.1479 0.065 +0.29145 0.14355 0.065 +0.2958 0.1392 0.065 +0.30015 0.13485 0.065 +0.3045 0.1305 0.065 +0.30885 0.12615 0.065 +0.3132 0.1218 0.065 +0.31755 0.11745 0.065 +0.3219 0.1131 0.065 +0.32625 0.10875 0.065 +0.3306 0.1044 0.065 +0.33495 0.10005 0.065 +0.3393 0.0957 0.065 +0.34365 0.09135 0.065 +0.348 0.087 0.065 +0.35235 0.08265 0.065 +0.3567 0.0783 0.065 +0.36105 0.07395 0.065 +0.3654 0.0696 0.065 +0.36975 0.06525 0.065 +0.3741 0.0609 0.065 +0.37845 0.05655 0.065 +0.3828 0.0522 0.065 +0.38715 0.04785 0.065 +0.3915 0.0435 0.065 +0.39585 0.03915 0.065 +0.4002 0.0348 0.065 +0.40455 0.03045 0.065 +0.4089 0.0261 0.065 +0.41325 0.02175 0.065 +0.4176 0.0174 0.065 +0.42195 0.01305 0.065 +0.4263 0.0087 0.065 +0.43065 0.00435 0.065 +0 0.44 0.06 +0.0044 0.4356 0.06 +0.0088 0.4312 0.06 +0.0132 0.4268 0.06 +0.0176 0.4224 0.06 +0.022 0.418 0.06 +0.0264 0.4136 0.06 +0.0308 0.4092 0.06 +0.0352 0.4048 0.06 +0.0396 0.4004 0.06 +0.044 0.396 0.06 +0.0484 0.3916 0.06 +0.0528 0.3872 0.06 +0.0572 0.3828 0.06 +0.0616 0.3784 0.06 +0.066 0.374 0.06 +0.0704 0.3696 0.06 +0.0748 0.3652 0.06 +0.0792 0.3608 0.06 +0.0836 0.3564 0.06 +0.088 0.352 0.06 +0.0924 0.3476 0.06 +0.0968 0.3432 0.06 +0.1012 0.3388 0.06 +0.1056 0.3344 0.06 +0.11 0.33 0.06 +0.1144 0.3256 0.06 +0.1188 0.3212 0.06 +0.1232 0.3168 0.06 +0.1276 0.3124 0.06 +0.132 0.308 0.06 +0.1364 0.3036 0.06 +0.1408 0.2992 0.06 +0.1452 0.2948 0.06 +0.1496 0.2904 0.06 +0.154 0.286 0.06 +0.1584 0.2816 0.06 +0.1628 0.2772 0.06 +0.1672 0.2728 0.06 +0.1716 0.2684 0.06 +0.176 0.264 0.06 +0.1804 0.2596 0.06 +0.1848 0.2552 0.06 +0.1892 0.2508 0.06 +0.1936 0.2464 0.06 +0.198 0.242 0.06 +0.2024 0.2376 0.06 +0.2068 0.2332 0.06 +0.2112 0.2288 0.06 +0.2156 0.2244 0.06 +0.22 0.22 0.06 +0.2244 0.2156 0.06 +0.2288 0.2112 0.06 +0.2332 0.2068 0.06 +0.2376 0.2024 0.06 +0.242 0.198 0.06 +0.2464 0.1936 0.06 +0.2508 0.1892 0.06 +0.2552 0.1848 0.06 +0.2596 0.1804 0.06 +0.264 0.176 0.06 +0.2684 0.1716 0.06 +0.2728 0.1672 0.06 +0.2772 0.1628 0.06 +0.2816 0.1584 0.06 +0.286 0.154 0.06 +0.2904 0.1496 0.06 +0.2948 0.1452 0.06 +0.2992 0.1408 0.06 +0.3036 0.1364 0.06 +0.308 0.132 0.06 +0.3124 0.1276 0.06 +0.3168 0.1232 0.06 +0.3212 0.1188 0.06 +0.3256 0.1144 0.06 +0.33 0.11 0.06 +0.3344 0.1056 0.06 +0.3388 0.1012 0.06 +0.3432 0.0968 0.06 +0.3476 0.0924 0.06 +0.352 0.088 0.06 +0.3564 0.0836 0.06 +0.3608 0.0792 0.06 +0.3652 0.0748 0.06 +0.3696 0.0704 0.06 +0.374 0.066 0.06 +0.3784 0.0616 0.06 +0.3828 0.0572 0.06 +0.3872 0.0528 0.06 +0.3916 0.0484 0.06 +0.396 0.044 0.06 +0.4004 0.0396 0.06 +0.4048 0.0352 0.06 +0.4092 0.0308 0.06 +0.4136 0.0264 0.06 +0.418 0.022 0.06 +0.4224 0.0176 0.06 +0.4268 0.0132 0.06 +0.4312 0.0088 0.06 +0.4356 0.0044 0.06 +0 0.445 0.055 +0.00445 0.44055 0.055 +0.0089 0.4361 0.055 +0.01335 0.43165 0.055 +0.0178 0.4272 0.055 +0.02225 0.42275 0.055 +0.0267 0.4183 0.055 +0.03115 0.41385 0.055 +0.0356 0.4094 0.055 +0.04005 0.40495 0.055 +0.0445 0.4005 0.055 +0.04895 0.39605 0.055 +0.0534 0.3916 0.055 +0.05785 0.38715 0.055 +0.0623 0.3827 0.055 +0.06675 0.37825 0.055 +0.0712 0.3738 0.055 +0.07565 0.36935 0.055 +0.0801 0.3649 0.055 +0.08455 0.36045 0.055 +0.089 0.356 0.055 +0.09345 0.35155 0.055 +0.0979 0.3471 0.055 +0.10235 0.34265 0.055 +0.1068 0.3382 0.055 +0.11125 0.33375 0.055 +0.1157 0.3293 0.055 +0.12015 0.32485 0.055 +0.1246 0.3204 0.055 +0.12905 0.31595 0.055 +0.1335 0.3115 0.055 +0.13795 0.30705 0.055 +0.1424 0.3026 0.055 +0.14685 0.29815 0.055 +0.1513 0.2937 0.055 +0.15575 0.28925 0.055 +0.1602 0.2848 0.055 +0.16465 0.28035 0.055 +0.1691 0.2759 0.055 +0.17355 0.27145 0.055 +0.178 0.267 0.055 +0.18245 0.26255 0.055 +0.1869 0.2581 0.055 +0.19135 0.25365 0.055 +0.1958 0.2492 0.055 +0.20025 0.24475 0.055 +0.2047 0.2403 0.055 +0.20915 0.23585 0.055 +0.2136 0.2314 0.055 +0.21805 0.22695 0.055 +0.2225 0.2225 0.055 +0.22695 0.21805 0.055 +0.2314 0.2136 0.055 +0.23585 0.20915 0.055 +0.2403 0.2047 0.055 +0.24475 0.20025 0.055 +0.2492 0.1958 0.055 +0.25365 0.19135 0.055 +0.2581 0.1869 0.055 +0.26255 0.18245 0.055 +0.267 0.178 0.055 +0.27145 0.17355 0.055 +0.2759 0.1691 0.055 +0.28035 0.16465 0.055 +0.2848 0.1602 0.055 +0.28925 0.15575 0.055 +0.2937 0.1513 0.055 +0.29815 0.14685 0.055 +0.3026 0.1424 0.055 +0.30705 0.13795 0.055 +0.3115 0.1335 0.055 +0.31595 0.12905 0.055 +0.3204 0.1246 0.055 +0.32485 0.12015 0.055 +0.3293 0.1157 0.055 +0.33375 0.11125 0.055 +0.3382 0.1068 0.055 +0.34265 0.10235 0.055 +0.3471 0.0979 0.055 +0.35155 0.09345 0.055 +0.356 0.089 0.055 +0.36045 0.08455 0.055 +0.3649 0.0801 0.055 +0.36935 0.07565 0.055 +0.3738 0.0712 0.055 +0.37825 0.06675 0.055 +0.3827 0.0623 0.055 +0.38715 0.05785 0.055 +0.3916 0.0534 0.055 +0.39605 0.04895 0.055 +0.4005 0.0445 0.055 +0.40495 0.04005 0.055 +0.4094 0.0356 0.055 +0.41385 0.03115 0.055 +0.4183 0.0267 0.055 +0.42275 0.02225 0.055 +0.4272 0.0178 0.055 +0.43165 0.01335 0.055 +0.4361 0.0089 0.055 +0.44055 0.00445 0.055 +0 0.45 0.05 +0.0045 0.4455 0.05 +0.009 0.441 0.05 +0.0135 0.4365 0.05 +0.018 0.432 0.05 +0.0225 0.4275 0.05 +0.027 0.423 0.05 +0.0315 0.4185 0.05 +0.036 0.414 0.05 +0.0405 0.4095 0.05 +0.045 0.405 0.05 +0.0495 0.4005 0.05 +0.054 0.396 0.05 +0.0585 0.3915 0.05 +0.063 0.387 0.05 +0.0675 0.3825 0.05 +0.072 0.378 0.05 +0.0765 0.3735 0.05 +0.081 0.369 0.05 +0.0855 0.3645 0.05 +0.09 0.36 0.05 +0.0945 0.3555 0.05 +0.099 0.351 0.05 +0.1035 0.3465 0.05 +0.108 0.342 0.05 +0.1125 0.3375 0.05 +0.117 0.333 0.05 +0.1215 0.3285 0.05 +0.126 0.324 0.05 +0.1305 0.3195 0.05 +0.135 0.315 0.05 +0.1395 0.3105 0.05 +0.144 0.306 0.05 +0.1485 0.3015 0.05 +0.153 0.297 0.05 +0.1575 0.2925 0.05 +0.162 0.288 0.05 +0.1665 0.2835 0.05 +0.171 0.279 0.05 +0.1755 0.2745 0.05 +0.18 0.27 0.05 +0.1845 0.2655 0.05 +0.189 0.261 0.05 +0.1935 0.2565 0.05 +0.198 0.252 0.05 +0.2025 0.2475 0.05 +0.207 0.243 0.05 +0.2115 0.2385 0.05 +0.216 0.234 0.05 +0.2205 0.2295 0.05 +0.225 0.225 0.05 +0.2295 0.2205 0.05 +0.234 0.216 0.05 +0.2385 0.2115 0.05 +0.243 0.207 0.05 +0.2475 0.2025 0.05 +0.252 0.198 0.05 +0.2565 0.1935 0.05 +0.261 0.189 0.05 +0.2655 0.1845 0.05 +0.27 0.18 0.05 +0.2745 0.1755 0.05 +0.279 0.171 0.05 +0.2835 0.1665 0.05 +0.288 0.162 0.05 +0.2925 0.1575 0.05 +0.297 0.153 0.05 +0.3015 0.1485 0.05 +0.306 0.144 0.05 +0.3105 0.1395 0.05 +0.315 0.135 0.05 +0.3195 0.1305 0.05 +0.324 0.126 0.05 +0.3285 0.1215 0.05 +0.333 0.117 0.05 +0.3375 0.1125 0.05 +0.342 0.108 0.05 +0.3465 0.1035 0.05 +0.351 0.099 0.05 +0.3555 0.0945 0.05 +0.36 0.09 0.05 +0.3645 0.0855 0.05 +0.369 0.081 0.05 +0.3735 0.0765 0.05 +0.378 0.072 0.05 +0.3825 0.0675 0.05 +0.387 0.063 0.05 +0.3915 0.0585 0.05 +0.396 0.054 0.05 +0.4005 0.0495 0.05 +0.405 0.045 0.05 +0.4095 0.0405 0.05 +0.414 0.036 0.05 +0.4185 0.0315 0.05 +0.423 0.027 0.05 +0.4275 0.0225 0.05 +0.432 0.018 0.05 +0.4365 0.0135 0.05 +0.441 0.009 0.05 +0.4455 0.0045 0.05 +0 0.455 0.045 +0.00455 0.45045 0.045 +0.0091 0.4459 0.045 +0.01365 0.44135 0.045 +0.0182 0.4368 0.045 +0.02275 0.43225 0.045 +0.0273 0.4277 0.045 +0.03185 0.42315 0.045 +0.0364 0.4186 0.045 +0.04095 0.41405 0.045 +0.0455 0.4095 0.045 +0.05005 0.40495 0.045 +0.0546 0.4004 0.045 +0.05915 0.39585 0.045 +0.0637 0.3913 0.045 +0.06825 0.38675 0.045 +0.0728 0.3822 0.045 +0.07735 0.37765 0.045 +0.0819 0.3731 0.045 +0.08645 0.36855 0.045 +0.091 0.364 0.045 +0.09555 0.35945 0.045 +0.1001 0.3549 0.045 +0.10465 0.35035 0.045 +0.1092 0.3458 0.045 +0.11375 0.34125 0.045 +0.1183 0.3367 0.045 +0.12285 0.33215 0.045 +0.1274 0.3276 0.045 +0.13195 0.32305 0.045 +0.1365 0.3185 0.045 +0.14105 0.31395 0.045 +0.1456 0.3094 0.045 +0.15015 0.30485 0.045 +0.1547 0.3003 0.045 +0.15925 0.29575 0.045 +0.1638 0.2912 0.045 +0.16835 0.28665 0.045 +0.1729 0.2821 0.045 +0.17745 0.27755 0.045 +0.182 0.273 0.045 +0.18655 0.26845 0.045 +0.1911 0.2639 0.045 +0.19565 0.25935 0.045 +0.2002 0.2548 0.045 +0.20475 0.25025 0.045 +0.2093 0.2457 0.045 +0.21385 0.24115 0.045 +0.2184 0.2366 0.045 +0.22295 0.23205 0.045 +0.2275 0.2275 0.045 +0.23205 0.22295 0.045 +0.2366 0.2184 0.045 +0.24115 0.21385 0.045 +0.2457 0.2093 0.045 +0.25025 0.20475 0.045 +0.2548 0.2002 0.045 +0.25935 0.19565 0.045 +0.2639 0.1911 0.045 +0.26845 0.18655 0.045 +0.273 0.182 0.045 +0.27755 0.17745 0.045 +0.2821 0.1729 0.045 +0.28665 0.16835 0.045 +0.2912 0.1638 0.045 +0.29575 0.15925 0.045 +0.3003 0.1547 0.045 +0.30485 0.15015 0.045 +0.3094 0.1456 0.045 +0.31395 0.14105 0.045 +0.3185 0.1365 0.045 +0.32305 0.13195 0.045 +0.3276 0.1274 0.045 +0.33215 0.12285 0.045 +0.3367 0.1183 0.045 +0.34125 0.11375 0.045 +0.3458 0.1092 0.045 +0.35035 0.10465 0.045 +0.3549 0.1001 0.045 +0.35945 0.09555 0.045 +0.364 0.091 0.045 +0.36855 0.08645 0.045 +0.3731 0.0819 0.045 +0.37765 0.07735 0.045 +0.3822 0.0728 0.045 +0.38675 0.06825 0.045 +0.3913 0.0637 0.045 +0.39585 0.05915 0.045 +0.4004 0.0546 0.045 +0.40495 0.05005 0.045 +0.4095 0.0455 0.045 +0.41405 0.04095 0.045 +0.4186 0.0364 0.045 +0.42315 0.03185 0.045 +0.4277 0.0273 0.045 +0.43225 0.02275 0.045 +0.4368 0.0182 0.045 +0.44135 0.01365 0.045 +0.4459 0.0091 0.045 +0.45045 0.00455 0.045 +0 0.46 0.04 +0.0046 0.4554 0.04 +0.0092 0.4508 0.04 +0.0138 0.4462 0.04 +0.0184 0.4416 0.04 +0.023 0.437 0.04 +0.0276 0.4324 0.04 +0.0322 0.4278 0.04 +0.0368 0.4232 0.04 +0.0414 0.4186 0.04 +0.046 0.414 0.04 +0.0506 0.4094 0.04 +0.0552 0.4048 0.04 +0.0598 0.4002 0.04 +0.0644 0.3956 0.04 +0.069 0.391 0.04 +0.0736 0.3864 0.04 +0.0782 0.3818 0.04 +0.0828 0.3772 0.04 +0.0874 0.3726 0.04 +0.092 0.368 0.04 +0.0966 0.3634 0.04 +0.1012 0.3588 0.04 +0.1058 0.3542 0.04 +0.1104 0.3496 0.04 +0.115 0.345 0.04 +0.1196 0.3404 0.04 +0.1242 0.3358 0.04 +0.1288 0.3312 0.04 +0.1334 0.3266 0.04 +0.138 0.322 0.04 +0.1426 0.3174 0.04 +0.1472 0.3128 0.04 +0.1518 0.3082 0.04 +0.1564 0.3036 0.04 +0.161 0.299 0.04 +0.1656 0.2944 0.04 +0.1702 0.2898 0.04 +0.1748 0.2852 0.04 +0.1794 0.2806 0.04 +0.184 0.276 0.04 +0.1886 0.2714 0.04 +0.1932 0.2668 0.04 +0.1978 0.2622 0.04 +0.2024 0.2576 0.04 +0.207 0.253 0.04 +0.2116 0.2484 0.04 +0.2162 0.2438 0.04 +0.2208 0.2392 0.04 +0.2254 0.2346 0.04 +0.23 0.23 0.04 +0.2346 0.2254 0.04 +0.2392 0.2208 0.04 +0.2438 0.2162 0.04 +0.2484 0.2116 0.04 +0.253 0.207 0.04 +0.2576 0.2024 0.04 +0.2622 0.1978 0.04 +0.2668 0.1932 0.04 +0.2714 0.1886 0.04 +0.276 0.184 0.04 +0.2806 0.1794 0.04 +0.2852 0.1748 0.04 +0.2898 0.1702 0.04 +0.2944 0.1656 0.04 +0.299 0.161 0.04 +0.3036 0.1564 0.04 +0.3082 0.1518 0.04 +0.3128 0.1472 0.04 +0.3174 0.1426 0.04 +0.322 0.138 0.04 +0.3266 0.1334 0.04 +0.3312 0.1288 0.04 +0.3358 0.1242 0.04 +0.3404 0.1196 0.04 +0.345 0.115 0.04 +0.3496 0.1104 0.04 +0.3542 0.1058 0.04 +0.3588 0.1012 0.04 +0.3634 0.0966 0.04 +0.368 0.092 0.04 +0.3726 0.0874 0.04 +0.3772 0.0828 0.04 +0.3818 0.0782 0.04 +0.3864 0.0736 0.04 +0.391 0.069 0.04 +0.3956 0.0644 0.04 +0.4002 0.0598 0.04 +0.4048 0.0552 0.04 +0.4094 0.0506 0.04 +0.414 0.046 0.04 +0.4186 0.0414 0.04 +0.4232 0.0368 0.04 +0.4278 0.0322 0.04 +0.4324 0.0276 0.04 +0.437 0.023 0.04 +0.4416 0.0184 0.04 +0.4462 0.0138 0.04 +0.4508 0.0092 0.04 +0.4554 0.0046 0.04 +0 0.465 0.035 +0.00465 0.46035 0.035 +0.0093 0.4557 0.035 +0.01395 0.45105 0.035 +0.0186 0.4464 0.035 +0.02325 0.44175 0.035 +0.0279 0.4371 0.035 +0.03255 0.43245 0.035 +0.0372 0.4278 0.035 +0.04185 0.42315 0.035 +0.0465 0.4185 0.035 +0.05115 0.41385 0.035 +0.0558 0.4092 0.035 +0.06045 0.40455 0.035 +0.0651 0.3999 0.035 +0.06975 0.39525 0.035 +0.0744 0.3906 0.035 +0.07905 0.38595 0.035 +0.0837 0.3813 0.035 +0.08835 0.37665 0.035 +0.093 0.372 0.035 +0.09765 0.36735 0.035 +0.1023 0.3627 0.035 +0.10695 0.35805 0.035 +0.1116 0.3534 0.035 +0.11625 0.34875 0.035 +0.1209 0.3441 0.035 +0.12555 0.33945 0.035 +0.1302 0.3348 0.035 +0.13485 0.33015 0.035 +0.1395 0.3255 0.035 +0.14415 0.32085 0.035 +0.1488 0.3162 0.035 +0.15345 0.31155 0.035 +0.1581 0.3069 0.035 +0.16275 0.30225 0.035 +0.1674 0.2976 0.035 +0.17205 0.29295 0.035 +0.1767 0.2883 0.035 +0.18135 0.28365 0.035 +0.186 0.279 0.035 +0.19065 0.27435 0.035 +0.1953 0.2697 0.035 +0.19995 0.26505 0.035 +0.2046 0.2604 0.035 +0.20925 0.25575 0.035 +0.2139 0.2511 0.035 +0.21855 0.24645 0.035 +0.2232 0.2418 0.035 +0.22785 0.23715 0.035 +0.2325 0.2325 0.035 +0.23715 0.22785 0.035 +0.2418 0.2232 0.035 +0.24645 0.21855 0.035 +0.2511 0.2139 0.035 +0.25575 0.20925 0.035 +0.2604 0.2046 0.035 +0.26505 0.19995 0.035 +0.2697 0.1953 0.035 +0.27435 0.19065 0.035 +0.279 0.186 0.035 +0.28365 0.18135 0.035 +0.2883 0.1767 0.035 +0.29295 0.17205 0.035 +0.2976 0.1674 0.035 +0.30225 0.16275 0.035 +0.3069 0.1581 0.035 +0.31155 0.15345 0.035 +0.3162 0.1488 0.035 +0.32085 0.14415 0.035 +0.3255 0.1395 0.035 +0.33015 0.13485 0.035 +0.3348 0.1302 0.035 +0.33945 0.12555 0.035 +0.3441 0.1209 0.035 +0.34875 0.11625 0.035 +0.3534 0.1116 0.035 +0.35805 0.10695 0.035 +0.3627 0.1023 0.035 +0.36735 0.09765 0.035 +0.372 0.093 0.035 +0.37665 0.08835 0.035 +0.3813 0.0837 0.035 +0.38595 0.07905 0.035 +0.3906 0.0744 0.035 +0.39525 0.06975 0.035 +0.3999 0.0651 0.035 +0.40455 0.06045 0.035 +0.4092 0.0558 0.035 +0.41385 0.05115 0.035 +0.4185 0.0465 0.035 +0.42315 0.04185 0.035 +0.4278 0.0372 0.035 +0.43245 0.03255 0.035 +0.4371 0.0279 0.035 +0.44175 0.02325 0.035 +0.4464 0.0186 0.035 +0.45105 0.01395 0.035 +0.4557 0.0093 0.035 +0.46035 0.00465 0.035 +0 0.47 0.03 +0.0047 0.4653 0.03 +0.0094 0.4606 0.03 +0.0141 0.4559 0.03 +0.0188 0.4512 0.03 +0.0235 0.4465 0.03 +0.0282 0.4418 0.03 +0.0329 0.4371 0.03 +0.0376 0.4324 0.03 +0.0423 0.4277 0.03 +0.047 0.423 0.03 +0.0517 0.4183 0.03 +0.0564 0.4136 0.03 +0.0611 0.4089 0.03 +0.0658 0.4042 0.03 +0.0705 0.3995 0.03 +0.0752 0.3948 0.03 +0.0799 0.3901 0.03 +0.0846 0.3854 0.03 +0.0893 0.3807 0.03 +0.094 0.376 0.03 +0.0987 0.3713 0.03 +0.1034 0.3666 0.03 +0.1081 0.3619 0.03 +0.1128 0.3572 0.03 +0.1175 0.3525 0.03 +0.1222 0.3478 0.03 +0.1269 0.3431 0.03 +0.1316 0.3384 0.03 +0.1363 0.3337 0.03 +0.141 0.329 0.03 +0.1457 0.3243 0.03 +0.1504 0.3196 0.03 +0.1551 0.3149 0.03 +0.1598 0.3102 0.03 +0.1645 0.3055 0.03 +0.1692 0.3008 0.03 +0.1739 0.2961 0.03 +0.1786 0.2914 0.03 +0.1833 0.2867 0.03 +0.188 0.282 0.03 +0.1927 0.2773 0.03 +0.1974 0.2726 0.03 +0.2021 0.2679 0.03 +0.2068 0.2632 0.03 +0.2115 0.2585 0.03 +0.2162 0.2538 0.03 +0.2209 0.2491 0.03 +0.2256 0.2444 0.03 +0.2303 0.2397 0.03 +0.235 0.235 0.03 +0.2397 0.2303 0.03 +0.2444 0.2256 0.03 +0.2491 0.2209 0.03 +0.2538 0.2162 0.03 +0.2585 0.2115 0.03 +0.2632 0.2068 0.03 +0.2679 0.2021 0.03 +0.2726 0.1974 0.03 +0.2773 0.1927 0.03 +0.282 0.188 0.03 +0.2867 0.1833 0.03 +0.2914 0.1786 0.03 +0.2961 0.1739 0.03 +0.3008 0.1692 0.03 +0.3055 0.1645 0.03 +0.3102 0.1598 0.03 +0.3149 0.1551 0.03 +0.3196 0.1504 0.03 +0.3243 0.1457 0.03 +0.329 0.141 0.03 +0.3337 0.1363 0.03 +0.3384 0.1316 0.03 +0.3431 0.1269 0.03 +0.3478 0.1222 0.03 +0.3525 0.1175 0.03 +0.3572 0.1128 0.03 +0.3619 0.1081 0.03 +0.3666 0.1034 0.03 +0.3713 0.0987 0.03 +0.376 0.094 0.03 +0.3807 0.0893 0.03 +0.3854 0.0846 0.03 +0.3901 0.0799 0.03 +0.3948 0.0752 0.03 +0.3995 0.0705 0.03 +0.4042 0.0658 0.03 +0.4089 0.0611 0.03 +0.4136 0.0564 0.03 +0.4183 0.0517 0.03 +0.423 0.047 0.03 +0.4277 0.0423 0.03 +0.4324 0.0376 0.03 +0.4371 0.0329 0.03 +0.4418 0.0282 0.03 +0.4465 0.0235 0.03 +0.4512 0.0188 0.03 +0.4559 0.0141 0.03 +0.4606 0.0094 0.03 +0.4653 0.0047 0.03 +0 0.475 0.025 +0.00475 0.47025 0.025 +0.0095 0.4655 0.025 +0.01425 0.46075 0.025 +0.019 0.456 0.025 +0.02375 0.45125 0.025 +0.0285 0.4465 0.025 +0.03325 0.44175 0.025 +0.038 0.437 0.025 +0.04275 0.43225 0.025 +0.0475 0.4275 0.025 +0.05225 0.42275 0.025 +0.057 0.418 0.025 +0.06175 0.41325 0.025 +0.0665 0.4085 0.025 +0.07125 0.40375 0.025 +0.076 0.399 0.025 +0.08075 0.39425 0.025 +0.0855 0.3895 0.025 +0.09025 0.38475 0.025 +0.095 0.38 0.025 +0.09975 0.37525 0.025 +0.1045 0.3705 0.025 +0.10925 0.36575 0.025 +0.114 0.361 0.025 +0.11875 0.35625 0.025 +0.1235 0.3515 0.025 +0.12825 0.34675 0.025 +0.133 0.342 0.025 +0.13775 0.33725 0.025 +0.1425 0.3325 0.025 +0.14725 0.32775 0.025 +0.152 0.323 0.025 +0.15675 0.31825 0.025 +0.1615 0.3135 0.025 +0.16625 0.30875 0.025 +0.171 0.304 0.025 +0.17575 0.29925 0.025 +0.1805 0.2945 0.025 +0.18525 0.28975 0.025 +0.19 0.285 0.025 +0.19475 0.28025 0.025 +0.1995 0.2755 0.025 +0.20425 0.27075 0.025 +0.209 0.266 0.025 +0.21375 0.26125 0.025 +0.2185 0.2565 0.025 +0.22325 0.25175 0.025 +0.228 0.247 0.025 +0.23275 0.24225 0.025 +0.2375 0.2375 0.025 +0.24225 0.23275 0.025 +0.247 0.228 0.025 +0.25175 0.22325 0.025 +0.2565 0.2185 0.025 +0.26125 0.21375 0.025 +0.266 0.209 0.025 +0.27075 0.20425 0.025 +0.2755 0.1995 0.025 +0.28025 0.19475 0.025 +0.285 0.19 0.025 +0.28975 0.18525 0.025 +0.2945 0.1805 0.025 +0.29925 0.17575 0.025 +0.304 0.171 0.025 +0.30875 0.16625 0.025 +0.3135 0.1615 0.025 +0.31825 0.15675 0.025 +0.323 0.152 0.025 +0.32775 0.14725 0.025 +0.3325 0.1425 0.025 +0.33725 0.13775 0.025 +0.342 0.133 0.025 +0.34675 0.12825 0.025 +0.3515 0.1235 0.025 +0.35625 0.11875 0.025 +0.361 0.114 0.025 +0.36575 0.10925 0.025 +0.3705 0.1045 0.025 +0.37525 0.09975 0.025 +0.38 0.095 0.025 +0.38475 0.09025 0.025 +0.3895 0.0855 0.025 +0.39425 0.08075 0.025 +0.399 0.076 0.025 +0.40375 0.07125 0.025 +0.4085 0.0665 0.025 +0.41325 0.06175 0.025 +0.418 0.057 0.025 +0.42275 0.05225 0.025 +0.4275 0.0475 0.025 +0.43225 0.04275 0.025 +0.437 0.038 0.025 +0.44175 0.03325 0.025 +0.4465 0.0285 0.025 +0.45125 0.02375 0.025 +0.456 0.019 0.025 +0.46075 0.01425 0.025 +0.4655 0.0095 0.025 +0.47025 0.00475 0.025 +0 0.48 0.02 +0.0048 0.4752 0.02 +0.0096 0.4704 0.02 +0.0144 0.4656 0.02 +0.0192 0.4608 0.02 +0.024 0.456 0.02 +0.0288 0.4512 0.02 +0.0336 0.4464 0.02 +0.0384 0.4416 0.02 +0.0432 0.4368 0.02 +0.048 0.432 0.02 +0.0528 0.4272 0.02 +0.0576 0.4224 0.02 +0.0624 0.4176 0.02 +0.0672 0.4128 0.02 +0.072 0.408 0.02 +0.0768 0.4032 0.02 +0.0816 0.3984 0.02 +0.0864 0.3936 0.02 +0.0912 0.3888 0.02 +0.096 0.384 0.02 +0.1008 0.3792 0.02 +0.1056 0.3744 0.02 +0.1104 0.3696 0.02 +0.1152 0.3648 0.02 +0.12 0.36 0.02 +0.1248 0.3552 0.02 +0.1296 0.3504 0.02 +0.1344 0.3456 0.02 +0.1392 0.3408 0.02 +0.144 0.336 0.02 +0.1488 0.3312 0.02 +0.1536 0.3264 0.02 +0.1584 0.3216 0.02 +0.1632 0.3168 0.02 +0.168 0.312 0.02 +0.1728 0.3072 0.02 +0.1776 0.3024 0.02 +0.1824 0.2976 0.02 +0.1872 0.2928 0.02 +0.192 0.288 0.02 +0.1968 0.2832 0.02 +0.2016 0.2784 0.02 +0.2064 0.2736 0.02 +0.2112 0.2688 0.02 +0.216 0.264 0.02 +0.2208 0.2592 0.02 +0.2256 0.2544 0.02 +0.2304 0.2496 0.02 +0.2352 0.2448 0.02 +0.24 0.24 0.02 +0.2448 0.2352 0.02 +0.2496 0.2304 0.02 +0.2544 0.2256 0.02 +0.2592 0.2208 0.02 +0.264 0.216 0.02 +0.2688 0.2112 0.02 +0.2736 0.2064 0.02 +0.2784 0.2016 0.02 +0.2832 0.1968 0.02 +0.288 0.192 0.02 +0.2928 0.1872 0.02 +0.2976 0.1824 0.02 +0.3024 0.1776 0.02 +0.3072 0.1728 0.02 +0.312 0.168 0.02 +0.3168 0.1632 0.02 +0.3216 0.1584 0.02 +0.3264 0.1536 0.02 +0.3312 0.1488 0.02 +0.336 0.144 0.02 +0.3408 0.1392 0.02 +0.3456 0.1344 0.02 +0.3504 0.1296 0.02 +0.3552 0.1248 0.02 +0.36 0.12 0.02 +0.3648 0.1152 0.02 +0.3696 0.1104 0.02 +0.3744 0.1056 0.02 +0.3792 0.1008 0.02 +0.384 0.096 0.02 +0.3888 0.0912 0.02 +0.3936 0.0864 0.02 +0.3984 0.0816 0.02 +0.4032 0.0768 0.02 +0.408 0.072 0.02 +0.4128 0.0672 0.02 +0.4176 0.0624 0.02 +0.4224 0.0576 0.02 +0.4272 0.0528 0.02 +0.432 0.048 0.02 +0.4368 0.0432 0.02 +0.4416 0.0384 0.02 +0.4464 0.0336 0.02 +0.4512 0.0288 0.02 +0.456 0.024 0.02 +0.4608 0.0192 0.02 +0.4656 0.0144 0.02 +0.4704 0.0096 0.02 +0.4752 0.0048 0.02 +0 0.485 0.015 +0.00485 0.48015 0.015 +0.0097 0.4753 0.015 +0.01455 0.47045 0.015 +0.0194 0.4656 0.015 +0.02425 0.46075 0.015 +0.0291 0.4559 0.015 +0.03395 0.45105 0.015 +0.0388 0.4462 0.015 +0.04365 0.44135 0.015 +0.0485 0.4365 0.015 +0.05335 0.43165 0.015 +0.0582 0.4268 0.015 +0.06305 0.42195 0.015 +0.0679 0.4171 0.015 +0.07275 0.41225 0.015 +0.0776 0.4074 0.015 +0.08245 0.40255 0.015 +0.0873 0.3977 0.015 +0.09215 0.39285 0.015 +0.097 0.388 0.015 +0.10185 0.38315 0.015 +0.1067 0.3783 0.015 +0.11155 0.37345 0.015 +0.1164 0.3686 0.015 +0.12125 0.36375 0.015 +0.1261 0.3589 0.015 +0.13095 0.35405 0.015 +0.1358 0.3492 0.015 +0.14065 0.34435 0.015 +0.1455 0.3395 0.015 +0.15035 0.33465 0.015 +0.1552 0.3298 0.015 +0.16005 0.32495 0.015 +0.1649 0.3201 0.015 +0.16975 0.31525 0.015 +0.1746 0.3104 0.015 +0.17945 0.30555 0.015 +0.1843 0.3007 0.015 +0.18915 0.29585 0.015 +0.194 0.291 0.015 +0.19885 0.28615 0.015 +0.2037 0.2813 0.015 +0.20855 0.27645 0.015 +0.2134 0.2716 0.015 +0.21825 0.26675 0.015 +0.2231 0.2619 0.015 +0.22795 0.25705 0.015 +0.2328 0.2522 0.015 +0.23765 0.24735 0.015 +0.2425 0.2425 0.015 +0.24735 0.23765 0.015 +0.2522 0.2328 0.015 +0.25705 0.22795 0.015 +0.2619 0.2231 0.015 +0.26675 0.21825 0.015 +0.2716 0.2134 0.015 +0.27645 0.20855 0.015 +0.2813 0.2037 0.015 +0.28615 0.19885 0.015 +0.291 0.194 0.015 +0.29585 0.18915 0.015 +0.3007 0.1843 0.015 +0.30555 0.17945 0.015 +0.3104 0.1746 0.015 +0.31525 0.16975 0.015 +0.3201 0.1649 0.015 +0.32495 0.16005 0.015 +0.3298 0.1552 0.015 +0.33465 0.15035 0.015 +0.3395 0.1455 0.015 +0.34435 0.14065 0.015 +0.3492 0.1358 0.015 +0.35405 0.13095 0.015 +0.3589 0.1261 0.015 +0.36375 0.12125 0.015 +0.3686 0.1164 0.015 +0.37345 0.11155 0.015 +0.3783 0.1067 0.015 +0.38315 0.10185 0.015 +0.388 0.097 0.015 +0.39285 0.09215 0.015 +0.3977 0.0873 0.015 +0.40255 0.08245 0.015 +0.4074 0.0776 0.015 +0.41225 0.07275 0.015 +0.4171 0.0679 0.015 +0.42195 0.06305 0.015 +0.4268 0.0582 0.015 +0.43165 0.05335 0.015 +0.4365 0.0485 0.015 +0.44135 0.04365 0.015 +0.4462 0.0388 0.015 +0.45105 0.03395 0.015 +0.4559 0.0291 0.015 +0.46075 0.02425 0.015 +0.4656 0.0194 0.015 +0.47045 0.01455 0.015 +0.4753 0.0097 0.015 +0.48015 0.00485 0.015 +0 0.49 0.01 +0.0049 0.4851 0.01 +0.0098 0.4802 0.01 +0.0147 0.4753 0.01 +0.0196 0.4704 0.01 +0.0245 0.4655 0.01 +0.0294 0.4606 0.01 +0.0343 0.4557 0.01 +0.0392 0.4508 0.01 +0.0441 0.4459 0.01 +0.049 0.441 0.01 +0.0539 0.4361 0.01 +0.0588 0.4312 0.01 +0.0637 0.4263 0.01 +0.0686 0.4214 0.01 +0.0735 0.4165 0.01 +0.0784 0.4116 0.01 +0.0833 0.4067 0.01 +0.0882 0.4018 0.01 +0.0931 0.3969 0.01 +0.098 0.392 0.01 +0.1029 0.3871 0.01 +0.1078 0.3822 0.01 +0.1127 0.3773 0.01 +0.1176 0.3724 0.01 +0.1225 0.3675 0.01 +0.1274 0.3626 0.01 +0.1323 0.3577 0.01 +0.1372 0.3528 0.01 +0.1421 0.3479 0.01 +0.147 0.343 0.01 +0.1519 0.3381 0.01 +0.1568 0.3332 0.01 +0.1617 0.3283 0.01 +0.1666 0.3234 0.01 +0.1715 0.3185 0.01 +0.1764 0.3136 0.01 +0.1813 0.3087 0.01 +0.1862 0.3038 0.01 +0.1911 0.2989 0.01 +0.196 0.294 0.01 +0.2009 0.2891 0.01 +0.2058 0.2842 0.01 +0.2107 0.2793 0.01 +0.2156 0.2744 0.01 +0.2205 0.2695 0.01 +0.2254 0.2646 0.01 +0.2303 0.2597 0.01 +0.2352 0.2548 0.01 +0.2401 0.2499 0.01 +0.245 0.245 0.01 +0.2499 0.2401 0.01 +0.2548 0.2352 0.01 +0.2597 0.2303 0.01 +0.2646 0.2254 0.01 +0.2695 0.2205 0.01 +0.2744 0.2156 0.01 +0.2793 0.2107 0.01 +0.2842 0.2058 0.01 +0.2891 0.2009 0.01 +0.294 0.196 0.01 +0.2989 0.1911 0.01 +0.3038 0.1862 0.01 +0.3087 0.1813 0.01 +0.3136 0.1764 0.01 +0.3185 0.1715 0.01 +0.3234 0.1666 0.01 +0.3283 0.1617 0.01 +0.3332 0.1568 0.01 +0.3381 0.1519 0.01 +0.343 0.147 0.01 +0.3479 0.1421 0.01 +0.3528 0.1372 0.01 +0.3577 0.1323 0.01 +0.3626 0.1274 0.01 +0.3675 0.1225 0.01 +0.3724 0.1176 0.01 +0.3773 0.1127 0.01 +0.3822 0.1078 0.01 +0.3871 0.1029 0.01 +0.392 0.098 0.01 +0.3969 0.0931 0.01 +0.4018 0.0882 0.01 +0.4067 0.0833 0.01 +0.4116 0.0784 0.01 +0.4165 0.0735 0.01 +0.4214 0.0686 0.01 +0.4263 0.0637 0.01 +0.4312 0.0588 0.01 +0.4361 0.0539 0.01 +0.441 0.049 0.01 +0.4459 0.0441 0.01 +0.4508 0.0392 0.01 +0.4557 0.0343 0.01 +0.4606 0.0294 0.01 +0.4655 0.0245 0.01 +0.4704 0.0196 0.01 +0.4753 0.0147 0.01 +0.4802 0.0098 0.01 +0.4851 0.0049 0.01 +0 0.495 0.005 +0.00495 0.49005 0.005 +0.0099 0.4851 0.005 +0.01485 0.48015 0.005 +0.0198 0.4752 0.005 +0.02475 0.47025 0.005 +0.0297 0.4653 0.005 +0.03465 0.46035 0.005 +0.0396 0.4554 0.005 +0.04455 0.45045 0.005 +0.0495 0.4455 0.005 +0.05445 0.44055 0.005 +0.0594 0.4356 0.005 +0.06435 0.43065 0.005 +0.0693 0.4257 0.005 +0.07425 0.42075 0.005 +0.0792 0.4158 0.005 +0.08415 0.41085 0.005 +0.0891 0.4059 0.005 +0.09405 0.40095 0.005 +0.099 0.396 0.005 +0.10395 0.39105 0.005 +0.1089 0.3861 0.005 +0.11385 0.38115 0.005 +0.1188 0.3762 0.005 +0.12375 0.37125 0.005 +0.1287 0.3663 0.005 +0.13365 0.36135 0.005 +0.1386 0.3564 0.005 +0.14355 0.35145 0.005 +0.1485 0.3465 0.005 +0.15345 0.34155 0.005 +0.1584 0.3366 0.005 +0.16335 0.33165 0.005 +0.1683 0.3267 0.005 +0.17325 0.32175 0.005 +0.1782 0.3168 0.005 +0.18315 0.31185 0.005 +0.1881 0.3069 0.005 +0.19305 0.30195 0.005 +0.198 0.297 0.005 +0.20295 0.29205 0.005 +0.2079 0.2871 0.005 +0.21285 0.28215 0.005 +0.2178 0.2772 0.005 +0.22275 0.27225 0.005 +0.2277 0.2673 0.005 +0.23265 0.26235 0.005 +0.2376 0.2574 0.005 +0.24255 0.25245 0.005 +0.2475 0.2475 0.005 +0.25245 0.24255 0.005 +0.2574 0.2376 0.005 +0.26235 0.23265 0.005 +0.2673 0.2277 0.005 +0.27225 0.22275 0.005 +0.2772 0.2178 0.005 +0.28215 0.21285 0.005 +0.2871 0.2079 0.005 +0.29205 0.20295 0.005 +0.297 0.198 0.005 +0.30195 0.19305 0.005 +0.3069 0.1881 0.005 +0.31185 0.18315 0.005 +0.3168 0.1782 0.005 +0.32175 0.17325 0.005 +0.3267 0.1683 0.005 +0.33165 0.16335 0.005 +0.3366 0.1584 0.005 +0.34155 0.15345 0.005 +0.3465 0.1485 0.005 +0.35145 0.14355 0.005 +0.3564 0.1386 0.005 +0.36135 0.13365 0.005 +0.3663 0.1287 0.005 +0.37125 0.12375 0.005 +0.3762 0.1188 0.005 +0.38115 0.11385 0.005 +0.3861 0.1089 0.005 +0.39105 0.10395 0.005 +0.396 0.099 0.005 +0.40095 0.09405 0.005 +0.4059 0.0891 0.005 +0.41085 0.08415 0.005 +0.4158 0.0792 0.005 +0.42075 0.07425 0.005 +0.4257 0.0693 0.005 +0.43065 0.06435 0.005 +0.4356 0.0594 0.005 +0.44055 0.05445 0.005 +0.4455 0.0495 0.005 +0.45045 0.04455 0.005 +0.4554 0.0396 0.005 +0.46035 0.03465 0.005 +0.4653 0.0297 0.005 +0.47025 0.02475 0.005 +0.4752 0.0198 0.005 +0.48015 0.01485 0.005 +0.4851 0.0099 0.005 +0.49005 0.00495 0.005 diff --git a/resources/data/ZDT1.pf b/jmetal/problem/resources/ZDT1.pf similarity index 100% rename from resources/data/ZDT1.pf rename to jmetal/problem/resources/ZDT1.pf diff --git a/jmetal/problem/resources/ZDT2.pf b/jmetal/problem/resources/ZDT2.pf new file mode 100644 index 00000000..9df822e4 --- /dev/null +++ b/jmetal/problem/resources/ZDT2.pf @@ -0,0 +1,1000 @@ +0 1 +0.003754873 0.999985901 +0.00563231 0.999968277 +0.007200271 0.999948156 +0.008597509 0.999926083 +0.009882778 0.999902331 +0.011102102 0.999876743 +0.012264475 0.999849583 +0.013371765 0.999821196 +0.014455677 0.999791033 +0.015498951 0.999759783 +0.016519826 0.999727095 +0.017509158 0.999693429 +0.018479218 0.999658519 +0.019438356 0.99962215 +0.020399442 0.999583863 +0.021350237 0.999544167 +0.022279862 0.999503608 +0.023213525 0.999461132 +0.024128412 0.99941782 +0.025054514 0.999372271 +0.0259635 0.999325897 +0.026883532 0.999277276 +0.027787821 0.999227837 +0.028698894 0.999176374 +0.029595506 0.999124106 +0.030500201 0.999069738 +0.031391478 0.999014575 +0.032299982 0.998956711 +0.03319571 0.998898045 +0.034102435 0.998837024 +0.035015421 0.99877392 +0.035916506 0.998710005 +0.036828477 0.998643663 +0.037729156 0.998576511 +0.038623319 0.998508239 +0.039534786 0.998437001 +0.040435746 0.99836495 +0.041383829 0.998287379 +0.042321051 0.998208929 +0.043259865 0.998128584 +0.044188493 0.998047377 +0.045127464 0.997963512 +0.046056667 0.997878783 +0.04699368 0.997791594 +0.047928593 0.99770285 +0.048854387 0.997613249 +0.049804185 0.997519543 +0.050755861 0.997423843 +0.051698616 0.997327253 +0.052643509 0.997228661 +0.053600651 0.99712697 +0.054549248 0.99702438 +0.055491619 0.99692068 +0.056449778 0.996813423 +0.057399805 0.996705262 +0.058367844 0.996593195 +0.059337093 0.996479109 +0.060298425 0.9963641 +0.061262107 0.996246954 +0.062218209 0.996128895 +0.063192226 0.996006743 +0.064158736 0.995883657 +0.065127027 0.99575847 +0.066097858 0.995631073 +0.06706156 0.995502747 +0.068027936 0.9953722 +0.06900275 0.995238621 +0.069970678 0.995104104 +0.070947611 0.994966437 +0.071917818 0.994827828 +0.072888719 0.994687235 +0.073866674 0.994543715 +0.074838154 0.994399251 +0.075810462 0.994252774 +0.076793322 0.994102786 +0.077769892 0.993951844 +0.078752878 0.993797984 +0.079735311 0.99364228 +0.080711692 0.993485623 +0.081695026 0.993325923 +0.082672441 0.993165268 +0.083652072 0.993002331 +0.084632485 0.992837342 +0.085612208 0.99267055 +0.086591595 0.992501896 +0.087565443 0.992332293 +0.088548617 0.992159143 +0.089526332 0.991985036 +0.090515945 0.991806864 +0.091500147 0.991627723 +0.092482981 0.991446898 +0.093471389 0.9912631 +0.094454571 0.991078334 +0.095446004 0.99089006 +0.096432288 0.990700814 +0.097423173 0.990508725 +0.098409018 0.990315665 +0.099393339 0.990120964 +0.100389139 0.989922021 +0.101380001 0.989722096 +0.102371646 0.989520046 +0.103358489 0.989317023 +0.104345726 0.98911197 +0.105336658 0.988904189 +0.106322929 0.988695435 +0.107317147 0.98848303 +0.108306759 0.988269646 +0.109294222 0.988054773 +0.110287174 0.987836739 +0.111279209 0.987616938 +0.112270294 0.987395381 +0.113257005 0.987172851 +0.114242858 0.986948569 +0.115228703 0.986722346 +0.116224291 0.986491914 +0.117217614 0.986260031 +0.118206729 0.986027169 +0.119200574 0.985791223 +0.120193704 0.985553473 +0.121182732 0.985314746 +0.122173842 0.985073552 +0.12316743 0.984829784 +0.124157011 0.984585037 +0.125151374 0.984337134 +0.126141787 0.98408825 +0.127130573 0.983837817 +0.128118845 0.983585562 +0.129112035 0.983330083 +0.130101405 0.983073625 +0.131098167 0.982813271 +0.13209114 0.982551931 +0.133082833 0.98228896 +0.134075717 0.982023702 +0.135066754 0.981756972 +0.136064006 0.981486586 +0.137057604 0.981215213 +0.138048207 0.980942692 +0.13904423 0.980666702 +0.140036685 0.980389727 +0.141028521 0.980110956 +0.14202975 0.97982755 +0.143027982 0.979542996 +0.14402273 0.979257453 +0.145020141 0.978969159 +0.146014123 0.978679876 +0.147010677 0.978387861 +0.148003855 0.978094859 +0.149000804 0.977798761 +0.149998797 0.977500361 +0.15099347 0.977200972 +0.151989217 0.976899278 +0.152984544 0.976595729 +0.153982473 0.976289398 +0.154981253 0.975980811 +0.155976814 0.975671234 +0.156973257 0.975359397 +0.157968263 0.975046028 +0.158963578 0.974730581 +0.159960237 0.974412723 +0.160953791 0.974093877 +0.161950816 0.973771933 +0.162944771 0.973449002 +0.163942018 0.973123015 +0.164936232 0.972796039 +0.16592856 0.972467713 +0.166926342 0.972135596 +0.167924272 0.971801439 +0.168919236 0.971466292 +0.169914381 0.971129103 +0.170913665 0.970788519 +0.171910027 0.970446943 +0.172909107 0.970102441 +0.17390752 0.969756175 +0.174903996 0.969408592 +0.175897633 0.969060023 +0.176893081 0.968708838 +0.177888598 0.968355647 +0.178885793 0.967999873 +0.179880967 0.967642838 +0.180873388 0.967284818 +0.181873751 0.966921939 +0.182871362 0.966558065 +0.183867528 0.966192732 +0.18486473 0.965825032 +0.185859242 0.965456342 +0.186857876 0.965084134 +0.187853842 0.964710934 +0.18884802 0.964336425 +0.18984793 0.963957763 +0.190845207 0.963578107 +0.191842618 0.96319641 +0.192837437 0.962813723 +0.193838641 0.962426581 +0.194837261 0.962038442 +0.195834564 0.961648823 +0.196834867 0.961256035 +0.197833873 0.960861759 +0.198830357 0.960466489 +0.199825584 0.960069736 +0.200822724 0.959670233 +0.201818526 0.959269283 +0.202816943 0.958865288 +0.203816095 0.958459 +0.204812798 0.958051718 +0.20580886 0.957642713 +0.206808496 0.957230246 +0.207805717 0.956816784 +0.208805291 0.956400351 +0.209802472 0.955982923 +0.210799601 0.955563528 +0.211801571 0.955140095 +0.212801691 0.954715441 +0.213800967 0.954289146 +0.214797909 0.953861858 +0.215794037 0.953432934 +0.216796225 0.952999397 +0.217798065 0.952564003 +0.218797601 0.95212761 +0.219796813 0.951689361 +0.220796814 0.951248767 +0.22179455 0.950807178 +0.222793474 0.950363068 +0.223790159 0.949917965 +0.224786745 0.949470919 +0.225787374 0.949020062 +0.226787411 0.94856747 +0.227787098 0.948113038 +0.228784592 0.947657611 +0.229781757 0.947200344 +0.230781535 0.946739883 +0.231779147 0.946278427 +0.23278029 0.945813337 +0.233780267 0.945346787 +0.234778866 0.944878884 +0.235775341 0.944409988 +0.236770468 0.943939746 +0.237771074 0.943464917 +0.238769574 0.94298909 +0.239769543 0.942510566 +0.240768517 0.942030521 +0.241765419 0.941549482 +0.242765057 0.941065127 +0.243763858 0.940579182 +0.244760612 0.940092243 +0.24575992 0.939602062 +0.246757197 0.939110886 +0.247753048 0.938618427 +0.248753037 0.938121926 +0.249751017 0.93762443 +0.250752523 0.937123172 +0.251754378 0.936619733 +0.25275424 0.936115294 +0.253754466 0.935608671 +0.254754003 0.935100398 +0.255752123 0.934590852 +0.256753691 0.934077542 +0.257754454 0.933562642 +0.258753847 0.933046447 +0.25975131 0.932529257 +0.260749971 0.932009453 +0.26174904 0.93148744 +0.262746202 0.930964433 +0.263745095 0.930438525 +0.264745097 0.929910033 +0.265744597 0.929379809 +0.266742217 0.92884859 +0.267739351 0.92831564 +0.26873679 0.927780538 +0.269737189 0.927241849 +0.270735732 0.926702163 +0.271736809 0.926159107 +0.272736189 0.925614971 +0.273736513 0.925068322 +0.274735008 0.924520675 +0.275735703 0.923969822 +0.276734582 0.923417971 +0.277735073 0.92286323 +0.278733762 0.92230749 +0.279733956 0.921748914 +0.28073421 0.921188303 +0.281733604 0.920626176 +0.282732653 0.920062247 +0.283729936 0.919497324 +0.284730615 0.918928477 +0.28573122 0.91835767 +0.286731613 0.917784982 +0.287730261 0.917211297 +0.288729785 0.916635111 +0.289729257 0.916056958 +0.290727841 0.915477322 +0.291724711 0.914896693 +0.292724743 0.914312225 +0.293723068 0.91372676 +0.294724221 0.913137633 +0.295723675 0.912547508 +0.296722291 0.911955882 +0.29772264 0.91136123 +0.298722642 0.910764783 +0.29972097 0.91016734 +0.300721162 0.909566783 +0.301719691 0.908965228 +0.302721345 0.908359787 +0.3037216 0.90775319 +0.304722428 0.907144242 +0.30572272 0.906533618 +0.306721376 0.905921998 +0.307721926 0.905307216 +0.308721783 0.90469086 +0.309720022 0.904073508 +0.310720442 0.903452807 +0.311719252 0.902831108 +0.312720231 0.902206057 +0.313720091 0.901579705 +0.314718357 0.900952356 +0.315718924 0.900321561 +0.316718644 0.8996893 +0.317716787 0.899056044 +0.318716733 0.898419644 +0.31971511 0.897782248 +0.320715026 0.897141872 +0.321713384 0.896500499 +0.322712288 0.895856779 +0.323713455 0.895209599 +0.324714549 0.894560462 +0.3257141 0.893910325 +0.326713269 0.89325844 +0.32771091 0.89260556 +0.328710354 0.891949504 +0.329708278 0.891292452 +0.330710659 0.89063046 +0.33171152 0.889967467 +0.332711717 0.889302913 +0.333712099 0.888636235 +0.334711776 0.887968027 +0.335713107 0.88729671 +0.336712945 0.886624393 +0.337714502 0.885948915 +0.338714573 0.885272438 +0.33971371 0.884594595 +0.340713135 0.88391456 +0.341713432 0.88323193 +0.342712758 0.882547965 +0.343710627 0.881863005 +0.34471121 0.881174182 +0.345711904 0.88048328 +0.346711149 0.879791379 +0.347711385 0.879096793 +0.348710182 0.878401209 +0.3497106 0.877702497 +0.350709586 0.877002786 +0.351709326 0.87630055 +0.352708223 0.875596909 +0.353706861 0.874891456 +0.354708467 0.874181903 +0.355708658 0.87347135 +0.356709672 0.87275821 +0.357709281 0.87204407 +0.358708778 0.871328013 +0.359706882 0.870610959 +0.360704206 0.869892476 +0.361705825 0.869168897 +0.362706056 0.868444317 +0.363707305 0.867716996 +0.364707177 0.866988675 +0.365707057 0.866258349 +0.366708627 0.865524783 +0.367709949 0.864789393 +0.368709935 0.864052984 +0.369710507 0.863314141 +0.370709726 0.862574299 +0.371710152 0.861831563 +0.372709539 0.861087599 +0.373707587 0.86034264 +0.374708412 0.859593606 +0.375709292 0.858842528 +0.376708838 0.858090452 +0.377709619 0.857335444 +0.378709074 0.856579437 +0.379708581 0.855821393 +0.380709731 0.855060101 +0.381709968 0.854297501 +0.382708893 0.853533903 +0.38371038 0.852766345 +0.384710559 0.851997786 +0.385711472 0.851226661 +0.386711085 0.850454537 +0.387710012 0.849680947 +0.388711615 0.848903281 +0.389711927 0.848124614 +0.390713005 0.847343348 +0.391713425 0.846560592 +0.392712568 0.845776839 +0.393711968 0.844990887 +0.394714017 0.844200844 +0.395714795 0.843409801 +0.396714891 0.842617295 +0.397715214 0.841822609 +0.398715654 0.841025827 +0.399716216 0.840226947 +0.400715525 0.839427068 +0.401716743 0.838623658 +0.402717603 0.837818533 +0.403717218 0.837012408 +0.404718153 0.836203216 +0.405719194 0.835391936 +0.406719 0.834579655 +0.407718505 0.833765621 +0.40871811 0.832949506 +0.409716971 0.832132004 +0.410715569 0.831312722 +0.411717243 0.830488912 +0.4127177 0.8296641 +0.413717405 0.828837909 +0.414718759 0.828008351 +0.415718903 0.827177793 +0.416718532 0.826345665 +0.417718333 0.825511395 +0.418719508 0.824673973 +0.419719487 0.823835552 +0.420719825 0.822994829 +0.421720476 0.82215184 +0.42271994 0.821307852 +0.423719721 0.820461598 +0.42472109 0.819611996 +0.425721279 0.818761393 +0.426722224 0.817908143 +0.427723227 0.817052841 +0.428723394 0.816196252 +0.429723685 0.815337555 +0.430723457 0.814477304 +0.431722069 0.813616055 +0.432722721 0.812751047 +0.433724258 0.811883268 +0.434724639 0.811014488 +0.435725666 0.810143144 +0.436725543 0.8092708 +0.437725425 0.808396452 +0.438725986 0.807519509 +0.43972581 0.806641213 +0.440726782 0.805759904 +0.441726618 0.804877595 +0.442728245 0.803991701 +0.443728738 0.803104807 +0.444728523 0.802216541 +0.44572962 0.801325106 +0.446729592 0.800432672 +0.447730039 0.799537812 +0.44873086 0.798640615 +0.449730565 0.797742419 +0.45073117 0.796841413 +0.451730664 0.795939407 +0.452730964 0.795034674 +0.453730159 0.794128943 +0.454731775 0.793219013 +0.455732287 0.792308082 +0.456733155 0.791394825 +0.457732927 0.790480568 +0.458734191 0.789562942 +0.459734994 0.788643735 +0.460735867 0.787722461 +0.461735653 0.786800187 +0.462735513 0.785875845 +0.463735666 0.784949233 +0.464737346 0.7840192 +0.46573913 0.783087063 +0.466740352 0.782153444 +0.4677405 0.781218825 +0.468741043 0.780281834 +0.46974148 0.779342942 +0.470740851 0.778403051 +0.471741786 0.777459687 +0.472741659 0.776515324 +0.473742137 0.775568388 +0.474742491 0.774619567 +0.475741792 0.773669747 +0.476742717 0.772716382 +0.47774312 0.771761512 +0.478742475 0.770805643 +0.479743722 0.769845962 +0.480744695 0.768884539 +0.481745407 0.767921363 +0.48274508 0.766957188 +0.483744498 0.765991261 +0.484744139 0.765023119 +0.48574275 0.764053981 +0.486743929 0.763080348 +0.487744078 0.762105715 +0.488744689 0.761128629 +0.489744275 0.760150545 +0.490743488 0.759170829 +0.491742974 0.758188848 +0.492744023 0.757203328 +0.493744056 0.756216808 +0.494744825 0.755227558 +0.495745017 0.754236879 +0.496745892 0.753243519 +0.497745759 0.75224916 +0.498746847 0.751251583 +0.49974693 0.750253006 +0.50074794 0.749251501 +0.501747949 0.748248996 +0.502748091 0.747244357 +0.503747238 0.74623872 +0.504747963 0.745229494 +0.505747696 0.744219269 +0.506748794 0.74320566 +0.507748903 0.742191051 +0.508748294 0.741175173 +0.509749451 0.740155497 +0.510750455 0.739133973 +0.511751386 0.738110519 +0.512751339 0.737086065 +0.513751222 0.736059682 +0.514752509 0.735029854 +0.515752905 0.733998941 +0.516752331 0.732967028 +0.517754385 0.731930397 +0.51875547 0.730892763 +0.519757093 0.729852564 +0.520757751 0.728811365 +0.521759212 0.727767324 +0.522759713 0.726722283 +0.523761102 0.725674308 +0.524762492 0.724624327 +0.525762927 0.723573345 +0.526764149 0.722519531 +0.52776442 0.721464717 +0.528765629 0.72040691 +0.529767331 0.719346575 +0.530768086 0.718285239 +0.531768474 0.71722229 +0.532769073 0.716157115 +0.533770758 0.715088778 +0.534771504 0.714019439 +0.535771803 0.712948575 +0.536772146 0.711875663 +0.537772898 0.71080031 +0.538772719 0.709723957 +0.539773599 0.708644462 +0.540773551 0.707563966 +0.541774944 0.70647991 +0.542775412 0.705394852 +0.543775105 0.704308636 +0.544776405 0.703218668 +0.545776786 0.7021277 +0.546777926 0.7010339 +0.547778149 0.699939099 +0.548779716 0.698840823 +0.549780369 0.697741546 +0.550780882 0.69664042 +0.551782293 0.695536301 +0.552782795 0.694431182 +0.553782752 0.693324663 +0.554783735 0.692215008 +0.555783933 0.69110422 +0.556783231 0.689992434 +0.557784579 0.688876364 +0.558785028 0.687759292 +0.559785073 0.686640672 +0.560786101 0.685518949 +0.561786236 0.684396225 +0.562786869 0.68327094 +0.563786613 0.682144655 +0.564786981 0.681015666 +0.565786463 0.679885678 +0.566786368 0.678753213 +0.567788081 0.677616695 +0.568788911 0.676479174 +0.569790337 0.675338972 +0.570791424 0.67419715 +0.571791633 0.673054328 +0.572792209 0.671909085 +0.573791911 0.670762842 +0.574792856 0.669613173 +0.575794003 0.668461266 +0.57679428 0.667308359 +0.577795454 0.666152414 +0.57879576 0.664995468 +0.579795893 0.663836723 +0.580795729 0.662676321 +0.581796603 0.661512713 +0.582796997 0.660347661 +0.583796532 0.659181609 +0.584798669 0.658010517 +0.585799946 0.656838423 +0.586801736 0.655663723 +0.58780267 0.654488021 +0.588803081 0.653310931 +0.589804416 0.652130751 +0.5908049 0.65094957 +0.591806087 0.649765556 +0.592806427 0.648580541 +0.593807246 0.647392954 +0.594808719 0.646202588 +0.595809913 0.645010548 +0.596810265 0.643817507 +0.597810315 0.642622827 +0.5988106 0.641425866 +0.599812183 0.640225345 +0.60081293 0.639023824 +0.601813408 0.637820622 +0.602814301 0.636614919 +0.60381475 0.635407748 +0.60481437 0.634199578 +0.605815641 0.632987409 +0.606816516 0.631773716 +0.607816566 0.630559023 +0.608817453 0.629341309 +0.609817517 0.628122596 +0.610818444 0.626900829 +0.61181855 0.625678062 +0.6128192 0.624452629 +0.613819032 0.623226196 +0.614818956 0.621997651 +0.615819256 0.620766644 +0.616820073 0.619532997 +0.617820079 0.618298351 +0.618821265 0.617060242 +0.619821642 0.615821133 +0.620822948 0.614578867 +0.621824386 0.613334433 +0.622825282 0.612088668 +0.623825373 0.610841904 +0.624824926 0.609593812 +0.625825621 0.608342292 +0.626825515 0.607089774 +0.62782689 0.605833397 +0.628827466 0.604576019 +0.629827741 0.603317017 +0.630828463 0.602055451 +0.63182839 0.600792885 +0.632829773 0.599526478 +0.633830364 0.59825907 +0.634831438 0.596989045 +0.635831724 0.595718019 +0.636832296 0.594444627 +0.637833406 0.593168546 +0.638833731 0.591891464 +0.639834603 0.59061168 +0.640835203 0.589330243 +0.641835022 0.588047805 +0.642836181 0.586761645 +0.64383656 0.585474484 +0.644838265 0.584183612 +0.645839811 0.582890939 +0.646841199 0.581596463 +0.647841812 0.580300986 +0.648841777 0.579004349 +0.649843084 0.577703966 +0.65084362 0.576402582 +0.651844427 0.575098843 +0.652845346 0.573792954 +0.653845497 0.572486066 +0.654845762 0.571177028 +0.655846618 0.569865214 +0.656846709 0.568552401 +0.65784831 0.567235601 +0.658849149 0.565917799 +0.65984954 0.564598585 +0.660850682 0.563276376 +0.66185203 0.561951891 +0.66285262 0.560626404 +0.663853235 0.559298882 +0.664854656 0.557968286 +0.665855748 0.556636122 +0.66685616 0.555302863 +0.667857028 0.553966991 +0.668857741 0.552629322 +0.669857706 0.551290654 +0.670858959 0.549948258 +0.671860472 0.548603506 +0.672861743 0.547257074 +0.67386227 0.545909642 +0.674863134 0.544559751 +0.67586426 0.543207502 +0.676864645 0.541854252 +0.677865707 0.540498083 +0.67886603 0.539140914 +0.679867373 0.537780355 +0.680867979 0.536418795 +0.681868987 0.535054685 +0.682870006 0.533688555 +0.683870291 0.532321425 +0.684871641 0.530950836 +0.685872258 0.529579246 +0.686873381 0.528204959 +0.687873774 0.526829671 +0.688874369 0.525452104 +0.689875499 0.524071796 +0.690876238 0.522690023 +0.691877025 0.521306182 +0.692877089 0.51992134 +0.693877201 0.51853443 +0.694877811 0.517144827 +0.695878921 0.515752528 +0.69687931 0.514359228 +0.697880198 0.512963229 +0.698880923 0.511565456 +0.699881174 0.510166342 +0.700880711 0.508766229 +0.701882425 0.507361061 +0.702883424 0.505954892 +0.703884444 0.50454669 +0.704884751 0.503137488 +0.705885202 0.501726082 +0.706885916 0.500312301 +0.707885923 0.49889752 +0.708887585 0.497478392 +0.70988854 0.496058261 +0.710888883 0.494636996 +0.711890387 0.493212077 +0.712891186 0.491786156 +0.713891983 0.490358237 +0.71489308 0.488927884 +0.71589424 0.487495438 +0.716895377 0.486061018 +0.717895816 0.484625598 +0.718896235 0.483188204 +0.719896551 0.481748956 +0.720896837 0.48030775 +0.721896915 0.478864844 +0.722898044 0.477418418 +0.723898479 0.475970992 +0.724898547 0.474522096 +0.725898573 0.473071263 +0.726899566 0.471617021 +0.72789987 0.47016178 +0.728900017 0.468704766 +0.729900778 0.467244855 +0.730901397 0.465783149 +0.731901331 0.464320442 +0.732901797 0.462854955 +0.733902934 0.461386483 +0.734903388 0.45991701 +0.735904183 0.458445033 +0.736905089 0.456970889 +0.737905316 0.455495745 +0.738906028 0.454017882 +0.739906062 0.452539019 +0.74090681 0.451057099 +0.741908464 0.449571832 +0.742909441 0.448085562 +0.743910566 0.44659707 +0.744911017 0.445107577 +0.745912131 0.443615093 +0.746912572 0.44212161 +0.747913078 0.440626028 +0.748914323 0.439127336 +0.74991549 0.437626758 +0.750915988 0.436125179 +0.751916409 0.434621713 +0.752917706 0.433114928 +0.753919107 0.43160598 +0.754919843 0.430096031 +0.755921335 0.428582935 +0.756922489 0.427068346 +0.75792298 0.425552757 +0.758924612 0.424033433 +0.759925584 0.422513107 +0.760926564 0.420990764 +0.761927881 0.419465904 +0.762929097 0.417939193 +0.763929656 0.416411481 +0.764930115 0.41488192 +0.765930379 0.413350654 +0.766930206 0.41181806 +0.767930802 0.410282284 +0.768930746 0.408745508 +0.769931032 0.407206206 +0.770932927 0.405662421 +0.771934172 0.404117635 +0.772935253 0.402571094 +0.773936362 0.401022507 +0.774936824 0.399472919 +0.7759378 0.397920531 +0.776938321 0.396366846 +0.777938197 0.394812161 +0.778939265 0.393253621 +0.779940598 0.391692664 +0.78094147 0.390130421 +0.7819417 0.388567177 +0.782942825 0.387000533 +0.783943309 0.385432888 +0.784944705 0.383861811 +0.785946188 0.382288589 +0.786947034 0.380714366 +0.787947541 0.379138673 +0.788947796 0.377561375 +0.78994862 0.375981177 +0.790949167 0.374399416 +0.791949081 0.372816654 +0.792949772 0.371230659 +0.793949832 0.369643664 +0.794950314 0.368053999 +0.795950301 0.366463118 +0.796951572 0.364868192 +0.797952893 0.363271181 +0.798953585 0.361673169 +0.7999548 0.360072318 +0.800955389 0.358470465 +0.801956101 0.356866413 +0.802956327 0.355261137 +0.803957644 0.353652107 +0.804958925 0.352041128 +0.805959584 0.350429149 +0.80696091 0.348814089 +0.807961615 0.347198029 +0.808962869 0.345579076 +0.809963578 0.343959003 +0.81096477 0.342336142 +0.811965852 0.340711455 +0.812966317 0.339085767 +0.813967717 0.337456556 +0.8149685 0.335826344 +0.815969566 0.334193668 +0.816970017 0.332559991 +0.817970544 0.33092419 +0.818971763 0.329285252 +0.819972946 0.327644368 +0.820973518 0.326002483 +0.821974056 0.324358651 +0.822974511 0.322712955 +0.823976062 0.321063449 +0.824977005 0.319412941 +0.825977698 0.317760843 +0.826978852 0.316105978 +0.827980067 0.314449009 +0.828980967 0.312790556 +0.829981264 0.311131102 +0.830981249 0.309470164 +0.831981775 0.307806327 +0.832983045 0.306139247 +0.833983844 0.304470949 +0.834984042 0.302801649 +0.835985856 0.301127649 +0.83698707 0.299452645 +0.837987785 0.297776473 +0.838988823 0.296097755 +0.839989264 0.294418036 +0.8409906 0.292734811 +0.841991339 0.291050584 +0.842991804 0.289364819 +0.843992911 0.287675966 +0.844993425 0.285986111 +0.845994522 0.28429327 +0.846995025 0.282599427 +0.847996062 0.28090268 +0.848996507 0.279204932 +0.849997551 0.277504163 +0.850998006 0.275802394 +0.851998515 0.27409853 +0.852999578 0.27239172 +0.854000053 0.27068391 +0.85500024 0.26897459 +0.856000438 0.267263251 +0.85700194 0.265547676 +0.858002856 0.263831099 +0.859003705 0.262112634 +0.860003971 0.260393169 +0.861005182 0.258670077 +0.86200581 0.256945983 +0.863006709 0.25521942 +0.864008061 0.25349007 +0.865008833 0.251759719 +0.866009708 0.250027186 +0.867010643 0.248292544 +0.868011255 0.246556462 +0.869011289 0.244819379 +0.870013027 0.243077333 +0.871014188 0.241334285 +0.872015265 0.239589377 +0.873016412 0.237842345 +0.874017562 0.236093302 +0.875018138 0.234343258 +0.876018719 0.232591204 +0.877019239 0.230837254 +0.878020612 0.229079804 +0.879021414 0.227321353 +0.880021966 0.225561339 +0.881022588 0.2237992 +0.882023921 0.222033803 +0.883024686 0.220267404 +0.884025646 0.218498658 +0.885026039 0.21672891 +0.886027052 0.214956064 +0.887027498 0.213182217 +0.888028349 0.211405652 +0.889028636 0.209628085 +0.8900303 0.207846065 +0.89103184 0.206062261 +0.892032816 0.204277455 +0.893034066 0.202490156 +0.894034755 0.200701857 +0.895036084 0.198910408 +0.896036854 0.197117957 +0.897037773 0.195323233 +0.898038573 0.193526722 +0.899039795 0.191727446 +0.90004046 0.18992717 +0.901040657 0.188125735 +0.902041837 0.186320525 +0.903042461 0.184514313 +0.904043745 0.182704907 +0.905044608 0.180894259 +0.90604568 0.179081225 +0.90704685 0.177266012 +0.908047468 0.175449797 +0.909048183 0.173631401 +0.91004892 0.171810963 +0.911049968 0.169987955 +0.912050467 0.168163946 +0.913051277 0.166337365 +0.914052372 0.164508262 +0.915052917 0.162678158 +0.916053465 0.160846049 +0.917054716 0.159010648 +0.91805542 0.157174245 +0.919056296 0.155335526 +0.920057176 0.153494793 +0.921057513 0.151653059 +0.922058521 0.149808085 +0.923058985 0.14796211 +0.924059762 0.146113556 +0.925060848 0.144262428 +0.92606148 0.142410135 +0.927061572 0.140556841 +0.928063085 0.13869891 +0.929064058 0.136839977 +0.930065542 0.134978088 +0.931066487 0.133115197 +0.932067584 0.13125002 +0.93306875 0.129382708 +0.934069379 0.127514396 +0.935070073 0.125643959 +0.936070232 0.123772521 +0.937071063 0.121897822 +0.938071361 0.120022122 +0.939072121 0.118143552 +0.940072347 0.116263982 +0.941073834 0.11438004 +0.942074787 0.112495096 +0.943076449 0.110606812 +0.944077578 0.108717526 +0.945078749 0.106826158 +0.946080071 0.1049325 +0.947080862 0.103037841 +0.948081834 0.101140836 +0.949082278 0.099242831 +0.95008348 0.097341382 +0.95108451 0.095438255 +0.952085014 0.093534126 +0.953085938 0.091627194 +0.954086337 0.089719261 +0.955086801 0.087809202 +0.95608777 0.085896177 +0.957088214 0.083982151 +0.958088406 0.082066607 +0.959088616 0.080149026 +0.960089678 0.078227811 +0.961090218 0.076305594 +0.962090446 0.074381974 +0.963091572 0.072454624 +0.964092178 0.070526272 +0.965092398 0.068596663 +0.966092367 0.066665539 +0.967092831 0.064731456 +0.968092778 0.062796373 +0.969092824 0.060859099 +0.970092534 0.058920476 +0.971092416 0.056979519 +0.972091784 0.055037563 +0.97309151 0.053092913 +0.974091408 0.051145929 +0.975090792 0.049197947 +0.976089889 0.047248528 +0.977088565 0.045297937 +0.978087703 0.043344446 +0.979086331 0.041389957 +0.980085274 0.039432855 +0.981083709 0.037474756 +0.982081926 0.035515091 +0.983080131 0.033553455 +0.984078117 0.03159026 +0.985075596 0.029626071 +0.986072881 0.027660274 +0.987069661 0.025693484 +0.988066574 0.023724446 +0.989062984 0.021754414 +0.99005913 0.01978292 +0.991054774 0.017810435 +0.992050319 0.015836164 +0.993045365 0.013860904 +0.994040223 0.011884036 +0.995034586 0.009906173 +0.996028452 0.007927323 +0.99702199 0.005947151 +0.998015124 0.003965813 +0.999007809 0.001983399 +1 0 \ No newline at end of file diff --git a/jmetal/problem/resources/ZDT3.pf b/jmetal/problem/resources/ZDT3.pf new file mode 100644 index 00000000..2025363b --- /dev/null +++ b/jmetal/problem/resources/ZDT3.pf @@ -0,0 +1,1000 @@ +0 1 +0.000166987 0.98707679 +0.000355607 0.981138473 +0.000502083 0.977584873 +0.000593637 0.975624266 +0.000852686 0.970776381 +0.000959449 0.968996105 +0.001538384 0.960703436 +0.002057097 0.954511926 +0.00260491 0.94874874 +0.003076769 0.944234435 +0.003418068 0.941169425 +0.003671756 0.938982376 +0.003888964 0.937164487 +0.004263428 0.934135735 +0.004567716 0.931761905 +0.004802503 0.929978078 +0.004949127 0.928883571 +0.005223175 0.926875232 +0.005634825 0.923942232 +0.005996533 0.921439721 +0.006230375 0.919855557 +0.006430139 0.918521724 +0.006619943 0.917270109 +0.006821484 0.91595702 +0.00722916 0.913347789 +0.00767417 0.910565357 +0.008063922 0.908179559 +0.008526856 0.90540208 +0.008878581 0.903329273 +0.009136669 0.90182738 +0.009368111 0.900493519 +0.009552807 0.899437484 +0.00965735 0.898842941 +0.00997842 0.897030893 +0.010232227 0.895612687 +0.01053175 0.893954332 +0.010777834 0.892603659 +0.011084912 0.890932402 +0.011424811 0.889099967 +0.011681606 0.887727089 +0.011937598 0.886367931 +0.012245012 0.884747627 +0.01245631 0.883641137 +0.012669429 0.882530827 +0.012868345 0.881499526 +0.013058329 0.880518917 +0.013198679 0.879797165 +0.013410387 0.87871264 +0.013642969 0.877526811 +0.01393321 0.876054973 +0.014132701 0.875048293 +0.014306897 0.874172453 +0.014495654 0.873226671 +0.014929326 0.87106616 +0.01534834 0.868994346 +0.015631348 0.867603294 +0.015834666 0.866607901 +0.016201026 0.864822344 +0.01663272 0.862731102 +0.017053711 0.86070434 +0.01731916 0.859432527 +0.017534487 0.858404212 +0.01773941 0.857428309 +0.018109615 0.855671816 +0.018592095 0.853394764 +0.01895565 0.85168768 +0.019277794 0.850181042 +0.019469022 0.849289282 +0.019803716 0.847733007 +0.020297467 0.845447337 +0.020654696 0.84380096 +0.020983165 0.84229237 +0.021248701 0.841076395 +0.021501877 0.839919934 +0.021735923 0.838853341 +0.021935899 0.837943868 +0.022188499 0.836797477 +0.022411883 0.835785892 +0.022514211 0.835323187 +0.022705336 0.834460097 +0.022860718 0.833759504 +0.022957917 0.833321737 +0.02302251 0.833031029 +0.023195636 0.832252667 +0.023211686 0.832180567 +0.023512383 0.830831629 +0.023875195 0.829208665 +0.024226921 0.827640058 +0.024566863 0.826128388 +0.025031393 0.824069562 +0.02541358 0.822381551 +0.025656404 0.821311788 +0.025845806 0.820478834 +0.02595436 0.82000201 +0.026171246 0.819050581 +0.026266265 0.818634276 +0.026503558 0.817596017 +0.026906984 0.815835372 +0.027285938 0.814186694 +0.027627037 0.812706966 +0.027962482 0.8112557 +0.028138623 0.810495202 +0.028183847 0.81030012 +0.028824322 0.807544896 +0.029343034 0.805323904 +0.029767499 0.803513427 +0.030183699 0.80174433 +0.030529693 0.800278293 +0.030710755 0.799512794 +0.030833156 0.798995962 +0.031215392 0.797385439 +0.031486063 0.796248163 +0.031711983 0.795300944 +0.032068078 0.79381172 +0.032327483 0.792729788 +0.032558413 0.791768721 +0.032754558 0.790953974 +0.032908932 0.790313749 +0.03308775 0.789573275 +0.033257419 0.788871802 +0.033414587 0.788222994 +0.03370838 0.787012714 +0.033940435 0.786059118 +0.034109669 0.785365001 +0.034432558 0.784043777 +0.034752839 0.782737301 +0.034960108 0.78189401 +0.035343349 0.780339336 +0.035582444 0.779372453 +0.035812793 0.778443172 +0.036043283 0.777515538 +0.036224065 0.776789524 +0.036259701 0.776646573 +0.036498492 0.775690081 +0.03667653 0.774978527 +0.037017204 0.773620794 +0.037503679 0.771690792 +0.03786989 0.77024487 +0.038221355 0.76886287 +0.038563285 0.767523807 +0.038816341 0.766536293 +0.038923575 0.766118732 +0.039223535 0.76495361 +0.039419386 0.764195196 +0.039726415 0.763009979 +0.039899223 0.762344913 +0.040076221 0.761665242 +0.040255145 0.760979754 +0.040572065 0.759769509 +0.040801967 0.758894741 +0.040928906 0.758412893 +0.041108833 0.757731332 +0.041131237 0.757646584 +0.041426647 0.756531547 +0.041781592 0.755197841 +0.042092169 0.754036333 +0.042332294 0.753141856 +0.042467291 0.752640358 +0.042755635 0.751572532 +0.042937985 0.750899599 +0.043319976 0.749495937 +0.043731912 0.747991475 +0.044003434 0.747005143 +0.044172662 0.746392565 +0.044504403 0.745196573 +0.044779942 0.744208141 +0.045025348 0.743331624 +0.045346338 0.742190623 +0.045659982 0.741081808 +0.04604502 0.73972891 +0.046332549 0.73872467 +0.046563732 0.73792102 +0.046861215 0.736891913 +0.047143253 0.735921507 +0.047408718 0.735012859 +0.047583404 0.734417455 +0.047660632 0.734154875 +0.047904707 0.733327603 +0.048022761 0.732928897 +0.048243242 0.732186771 +0.048603076 0.730982666 +0.048890205 0.730028212 +0.049026409 0.729577443 +0.049122619 0.729259808 +0.049290632 0.728706672 +0.049455762 0.728164952 +0.049476271 0.728097805 +0.049680579 0.727430517 +0.049993754 0.726413417 +0.050141461 0.725936144 +0.050348432 0.725270023 +0.050447723 0.724951561 +0.050721169 0.724078242 +0.050994146 0.723211887 +0.051411166 0.721899044 +0.051699361 0.720999363 +0.051933356 0.720273499 +0.052013819 0.720024859 +0.052365544 0.718943803 +0.052709439 0.717896033 +0.053050501 0.716865981 +0.053324767 0.716044294 +0.053552203 0.715367421 +0.053696186 0.714941044 +0.053922679 0.714273687 +0.054272946 0.713249772 +0.054571875 0.712383813 +0.054842235 0.711606918 +0.054980734 0.711211266 +0.0552523 0.710440094 +0.055424561 0.709954103 +0.055464203 0.709842615 +0.05573551 0.709083139 +0.055925162 0.708555926 +0.056277246 0.707585265 +0.056795959 0.706174565 +0.057285635 0.704864199 +0.057650742 0.703900825 +0.057872275 0.703322019 +0.057982618 0.703035347 +0.05832337 0.70215691 +0.058510706 0.701678398 +0.058668316 0.701278258 +0.058915217 0.700655939 +0.059171206 0.700016555 +0.059331341 0.699619621 +0.059567926 0.699037486 +0.059687989 0.69874403 +0.059791927 0.698491056 +0.059853201 0.698342393 +0.060142042 0.697646276 +0.060373687 0.697093609 +0.060576078 0.69661484 +0.060764734 0.696172023 +0.060883573 0.695894798 +0.06114813 0.695282435 +0.06139336 0.694720733 +0.061625241 0.694194873 +0.06171148 0.694000608 +0.062079059 0.693180594 +0.062371947 0.692536518 +0.062586013 0.692071027 +0.063098731 0.690974247 +0.063506117 0.69012114 +0.06378443 0.689547729 +0.064091898 0.688923166 +0.064470128 0.68816777 +0.064702344 0.687711078 +0.065024953 0.687085594 +0.065233003 0.686687783 +0.065342354 0.686480448 +0.065448848 0.686279693 +0.06561723 0.685964618 +0.065656787 0.685891016 +0.065832723 0.685565591 +0.066007489 0.685245453 +0.066199541 0.684897247 +0.066307406 0.684703333 +0.066509473 0.684343279 +0.06676994 0.683885355 +0.067143616 0.683240613 +0.067362159 0.682870231 +0.067654875 0.682381906 +0.068047857 0.681740336 +0.068327052 0.681294333 +0.068733556 0.680659564 +0.069030097 0.680207468 +0.069329314 0.679760689 +0.069550522 0.679436478 +0.069753229 0.679143933 +0.070026135 0.678756964 +0.070391767 0.678250932 +0.070772901 0.677738621 +0.071291613 0.677066344 +0.071677462 0.676584983 +0.071977312 0.676221963 +0.072271235 0.67587552 +0.072496024 0.675616854 +0.072887544 0.675179364 +0.073236447 0.674803474 +0.073586173 0.674439936 +0.073837978 0.674186404 +0.074016656 0.674010677 +0.074221533 0.673813454 +0.074535368 0.673520196 +0.074832473 0.673252448 +0.075221067 0.672916761 +0.075596574 0.672608015 +0.075868863 0.672393751 +0.076078364 0.6722344 +0.07620904 0.67213743 +0.076272069 0.672091324 +0.076418791 0.671985675 +0.076574713 0.671875976 +0.076601145 0.671857642 +0.076749759 0.671755982 +0.07680785 0.6717169 +0.077048547 0.671558887 +0.077427398 0.671322979 +0.077699377 0.671163272 +0.078280084 0.670849264 +0.078852518 0.67057567 +0.079299756 0.670386711 +0.079703425 0.670234809 +0.0799847 0.670139411 +0.080152442 0.670086598 +0.080435941 0.67000426 +0.080671154 0.669942539 +0.080907606 0.669886512 +0.081119257 0.669841473 +0.081421147 0.669785578 +0.081690826 0.66974393 +0.081918188 0.669714879 +0.082376525 0.669673142 +0.082847367 0.66965362 +0.182474708 0.668295783 +0.182737304 0.666837918 +0.18299342 0.665406486 +0.183200883 0.664240102 +0.183532581 0.662362557 +0.184013092 0.65961518 +0.184413656 0.657300308 +0.184654795 0.65589608 +0.185032765 0.653679022 +0.185551477 0.650604919 +0.185903232 0.64849978 +0.186257144 0.646365211 +0.186578122 0.644415102 +0.186738136 0.643437942 +0.187056738 0.641482507 +0.187350681 0.639666921 +0.187590821 0.63817555 +0.187757285 0.637137494 +0.187838695 0.636628564 +0.18827652 0.633877463 +0.188844126 0.63027599 +0.189296192 0.627379928 +0.189647918 0.625109988 +0.189921684 0.623333209 +0.19015968 0.62178157 +0.190502156 0.619537458 +0.190743768 0.617946329 +0.190854193 0.617216964 +0.191001563 0.616241472 +0.191059222 0.615859163 +0.191379553 0.613728563 +0.191602209 0.612241076 +0.191854249 0.610550892 +0.192063063 0.609145494 +0.192270735 0.607743247 +0.192357481 0.607156192 +0.192539948 0.60591882 +0.192712783 0.604743624 +0.193225647 0.60123866 +0.193730363 0.597764016 +0.194412306 0.593030527 +0.194931018 0.58940117 +0.195290765 0.586869861 +0.195542823 0.585089515 +0.195733895 0.583736269 +0.19595069 0.582197082 +0.196147625 0.580795474 +0.19635128 0.579342656 +0.196534641 0.57803171 +0.196803376 0.576105495 +0.197060737 0.574255442 +0.197478125 0.571244137 +0.197823048 0.568745736 +0.19834176 0.564972203 +0.198758541 0.561926491 +0.199031193 0.559927655 +0.199235808 0.558424367 +0.199361432 0.557500077 +0.1995662 0.55599132 +0.199775161 0.554448959 +0.199966729 0.553032619 +0.200256494 0.550886081 +0.200381105 0.549961464 +0.200603841 0.548306528 +0.201002182 0.545339927 +0.20123379 0.543611105 +0.201529007 0.541403419 +0.201886037 0.538727626 +0.202086476 0.537222712 +0.20241467 0.534754552 +0.202772174 0.532060486 +0.202965291 0.53060293 +0.203649433 0.525427306 +0.203791847 0.524347696 +0.204075937 0.52219192 +0.204254597 0.520834769 +0.20437345 0.519931356 +0.204644532 0.517869154 +0.204856106 0.516258108 +0.205407351 0.512054736 +0.205497218 0.511368733 +0.205665061 0.510086965 +0.206061814 0.507054551 +0.206349903 0.504850604 +0.206380699 0.504614919 +0.206528998 0.503479703 +0.206538678 0.503405596 +0.206765283 0.501670195 +0.206875627 0.500824856 +0.207202589 0.498318984 +0.207986536 0.492305658 +0.208055274 0.491778134 +0.208232458 0.490418221 +0.208276792 0.490077919 +0.208457259 0.48869258 +0.2084982 0.488378283 +0.20890796 0.485232354 +0.209052098 0.484125676 +0.209632053 0.479673102 +0.209760646 0.478685982 +0.210321845 0.47437924 +0.210543329 0.472680258 +0.210613331 0.472143388 +0.211256944 0.467210172 +0.211466017 0.465608973 +0.212318702 0.459087165 +0.213171388 0.452582414 +0.214024073 0.446099191 +0.214174486 0.44495813 +0.214742981 0.440653153 +0.214876759 0.43964198 +0.215022657 0.438540054 +0.215161001 0.437496031 +0.215588042 0.434278733 +0.215671537 0.433650675 +0.215729444 0.433215281 +0.215769498 0.432914223 +0.215819374 0.432539441 +0.21640192 0.428171299 +0.21658213 0.426823601 +0.216586863 0.426788226 +0.216638298 0.426403906 +0.216671689 0.426154487 +0.216897192 0.424471674 +0.217434816 0.420471452 +0.217728662 0.418292397 +0.218287501 0.414163347 +0.219140187 0.4079038 +0.219209247 0.407399092 +0.219325954 0.406546968 +0.219773905 0.403285809 +0.219840681 0.402800985 +0.219992872 0.401697314 +0.220043496 0.401330601 +0.220366451 0.398995998 +0.220845558 0.395548386 +0.221185767 0.393112115 +0.221698243 0.3894615 +0.222484163 0.383910018 +0.222550929 0.383441118 +0.223070856 0.379804712 +0.223403614 0.377491688 +0.223674904 0.375614414 +0.224170567 0.372204697 +0.2242563 0.371617627 +0.224701246 0.368583833 +0.225108986 0.365823328 +0.225484697 0.363296681 +0.225638039 0.362270235 +0.225961671 0.36011315 +0.226814357 0.354491415 +0.226903761 0.353907269 +0.227667042 0.348962408 +0.228110395 0.346125656 +0.228452638 0.343954153 +0.228519728 0.343530368 +0.229320072 0.338523727 +0.229339646 0.338402424 +0.229372413 0.338199488 +0.229496885 0.337430013 +0.229680017 0.336302018 +0.229757772 0.335824577 +0.230027525 0.334175127 +0.230225099 0.33297391 +0.23047802 0.331444766 +0.230913944 0.328832102 +0.231077784 0.327857722 +0.231644752 0.324518398 +0.231746689 0.323923423 +0.23193047 0.322854953 +0.232264618 0.320926277 +0.23226751 0.320909664 +0.232616519 0.318914886 +0.232783155 0.317969572 +0.233412283 0.314442588 +0.233618536 0.313300932 +0.233635841 0.313205479 +0.234488527 0.308566509 +0.235078588 0.305431554 +0.235341212 0.304056423 +0.235357477 0.303971672 +0.235710637 0.302143383 +0.236149458 0.299903715 +0.236193898 0.299678906 +0.236215739 0.29956855 +0.236245157 0.299420056 +0.236522235 0.298029408 +0.236548616 0.297897757 +0.237046583 0.295437562 +0.237241238 0.29448879 +0.237354798 0.293938661 +0.237494398 0.293265818 +0.237899269 0.291335917 +0.238751954 0.287377405 +0.239147527 0.285590538 +0.239509683 0.283982539 +0.239580135 0.283672852 +0.23960464 0.283565376 +0.240457325 0.279903083 +0.24114905 0.277044304 +0.241310011 0.276393686 +0.241433614 0.275897847 +0.242088241 0.273326775 +0.242162697 0.273040247 +0.242573067 0.271482807 +0.243015382 0.269845722 +0.24320279 0.269165198 +0.243341945 0.268664967 +0.243365194 0.268581816 +0.243367401 0.268573925 +0.243710539 0.267360942 +0.24372179 0.267321618 +0.243732037 0.267285827 +0.243868068 0.266812966 +0.243983042 0.266416564 +0.244720753 0.263944725 +0.244892805 0.263386164 +0.244951724 0.263196453 +0.245176962 0.262478615 +0.245281604 0.262149119 +0.245381017 0.261838439 +0.245573439 0.261243633 +0.245573649 0.261242988 +0.245809229 0.260526552 +0.245877827 0.260320377 +0.246314 0.259035308 +0.246414109 0.258746694 +0.246426124 0.258712214 +0.24727881 0.256352872 +0.247387089 0.2560657 +0.247575938 0.255571586 +0.248018966 0.254446183 +0.248089183 0.254272174 +0.248131495 0.254167895 +0.248202017 0.253995061 +0.248684471 0.252845147 +0.248984181 0.252159448 +0.249255301 0.251558164 +0.24933718 0.251380135 +0.24934575 0.251361596 +0.249410452 0.251222222 +0.249437841 0.251163535 +0.249688818 0.250634393 +0.249755203 0.25049704 +0.249836866 0.250329575 +0.249880786 0.250240195 +0.250090145 0.24982072 +0.250525197 0.248983982 +0.250689552 0.248680191 +0.2510572 0.248025174 +0.251542238 0.247213084 +0.251662074 0.247021602 +0.251840664 0.246742991 +0.252259607 0.246121201 +0.252311552 0.246047218 +0.252394923 0.245929912 +0.25243763 0.24587051 +0.252566344 0.245694291 +0.253247609 0.244832201 +0.253532537 0.244506982 +0.253563943 0.244472413 +0.253564435 0.244471874 +0.253907663 0.24411071 +0.254100294 0.243921341 +0.254662195 0.243423853 +0.25495298 0.243198586 +0.255048859 0.243129132 +0.255193693 0.243028756 +0.255374261 0.242911274 +0.255805665 0.242665054 +0.255910039 0.242612794 +0.256421635 0.242397911 +0.256576675 0.242346346 +0.256658351 0.24232172 +0.256658883 0.242321565 +0.257018098 0.242234124 +0.257298927 0.242189415 +0.257511036 0.242169419 +0.409858202 0.234882855 +0.410004029 0.232936869 +0.41014175 0.231100335 +0.41019868 0.230341545 +0.410414178 0.227471313 +0.410883322 0.221234432 +0.410994436 0.219759724 +0.411171494 0.217411815 +0.411240429 0.216498381 +0.411308599 0.215595475 +0.411482978 0.213287588 +0.411847121 0.20847667 +0.412039628 0.205938132 +0.412699807 0.197259221 +0.413552492 0.186115408 +0.413911521 0.181447193 +0.414010512 0.180162712 +0.414106986 0.178911997 +0.414405178 0.175053238 +0.415143107 0.165551901 +0.415198612 0.164840093 +0.415257863 0.164080693 +0.415603732 0.159657348 +0.415646676 0.159109279 +0.415721443 0.158155682 +0.415808949 0.157040612 +0.416110549 0.153205718 +0.416546684 0.14768362 +0.416963234 0.142436218 +0.41781592 0.131780053 +0.418321705 0.125515908 +0.418668606 0.12124503 +0.418678787 0.121120006 +0.418681451 0.121087295 +0.418757318 0.120156245 +0.419521291 0.110838895 +0.419691299 0.108780218 +0.419744699 0.108134704 +0.420373977 0.100569333 +0.421226662 0.090443955 +0.422079348 0.080470297 +0.422842526 0.071678352 +0.422932033 0.070655812 +0.422937657 0.070591623 +0.423019187 0.069661919 +0.42315616 0.068103432 +0.423784719 0.061007865 +0.424065876 0.057864389 +0.424500296 0.053045104 +0.424637404 0.051533726 +0.424650785 0.051386476 +0.425416907 0.043030888 +0.425439343 0.042788451 +0.425457917 0.042587835 +0.42549009 0.042240565 +0.425917092 0.037657025 +0.426342776 0.033135446 +0.427195461 0.02422532 +0.427458565 0.021516447 +0.427714154 0.018903541 +0.428048147 0.015517025 +0.428797384 0.008037128 +0.428900832 0.007017271 +0.429092668 0.00513442 +0.429147886 0.004594495 +0.429268776 0.003415588 +0.429705028 -0.000802113 +0.429753518 -0.001267358 +0.429843984 -0.002133433 +0.429904663 -0.002712936 +0.43007071 -0.004292968 +0.430606203 -0.00933041 +0.430799144 -0.011123474 +0.430963078 -0.012637751 +0.431045881 -0.013399377 +0.431419174 -0.016805793 +0.431458889 -0.017165575 +0.431871141 -0.020870121 +0.432311574 -0.024766686 +0.432364093 -0.025227061 +0.432377828 -0.025347319 +0.432498439 -0.026400589 +0.432663257 -0.027832104 +0.43316426 -0.032127725 +0.433216403 -0.032569945 +0.433255957 -0.032904779 +0.433290822 -0.033199489 +0.433381994 -0.033968187 +0.433442658 -0.034478095 +0.43373407 -0.036910037 +0.43382585 -0.037669938 +0.433900165 -0.038283118 +0.434016946 -0.03924283 +0.434547667 -0.04354466 +0.434662882 -0.044465534 +0.434847861 -0.04593424 +0.434869631 -0.046106296 +0.435374956 -0.050052754 +0.435563236 -0.051499854 +0.435722317 -0.052712585 +0.436253906 -0.056698616 +0.436337888 -0.057318923 +0.436380779 -0.057634727 +0.436464632 -0.058250176 +0.436575002 -0.059056326 +0.437427688 -0.065132323 +0.437452968 -0.065308322 +0.437894024 -0.068340237 +0.438037418 -0.069310115 +0.438280373 -0.070935559 +0.438353457 -0.071420105 +0.438378751 -0.071587332 +0.438739844 -0.073947844 +0.439133059 -0.076461196 +0.439133288 -0.076462644 +0.43938526 -0.078041651 +0.439388854 -0.078063992 +0.439628825 -0.079544432 +0.439782203 -0.080478844 +0.439808569 -0.080638544 +0.439985744 -0.081704588 +0.440102581 -0.082400812 +0.440472457 -0.084569264 +0.44083843 -0.086661275 +0.441181065 -0.088571306 +0.44152638 -0.090448467 +0.441556108 -0.09060782 +0.441691115 -0.091326997 +0.441696609 -0.091356104 +0.441781296 -0.091803262 +0.441785162 -0.091823609 +0.442165858 -0.093797085 +0.442298595 -0.094471262 +0.442303225 -0.094494649 +0.442419999 -0.095081564 +0.442441563 -0.095189334 +0.442543801 -0.095697689 +0.442683391 -0.096384829 +0.442744746 -0.096684314 +0.443396487 -0.099769491 +0.443466635 -0.10009105 +0.443795099 -0.101569413 +0.443883056 -0.101957639 +0.444200092 -0.103330062 +0.444249172 -0.103538749 +0.4447258 -0.10551255 +0.445101858 -0.107002019 +0.44588935 -0.109925908 +0.445954543 -0.110156069 +0.446122009 -0.110738928 +0.446134283 -0.11078117 +0.446256835 -0.111199414 +0.446807229 -0.112997885 +0.446886282 -0.113245437 +0.447030093 -0.113688821 +0.447085841 -0.113858285 +0.447232033 -0.114296263 +0.447273521 -0.114418864 +0.447608723 -0.11538191 +0.447616724 -0.115404298 +0.447659914 -0.115524671 +0.448359614 -0.117360979 +0.4485126 -0.117733856 +0.448722179 -0.118227946 +0.449152622 -0.119181974 +0.449365285 -0.11962309 +0.44964936 -0.120181069 +0.449735342 -0.120342897 +0.449753698 -0.12037702 +0.449803967 -0.1204697 +0.450151561 -0.121079808 +0.450217971 -0.121190255 +0.450810413 -0.12208848 +0.450876298 -0.122178682 +0.451070657 -0.122433459 +0.451384306 -0.12280892 +0.45173611 -0.123177537 +0.451923342 -0.123351044 +0.452222849 -0.123595801 +0.452454762 -0.123757567 +0.452547099 -0.123815226 +0.452776028 -0.123941588 +0.452803217 -0.123955024 +0.45312425 -0.124088423 +0.453158182 -0.124099801 +0.45319617 -0.124111922 +0.453628713 -0.124203902 +0.618402076 -0.124310619 +0.618445487 -0.125067997 +0.61904971 -0.135553838 +0.619667106 -0.146157829 +0.619902396 -0.15016878 +0.6199588 -0.151127773 +0.620755081 -0.164560037 +0.620793444 -0.165202077 +0.620998308 -0.168622612 +0.621250878 -0.172820815 +0.621607767 -0.178716943 +0.621972709 -0.184701751 +0.621987621 -0.184945336 +0.622460452 -0.192628973 +0.622574606 -0.194472313 +0.623313138 -0.206285752 +0.623982575 -0.216822072 +0.623983971 -0.216843879 +0.624071076 -0.218202494 +0.62409674 -0.218602248 +0.624165823 -0.219677064 +0.624319238 -0.222057469 +0.624537804 -0.225433235 +0.624663148 -0.227360901 +0.625018509 -0.232792857 +0.625221019 -0.235866238 +0.625255576 -0.236389081 +0.625641517 -0.242195923 +0.625659114 -0.242459265 +0.625871194 -0.245623254 +0.625953237 -0.246842338 +0.62672388 -0.258158559 +0.627576566 -0.270389265 +0.627727026 -0.272515118 +0.628429251 -0.28230606 +0.628696132 -0.285969929 +0.628732575 -0.286467768 +0.629281937 -0.293899839 +0.62993944 -0.302613581 +0.630134622 -0.305161704 +0.630409901 -0.308725143 +0.630754612 -0.313136869 +0.630987308 -0.316082979 +0.631048751 -0.316856567 +0.631305113 -0.32006461 +0.631839993 -0.326655209 +0.631899944 -0.32738518 +0.632127644 -0.330141534 +0.632515107 -0.33477276 +0.632692679 -0.336870175 +0.633247821 -0.343324826 +0.633420462 -0.345300228 +0.633545364 -0.346719893 +0.633657346 -0.347985893 +0.633697176 -0.348434639 +0.633977389 -0.351568494 +0.63439805 -0.356196624 +0.634438846 -0.356640557 +0.634860799 -0.361180802 +0.635250736 -0.365292884 +0.635615442 -0.36906553 +0.636103421 -0.37400144 +0.636445264 -0.37738227 +0.636858305 -0.38138199 +0.636956107 -0.382315329 +0.636970575 -0.382452955 +0.637084518 -0.383532757 +0.637508025 -0.387483096 +0.637808792 -0.390227852 +0.638202022 -0.393739828 +0.638219477 -0.393893695 +0.638661478 -0.397732588 +0.6387381 -0.398386782 +0.638963837 -0.400294638 +0.639191805 -0.402191754 +0.639514163 -0.404823393 +0.640366849 -0.411494411 +0.64046511 -0.412235929 +0.640762708 -0.414447184 +0.640763819 -0.414455341 +0.641219534 -0.417740075 +0.642029206 -0.423272167 +0.64207222 -0.423555114 +0.642253232 -0.42473367 +0.642499118 -0.426303088 +0.642924905 -0.428934556 +0.643777591 -0.433873734 +0.643779673 -0.433885252 +0.643823459 -0.434126861 +0.644630277 -0.438368288 +0.644800747 -0.439213155 +0.644982075 -0.440092115 +0.645482962 -0.442414173 +0.646059821 -0.444894956 +0.646335648 -0.446007657 +0.646426477 -0.446363636 +0.647188333 -0.449145331 +0.647509136 -0.450207161 +0.64787214 -0.45133014 +0.648041019 -0.451824106 +0.648368061 -0.452729184 +0.64867364 -0.45351336 +0.648893704 -0.454041222 +0.649044596 -0.454385298 +0.649076965 -0.454457214 +0.649669178 -0.455654672 +0.649714196 -0.455736514 +0.64974639 -0.455794244 +0.650226236 -0.456575881 +0.650401406 -0.456824369 +0.650599075 -0.457081074 +0.65089151 -0.457414715 +0.651214227 -0.457718941 +0.651356164 -0.457831477 +0.651451761 -0.457899944 +0.651814836 -0.458106205 +0.652304447 -0.458249422 +0.823694242 -0.465639917 +0.824461132 -0.481028081 +0.824546928 -0.482730763 +0.82478499 -0.487435079 +0.824937958 -0.490442119 +0.825276478 -0.497052495 +0.82530525 -0.497611505 +0.825399613 -0.499441756 +0.825490092 -0.501192148 +0.825610895 -0.503522296 +0.825990152 -0.510785938 +0.826252299 -0.515760379 +0.826378122 -0.518134394 +0.826399899 -0.518544394 +0.826487909 -0.520198639 +0.826632393 -0.522904915 +0.826660917 -0.523437804 +0.826749317 -0.525086378 +0.826962482 -0.529043477 +0.827104985 -0.531674373 +0.827105862 -0.531690539 +0.827163132 -0.532744564 +0.82795767 -0.547171744 +0.828634118 -0.559161909 +0.828667588 -0.559748076 +0.828810356 -0.56224078 +0.82891172 -0.564003118 +0.829368248 -0.571862811 +0.829663041 -0.57687005 +0.830218057 -0.586150711 +0.830515727 -0.591048422 +0.830812672 -0.59587814 +0.831049984 -0.599697387 +0.831368412 -0.604765067 +0.832221098 -0.618009467 +0.832642596 -0.624378856 +0.833073783 -0.630771426 +0.833169062 -0.632167043 +0.83355794 -0.637799185 +0.833596218 -0.638347983 +0.833926469 -0.643041076 +0.834375646 -0.649303256 +0.83454594 -0.651640715 +0.834779154 -0.654808885 +0.834925395 -0.656776046 +0.83563184 -0.666065666 +0.835757056 -0.667675143 +0.836484526 -0.676802583 +0.836808855 -0.680748253 +0.836833229 -0.68104167 +0.837003108 -0.683074672 +0.837185378 -0.685232406 +0.837337211 -0.687011159 +0.837962168 -0.694153078 +0.838092858 -0.695609864 +0.838189897 -0.696683282 +0.838209485 -0.696899111 +0.838735166 -0.702583553 +0.838798229 -0.703251491 +0.839042582 -0.705811211 +0.83937427 -0.709213286 +0.839785209 -0.71331186 +0.839831249 -0.713762993 +0.839895268 -0.714387586 +0.840097618 -0.716341089 +0.840747953 -0.722405428 +0.841091873 -0.725479746 +0.841249875 -0.726861199 +0.841600639 -0.729858153 +0.84171139 -0.730784356 +0.842453324 -0.736739569 +0.84330601 -0.743043886 +0.843878956 -0.746953078 +0.844158696 -0.748765722 +0.844274793 -0.74949945 +0.84483828 -0.752905542 +0.845011381 -0.753900105 +0.845813994 -0.758192171 +0.845864067 -0.758442477 +0.846236939 -0.760241703 +0.846409879 -0.761037402 +0.846716752 -0.762388701 +0.846729749 -0.762444219 +0.846786533 -0.762685141 +0.847569438 -0.765735063 +0.847587321 -0.765798799 +0.847995837 -0.767182433 +0.848198255 -0.767816616 +0.848422123 -0.768478277 +0.848671685 -0.769166632 +0.848888334 -0.76972206 +0.848946663 -0.769864902 +0.849042471 -0.770093354 +0.849274809 -0.770615484 +0.849894076 -0.771786369 +0.84989561 -0.77178887 +0.850127494 -0.772144262 +0.85098018 -0.773062621 +0.851195663 -0.773197886 +0.851378205 -0.773281878 +0.851720144 -0.773363655 +0.851832865 -0.773369012 \ No newline at end of file diff --git a/jmetal/problem/resources/ZDT4.pf b/jmetal/problem/resources/ZDT4.pf new file mode 100644 index 00000000..2680c39e --- /dev/null +++ b/jmetal/problem/resources/ZDT4.pf @@ -0,0 +1,1000 @@ +1E-10 0.999989473 +0.000210548 0.985489736 +0.000631265 0.974875018 +0.00116308 0.965896038 +0.001774631 0.957873636 +0.00245054 0.950497073 +0.003176897 0.943636034 +0.003950327 0.93714837 +0.004762835 0.930986705 +0.005613309 0.925077984 +0.006484427 0.91947406 +0.007382509 0.91407847 +0.008304651 0.908870141 +0.009251322 0.903816209 +0.010223535 0.898888505 +0.011203702 0.894152457 +0.012206301 0.889517873 +0.013228986 0.88498267 +0.01425332 0.880612732 +0.015286695 0.876360627 +0.01633815 0.872179227 +0.017392079 0.86812097 +0.018448234 0.864175724 +0.019514877 0.86030434 +0.020596508 0.856485163 +0.021666651 0.852804038 +0.022738313 0.849207716 +0.023822908 0.845653286 +0.024901955 0.842196467 +0.025992952 0.838776702 +0.027066063 0.835482331 +0.028150028 0.8322203 +0.029233371 0.829022309 +0.030312873 0.825894074 +0.031402162 0.822793449 +0.032491107 0.819747104 +0.03357658 0.816760867 +0.03467097 0.813798576 +0.035737015 0.810957638 +0.03681113 0.808137732 +0.03788959 0.805347514 +0.038953278 0.802634151 +0.040024329 0.799939187 +0.041089496 0.79729456 +0.042161656 0.794666963 +0.043221344 0.792102563 +0.044287608 0.789553788 +0.045341209 0.787065248 +0.046390983 0.784614338 +0.047446765 0.782177217 +0.048498354 0.779776582 +0.049545006 0.777412925 +0.050585378 0.775088066 +0.051631155 0.7727751 +0.052667329 0.770506363 +0.053708651 0.768248731 +0.054736876 0.766040867 +0.055769976 0.763843323 +0.056803762 0.761664603 +0.057831465 0.759518266 +0.058863774 0.757381422 +0.059898497 0.755258305 +0.060929865 0.753160245 +0.061960671 0.751080995 +0.062983676 0.749034513 +0.064010869 0.746996307 +0.065029993 0.74499021 +0.066045076 0.743007634 +0.06706409 0.741032647 +0.06808259 0.739073593 +0.069103523 0.737124511 +0.070117914 0.735202127 +0.071136 0.733286671 +0.07215315 0.731386616 +0.073170602 0.729499349 +0.074180682 0.727638692 +0.075192429 0.72578762 +0.076206216 0.723945266 +0.077223398 0.722109018 +0.078242556 0.720281291 +0.079251094 0.718484292 +0.080262861 0.716692992 +0.081275997 0.714910545 +0.082288448 0.713140369 +0.083301273 0.711380401 +0.084317196 0.709625766 +0.085333422 0.707881152 +0.086341193 0.706161281 +0.087351923 0.704446413 +0.08836372 0.702739644 +0.089373262 0.701046389 +0.090385671 0.699357902 +0.09139497 0.69768399 +0.09240707 0.696014688 +0.093420016 0.694353118 +0.094427542 0.692709353 +0.095437769 0.691069961 +0.096447533 0.689439968 +0.097455926 0.687820683 +0.098466941 0.686205576 +0.099473278 0.684606154 +0.100480551 0.683013327 +0.101490361 0.681424481 +0.102494993 0.679851609 +0.103502098 0.678282581 +0.104507411 0.676723939 +0.105512033 0.675173842 +0.106519058 0.673627425 +0.107523642 0.672092022 +0.108530584 0.670560196 +0.109535909 0.669037904 +0.110543551 0.667519096 +0.11155123 0.666007141 +0.112557001 0.664504842 +0.113563938 0.663007511 +0.114573116 0.661513493 +0.115578425 0.66003173 +0.116585929 0.658553183 +0.117589244 0.657087119 +0.118593086 0.655626531 +0.119599062 0.654169028 +0.120604064 0.652719041 +0.12161117 0.65127207 +0.122616893 0.64983305 +0.123622273 0.648400408 +0.124629705 0.646970674 +0.125634334 0.645550661 +0.126640979 0.644133482 +0.127647198 0.642722519 +0.128651341 0.641320002 +0.129656428 0.639921636 +0.13066347 0.638525976 +0.131666848 0.637140733 +0.132672144 0.635758124 +0.13367795 0.634380048 +0.134682449 0.633008925 +0.135685348 0.631645079 +0.136687337 0.630287494 +0.13769117 0.628932392 +0.138694059 0.627583488 +0.139696789 0.626239664 +0.140700662 0.624899131 +0.141703883 0.623564238 +0.142708885 0.622231704 +0.143711339 0.620907216 +0.144714066 0.619586979 +0.145718537 0.618269026 +0.146724196 0.616954055 +0.147728198 0.61564574 +0.148731772 0.614342416 +0.149737046 0.613041287 +0.150739561 0.61174807 +0.151743749 0.610457 +0.152749142 0.609168653 +0.153752109 0.607887633 +0.154756717 0.606608698 +0.155759238 0.605336552 +0.156762243 0.604067881 +0.157766859 0.602801236 +0.158768745 0.601542041 +0.159772217 0.60028483 +0.160774263 0.599033339 +0.161776554 0.597785438 +0.162780402 0.596539467 +0.163784477 0.595297051 +0.164786301 0.59406121 +0.165789653 0.592827244 +0.166791964 0.591598282 +0.167795785 0.590371162 +0.168799926 0.589147318 +0.169802577 0.587928917 +0.170806713 0.586712312 +0.171809342 0.585501096 +0.172813438 0.584291644 +0.173818632 0.583084382 +0.174821177 0.581883776 +0.175823924 0.580686366 +0.176826582 0.579492471 +0.177830666 0.578300266 +0.178833215 0.577113237 +0.179835826 0.575929456 +0.18083984 0.574747323 +0.18184185 0.573570815 +0.182845244 0.572395926 +0.183846892 0.571226293 +0.184849371 0.570058875 +0.185853213 0.568893038 +0.186855933 0.567731643 +0.187859267 0.56657265 +0.188862007 0.565417433 +0.189866082 0.564263748 +0.190867468 0.563116185 +0.191870172 0.561970125 +0.192873765 0.560826043 +0.193876162 0.559686291 +0.194878919 0.558549075 +0.19588297 0.55741332 +0.196883948 0.556283933 +0.197885174 0.555157136 +0.19888767 0.554031762 +0.1998904 0.552908958 +0.2008923 0.551789893 +0.201895452 0.550672222 +0.202898908 0.549556987 +0.203900702 0.548446346 +0.204901152 0.547339916 +0.205902825 0.546234835 +0.2069049 0.545131997 +0.207908192 0.544030492 +0.208909166 0.542934178 +0.209911342 0.541839175 +0.210913267 0.540747056 +0.21191524 0.539657475 +0.212918401 0.538569181 +0.213919823 0.537485327 +0.21492242 0.536402739 +0.215925047 0.535322643 +0.216927737 0.534244982 +0.217931589 0.533168565 +0.218935326 0.532094747 +0.219940216 0.531022158 +0.220940657 0.52995675 +0.221942232 0.528892547 +0.222944499 0.527830011 +0.223946892 0.526769726 +0.22495041 0.525710626 +0.225951107 0.524656853 +0.226952915 0.523604246 +0.227954623 0.522554063 +0.228956432 0.52150608 +0.229958345 0.520460278 +0.230960855 0.519416131 +0.231964455 0.518373116 +0.232965995 0.51733449 +0.233968613 0.516296979 +0.234970711 0.515262225 +0.23597182 0.514230693 +0.236973993 0.513200254 +0.237975164 0.512173019 +0.238976269 0.511148009 +0.239977453 0.510125064 +0.240978726 0.509104159 +0.241980564 0.5080848 +0.24298344 0.507066495 +0.243985524 0.506051091 +0.24498864 0.505036729 +0.245990666 0.504025539 +0.246992576 0.503016524 +0.247995503 0.502008532 +0.248997051 0.501003957 +0.249999608 0.500000392 +0.251001917 0.498999085 +0.252003884 0.498000116 +0.253005796 0.497003185 +0.254008701 0.496007241 +0.255010347 0.495014508 +0.256012979 0.494022749 +0.257015263 0.493033272 +0.25801714 0.492046124 +0.259019991 0.491059934 +0.260020818 0.490077636 +0.261022609 0.489096282 +0.262025236 0.488115994 +0.26302678 0.487138635 +0.264029279 0.486162205 +0.265031961 0.485187451 +0.266033348 0.484215793 +0.267034712 0.483245985 +0.268035788 0.482278271 +0.269037101 0.481312135 +0.270039347 0.480346897 +0.271041823 0.479383228 +0.272044069 0.47842156 +0.273045414 0.477462524 +0.274047173 0.476504849 +0.27504985 0.475548049 +0.276052615 0.474592906 +0.277056293 0.473638629 +0.278056966 0.472688929 +0.279057792 0.471740791 +0.280059517 0.470793503 +0.281060578 0.469848533 +0.282062532 0.468904404 +0.283063367 0.467963002 +0.284065089 0.467022431 +0.285066238 0.466084054 +0.286068267 0.4651465 +0.287069858 0.464210995 +0.288071283 0.463277276 +0.289073579 0.462344368 +0.290075702 0.461413237 +0.291078351 0.460483225 +0.292079886 0.459555843 +0.293082282 0.458629256 +0.294084239 0.457704658 +0.295085698 0.456782089 +0.296087073 0.455861164 +0.297088637 0.45494162 +0.298091048 0.454022851 +0.299093643 0.453105456 +0.300095032 0.452190697 +0.301096755 0.45127716 +0.302099312 0.450364382 +0.303101439 0.449453509 +0.304102902 0.448544742 +0.305105191 0.447636722 +0.306106738 0.446730864 +0.307108005 0.445826737 +0.30811009 0.444923348 +0.30911189 0.444021682 +0.310112773 0.4431223 +0.311114464 0.442223644 +0.312116751 0.441325899 +0.313118627 0.440429963 +0.314119953 0.439535949 +0.31512117 0.438643455 +0.316122977 0.437751855 +0.317125578 0.43686096 +0.318126401 0.43597305 +0.319128012 0.435085837 +0.320130103 0.434199591 +0.321131311 0.43331551 +0.322133301 0.432432118 +0.323135178 0.431550197 +0.324135816 0.430670732 +0.325137227 0.429791944 +0.326137921 0.428915137 +0.327139383 0.428039003 +0.328140137 0.427164826 +0.329141031 0.426291859 +0.330142687 0.425419556 +0.331144334 0.424548583 +0.332144619 0.423680107 +0.333145658 0.422812285 +0.334146954 0.421945545 +0.335148809 0.421079618 +0.336151033 0.420214667 +0.337152451 0.419351698 +0.338154615 0.418489369 +0.339156631 0.417628442 +0.34015939 0.416768151 +0.341160455 0.415910576 +0.34216203 0.415053823 +0.343164338 0.414197697 +0.344165195 0.413344058 +0.345166256 0.412491485 +0.346167658 0.411639857 +0.347169785 0.410788845 +0.348170901 0.409939917 +0.349172738 0.409091599 +0.350174624 0.408244456 +0.351175766 0.407399152 +0.352177419 0.40655462 +0.353179786 0.405710688 +0.354182695 0.404867498 +0.355182773 0.404027876 +0.356183556 0.403188844 +0.35718499 0.402350445 +0.35818578 0.401513759 +0.35918727 0.400677658 +0.360188287 0.399843115 +0.36119 0.399009152 +0.362190867 0.398177047 +0.363192426 0.397345517 +0.364193638 0.39651542 +0.365195539 0.395685894 +0.366196905 0.394857947 +0.367198467 0.394030969 +0.368200712 0.393204555 +0.36920194 0.392380102 +0.370203847 0.391556209 +0.371205538 0.390733607 +0.372207905 0.38991156 +0.373208988 0.38909167 +0.374210008 0.38827293 +0.375211699 0.387454737 +0.376213324 0.38663769 +0.377214826 0.385821829 +0.378215706 0.385007556 +0.379217249 0.384193822 +0.3802181 0.383381723 +0.381219611 0.382570157 +0.382220602 0.381760078 +0.383222249 0.380950528 +0.384223571 0.380142298 +0.385225176 0.379334892 +0.386227434 0.378528011 +0.387228228 0.377723351 +0.388229669 0.376919211 +0.389230742 0.376116404 +0.390232458 0.375314112 +0.39123468 0.374512446 +0.392236807 0.373711881 +0.393237813 0.372913233 +0.394239457 0.372115093 +0.395240585 0.371318376 +0.396242347 0.370522164 +0.397243596 0.369727364 +0.398245477 0.368933065 +0.399247219 0.368139874 +0.400248048 0.367348399 +0.401248956 0.366557851 +0.402249684 0.36576843 +0.403250353 0.364980037 +0.404251643 0.364192134 +0.405252743 0.363405354 +0.406254463 0.36261906 +0.407255769 0.361834059 +0.408257691 0.36104954 +0.409258995 0.360266465 +0.410260913 0.35948387 +0.411262607 0.358702404 +0.412263632 0.35792241 +0.413265265 0.357142889 +0.414267443 0.356363889 +0.41526888 0.355586406 +0.416270921 0.354809392 +0.417272012 0.354034047 +0.418273704 0.353259168 +0.419274758 0.352485708 +0.420276411 0.35171271 +0.421277298 0.350941221 +0.422278781 0.350170191 +0.423280403 0.349399967 +0.424281319 0.348631196 +0.425282826 0.347862878 +0.426283754 0.347095908 +0.427284657 0.346329856 +0.428285633 0.345564646 +0.429287194 0.344799882 +0.430288825 0.344035958 +0.431290432 0.343272939 +0.432291034 0.342511571 +0.433291987 0.341750817 +0.434293518 0.340990502 +0.435295398 0.3402308 +0.436297352 0.339471915 +0.437298238 0.338714708 +0.438299698 0.337957934 +0.439300627 0.337202424 +0.440302126 0.336447345 +0.44130349 0.335693226 +0.442305422 0.334939535 +0.443306896 0.334187041 +0.444308574 0.333435244 +0.445309687 0.332684717 +0.446310797 0.331935035 +0.44731247 0.331185773 +0.448313026 0.330438184 +0.44931414 0.329691011 +0.450315579 0.328944429 +0.451316367 0.328199162 +0.452317635 0.327454362 +0.453319459 0.326709974 +0.454320405 0.325967059 +0.455321904 0.325224553 +0.456323793 0.324482574 +0.457324275 0.323742449 +0.458325305 0.323002729 +0.459326281 0.322263856 +0.460327802 0.321525386 +0.461329145 0.32078785 +0.462331031 0.320050714 +0.463332062 0.319315005 +0.464333635 0.318579693 +0.465335654 0.317844846 +0.466336105 0.317111938 +0.467337093 0.316379423 +0.46833784 0.315647868 +0.469339123 0.314916704 +0.470340235 0.314186443 +0.471341017 0.313457199 +0.472342332 0.312728342 +0.473343453 0.312000398 +0.474345104 0.311272838 +0.475346708 0.31054608 +0.47634731 0.309820814 +0.477348437 0.309095928 +0.478349542 0.308371818 +0.479351171 0.307648087 +0.480352287 0.306925482 +0.481353925 0.306203254 +0.482355569 0.305481772 +0.483356552 0.304761514 +0.484358054 0.304041629 +0.485358432 0.303323294 +0.486358965 0.302605589 +0.487360013 0.301888252 +0.488361214 0.301171542 +0.489362079 0.300455807 +0.490363455 0.299740437 +0.491364286 0.299026188 +0.492365388 0.298312471 +0.493367 0.297599117 +0.494368883 0.296886294 +0.49537009 0.296174673 +0.496371804 0.295463412 +0.497373252 0.294753056 +0.498375204 0.294043058 +0.499377073 0.293333832 +0.5003794 0.292624994 +0.501379872 0.291918174 +0.502380844 0.291211707 +0.503381784 0.290505966 +0.504383223 0.289800576 +0.505384188 0.289096218 +0.50638565 0.288392208 +0.507386833 0.287689089 +0.508387758 0.286986846 +0.509389176 0.286284948 +0.510390754 0.285583627 +0.511392083 0.284883168 +0.512393903 0.284183052 +0.513395464 0.283483801 +0.51439631 0.28278573 +0.515397288 0.282088245 +0.516398318 0.281391402 +0.517399834 0.280694895 +0.5184014 0.279999028 +0.519402336 0.27930427 +0.52040323 0.278610209 +0.521404345 0.277916663 +0.522405453 0.277223788 +0.52340704 0.276531245 +0.524408322 0.275839575 +0.525410081 0.275148235 +0.526410989 0.274458141 +0.527412373 0.273768375 +0.528413336 0.273079553 +0.529414427 0.272391295 +0.53041535 0.271703803 +0.531416746 0.271016636 +0.532417804 0.270330346 +0.533419333 0.269644379 +0.534420269 0.268959461 +0.535421675 0.268274864 +0.536422998 0.267590963 +0.537424788 0.266907381 +0.538425652 0.266225067 +0.539426564 0.265543355 +0.54042794 0.264861959 +0.541428973 0.264181427 +0.542430468 0.26350121 +0.543431388 0.262822011 +0.544432768 0.262143125 +0.545433211 0.261465498 +0.546434114 0.260788181 +0.547435307 0.260111288 +0.548436619 0.259434933 +0.54943722 0.258759675 +0.550437921 0.258084964 +0.551439077 0.25741056 +0.552440331 0.256736702 +0.553441948 0.25606321 +0.554443144 0.25539061 +0.555444447 0.254718545 +0.556445625 0.25404717 +0.557447254 0.253376096 +0.55844788 0.252706296 +0.559448954 0.252036796 +0.560449962 0.25136794 +0.561451256 0.250699489 +0.562452996 0.250031337 +0.563454172 0.249364155 +0.564455029 0.248697778 +0.56545633 0.248031696 +0.56645738 0.247366371 +0.567458873 0.246701339 +0.568460314 0.246036928 +0.569461129 0.245373517 +0.570462383 0.244710398 +0.571463437 0.244047993 +0.57246493 0.243385878 +0.573465981 0.242724633 +0.57446747 0.242063677 +0.575468208 0.241403791 +0.576469382 0.240744192 +0.577470407 0.240085263 +0.578471866 0.23942662 +0.579472971 0.23876878 +0.580474509 0.238111223 +0.581475587 0.237454534 +0.582477098 0.236798128 +0.583478177 0.236142568 +0.584479686 0.235487288 +0.585481248 0.234832536 +0.586481962 0.234178897 +0.587482637 0.23352584 +0.588483348 0.232873317 +0.589484485 0.23222107 +0.590485656 0.231569355 +0.591486649 0.230918308 +0.592487852 0.230267675 +0.593489183 0.229617508 +0.594490938 0.228967616 +0.595491798 0.22831885 +0.596492587 0.227670675 +0.597493795 0.227022772 +0.598495325 0.226375204 +0.599496559 0.225728369 +0.600498211 0.225081804 +0.601500218 0.224435549 +0.602501343 0.2237904 +0.603502294 0.223145899 +0.604503365 0.222501855 +0.605504674 0.221858192 +0.606506397 0.221214794 +0.607506771 0.220572793 +0.608507557 0.219931057 +0.60950842 0.219289798 +0.610509695 0.218648802 +0.611510758 0.218008467 +0.612512231 0.217368394 +0.613513664 0.21672887 +0.614514997 0.216089931 +0.615516738 0.215451252 +0.616517872 0.21481348 +0.617519412 0.214175966 +0.618520247 0.213539418 +0.619521071 0.212903392 +0.620522299 0.212267622 +0.621523514 0.211632374 +0.62252478 0.210997605 +0.623526449 0.210363091 +0.624527035 0.209729771 +0.625527608 0.209096967 +0.626528581 0.208464416 +0.627529817 0.207832204 +0.628531179 0.207200417 +0.629532032 0.206569454 +0.630533283 0.205938741 +0.631534416 0.205308603 +0.632535485 0.204679005 +0.633536951 0.204049656 +0.634537941 0.203421102 +0.635539029 0.202792983 +0.636540511 0.202165111 +0.637541408 0.201538099 +0.638542217 0.200911634 +0.639543418 0.200285415 +0.640544112 0.199660002 +0.641545197 0.199034834 +0.64254649 0.198410024 +0.643547294 0.197786005 +0.644548487 0.197162229 +0.645549807 0.196538858 +0.646550989 0.195916056 +0.647552064 0.195293803 +0.648553526 0.19467179 +0.6495552 0.194050126 +0.650556178 0.193429372 +0.651557168 0.192809088 +0.652558542 0.192189043 +0.653559927 0.191569467 +0.654560847 0.190950652 +0.65556215 0.190332074 +0.656563074 0.189714202 +0.657564379 0.189096566 +0.658565016 0.188479812 +0.659565663 0.187863519 +0.66056669 0.187247461 +0.661567466 0.186632023 +0.66256849 0.186016898 +0.663569892 0.185402006 +0.664570991 0.184787763 +0.665572467 0.184173752 +0.666574278 0.183559997 +0.667575358 0.182947151 +0.668576814 0.182334534 +0.669577622 0.181722772 +0.670578805 0.181111238 +0.671579758 0.180500301 +0.672580737 0.179889802 +0.67358209 0.17927953 +0.674583469 0.178669696 +0.675585005 0.178060218 +0.676586221 0.177451387 +0.677587808 0.176842781 +0.67858923 0.176234724 +0.679591021 0.175626892 +0.680591809 0.175020116 +0.681592966 0.174413562 +0.682594232 0.173807388 +0.68359508 0.173201911 +0.684596293 0.172596656 +0.685597419 0.171991897 +0.686598911 0.171387358 +0.687599545 0.170783777 +0.688600269 0.17018058 +0.689601358 0.169577603 +0.690602536 0.168975009 +0.691603432 0.168373021 +0.692604692 0.167771251 +0.693605477 0.1671702 +0.694606261 0.166569583 +0.695607223 0.165969292 +0.696608545 0.165369216 +0.697610045 0.164769466 +0.698610572 0.164170728 +0.699611457 0.163572204 +0.700612126 0.162974238 +0.701613152 0.162376485 +0.702614378 0.16177904 +0.703615646 0.161181995 +0.704616604 0.160585559 +0.705617918 0.159989335 +0.706618814 0.159393782 +0.707619794 0.158798601 +0.708621129 0.15820363 +0.709622548 0.157609029 +0.710624199 0.15701471 +0.711625281 0.156421147 +0.712626376 0.155827994 +0.713627823 0.155235049 +0.714628796 0.1546428 +0.71563012 0.154050758 +0.716631665 0.153459 +0.717632687 0.152867964 +0.718634058 0.152277134 +0.719635024 0.151686954 +0.720636339 0.151096979 +0.721636966 0.150507819 +0.72263794 0.149918863 +0.723638853 0.14933035 +0.724640112 0.148742041 +0.725640761 0.148154497 +0.726641698 0.147567188 +0.727642981 0.146980082 +0.728644331 0.14639334 +0.729645722 0.145806976 +0.730647141 0.145220999 +0.731647945 0.144635783 +0.732649091 0.144050766 +0.733650241 0.143466147 +0.734651733 0.142881728 +0.735652824 0.14229794 +0.736654257 0.14171435 +0.73765549 0.141131273 +0.738656039 0.14054899 +0.739656926 0.139966904 +0.740657753 0.139385247 +0.741658918 0.138803787 +0.742659881 0.138222836 +0.743661181 0.137642081 +0.744662119 0.137061926 +0.745663393 0.136481967 +0.746664314 0.135902601 +0.747665571 0.13532343 +0.748666737 0.134744699 +0.749667809 0.134166408 +0.750669216 0.13358831 +0.751670091 0.133010905 +0.752671298 0.132433692 +0.753672654 0.131856778 +0.754673667 0.131280444 +0.755675013 0.130704301 +0.756675972 0.130128762 +0.757677262 0.129553413 +0.758678308 0.128978584 +0.759679684 0.128403944 +0.760680729 0.127829874 +0.761682104 0.127255992 +0.762683589 0.126682424 +0.763684422 0.126109605 +0.764685583 0.125536975 +0.765686692 0.124964748 +0.766688128 0.124392709 +0.767689005 0.123821362 +0.768689889 0.123250384 +0.7696911 0.122679591 +0.770692133 0.12210927 +0.771693493 0.121539134 +0.77269404 0.12096983 +0.773694911 0.12040071 +0.774695721 0.119831993 +0.775696499 0.119263661 +0.7766976 0.118695512 +0.777698621 0.118127775 +0.778699964 0.117560221 +0.779701391 0.116992984 +0.780702839 0.116426099 +0.781703234 0.115860173 +0.782703818 0.115294502 +0.783704723 0.114729012 +0.784705817 0.114163775 +0.785706744 0.113598994 +0.786707661 0.113034577 +0.787708897 0.11247034 +0.788710123 0.111906468 +0.789711097 0.111343094 +0.790712141 0.110780038 +0.791713502 0.11021716 +0.792714519 0.109654832 +0.793715852 0.10909268 +0.794716824 0.108531087 +0.79571811 0.10796967 +0.796719447 0.107408578 +0.797720293 0.106848113 +0.798721454 0.106287824 +0.799722298 0.105728062 +0.800723456 0.105168476 +0.801724835 0.104609116 +0.802725503 0.104050502 +0.803726484 0.103492062 +0.804727656 0.102933862 +0.805728455 0.102376218 +0.806729565 0.101818746 +0.807730547 0.101261692 +0.808731439 0.100705032 +0.809732641 0.100148545 +0.810734043 0.099592291 +0.811735538 0.099036328 +0.812736432 0.098481042 +0.813737634 0.097925927 +0.814738943 0.097371093 +0.815739877 0.096816809 +0.816741119 0.096262694 +0.817741965 0.095709137 +0.818743117 0.09515575 +0.819744154 0.094602764 +0.820745167 0.09405013 +0.821746485 0.093497664 +0.82274736 0.092945779 +0.823748245 0.092394224 +0.824749433 0.091842837 +0.825750629 0.09129178 +0.826752045 0.090740936 +0.827753079 0.090190636 +0.828754415 0.089640502 +0.82975574 0.089090707 +0.830757366 0.088541078 +0.831758642 0.087991973 +0.832759871 0.087443223 +0.833761401 0.086894638 +0.83476259 0.08634657 +0.835763692 0.085798878 +0.836765094 0.085251349 +0.837766409 0.084704196 +0.838767089 0.084157716 +0.839768067 0.083611399 +0.840769119 0.083065368 +0.841770221 0.082519635 +0.842771621 0.081974063 +0.843772283 0.081429217 +0.844773242 0.080884533 +0.845774443 0.08034004 +0.846775502 0.079795945 +0.847776858 0.079252012 +0.848777719 0.078708668 +0.849778876 0.078165483 +0.850780088 0.077622589 +0.851781595 0.077079855 +0.852782292 0.076537877 +0.853783283 0.075996059 +0.854784193 0.075454602 +0.855785231 0.074913393 +0.856786562 0.074372342 +0.857787302 0.073831926 +0.858788335 0.073291667 +0.859789487 0.072751658 +0.860790301 0.072212146 +0.861791407 0.071672791 +0.86279227 0.071133879 +0.863793424 0.070595124 +0.864794379 0.070056787 +0.865795501 0.069518672 +0.866796913 0.068980713 +0.867797847 0.068443321 +0.86879907 0.067906083 +0.869799865 0.067369385 +0.870800744 0.06683295 +0.871801652 0.066296807 +0.872802848 0.065760819 +0.873804073 0.065225122 +0.87480493 0.064689928 +0.875806074 0.064154888 +0.876807161 0.063620183 +0.877808238 0.063085789 +0.878809601 0.062551548 +0.879810501 0.062017857 +0.880811362 0.06148449 +0.881812507 0.060951275 +0.882813614 0.060418384 +0.88381461 0.059885853 +0.884815527 0.059353665 +0.885816728 0.058821628 +0.886817538 0.058290099 +0.88781863 0.05775872 +0.888819906 0.057227543 +0.8898209 0.056696814 +0.890822176 0.056166235 +0.891822967 0.05563621 +0.892824039 0.055106334 +0.893824892 0.054576871 +0.894825699 0.054047729 +0.895826786 0.053518734 +0.896827827 0.05299006 +0.897828832 0.052461699 +0.898830116 0.051933486 +0.899831131 0.051405708 +0.900832425 0.050878077 +0.901833502 0.050350853 +0.902834379 0.049824027 +0.903835533 0.049297348 +0.904836832 0.048770884 +0.905838142 0.048244705 +0.906839163 0.047718969 +0.907840035 0.0471936 +0.908841183 0.046668377 +0.909842365 0.046143426 +0.910843129 0.045618981 +0.91184408 0.045094727 +0.912845306 0.044570617 +0.913846175 0.044046981 +0.914847317 0.043523489 +0.91584854 0.04300024 +0.916849703 0.04247731 +0.917850803 0.041954697 +0.918852008 0.041432315 +0.919853485 0.040910074 +0.920854219 0.040388506 +0.921855225 0.039867079 +0.92285629 0.039345905 +0.923857541 0.038824917 +0.924858469 0.038304378 +0.925859668 0.037783981 +0.926860612 0.037263997 +0.927861825 0.036744154 +0.92886271 0.036224762 +0.929863864 0.03570551 +0.930865196 0.035186445 +0.931866615 0.034667614 +0.932867402 0.034149389 +0.933868458 0.033631304 +0.934869383 0.033113563 +0.935870577 0.03259596 +0.936871497 0.032078775 +0.937872686 0.031561729 +0.938874082 0.031044851 +0.939874896 0.030528548 +0.940875818 0.030012465 +0.941877007 0.029496519 +0.942878304 0.028980791 +0.943879368 0.028465457 +0.94488035 0.027950439 +0.945881425 0.027435645 +0.946882764 0.026920988 +0.947883916 0.026406699 +0.948885333 0.025892546 +0.949886316 0.025378886 +0.950887563 0.024865362 +0.951888409 0.024352313 +0.952889519 0.023839399 +0.953890777 0.023326679 +0.954892066 0.022814211 +0.955893 0.022302194 +0.956894195 0.021790311 +0.957895178 0.021278805 +0.958896422 0.020767432 +0.959897632 0.020256344 +0.960898621 0.019745635 +0.961899872 0.019235058 +0.962900965 0.018724827 +0.963902319 0.018214729 +0.964903805 0.017704828 +0.965905057 0.017195311 +0.966906568 0.016685926 +0.967907673 0.016177011 +0.968909038 0.015668228 +0.96991048 0.015159668 +0.970912181 0.014651239 +0.971914114 0.014142955 +0.97291547 0.013635225 +0.973916926 0.013127705 +0.97491864 0.012620316 +0.975920408 0.01211316 +0.976922433 0.011606135 +0.977924167 0.011099516 +0.978926069 0.010593072 +0.979928199 0.010086772 +0.980930586 0.009580601 +0.981933085 0.009074632 +0.982935517 0.008568955 +0.983938206 0.008063407 +0.984941084 0.00755802 +0.985943789 0.007052978 +0.986946632 0.006548123 +0.987949729 0.006043397 +0.988952849 0.005538915 +0.989956223 0.005034562 +0.990959736 0.004530394 +0.991963354 0.004026429 +0.992967226 0.003522592 +0.993971225 0.003018945 +0.994975478 0.002515425 +0.995979929 0.00201206 +0.996984613 0.001508832 +0.997989495 0.001005758 +0.998994621 0.000502816 +1 0 \ No newline at end of file diff --git a/jmetal/problem/resources/ZDT6.pf b/jmetal/problem/resources/ZDT6.pf new file mode 100644 index 00000000..6e240aaf --- /dev/null +++ b/jmetal/problem/resources/ZDT6.pf @@ -0,0 +1,1000 @@ +0.280775319 0.92116522 +0.281499068 0.920758275 +0.282222229 0.920350613 +0.282944464 0.91994243 +0.283665793 0.919533718 +0.284387387 0.919123814 +0.285109031 0.91871284 +0.285829762 0.918301347 +0.286549863 0.917889176 +0.287269615 0.917476168 +0.287989783 0.917061885 +0.28870905 0.916647084 +0.289429667 0.916230468 +0.290150028 0.915812961 +0.290869496 0.915394937 +0.291588714 0.914976022 +0.292308153 0.914555944 +0.293028387 0.914134364 +0.293747736 0.913712268 +0.294468657 0.91328821 +0.295188697 0.912863634 +0.295909219 0.912437734 +0.296628864 0.912011317 +0.297348605 0.911583807 +0.298068798 0.911154992 +0.298788994 0.910725137 +0.299508759 0.910294503 +0.300227658 0.909863353 +0.300948579 0.909429953 +0.301669222 0.908995681 +0.302389003 0.908560891 +0.303109371 0.908124709 +0.303828883 0.90768801 +0.3045484 0.907250272 +0.305268871 0.906810916 +0.305988492 0.906371043 +0.306708669 0.905929793 +0.307428 0.905488025 +0.308148104 0.905044746 +0.308867366 0.90460095 +0.309587509 0.904155574 +0.310306815 0.903709681 +0.311026996 0.903262208 +0.311746779 0.902813946 +0.312465731 0.902365167 +0.313185512 0.901914835 +0.313905711 0.901463204 +0.314626023 0.901010466 +0.315345509 0.90055721 +0.316065112 0.900102845 +0.316785545 0.899646918 +0.317505159 0.899190474 +0.318225646 0.898732438 +0.318945318 0.898273884 +0.319665319 0.897814084 +0.320385434 0.897353174 +0.32110474 0.896891746 +0.321825549 0.896428316 +0.322545551 0.895964367 +0.323265416 0.895499471 +0.323984746 0.895033884 +0.324705403 0.894566402 +0.32542526 0.8940984 +0.326146153 0.893628687 +0.326866249 0.893158455 +0.327585737 0.892687585 +0.328305373 0.892215582 +0.32902613 0.891741806 +0.329746098 0.891267511 +0.330466369 0.890791979 +0.331186705 0.890315367 +0.331906257 0.889838236 +0.332625465 0.8893603 +0.333345893 0.888880516 +0.334065542 0.888400214 +0.334785756 0.887918498 +0.335505195 0.887436264 +0.33622541 0.886952474 +0.336944854 0.886468166 +0.337664781 0.885982496 +0.338383941 0.885496309 +0.33910425 0.885008308 +0.339824202 0.884519512 +0.340544537 0.884029418 +0.341264111 0.883538807 +0.341983154 0.883047522 +0.342703317 0.882554436 +0.343423772 0.882060113 +0.344143712 0.881565105 +0.3448629 0.88106958 +0.345582548 0.880572703 +0.346302137 0.88007483 +0.347022403 0.879575452 +0.347743009 0.8790748 +0.348462869 0.878573629 +0.349183069 0.878071184 +0.349903006 0.877567886 +0.350622546 0.87706383 +0.351341348 0.876559257 +0.352061845 0.876052458 +0.352782289 0.875544656 +0.353501998 0.875036337 +0.354222955 0.874526098 +0.354943179 0.87401534 +0.355662955 0.873503863 +0.356382569 0.872991465 +0.35710254 0.872477776 +0.357823192 0.871962564 +0.358543117 0.871446833 +0.359263435 0.870929784 +0.359983032 0.870412217 +0.360702707 0.869893557 +0.361421665 0.86937438 +0.362142066 0.868853124 +0.362862305 0.868330948 +0.36358183 0.867808253 +0.364301196 0.867284639 +0.365020451 0.86676007 +0.365740585 0.866233825 +0.36646001 0.865707061 +0.367179589 0.865179149 +0.367900454 0.864649256 +0.368620672 0.8641188 +0.3693408 0.863587373 +0.370060227 0.863055429 +0.370779936 0.862522239 +0.371498946 0.861988533 +0.372218264 0.861453564 +0.372936887 0.860918078 +0.373657933 0.860379749 +0.374378283 0.859840901 +0.375098148 0.85930138 +0.375817997 0.858760834 +0.376537156 0.85821977 +0.377258115 0.857676314 +0.377978386 0.85713234 +0.378698031 0.856587802 +0.379417552 0.856042322 +0.380138236 0.855494921 +0.380858238 0.854947003 +0.381579057 0.854397423 +0.382299701 0.853846939 +0.383019666 0.853295935 +0.38373946 0.852744027 +0.384459889 0.852190594 +0.385179643 0.851636642 +0.385899355 0.851081688 +0.386618396 0.850526216 +0.387337639 0.849969554 +0.388057454 0.849411413 +0.388777149 0.848852329 +0.389496177 0.848292728 +0.390216268 0.847731264 +0.390936155 0.847168923 +0.39165538 0.846606064 +0.392376004 0.846041072 +0.393095966 0.845475562 +0.39381683 0.844908305 +0.394537034 0.844340529 +0.395257448 0.84377155 +0.39597735 0.843201938 +0.396697341 0.84263122 +0.397416678 0.842059984 +0.398136719 0.841487153 +0.398856558 0.840913446 +0.399575747 0.840339222 +0.40029527 0.839763697 +0.401015708 0.839186402 +0.401736077 0.838608125 +0.4024558 0.838029329 +0.403175458 0.83744955 +0.40389572 0.836868248 +0.404615635 0.836286188 +0.405335108 0.83570345 +0.406053942 0.835120196 +0.406774652 0.834534382 +0.407494724 0.83394805 +0.408214975 0.833360535 +0.40893459 0.832772501 +0.40965434 0.832183322 +0.41037509 0.831592286 +0.411095598 0.831000409 +0.411815475 0.830408015 +0.412535718 0.829814282 +0.413255633 0.829219782 +0.413975929 0.828623931 +0.414695598 0.828027561 +0.415415679 0.827429813 +0.41613594 0.82683088 +0.416855577 0.826231428 +0.417575823 0.825630433 +0.418295986 0.825028468 +0.419015529 0.824425987 +0.419735696 0.823821945 +0.420455686 0.823217017 +0.421175058 0.82261157 +0.421895113 0.822004514 +0.422614981 0.821396578 +0.423335018 0.820787463 +0.424054443 0.82017783 +0.424774038 0.819567017 +0.42549453 0.818954405 +0.426214412 0.818341275 +0.4269345 0.817726933 +0.427654348 0.817111759 +0.428373589 0.816496068 +0.429092594 0.815879546 +0.429812895 0.815260876 +0.430533279 0.814641095 +0.431253062 0.814020797 +0.43197293 0.813399388 +0.432692908 0.812776847 +0.433412793 0.812153351 +0.434132332 0.811529118 +0.43485231 0.810903468 +0.435571692 0.810277301 +0.436291514 0.809649715 +0.437011463 0.809020982 +0.437731468 0.808391162 +0.438451463 0.807760314 +0.439170867 0.80712895 +0.43989148 0.806495486 +0.440611502 0.805861504 +0.441332152 0.805225932 +0.442052342 0.804589727 +0.442772313 0.803952679 +0.443491699 0.803315113 +0.44421222 0.802675504 +0.444932157 0.802035376 +0.445651744 0.801394523 +0.446371908 0.80075212 +0.44709208 0.800108672 +0.447811967 0.799464442 +0.448532274 0.798818799 +0.4492525 0.798172191 +0.449972149 0.797525065 +0.450692414 0.796876348 +0.451412815 0.796226471 +0.45213264 0.795576076 +0.452853116 0.794924055 +0.45357302 0.794271516 +0.454292866 0.793617992 +0.455012393 0.792963722 +0.455731792 0.792308534 +0.456451547 0.791651985 +0.457171639 0.790994093 +0.457891163 0.790335683 +0.458610237 0.78967665 +0.459330328 0.78901565 +0.460049855 0.788354131 +0.460770106 0.787690909 +0.461489795 0.787027169 +0.462209778 0.786362122 +0.462929554 0.785696228 +0.463649678 0.785028976 +0.464369243 0.784361206 +0.46508959 0.783691673 +0.465809379 0.783021622 +0.466529455 0.782350268 +0.467248974 0.781678396 +0.467969159 0.781004867 +0.468689412 0.780330235 +0.469409112 0.779655086 +0.470128882 0.778978834 +0.470848171 0.778302 +0.471568624 0.777623033 +0.472289087 0.776943018 +0.47300944 0.776262069 +0.473729245 0.775580602 +0.474449523 0.77489765 +0.475170063 0.774213411 +0.475890057 0.773528653 +0.476609926 0.772842979 +0.477329903 0.772156164 +0.478049337 0.771468831 +0.478768882 0.770780358 +0.479489194 0.770090113 +0.480208964 0.769399351 +0.480929234 0.768707072 +0.481648965 0.768014275 +0.482368899 0.767320245 +0.483089055 0.766624965 +0.483808675 0.765929167 +0.484529217 0.765231438 +0.485249507 0.764532916 +0.485969262 0.763833877 +0.48668874 0.763134071 +0.487408762 0.762432698 +0.488128253 0.761730809 +0.488847778 0.76102785 +0.489567255 0.760323903 +0.490287164 0.759618497 +0.4910075 0.758911635 +0.491727307 0.758204255 +0.492447587 0.757495374 +0.49316734 0.756785975 +0.493887251 0.756075384 +0.49460738 0.755363539 +0.495327846 0.754650325 +0.496047788 0.753936592 +0.496768153 0.753221402 +0.497487995 0.752505694 +0.49820804 0.751788749 +0.498927564 0.751071286 +0.499646927 0.750352949 +0.500367235 0.74963263 +0.501087299 0.748911519 +0.501807256 0.748189477 +0.502526698 0.747466918 +0.503246034 0.746743429 +0.503966512 0.746017755 +0.504686907 0.745291126 +0.505406788 0.744563979 +0.506126445 0.743836022 +0.506846167 0.743106963 +0.507566505 0.742376243 +0.508286331 0.741645006 +0.509005835 0.740913061 +0.509725902 0.740179505 +0.510445462 0.739445431 +0.51116529 0.738710046 +0.511884612 0.737974144 +0.512604924 0.737236192 +0.513325271 0.736497166 +0.514045384 0.735757344 +0.5147657 0.735016274 +0.515485512 0.734274687 +0.516205843 0.733531527 +0.516925672 0.73278785 +0.517645313 0.73204333 +0.518365146 0.731297575 +0.51908448 0.730551303 +0.519804909 0.729802857 +0.520524991 0.729053734 +0.521245296 0.728303341 +0.521965104 0.72755243 +0.522685136 0.726800249 +0.523405048 0.726047155 +0.524124466 0.725293544 +0.524844433 0.724538322 +0.525564561 0.723781892 +0.526284197 0.723024944 +0.527003472 0.722267341 +0.527723858 0.72150753 +0.528443753 0.720747201 +0.529163406 0.71998609 +0.529883944 0.719223006 +0.530603991 0.718459404 +0.531323778 0.717695043 +0.53204353 0.716929682 +0.53276325 0.716163319 +0.533483447 0.715395412 +0.534203659 0.714626451 +0.534923385 0.713856972 +0.535643343 0.713086209 +0.536362818 0.712314928 +0.537083413 0.711541407 +0.537803575 0.710767315 +0.538523254 0.709992705 +0.539243552 0.709216392 +0.539963369 0.70843956 +0.540684104 0.7076607 +0.541404461 0.706881209 +0.54212434 0.7061012 +0.542843977 0.705320417 +0.54356319 0.704539058 +0.54428352 0.70375545 +0.545003373 0.702971323 +0.545723475 0.702185889 +0.546443553 0.701399444 +0.547163156 0.70061248 +0.547883081 0.69982413 +0.548602532 0.699035262 +0.54932259 0.698244692 +0.550042176 0.697453605 +0.550762423 0.696660754 +0.551482199 0.695867385 +0.5522019 0.695073061 +0.552922253 0.694276982 +0.553642137 0.693480384 +0.554362493 0.692682226 +0.555082381 0.69188355 +0.555802685 0.691083375 +0.556522523 0.690282682 +0.557242353 0.68948096 +0.557962353 0.688678013 +0.558681888 0.687874548 +0.559401678 0.687069763 +0.560121005 0.686264459 +0.560841093 0.685457268 +0.561561269 0.684648941 +0.562280984 0.683840095 +0.563001208 0.68302964 +0.563721434 0.682218145 +0.564441199 0.681406133 +0.565160966 0.680593083 +0.565881572 0.679778046 +0.56660172 0.678962491 +0.567321445 0.678146378 +0.568041456 0.677328904 +0.568761011 0.676510912 +0.569480963 0.675691433 +0.570200904 0.674870929 +0.570920391 0.674049907 +0.571639868 0.673227861 +0.572360008 0.672404021 +0.57308021 0.671579073 +0.57379996 0.670753606 +0.574520201 0.669926539 +0.575240453 0.669098421 +0.575960255 0.668269785 +0.576680542 0.667439553 +0.577400379 0.666608803 +0.578120718 0.665776436 +0.578840608 0.664943551 +0.579560618 0.66410949 +0.580280181 0.663274912 +0.580999991 0.66243901 +0.581719565 0.661602348 +0.582438694 0.660765168 +0.583159249 0.65992529 +0.583879359 0.659084894 +0.584599654 0.658243244 +0.585319506 0.657401077 +0.586039405 0.656557815 +0.586758863 0.655714036 +0.587479261 0.654868118 +0.588199217 0.654021682 +0.588919204 0.653174171 +0.589638823 0.652326058 +0.590358967 0.65147629 +0.591078672 0.650626003 +0.591798025 0.649775098 +0.592517803 0.648922654 +0.593238327 0.648068288 +0.593958413 0.647213403 +0.594678581 0.646357385 +0.595398313 0.645500849 +0.596118406 0.644642846 +0.596838604 0.643783681 +0.597558367 0.642923998 +0.598278646 0.642062662 +0.598998491 0.641200808 +0.599718578 0.640337627 +0.600438687 0.639473383 +0.601158364 0.638608621 +0.601878333 0.637742472 +0.602597871 0.636875805 +0.603317849 0.636007573 +0.604037397 0.635138823 +0.604757117 0.63426883 +0.605476508 0.633398198 +0.606197287 0.632524849 +0.606917638 0.631650981 +0.607637693 0.630776435 +0.608357706 0.629900901 +0.609077604 0.629024472 +0.609797701 0.628146764 +0.610517373 0.627268537 +0.611237245 0.62638903 +0.611957367 0.625508182 +0.612677458 0.624626333 +0.613397126 0.623743966 +0.614116937 0.622860387 +0.614836327 0.621976291 +0.615556648 0.621090014 +0.616276547 0.620203218 +0.616996626 0.619315164 +0.617716589 0.618426215 +0.618436134 0.617536749 +0.619156226 0.616645568 +0.619875899 0.61575387 +0.620595816 0.614860833 +0.621316243 0.613966126 +0.622036668 0.613070384 +0.622756901 0.612173842 +0.623476718 0.611276782 +0.624196934 0.610378187 +0.624916735 0.609479075 +0.625636149 0.60857941 +0.626356178 0.607677939 +0.627075876 0.606775846 +0.627795371 0.605872973 +0.62851513 0.604968732 +0.629234477 0.604063973 +0.629954089 0.603157846 +0.630674305 0.602249921 +0.63139411 0.601341477 +0.63211444 0.600431334 +0.63283436 0.599520673 +0.633554509 0.598608684 +0.634274556 0.597695788 +0.634995022 0.596781322 +0.635715079 0.595866338 +0.63643539 0.594949995 +0.637155535 0.594032824 +0.637875274 0.593115136 +0.638595066 0.592196342 +0.639314452 0.591277031 +0.640033652 0.590356925 +0.640753919 0.589434416 +0.641473802 0.588511362 +0.642194044 0.58758681 +0.642913882 0.58666174 +0.643634079 0.585735172 +0.644353913 0.584808035 +0.645073968 0.583879575 +0.645794069 0.58295002 +0.646513768 0.582019947 +0.647233766 0.581088453 +0.647953362 0.58015644 +0.648673815 0.579222281 +0.649393943 0.578287506 +0.650113672 0.577352213 +0.650833279 0.576416043 +0.651553738 0.575477727 +0.652273798 0.574538893 +0.652993817 0.573599075 +0.65371344 0.572658739 +0.654433576 0.571716695 +0.655153315 0.570774134 +0.655873467 0.569829996 +0.656593223 0.56888534 +0.657313018 0.567939597 +0.658032904 0.566992697 +0.658752989 0.5660445 +0.659472679 0.565095785 +0.660192648 0.564145668 +0.660912224 0.563195032 +0.661631805 0.562243354 +0.662351781 0.561290118 +0.663071748 0.560335857 +0.66379214 0.559379995 +0.664512141 0.558423614 +0.665231956 0.557466445 +0.665951894 0.556508075 +0.666671442 0.555549188 +0.667391397 0.554588724 +0.668110963 0.553627741 +0.668831342 0.552664636 +0.669551333 0.551701013 +0.670270945 0.55073686 +0.670991047 0.549771016 +0.671710762 0.548804653 +0.672430881 0.547836711 +0.67315135 0.54686726 +0.673871605 0.54589706 +0.674591475 0.544926342 +0.675311131 0.543954877 +0.676031102 0.542981949 +0.67675069 0.542008503 +0.67747112 0.541032881 +0.678191384 0.540056446 +0.678911266 0.539079494 +0.679631201 0.538101431 +0.680350754 0.537122851 +0.681070857 0.536142487 +0.68179058 0.535161606 +0.682510189 0.534179842 +0.683230422 0.53319619 +0.683950276 0.53221202 +0.684670518 0.531226282 +0.685390381 0.530240026 +0.686110612 0.529252228 +0.686830465 0.528263912 +0.687550502 0.527274307 +0.688270679 0.526283473 +0.688990479 0.52529212 +0.68971042 0.524299537 +0.690430162 0.523306192 +0.691149881 0.522311842 +0.691870038 0.521315851 +0.692589926 0.520319194 +0.69330944 0.51932202 +0.694029111 0.518323593 +0.694749245 0.517323486 +0.695469006 0.516322862 +0.696189274 0.515320495 +0.696909169 0.51431761 +0.697629439 0.513313166 +0.698349361 0.51230817 +0.699069513 0.511301815 +0.699789295 0.510294943 +0.700509308 0.50928671 +0.701229481 0.508277215 +0.701949424 0.507267007 +0.702668997 0.506256281 +0.703388933 0.505244009 +0.704108886 0.504230677 +0.704828471 0.503216827 +0.705548328 0.502201557 +0.706268057 0.501185431 +0.70698742 0.500168788 +0.707707659 0.49914987 +0.708427531 0.498130433 +0.709147857 0.497109316 +0.709868203 0.496087134 +0.710588183 0.495064434 +0.711308327 0.494040464 +0.712028107 0.493015975 +0.712747888 0.491990448 +0.713467838 0.490963645 +0.714187424 0.489936324 +0.714907453 0.488907333 +0.715627684 0.487877019 +0.716347551 0.486846186 +0.717067687 0.485813933 +0.717787627 0.484780923 +0.718507206 0.483747396 +0.719227364 0.482712 +0.719947377 0.481675774 +0.720667467 0.480638402 +0.721387197 0.479600512 +0.72210727 0.478561091 +0.722826984 0.477521152 +0.723546964 0.476479791 +0.724266586 0.475437912 +0.724986899 0.474393996 +0.725706855 0.473349561 +0.726426656 0.472304314 +0.727146832 0.471257484 +0.727866653 0.470210136 +0.728586473 0.469161751 +0.729305939 0.468112848 +0.730026104 0.467061888 +0.730746398 0.466009702 +0.731466337 0.464956999 +0.732186576 0.463902818 +0.732906461 0.462848119 +0.733626088 0.461792763 +0.734346273 0.460735552 +0.735066104 0.459677823 +0.735786087 0.458618834 +0.736506325 0.457558433 +0.737226398 0.456497239 +0.737946295 0.455435265 +0.738665842 0.454372774 +0.739385646 0.453308867 +0.7401051 0.452244442 +0.740825242 0.45117796 +0.741545245 0.45011065 +0.742265222 0.44904234 +0.74298485 0.447973512 +0.743704903 0.446903018 +0.744424607 0.445832005 +0.74514441 0.444759808 +0.745864321 0.443686415 +0.746584344 0.442611818 +0.747304178 0.441536466 +0.748023665 0.440460596 +0.748743831 0.439382676 +0.749464118 0.438303536 +0.750184059 0.437223878 +0.750904501 0.43614243 +0.751624599 0.435060463 +0.752344894 0.433977161 +0.753064844 0.432893341 +0.753785101 0.431808022 +0.754505013 0.430722185 +0.75522507 0.429635093 +0.75594524 0.428546794 +0.756665553 0.427457242 +0.757385522 0.426367171 +0.758105437 0.425276146 +0.758825011 0.424184603 +0.759544622 0.423091967 +0.760264555 0.421997806 +0.760984418 0.420902716 +0.761704589 0.41980612 +0.762424419 0.418709005 +0.763144089 0.4176111 +0.763863902 0.41651194 +0.764583618 0.415411891 +0.765302996 0.414311324 +0.766023383 0.413208177 +0.76674343 0.412104512 +0.76746323 0.41100019 +0.768182873 0.409895073 +0.768903203 0.408787864 +0.769623196 0.407680137 +0.7703434 0.406571046 +0.771063268 0.405461436 +0.771783301 0.404350537 +0.772502998 0.403239119 +0.773223112 0.402126019 +0.773942891 0.401012401 +0.774662735 0.399897647 +0.775382811 0.398781496 +0.776102932 0.397664239 +0.776822719 0.396546463 +0.777542552 0.39542758 +0.778262363 0.394307695 +0.778982203 0.393186727 +0.779701711 0.392065242 +0.780421856 0.390941726 +0.781141988 0.389817194 +0.781861788 0.388692144 +0.782581911 0.387565553 +0.783302085 0.386437844 +0.784021928 0.385309617 +0.78474212 0.384179805 +0.785461982 0.383049475 +0.78618181 0.381918162 +0.786901984 0.380785268 +0.787622198 0.379651273 +0.788342083 0.37851676 +0.789061759 0.377381541 +0.789781344 0.37624543 +0.790501423 0.3751075 +0.791221175 0.373969052 +0.791941198 0.37282914 +0.792661003 0.371688535 +0.793380701 0.370547063 +0.79410048 0.369404428 +0.794820884 0.368259763 +0.795540961 0.367114579 +0.796261015 0.365968396 +0.796981136 0.364821068 +0.797700932 0.363673223 +0.798420795 0.362524234 +0.799141056 0.361373573 +0.799861131 0.360222171 +0.800581306 0.359069572 +0.801301157 0.357916455 +0.802021108 0.356762142 +0.802740896 0.355607054 +0.803460946 0.354450509 +0.804180673 0.353293445 +0.804900614 0.352135002 +0.805620379 0.350975805 +0.806340305 0.349815312 +0.80705991 0.348654301 +0.807779676 0.347491994 +0.808499969 0.3463278 +0.809219941 0.345163087 +0.809939772 0.343997566 +0.810659981 0.342830396 +0.81137987 0.341662707 +0.812099883 0.34049378 +0.812819578 0.339324334 +0.813539103 0.338154129 +0.814259122 0.336982083 +0.81497908 0.3358091 +0.815698719 0.334635599 +0.816418395 0.333461004 +0.817138554 0.332284584 +0.817858395 0.331107646 +0.818578526 0.329929197 +0.819298695 0.328749649 +0.820018547 0.327569583 +0.820738132 0.326388918 +0.821458447 0.32520602 +0.822178446 0.324022603 +0.822898598 0.322837897 +0.823618694 0.321652247 +0.824338475 0.320466079 +0.8250582 0.319278967 +0.825777883 0.318090888 +0.826498198 0.316900729 +0.8272182 0.31571005 +0.827938273 0.314518216 +0.828658033 0.313325865 +0.829377739 0.312132567 +0.830097636 0.310937916 +0.83081722 0.309742746 +0.831537703 0.308545049 +0.832257873 0.307346832 +0.832977931 0.306147766 +0.833697993 0.304947656 +0.834417744 0.303747028 +0.8351375 0.302545356 +0.835857665 0.301341964 +0.836577519 0.300138055 +0.837297617 0.2989327 +0.838017577 0.29772654 +0.838737228 0.296519862 +0.839457369 0.295311325 +0.840177202 0.29410227 +0.840897458 0.292891466 +0.841617405 0.291680143 +0.84233717 0.290468092 +0.843056879 0.289255099 +0.843777079 0.288040241 +0.844497074 0.286824693 +0.845216761 0.285608627 +0.845937093 0.284390434 +0.846657163 0.283171649 +0.847376926 0.281952345 +0.848096871 0.280731697 +0.848816511 0.279510531 +0.84953662 0.278287531 +0.850256424 0.277064014 +0.850976572 0.275838874 +0.851696667 0.274612787 +0.852416457 0.273386183 +0.853136403 0.272158277 +0.853856045 0.270929854 +0.854575664 0.269700434 +0.855295949 0.26846884 +0.85601593 0.267236727 +0.856735769 0.266003823 +0.857455369 0.264770291 +0.858175456 0.263534886 +0.858895242 0.262298963 +0.859615427 0.261061318 +0.86033531 0.259823154 +0.861055335 0.258583709 +0.861775476 0.257343028 +0.862495553 0.256101422 +0.863215329 0.254859296 +0.863935041 0.253616246 +0.864655336 0.252371151 +0.865375331 0.251125537 +0.866095351 0.249878842 +0.866815073 0.248631629 +0.867535266 0.247382563 +0.868255483 0.246132417 +0.868975401 0.244881753 +0.869695164 0.243630322 +0.870414917 0.242377872 +0.871135112 0.241123617 +0.871855252 0.239868419 +0.872575095 0.238612703 +0.873294957 0.237355919 +0.874014521 0.236098617 +0.874734274 0.23483995 +0.875454392 0.233579608 +0.876174691 0.232317911 +0.876894694 0.231055695 +0.877614574 0.22979266 +0.878334671 0.228528205 +0.879054653 0.227262917 +0.87977434 0.225997111 +0.880493912 0.224730471 +0.881213845 0.22346216 +0.881933716 0.22219292 +0.882653595 0.220922632 +0.88337318 0.219651825 +0.884092947 0.21837966 +0.884813276 0.217105467 +0.885533608 0.21583023 +0.886253646 0.214554475 +0.886973496 0.213278017 +0.887693373 0.212000475 +0.888413313 0.210721785 +0.889132961 0.209442578 +0.889853017 0.208161608 +0.890573126 0.206879507 +0.891292944 0.205596888 +0.892013125 0.204312585 +0.892733015 0.203027764 +0.893452924 0.201741873 +0.894173085 0.200454494 +0.894892956 0.199166597 +0.895612805 0.197877704 +0.896332775 0.196587557 +0.897052781 0.195296308 +0.897772499 0.19400454 +0.898492409 0.19271139 +0.899212568 0.191416757 +0.899932526 0.190121449 +0.900652196 0.188825622 +0.901371665 0.187529122 +0.902091707 0.186230552 +0.902811462 0.184931464 +0.903531337 0.183631124 +0.904251405 0.182329398 +0.904971186 0.181027153 +0.905691252 0.179723357 +0.906411031 0.178419043 +0.907131418 0.17711259 +0.907851519 0.17580562 +0.908571502 0.174497827 +0.909291671 0.173188658 +0.910011593 0.171878902 +0.910731695 0.17056778 +0.911451513 0.16925614 +0.912171596 0.16794298 +0.912891394 0.166629302 +0.913610993 0.165314953 +0.914330915 0.163998978 +0.91505089 0.162681869 +0.915770581 0.161364243 +0.916490671 0.160044851 +0.917210806 0.158724338 +0.917930928 0.157402811 +0.918650768 0.156080766 +0.919370597 0.154757706 +0.920090525 0.153433426 +0.920810171 0.152108628 +0.921530541 0.150781462 +0.922250629 0.149453778 +0.922970826 0.148124854 +0.923690743 0.146795412 +0.924410652 0.145464946 +0.925130608 0.144133359 +0.92585056 0.14280074 +0.926570233 0.141467603 +0.927289903 0.140133435 +0.928010009 0.138797423 +0.928729835 0.137460893 +0.929449835 0.136123003 +0.930169557 0.134784596 +0.930889867 0.133444056 +0.931609898 0.132102998 +0.93232984 0.13076107 +0.933049674 0.129418305 +0.933769652 0.128074237 +0.934489352 0.126729651 +0.935209535 0.125383126 +0.935929628 0.124035731 +0.936649752 0.122687242 +0.937369599 0.121338234 +0.938089327 0.119988414 +0.938809222 0.118637246 +0.939529243 0.117284801 +0.940248989 0.115931839 +0.940968671 0.114577961 +0.9416885 0.113222769 +0.942408655 0.111865927 +0.943128535 0.110508567 +0.943848578 0.109149861 +0.944568569 0.107790219 +0.945288285 0.106430058 +0.946007949 0.105068961 +0.946728064 0.103705973 +0.947448213 0.102341885 +0.948168087 0.100977278 +0.948887996 0.099611571 +0.94960831 0.098244058 +0.950328351 0.096876026 +0.951048301 0.09550713 +0.951767978 0.094137716 +0.952488054 0.092766508 +0.953207857 0.091394782 +0.95392805 0.090021275 +0.95464825 0.088646719 +0.955368178 0.087271644 +0.956088114 0.085895519 +0.9568081 0.08451826 +0.957527815 0.083140483 +0.958247949 0.081760869 +0.958967989 0.080380395 +0.95968776 0.078999404 +0.960407437 0.077617554 +0.961127634 0.07623367 +0.961847636 0.074849125 +0.962567368 0.073464062 +0.963287571 0.072077055 +0.964007505 0.07068953 +0.964727265 0.069301304 +0.96544734 0.067911434 +0.966167147 0.066521045 +0.966887145 0.065129248 +0.967606876 0.063736934 +0.968326861 0.06234309 +0.969046579 0.060948728 +0.969766384 0.059553161 +0.970485937 0.058157046 +0.971205224 0.056760413 +0.971925803 0.055360234 +0.972646115 0.053959536 +0.973366468 0.052557719 +0.974086555 0.051155383 +0.97480661 0.049752073 +0.975526658 0.04834774 +0.976246439 0.04694289 +0.976966397 0.045536659 +0.977686326 0.044129448 +0.978406108 0.042721488 +0.979125626 0.04131301 +0.979845639 0.039902524 +0.980565589 0.038491125 +0.981285785 0.037078208 +0.982005717 0.035664772 +0.982725894 0.034249817 +0.983446051 0.032833865 +0.984165944 0.031417394 +0.984885748 0.030000064 +0.985605798 0.028581211 +0.986325585 0.027161841 +0.987045123 0.025741926 +0.987765355 0.024319604 +0.988485324 0.022896765 +0.989205132 0.021473206 +0.989925181 0.020048137 +0.990644967 0.01862255 +0.991364789 0.017195855 +0.99208481 0.015767731 +0.992804569 0.014339088 +0.993524516 0.012909036 +0.994244202 0.011478466 +0.994964247 0.010046147 +0.995684151 0.008613071 +0.996403807 0.007179454 +0.9971234 0.005744926 +0.997842733 0.00430988 +0.998562004 0.002873923 +0.999281132 0.00143722 +1 0 \ No newline at end of file diff --git a/jmetal/runner/multiobjective/nsgaii_standard_settings.py b/jmetal/runner/multiobjective/nsgaii_standard_settings.py index c918e279..f3bb15ba 100644 --- a/jmetal/runner/multiobjective/nsgaii_standard_settings.py +++ b/jmetal/runner/multiobjective/nsgaii_standard_settings.py @@ -18,7 +18,7 @@ def main(): algorithm = NSGAII[FloatSolution, List[FloatSolution]]( problem=problem, population_size=100, - max_evaluations=1000, + max_evaluations=25000, mutation=Polynomial(1.0 / problem.number_of_variables, distribution_index=20), crossover=SBX(1.0, distribution_index=20), selection=BinaryTournament2Selection([SolutionAttributeComparator("dominance_ranking"), @@ -31,10 +31,10 @@ def main(): result = algorithm.get_result() # Plot frontier - pareto_front = ScatterBokeh(plot_title='NSGAII', number_of_objectives=problem.number_of_objectives) + pareto_front = ScatterBokeh(plot_title='NSGAII for DTLZ1', number_of_objectives=problem.number_of_objectives) pareto_front.plot(result, reference=problem.get_reference_front(), output='output') - pareto_front = ScatterMatplotlib(plot_title='NSGAII', number_of_objectives=problem.number_of_objectives) + pareto_front = ScatterMatplotlib(plot_title='NSGAII for DTLZ1', number_of_objectives=problem.number_of_objectives) pareto_front.plot(result, reference=problem.get_reference_front(), output='output2') # Save variables to file diff --git a/jmetal/runner/multiobjective/smpso_standard_settings.py b/jmetal/runner/multiobjective/smpso_standard_settings.py index ef70d59b..caeadfa5 100644 --- a/jmetal/runner/multiobjective/smpso_standard_settings.py +++ b/jmetal/runner/multiobjective/smpso_standard_settings.py @@ -1,16 +1,17 @@ import logging +from jmetal.util.graphic import ScatterBokeh + from jmetal.algorithm.multiobjective.smpso import SMPSO from jmetal.component.archive import CrowdingDistanceArchive from jmetal.component.observer import VisualizerObserver -from jmetal.core.solution import FloatSolution from jmetal.operator.mutation import Polynomial -from jmetal.problem.multiobjective.dtlz import DTLZ1 from jmetal.problem.multiobjective.zdt import ZDT1 +from jmetal.problem.multiobjective.dtlz import DTLZ1 def main() -> None: - problem = ZDT1() + problem = DTLZ1() algorithm = SMPSO( problem=problem, swarm_size=100, @@ -23,6 +24,11 @@ def main() -> None: algorithm.observable.register(observer=observer) algorithm.run() + result = algorithm.get_result() + + # Plot frontier + pareto_front = ScatterBokeh(plot_title='SMPSO for DTLZ1', number_of_objectives=problem.number_of_objectives) + pareto_front.plot(result, reference=problem.get_reference_front(), output='output') print("Algorithm (continuous problem): " + algorithm.get_name()) print("Problem: " + problem.get_name()) diff --git a/jmetal/util/front_file.py b/jmetal/util/front_file.py index 53cc4ab3..d1f8a2cd 100644 --- a/jmetal/util/front_file.py +++ b/jmetal/util/front_file.py @@ -2,9 +2,17 @@ from jmetal.core.solution import FloatSolution +""" +.. module:: front_file + :platform: Unix, Windows + :synopsis: Utils to read reference frontiers from files. + +.. moduleauthor:: Antonio J. Nebro +""" + def read_front_from_file(file_name: str): - """ Reads a front from a file and returns a list + """ Reads a front from a file and returns a list. """ front = [] with open(file_name) as file: @@ -15,7 +23,9 @@ def read_front_from_file(file_name: str): def read_front_from_file_as_solutions(file_name: str): - """ Reads a front from a file and returns a list of solution objects + """ Reads a front from a file and returns a list of solution objects. + + :return: List of solution objects. """ front = [] with open(file_name) as file: @@ -34,4 +44,4 @@ def walk_up_folder(path, depth: int =1): while _cur_depth < depth: path = dirname(path) _cur_depth += 1 - return path \ No newline at end of file + return path diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index 208cdeb4..1871b532 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -98,6 +98,8 @@ def __initialize(self) -> None: self.axis.grid(color='#f0f0f5', linestyle='-', linewidth=1, alpha=0.5) self.fig.suptitle(self.plot_title, fontsize=13) + logger.info("Plot initialized") + def __plot(self, x_values, y_values, z_values, color: str = '#98FB98', marker: str = 'o', msize: int = 3): if self.number_of_objectives == 2: self.sc, = self.axis.plot(x_values, y_values, @@ -108,6 +110,7 @@ def __plot(self, x_values, y_values, z_values, color: str = '#98FB98', marker: s def plot(self, solution_list: List[S], reference: List[S], output: str='', show: bool=True) -> None: if reference: + logger.info("Reference front found") ref_x_values, ref_y_values, ref_z_values = self.get_objectives(reference) self.__plot(ref_x_values, ref_y_values, ref_z_values, color='#323232', marker='*') @@ -122,6 +125,7 @@ def plot(self, solution_list: List[S], reference: List[S], output: str='', show: def update(self, solution_list: List[S], reference: List[S], new_title: str='', persistence: bool=True) -> None: if self.sc is None: + logger.warning("Plot is none! Generating first plot...") self.plot(solution_list, reference, show=False) x_values, y_values, z_values = self.get_objectives(solution_list) @@ -174,7 +178,7 @@ def __pick_handler(self, event, solution_list: List[S]): line, ind = event.artist, event.ind[0] x, y = line.get_xdata(), line.get_ydata() - logger.debug('Selected data point ({0}): ({1}, {2})'.format(ind, x[ind], y[ind])) + logger.debug('Selected resources point ({0}): ({1}, {2})'.format(ind, x[ind], y[ind])) sol = next((solution for solution in solution_list if solution.objectives[0] == x[ind] and solution.objectives[1] == y[ind]), None) @@ -211,7 +215,7 @@ def __initialize(self) -> None: """ Set-up tools for plot. """ code = ''' selected = source.selected['1d']['indices'][0] - var str = source.data.str[selected] + var str = source.resources.str[selected] alert(str) ''' @@ -220,7 +224,7 @@ def __initialize(self) -> None: HoverTool(tooltips=[("index", "$index"), ("(x,y)", "($x, $y)")])] def plot(self, solution_list: List[S], reference: List[S]=None, output: str='', show: bool=True) -> None: - # This is important to purge data (if any) between calls + # This is important to purge resources (if any) between calls reset_output() # Set up figure @@ -237,7 +241,7 @@ def plot(self, solution_list: List[S], reference: List[S]=None, output: str='', ref_x_values, ref_y_values, _ = self.get_objectives(reference) self.figure_xy.line(x=ref_x_values, y=ref_y_values, legend='reference', color='green') - # Push data to server + # Push resources to server self.source.stream({'x': x_values, 'y': y_values, 'str': [s.__str__() for s in solution_list]}) self.doc.add_root(column(self.figure_xy)) else: @@ -259,7 +263,7 @@ def plot(self, solution_list: List[S], reference: List[S]=None, output: str='', self.figure_xz.line(x=ref_x_values, y=ref_z_values, legend='reference', color='green') self.figure_yz.line(x=ref_y_values, y=ref_z_values, legend='reference', color='green') - # Push data to server + # Push resources to server self.source.stream({'x': x_values, 'y': y_values, 'z': z_values, 'str': [s.__str__() for s in solution_list]}) self.doc.add_root(row(self.figure_xy, self.figure_xz, self.figure_yz)) diff --git a/jmetal/util/observable.py b/jmetal/util/observable.py index de4ca31e..67a40b38 100644 --- a/jmetal/util/observable.py +++ b/jmetal/util/observable.py @@ -1,7 +1,16 @@ from abc import ABCMeta, abstractmethod +""" +.. module:: observable + :platform: Unix, Windows + :synopsis: Implementation of the observer-observable pattern. + +.. moduleauthor:: Antonio J. Nebro +""" + class Observable(object): + def register(self, observer): pass @@ -30,6 +39,7 @@ def update(self, *args, **kwargs): class DefaultObservable(Observable): + def __init__(self): self.observers = [] diff --git a/jmetal/util/quality_indicator.py b/jmetal/util/quality_indicator.py index 6dd56df3..317d8f5d 100644 --- a/jmetal/util/quality_indicator.py +++ b/jmetal/util/quality_indicator.py @@ -150,7 +150,7 @@ def hvRecursive(self, dimIndex, length, bounds): return hvol def preProcess(self, front): - """Sets up the list data structure needed for calculation.""" + """Sets up the list resources structure needed for calculation.""" dimensions = len(self.referencePoint) nodeList = MultiList(dimensions) nodes = [MultiList.Node(dimensions, point) for point in front] @@ -170,7 +170,7 @@ def sortByDimension(self, nodes, i): class MultiList: - """A special data structure needed by FonsecaHyperVolume. + """A special resources structure needed by FonsecaHyperVolume. It consists of several doubly linked lists that share common nodes. So, every node has multiple predecessors and successors, one in every list. diff --git a/jmetal/util/ranking.py b/jmetal/util/ranking.py index fd478420..ac770685 100644 --- a/jmetal/util/ranking.py +++ b/jmetal/util/ranking.py @@ -6,8 +6,10 @@ class Ranking(List[S]): + def __init__(self): - self.number_of_comparions = 0 + super().__init__() + self.number_of_comparisons = 0 self.ranked_sublists = [] def compute_ranking(self, solution_list: List[S]): @@ -21,12 +23,12 @@ def get_subfront(self, rank: int): def get_number_of_subfronts(self): return len(self.ranked_sublists) - def get_number_of_comparions(self) -> int: + def number_of_comparisons(self) -> int: return self.number_of_comparisons class FastNonDominatedRanking(Ranking[List[S]]): - """ Class implementing the non-dominated ranking of NSGA-II """ + """ Class implementing the non-dominated ranking of NSGA-II. """ def __init__(self): super(FastNonDominatedRanking, self).__init__() @@ -44,7 +46,7 @@ def compute_ranking(self, solution_list: List[S]): for p in range(len(solution_list) - 1): for q in range(p + 1, len(solution_list)): dominance_test_result = DominanceComparator().compare(solution_list[p], solution_list[q]) - self.number_of_comparions += 1 + self.number_of_comparisons += 1 if dominance_test_result is -1: i_dominate[p].append(q) dominate_me[q] += 1 @@ -80,7 +82,7 @@ def compute_ranking(self, solution_list: List[S]): class EfficientNonDominatedRanking(Ranking[List[S]]): - """ Class implementing the EDS (efficient non-dominated sorting) algorithm """ + """ Class implementing the EDS (efficient non-dominated sorting) algorithm. """ def __init__(self): super(EfficientNonDominatedRanking, self).__init__() diff --git a/jmetal/util/test/test_comparator.py b/jmetal/util/test/test_comparator.py index 876062a8..7c6ad6d6 100644 --- a/jmetal/util/test/test_comparator.py +++ b/jmetal/util/test/test_comparator.py @@ -6,6 +6,7 @@ class DominanceComparatorTestCases(unittest.TestCase): + def setUp(self): self.comparator = DominanceComparator() @@ -57,8 +58,7 @@ def test_should_dominance_comparator_return_minus_one_if_the_two_solutions_have_ self.assertEqual(-1, self.comparator.compare(solution, solution2)) def test_should_dominance_comparator_work_properly_case_a(self): - """ - Case A: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [2.0, 6.0, 15.0] + """ Case A: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [2.0, 6.0, 15.0] """ solution = FloatSolution(3, 3, 0, [], []) solution2 = FloatSolution(3, 3, 0, [], []) @@ -69,8 +69,7 @@ def test_should_dominance_comparator_work_properly_case_a(self): self.assertEqual(-1, self.comparator.compare(solution, solution2)) def test_should_dominance_comparator_work_properly_case_b(self): - """ - Case b: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-1.0, 5.0, 10.0] + """ Case b: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-1.0, 5.0, 10.0] """ solution = FloatSolution(3, 3, 0, [], []) solution2 = FloatSolution(3, 3, 0, [], []) @@ -81,8 +80,7 @@ def test_should_dominance_comparator_work_properly_case_b(self): self.assertEqual(-1, self.comparator.compare(solution, solution2)) def test_should_dominance_comparator_work_properly_case_c(self): - """ - Case c: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-2.0, 5.0, 9.0] + """ Case c: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-2.0, 5.0, 9.0] """ solution = FloatSolution(3, 3, 0, [], []) solution2 = FloatSolution(3, 3, 0, [], []) @@ -93,8 +91,7 @@ def test_should_dominance_comparator_work_properly_case_c(self): self.assertEqual(1, self.comparator.compare(solution, solution2)) def test_should_dominance_comparator_work_properly_case_d(self): - """ - Case d: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-1.0, 5.0, 8.0] + """ Case d: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-1.0, 5.0, 8.0] """ solution = FloatSolution(3, 3, 0, [], []) solution2 = FloatSolution(3, 3, 0 , [], []) @@ -105,8 +102,7 @@ def test_should_dominance_comparator_work_properly_case_d(self): self.assertEqual(1, self.comparator.compare(solution, solution2)) def test_should_dominance_comparator_work_properly_case_3(self): - """ - Case d: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-2.0, 5.0, 10.0] + """ Case d: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-2.0, 5.0, 10.0] """ solution = FloatSolution(3, 3, 0, [], []) solution2 = FloatSolution(3, 3, 0, [], []) @@ -117,8 +113,7 @@ def test_should_dominance_comparator_work_properly_case_3(self): self.assertEqual(0, self.comparator.compare(solution, solution2)) def test_should_dominance_comparator_work_properly_with_constrains_case_1(self): - """ - Case 1: solution1 has a higher degree of constraint violation than solution 2 + """ Case 1: solution1 has a higher degree of constraint violation than solution 2 """ solution1 = FloatSolution(3, 3, 0, [], []) solution2 = FloatSolution(3, 3, 0, [], []) @@ -131,8 +126,7 @@ def test_should_dominance_comparator_work_properly_with_constrains_case_1(self): self.assertEqual(-1, self.comparator.compare(solution1, solution2)) def test_should_dominance_comparator_work_properly_with_constrains_case_2(self): - """ - Case 2: solution1 has a lower degree of constraint violation than solution 2 + """ Case 2: solution1 has a lower degree of constraint violation than solution 2 """ solution1 = FloatSolution(3, 3, 0, [], []) solution2 = FloatSolution(3, 3, 0, [], []) @@ -146,6 +140,7 @@ def test_should_dominance_comparator_work_properly_with_constrains_case_2(self): class SolutionAttributeComparatorTestCases(unittest.TestCase): + def setUp(self): self.comparator = SolutionAttributeComparator("attribute") @@ -178,8 +173,7 @@ def test_should_compare_return_zero_if_both_solutions_have_the_same_attribute_va self.assertEqual(0, self.comparator.compare(solution1, solution2)) def test_should_compare_works_properly_case1(self): - """ - Case 1: solution1.attribute < solution2.attribute (lowest is best) + """ Case 1: solution1.attribute < solution2.attribute (lowest is best) """ solution1 = Solution(1, 1) solution2 = Solution(1, 1) @@ -189,8 +183,7 @@ def test_should_compare_works_properly_case1(self): self.assertEqual(-1, self.comparator.compare(solution1, solution2)) def test_should_compare_works_properly_case2(self): - """ - Case 2: solution1.attribute > solution2.attribute (lowest is best) + """ Case 2: solution1.attribute > solution2.attribute (lowest is best) """ solution1 = Solution(1, 1) solution2 = Solution(1, 1) @@ -200,8 +193,7 @@ def test_should_compare_works_properly_case2(self): self.assertEqual(1, self.comparator.compare(solution1, solution2)) def test_should_compare_works_properly_case3(self): - """ - Case 3: solution1.attribute < solution2.attribute (highest is best) + """ Case 3: solution1.attribute < solution2.attribute (highest is best) """ comparator = SolutionAttributeComparator("attribute", False) solution1 = Solution(1, 1) @@ -212,8 +204,7 @@ def test_should_compare_works_properly_case3(self): self.assertEqual(1, comparator.compare(solution1, solution2)) def test_should_compare_works_properly_case4(self): - """ - Case 4: solution1.attribute > solution2.attribute (highest is best) + """ Case 4: solution1.attribute > solution2.attribute (highest is best) """ solution1 = Solution(1, 1) solution2 = Solution(1, 1) @@ -225,12 +216,12 @@ def test_should_compare_works_properly_case4(self): class RankingAndCrowdingComparatorTestCases(unittest.TestCase): + def setUp(self): self.comparator = RankingAndCrowdingDistanceComparator() def test_should_compare_work_properly_case_1(self): - """ - Case 1: solution1.ranking < solution2.ranking + """ Case 1: solution1.ranking < solution2.ranking """ solution1 = Solution(1, 1) solution2 = Solution(1, 1) @@ -240,8 +231,7 @@ def test_should_compare_work_properly_case_1(self): self.assertEqual(-1, self.comparator.compare(solution1, solution2)) def test_should_compare_work_properly_case_2(self): - """ - Case 2: solution1.ranking > solution2.ranking + """ Case 2: solution1.ranking > solution2.ranking """ solution1 = Solution(1, 1) solution2 = Solution(1, 1) @@ -251,9 +241,8 @@ def test_should_compare_work_properly_case_2(self): self.assertEqual(1, self.comparator.compare(solution1, solution2)) def test_should_compare_work_properly_case_3(self): - """ - Case 3: solution1.ranking == solution2.ranking - solution1.crowding < solution2.crowding + """ Case 3: solution1.ranking == solution2.ranking + solution1.crowding < solution2.crowding """ solution1 = Solution(1, 1) solution2 = Solution(1, 1) @@ -265,9 +254,8 @@ def test_should_compare_work_properly_case_3(self): self.assertEqual(1, self.comparator.compare(solution1, solution2)) def test_should_compare_work_properly_case_4(self): - """ - Case 4: solution1.ranking == solution2.ranking - solution1.crowding > solution2.crowding + """ Case 4: solution1.ranking == solution2.ranking + solution1.crowding > solution2.crowding """ solution1 = Solution(1, 1) solution2 = Solution(1, 1) @@ -279,9 +267,8 @@ def test_should_compare_work_properly_case_4(self): self.assertEqual(-1, self.comparator.compare(solution1, solution2)) def test_should_compare_work_properly_case_5(self): - """ - Case 5: solution1.ranking == solution2.ranking - solution1.crowding == solution2.crowding + """ Case 5: solution1.ranking == solution2.ranking + solution1.crowding == solution2.crowding """ solution1 = Solution(1, 1) solution2 = Solution(1, 1) diff --git a/jmetal/util/test/test_observable.py b/jmetal/util/test/test_observable.py index 71774e85..4e4c8316 100644 --- a/jmetal/util/test/test_observable.py +++ b/jmetal/util/test/test_observable.py @@ -4,6 +4,7 @@ class ObservableTestCases(unittest.TestCase): + def setUp(self): self.observable = DefaultObservable() @@ -52,14 +53,6 @@ def test_should_deregister_all_remove_all_the_observers(self): self.assertEqual(0, len(self.observable.observers)) - """ - def test_should_notify_all_update_an_observer(self): - observer = mock(Observer) - self.observable.register(observer) - - self.observable.notify_all("color", "blue") - """ - if __name__ == "__main__": unittest.main() diff --git a/jmetal/util/test/test_quality_indicator.py b/jmetal/util/test/test_quality_indicator.py index fad4d7f4..6c753805 100644 --- a/jmetal/util/test/test_quality_indicator.py +++ b/jmetal/util/test/test_quality_indicator.py @@ -4,13 +4,11 @@ from jmetal.util.front_file import read_front_from_file, walk_up_folder from jmetal.util.quality_indicator import HyperVolume -FILE_PATH = dirname(join(dirname(__file__))) - class HyperVolumeTestCases(unittest.TestCase): def setUp(self): - pass + self.file_path = dirname(join(dirname(__file__))) def test_should_hypervolume_return_5_0(self): reference_point = [2, 2, 2] @@ -23,7 +21,7 @@ def test_should_hypervolume_return_5_0(self): def test_should_hypervolume_return_the_correct_value_when_applied_to_the_ZDT1_reference_front(self): reference_point = [1, 1] - front = read_front_from_file(join(walk_up_folder(FILE_PATH, 3), 'resources/data/ZDT1.pf')) + front = read_front_from_file(join(walk_up_folder(self.file_path, 3), 'resources/resources/ZDT1.pf')) hv = HyperVolume(reference_point) value = hv.compute(front) diff --git a/jmetal/util/test/test_ranking.py b/jmetal/util/test/test_ranking.py index 43634a34..f8fe24ea 100644 --- a/jmetal/util/test/test_ranking.py +++ b/jmetal/util/test/test_ranking.py @@ -5,6 +5,7 @@ class FastNonDominatedRankingTestCases(unittest.TestCase): + def setUp(self): self.ranking = FastNonDominatedRanking() @@ -40,7 +41,8 @@ def test_should_compute_ranking_return_a_subfront_if_the_solution_list_contains_ self.assertEqual(solution2, ranking[0][1]) def test_should_compute_ranking_work_properly_case1(self): - """ The list contains two solutions and one of them is dominated by the other one """ + """ The list contains two solutions and one of them is dominated by the other one. + """ solution = Solution(2, 2) solution.objectives = [2, 3] solution2 = Solution(2, 2) diff --git a/jmetal/util/time.py b/jmetal/util/time.py deleted file mode 100644 index ea5a89c7..00000000 --- a/jmetal/util/time.py +++ /dev/null @@ -1,17 +0,0 @@ -import logging -import time - -logger = logging.getLogger(__name__) - - -def get_time_of_execution(fn): - """ Decorator to get time of execution of any method inside a class. """ - - def wrapped(*args, **kwargs): - start_time = time.time() - res = fn(*args, **kwargs) - logger.debug("Computing time to " + fn.__name__ + " (in seconds): " + str(time.time() - start_time)) - - return res - - return wrapped From 1d48d03a5b24c30257b128f6b406fcd5c3ec8ac4 Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 26 Jun 2018 09:49:08 +0200 Subject: [PATCH 67/90] Fix test --- jmetal/util/test/test_quality_indicator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jmetal/util/test/test_quality_indicator.py b/jmetal/util/test/test_quality_indicator.py index 6c753805..43c24821 100644 --- a/jmetal/util/test/test_quality_indicator.py +++ b/jmetal/util/test/test_quality_indicator.py @@ -21,7 +21,7 @@ def test_should_hypervolume_return_5_0(self): def test_should_hypervolume_return_the_correct_value_when_applied_to_the_ZDT1_reference_front(self): reference_point = [1, 1] - front = read_front_from_file(join(walk_up_folder(self.file_path, 3), 'resources/resources/ZDT1.pf')) + front = read_front_from_file(join(walk_up_folder(self.file_path, 2), 'problem/resources/ZDT1.pf')) hv = HyperVolume(reference_point) value = hv.compute(front) From 43b81a8620ca52dd44f19c24704c716e988301f1 Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 26 Jun 2018 14:29:42 +0200 Subject: [PATCH 68/90] New method for exporting variables --- jmetal/util/solution_list_output.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/jmetal/util/solution_list_output.py b/jmetal/util/solution_list_output.py index ad255580..141c8f6e 100644 --- a/jmetal/util/solution_list_output.py +++ b/jmetal/util/solution_list_output.py @@ -12,6 +12,15 @@ def print_variables_to_screen(solution_list: list): for solution in solution_list: print(solution.variables[0]) + @staticmethod + def print_variables_to_file(solution_list: list, file_name): + logger.info("Output file (variables): " + file_name) + with open(file_name, 'w') as of: + for solution in solution_list: + for variables in solution.variables: + of.write(str(variables) + " ") + of.write("\n") + @staticmethod def print_function_values_to_screen(solution_list: list): for solution in solution_list: From 6579e8d5a9e98c3c85bfe5096bc74a1611e944ff Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 26 Jun 2018 21:31:34 +0200 Subject: [PATCH 69/90] Added parameters to multithreading evaluator --- jmetal/component/evaluator.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/jmetal/component/evaluator.py b/jmetal/component/evaluator.py index 280bb949..def59202 100644 --- a/jmetal/component/evaluator.py +++ b/jmetal/component/evaluator.py @@ -1,7 +1,7 @@ from multiprocessing.pool import ThreadPool from typing import TypeVar, List, Generic -from dask.distributed import Client, as_completed +from dask.distributed import LocalCluster, Client, as_completed from jmetal.core.problem import Problem @@ -42,8 +42,12 @@ def evaluate(self, solution_list: List[S], problem: Problem) -> List[S]: class DaskMultithreadedEvaluator(Evaluator[S]): - def __init__(self): - self.client = Client() + def __init__(self, n_workers: int, processes: bool=True): + """ :param n_workers: Number of workers to start. + :param processes: Whether to use processes (True) or threads (False). + """ + cluster = LocalCluster(n_workers=n_workers, processes=processes) + self.client = Client(cluster) def evaluate(self, solution_list: List[S], problem: Problem) -> List[S]: futures = [] From 35255d7d7235003e98a2a3ab51e9330a2be443f7 Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 28 Jun 2018 12:00:13 +0200 Subject: [PATCH 70/90] Minor changes --- .gitignore | 5 +- jmetal/algorithm/multiobjective/nsgaii.py | 14 ++--- .../algorithm/multiobjective/randomSearch.py | 8 +-- .../singleobjective/evolutionaryalgorithm.py | 12 ++-- jmetal/component/archive.py | 9 ++- jmetal/component/test/test_evaluator.py | 29 +++++++++- jmetal/core/algorithm.py | 4 ++ .../multiobjective/nsgaii_full_settings.py | 55 +++++++++++++++++++ .../nsgaii_standard_settings.py | 28 ++-------- .../multiobjective/smpso_standard_settings.py | 18 ++---- .../smpsorp_standard_settings.py | 4 +- 11 files changed, 124 insertions(+), 62 deletions(-) create mode 100644 jmetal/runner/multiobjective/nsgaii_full_settings.py diff --git a/.gitignore b/.gitignore index c6065b07..a26b9748 100644 --- a/.gitignore +++ b/.gitignore @@ -104,4 +104,7 @@ ENV/ .idea # pypi -.pypirc \ No newline at end of file +.pypirc + +# Dask +dask-worker-space \ No newline at end of file diff --git a/jmetal/algorithm/multiobjective/nsgaii.py b/jmetal/algorithm/multiobjective/nsgaii.py index 924eb460..18750409 100644 --- a/jmetal/algorithm/multiobjective/nsgaii.py +++ b/jmetal/algorithm/multiobjective/nsgaii.py @@ -27,8 +27,8 @@ def __init__(self, mutation: Mutation[S], crossover: Crossover[S, S], selection: Selection[List[S], S], - observable: Observable = DefaultObservable(), - evaluator: Evaluator[S] = SequentialEvaluator[S]()): + evaluator: Evaluator[S] = SequentialEvaluator[S](), + observable: Observable = DefaultObservable()): """ NSGA-II is a genetic algorithm (GA), i.e. it belongs to the evolutionary algorithms (EAs) family. The implementation of NSGA-II provided in jMetalPy follows the evolutionary algorithm template described in the algorithm templates section (:mod:`algorithm`) of the documentation. @@ -49,8 +49,8 @@ def __init__(self, mutation, crossover, selection, - observable, - evaluator) + evaluator, + observable) def replacement(self, population: List[S], offspring_population: List[S]) -> List[List[TypeVar('S')]]: """ This method joins the current and offspring populations to produce the population of the next generation @@ -63,12 +63,10 @@ def replacement(self, population: List[S], offspring_population: List[S]) -> Lis join_population = population + offspring_population return RankingAndCrowdingDistanceSelection(self.population_size).execute(join_population) - def get_name(self) -> str: - return "NSGA-II" - def get_result(self) -> R: """:return: Population. """ return self.population - + def get_name(self) -> str: + return 'NSGA-II' diff --git a/jmetal/algorithm/multiobjective/randomSearch.py b/jmetal/algorithm/multiobjective/randomSearch.py index 16f44535..f2559946 100644 --- a/jmetal/algorithm/multiobjective/randomSearch.py +++ b/jmetal/algorithm/multiobjective/randomSearch.py @@ -26,8 +26,8 @@ def run(self) -> None: self.problem.evaluate(new_solution) self.archive.add(new_solution) - def get_name(self) -> str: - return "Random Search Algorithm" - def get_result(self) -> List[S]: - return self.archive.get_solution_list() \ No newline at end of file + return self.archive.get_solution_list() + + def get_name(self) -> str: + return 'Random Search Algorithm' diff --git a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py index 0fbe2b4a..9cbaafd4 100644 --- a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py +++ b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py @@ -119,8 +119,8 @@ def __init__(self, mutation: Mutation[S], crossover: Crossover[S, S], selection: Selection[List[S], S], - observable: Observable = DefaultObservable(), - evaluator: Evaluator[S] = SequentialEvaluator[S]()): + evaluator: Evaluator[S] = SequentialEvaluator[S](), + observable: Observable = DefaultObservable()): super(GenerationalGeneticAlgorithm, self).__init__(evaluator) self.problem = problem self.population_size = population_size @@ -183,8 +183,7 @@ def reproduction(self, population: List[S]) -> List[S]: return offspring_population - def replacement(self, population: List[S], offspring_population: List[S]) \ - -> List[S]: + def replacement(self, population: List[S], offspring_population: List[S]) -> List[S]: population.sort(key=lambda s: s.objectives[0]) offspring_population.append(population[0]) @@ -203,9 +202,8 @@ def get_result(self) -> R: return self.population[0] def get_name(self) -> str: - return "Generational Genetic Algorithm" + return 'Generational Genetic Algorithm' def __check_number_of_parents(self, population: List[S], number_of_parents_for_crossover: int): if self.population_size % number_of_parents_for_crossover != 0: - raise Exception("Wrong number of parents") - + raise Exception('Wrong number of parents') diff --git a/jmetal/component/archive.py b/jmetal/component/archive.py index a700a64b..2cb024b3 100644 --- a/jmetal/component/archive.py +++ b/jmetal/component/archive.py @@ -1,7 +1,6 @@ import random -from typing import TypeVar, Generic, List - import copy +from typing import TypeVar, Generic, List from jmetal.component.density_estimator import CrowdingDistance, DensityEstimator from jmetal.util.comparator import Comparator, DominanceComparator, EqualSolutionsComparator, SolutionAttributeComparator @@ -18,6 +17,7 @@ class Archive(Generic[S]): + def __init__(self): self.solution_list: List[S] = [] @@ -38,6 +38,7 @@ def get_comparator(self): class BoundedArchive(Archive[S]): + def __init__(self, maximum_size: int, comparator: Comparator[S]=None, density_estimator: DensityEstimator=None): super(BoundedArchive, self).__init__() self.maximum_size = maximum_size @@ -80,6 +81,7 @@ def get_comparator(self): class NonDominatedSolutionListArchive(Archive[S]): + def __init__(self): super(NonDominatedSolutionListArchive, self).__init__() self.comparator = DominanceComparator() @@ -119,6 +121,7 @@ def get_comparator(self): class CrowdingDistanceArchive(BoundedArchive[S]): + def __init__(self, maximum_size: int): super(CrowdingDistanceArchive, self).__init__( maximum_size=maximum_size, @@ -127,6 +130,7 @@ def __init__(self, maximum_size: int): class ArchiveWithReferencePoint(BoundedArchive[S]): + def __init__(self, maximum_size: int, reference_point: List[float], comparator: Comparator[S], density_estimator: DensityEstimator): super(ArchiveWithReferencePoint, self).__init__(maximum_size, comparator, density_estimator) self.__reference_point = reference_point @@ -190,6 +194,7 @@ def __dominance_test(self, solution1:S, solution2:S)->int: class CrowdingDistanceArchiveWithReferencePoint(ArchiveWithReferencePoint[S]): + def __init__(self, maximum_size: int, reference_point:List[float]): super(CrowdingDistanceArchiveWithReferencePoint, self).__init__( maximum_size=maximum_size, diff --git a/jmetal/component/test/test_evaluator.py b/jmetal/component/test/test_evaluator.py index fb15c491..3e6dd4e3 100644 --- a/jmetal/component/test/test_evaluator.py +++ b/jmetal/component/test/test_evaluator.py @@ -1,6 +1,6 @@ import unittest -from jmetal.component.evaluator import SequentialEvaluator +from jmetal.component.evaluator import SequentialEvaluator, ParallelEvaluator from jmetal.core.problem import FloatProblem from jmetal.core.solution import FloatSolution @@ -53,5 +53,32 @@ def test_should_evaluate_a_list_of_problem_work_properly(self): self.assertEqual(2.3, problem_list[i].objectives[1]) +class ParallelEvaluatorTestCases(unittest.TestCase): + + def setUp(self): + self.evaluator = ParallelEvaluator() + self.problem = MockedProblem() + + def test_should_constructor_create_a_non_null_object(self): + self.assertIsNotNone(self.evaluator) + + def test_should_evaluate_a_list_of_problem_work_properly_with_a_solution(self): + problem_list = [self.problem.create_solution() for _ in range(1)] + + self.evaluator.evaluate(problem_list, self.problem) + + self.assertEqual(1.2, problem_list[0].objectives[0]) + self.assertEqual(2.3, problem_list[0].objectives[1]) + + def test_should_evaluate_a_list_of_problem_work_properly(self): + problem_list = [self.problem.create_solution() for _ in range(10)] + + self.evaluator.evaluate(problem_list, self.problem) + + for i in range(10): + self.assertEqual(1.2, problem_list[i].objectives[0]) + self.assertEqual(2.3, problem_list[i].objectives[1]) + + if __name__ == "__main__": unittest.main() diff --git a/jmetal/core/algorithm.py b/jmetal/core/algorithm.py index c67d9baa..333da49e 100644 --- a/jmetal/core/algorithm.py +++ b/jmetal/core/algorithm.py @@ -21,6 +21,7 @@ class Algorithm(Generic[S, R], threading.Thread): + def __init__(self): threading.Thread.__init__(self) self.observable = None @@ -39,6 +40,7 @@ def get_current_computing_time(self) -> float: class EvolutionaryAlgorithm(Algorithm[S, R]): + def __init__(self, evaluator: Evaluator[S] = SequentialEvaluator[S]()): super(EvolutionaryAlgorithm,self).__init__() self.population = [] @@ -46,6 +48,7 @@ def __init__(self, evaluator: Evaluator[S] = SequentialEvaluator[S]()): def create_initial_population(self) -> List[S]: pass + def evaluate_population(self, population: List[S]) -> List[S]: pass @@ -100,6 +103,7 @@ def run(self): class ParticleSwarmOptimization(Algorithm[FloatSolution, List[FloatSolution]]): + def __init__(self): super(ParticleSwarmOptimization, self).__init__() self.swarm = [] diff --git a/jmetal/runner/multiobjective/nsgaii_full_settings.py b/jmetal/runner/multiobjective/nsgaii_full_settings.py new file mode 100644 index 00000000..b3b0e782 --- /dev/null +++ b/jmetal/runner/multiobjective/nsgaii_full_settings.py @@ -0,0 +1,55 @@ +import logging + +from jmetal.algorithm.multiobjective.nsgaii import NSGAII +from jmetal.component.observer import VisualizerObserver +from jmetal.core.solution import FloatSolution +from jmetal.operator.crossover import SBX +from jmetal.operator.mutation import Polynomial +from jmetal.operator.selection import BinaryTournament2Selection +from jmetal.problem.multiobjective.dtlz import DTLZ1 +from jmetal.util.comparator import SolutionAttributeComparator +from jmetal.util.graphic import ScatterMatplotlib +from jmetal.util.solution_list_output import SolutionList + + +def main() -> None: + problem = DTLZ1() + + algorithm = NSGAII( + problem=problem, + population_size=100, + max_evaluations=25000, + mutation=Polynomial(1.0 / problem.number_of_variables, distribution_index=20), + crossover=SBX(1.0, distribution_index=20), + selection=BinaryTournament2Selection([SolutionAttributeComparator('dominance_ranking'), + SolutionAttributeComparator('crowding_distance', lowest_is_best=False)])) + + observer = VisualizerObserver(problem) + algorithm.observable.register(observer=observer) + + algorithm.run() + result = algorithm.get_result() + + # Plot frontier + pareto_front = ScatterMatplotlib(plot_title='NSGAII for DTLZ1', number_of_objectives=problem.number_of_objectives) + pareto_front.plot(result, reference=problem.get_reference_front(), output='output2') + + # Save variables to file + SolutionList[FloatSolution].print_function_values_to_file(result, 'NSGAII.' + problem.get_name()) + + print("Algorithm (continuous problem): " + algorithm.get_name()) + print("Problem: " + problem.get_name()) + print("Computing time: " + str(algorithm.total_computing_time)) + + +if __name__ == '__main__': + logging.basicConfig( + level=logging.INFO, + format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s", + handlers=[ + logging.FileHandler('jmetalpy.log'), + logging.StreamHandler() + ] + ) + + main() \ No newline at end of file diff --git a/jmetal/runner/multiobjective/nsgaii_standard_settings.py b/jmetal/runner/multiobjective/nsgaii_standard_settings.py index f3bb15ba..f875b192 100644 --- a/jmetal/runner/multiobjective/nsgaii_standard_settings.py +++ b/jmetal/runner/multiobjective/nsgaii_standard_settings.py @@ -1,44 +1,26 @@ import logging -from typing import List from jmetal.algorithm.multiobjective.nsgaii import NSGAII -from jmetal.component.observer import VisualizerObserver -from jmetal.core.solution import FloatSolution from jmetal.operator.crossover import SBX from jmetal.operator.mutation import Polynomial from jmetal.operator.selection import BinaryTournament2Selection from jmetal.problem.multiobjective.dtlz import DTLZ1 from jmetal.util.comparator import SolutionAttributeComparator -from jmetal.util.graphic import ScatterBokeh, ScatterMatplotlib -from jmetal.util.solution_list_output import SolutionList -def main(): +def main() -> None: problem = DTLZ1() - algorithm = NSGAII[FloatSolution, List[FloatSolution]]( + + algorithm = NSGAII( problem=problem, population_size=100, max_evaluations=25000, mutation=Polynomial(1.0 / problem.number_of_variables, distribution_index=20), crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournament2Selection([SolutionAttributeComparator("dominance_ranking"), - SolutionAttributeComparator("crowding_distance", lowest_is_best=False)])) - - observer = VisualizerObserver(problem) - algorithm.observable.register(observer=observer) + selection=BinaryTournament2Selection([SolutionAttributeComparator('dominance_ranking'), + SolutionAttributeComparator('crowding_distance', lowest_is_best=False)])) algorithm.run() - result = algorithm.get_result() - - # Plot frontier - pareto_front = ScatterBokeh(plot_title='NSGAII for DTLZ1', number_of_objectives=problem.number_of_objectives) - pareto_front.plot(result, reference=problem.get_reference_front(), output='output') - - pareto_front = ScatterMatplotlib(plot_title='NSGAII for DTLZ1', number_of_objectives=problem.number_of_objectives) - pareto_front.plot(result, reference=problem.get_reference_front(), output='output2') - - # Save variables to file - SolutionList[FloatSolution].print_function_values_to_file(result, "NSGAII." + problem.get_name()) print("Algorithm (continuous problem): " + algorithm.get_name()) print("Problem: " + problem.get_name()) diff --git a/jmetal/runner/multiobjective/smpso_standard_settings.py b/jmetal/runner/multiobjective/smpso_standard_settings.py index caeadfa5..6e59b57b 100644 --- a/jmetal/runner/multiobjective/smpso_standard_settings.py +++ b/jmetal/runner/multiobjective/smpso_standard_settings.py @@ -1,17 +1,14 @@ import logging -from jmetal.util.graphic import ScatterBokeh - +from jmetal.problem.multiobjective.zdt import ZDT1 from jmetal.algorithm.multiobjective.smpso import SMPSO from jmetal.component.archive import CrowdingDistanceArchive -from jmetal.component.observer import VisualizerObserver from jmetal.operator.mutation import Polynomial -from jmetal.problem.multiobjective.zdt import ZDT1 -from jmetal.problem.multiobjective.dtlz import DTLZ1 def main() -> None: - problem = DTLZ1() + problem = ZDT1() + algorithm = SMPSO( problem=problem, swarm_size=100, @@ -20,18 +17,11 @@ def main() -> None: leaders=CrowdingDistanceArchive(100) ) - observer = VisualizerObserver(problem) - algorithm.observable.register(observer=observer) - algorithm.run() - result = algorithm.get_result() - - # Plot frontier - pareto_front = ScatterBokeh(plot_title='SMPSO for DTLZ1', number_of_objectives=problem.number_of_objectives) - pareto_front.plot(result, reference=problem.get_reference_front(), output='output') print("Algorithm (continuous problem): " + algorithm.get_name()) print("Problem: " + problem.get_name()) + print("Computing time: " + str(algorithm.total_computing_time)) if __name__ == '__main__': diff --git a/jmetal/runner/multiobjective/smpsorp_standard_settings.py b/jmetal/runner/multiobjective/smpsorp_standard_settings.py index 2fa7a870..d1a9c449 100644 --- a/jmetal/runner/multiobjective/smpsorp_standard_settings.py +++ b/jmetal/runner/multiobjective/smpsorp_standard_settings.py @@ -28,14 +28,14 @@ def main() -> None: leaders=archives_with_reference_points ) - observer = VisualizerObserver() + observer = VisualizerObserver(problem) algorithm.observable.register(observer=observer) algorithm.run() - result = algorithm.get_result() print("Algorithm (continuous problem): " + algorithm.get_name()) print("Problem: " + problem.get_name()) + print("Computing time: " + str(algorithm.total_computing_time)) if __name__ == '__main__': From dcc7751b5f6bafc701ad09753c599176f63ca3ac Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 28 Jun 2018 14:51:13 +0200 Subject: [PATCH 71/90] Added (fancy) progress bar! --- jmetal/algorithm/multiobjective/nsgaii.py | 1 + jmetal/algorithm/multiobjective/smpso.py | 13 ++++++------ .../singleobjective/evolutionaryalgorithm.py | 20 ++++++++++--------- jmetal/component/observer.py | 18 +++++++++++++++++ jmetal/core/algorithm.py | 5 ++++- .../nsgaii_standard_settings.py | 4 ++++ .../multiobjective/smpso_standard_settings.py | 4 ++++ .../smpsorp_standard_settings.py | 6 +++--- requirements.txt | 1 + 9 files changed, 52 insertions(+), 20 deletions(-) diff --git a/jmetal/algorithm/multiobjective/nsgaii.py b/jmetal/algorithm/multiobjective/nsgaii.py index 18750409..2567212c 100644 --- a/jmetal/algorithm/multiobjective/nsgaii.py +++ b/jmetal/algorithm/multiobjective/nsgaii.py @@ -20,6 +20,7 @@ class NSGAII(GenerationalGeneticAlgorithm[S, R]): + def __init__(self, problem: Problem[S], population_size: int, diff --git a/jmetal/algorithm/multiobjective/smpso.py b/jmetal/algorithm/multiobjective/smpso.py index 0463b499..13d70efb 100644 --- a/jmetal/algorithm/multiobjective/smpso.py +++ b/jmetal/algorithm/multiobjective/smpso.py @@ -79,7 +79,7 @@ def __init__(self, self.dominance_comparator = DominanceComparator() self.speed = numpy.zeros((self.swarm_size, self.problem.number_of_variables), dtype=float) - self.delta_max, self.delta_min = numpy.empty(problem.number_of_variables),\ + self.delta_max, self.delta_min = numpy.empty(problem.number_of_variables), \ numpy.empty(problem.number_of_variables) for i in range(problem.number_of_variables): self.delta_max[i] = (self.problem.upper_bound[i] - self.problem.lower_bound[i]) / 2.0 @@ -94,7 +94,8 @@ def update_progress(self) -> None: self.evaluations += self.swarm_size self.leaders.compute_density_estimator() - observable_data = {'evaluations': self.evaluations, 'computing time': self.get_current_computing_time(), + observable_data = {'evaluations': self.evaluations, + 'computing time': self.get_current_computing_time(), 'population': self.leaders.solution_list} self.observable.notify_all(**observable_data) @@ -139,7 +140,7 @@ def update_velocity(self, swarm: List[FloatSolution]) -> None: self.__velocity_constriction( self.__constriction_coefficient(c1, c2) * ((self.__inertia_weight(self.evaluations, self.max_evaluations, wmax, wmin) - * self.speed[i][var]) + * self.speed[i][var]) + (c1 * r1 * (best_particle.variables[var] - swarm[i].variables[var])) + (c2 * r2 * (best_global.variables[var] - swarm[i].variables[var])) ), @@ -266,12 +267,10 @@ def update_progress(self) -> None: point.objectives = self.reference_points[i] reference_points.append(point) - observable_data = {'evaluations': self.evaluations, 'computing time': self.get_current_computing_time(), + observable_data = {'evaluations': self.evaluations, + 'computing time': self.get_current_computing_time(), 'population': self.get_result() + reference_points} - if self.problem.reference_front_path: - observable_data['reference'] = self.problem.get_reference_front() - self.observable.notify_all(**observable_data) def initialize_global_best(self, swarm: List[FloatSolution]) -> None: diff --git a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py index 9cbaafd4..c0c269a1 100644 --- a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py +++ b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py @@ -1,6 +1,8 @@ from copy import copy from typing import TypeVar, List +from tqdm import tqdm + from jmetal.component.evaluator import Evaluator, SequentialEvaluator from jmetal.core.algorithm import EvolutionaryAlgorithm from jmetal.core.operator import Mutation, Crossover, Selection @@ -24,13 +26,13 @@ class ElitistEvolutionStrategy(EvolutionaryAlgorithm[S, R]): def __init__(self, problem: Problem[S], mu: int, - lambdA: int, + lambd_a: int, max_evaluations: int, mutation: Mutation[S]): super(ElitistEvolutionStrategy, self).__init__() self.problem = problem self.mu = mu - self.lambdA = lambdA + self.lambd_a = lambd_a self.max_evaluations = max_evaluations self.mutation = mutation @@ -38,7 +40,7 @@ def init_progress(self): self.evaluations = self.mu def update_progress(self): - self.evaluations += self.lambdA + self.evaluations += self.lambd_a def is_stopping_condition_reached(self) -> bool: return self.evaluations >= self.max_evaluations @@ -60,14 +62,13 @@ def selection(self, population: List[S]): def reproduction(self, population: List[S]): offspring_population = [] for solution in population: - for j in range((int)(self.lambdA / self.mu)): + for j in range((int)(self.lambd_a / self.mu)): new_solution = copy(solution) offspring_population.append(self.mutation.execute(new_solution)) return offspring_population - def replacement(self, population: List[S], offspring_population: List[S]) \ - -> List[S]: + def replacement(self, population: List[S], offspring_population: List[S]) -> List[S]: for solution in offspring_population: self.population.append(solution) @@ -83,7 +84,7 @@ def get_result(self) -> R: return self.population[0] def get_name(self): - return "(" + str(self.mu) + "+" + str(self.lambdA) + ")ES" + return "(" + str(self.mu) + "+" + str(self.lambd_a) + ")ES" class NonElitistEvolutionStrategy(ElitistEvolutionStrategy[S, R]): @@ -107,7 +108,7 @@ def replacement(self, population: List[S], offspring_population: List[S]) \ return new_population def get_name(self) -> str: - return "(" + str(self.mu) + "," + str(self.lambdA) + ")ES" + return "(" + str(self.mu) + "," + str(self.lambd_a) + ")ES" class GenerationalGeneticAlgorithm(EvolutionaryAlgorithm[S, R]): @@ -137,7 +138,8 @@ def init_progress(self): def update_progress(self): self.evaluations += self.population_size - observable_data = {'evaluations': self.evaluations, 'computing time': self.get_current_computing_time(), + observable_data = {'evaluations': self.evaluations, + 'computing time': self.get_current_computing_time(), 'population': self.population} self.observable.notify_all(**observable_data) diff --git a/jmetal/component/observer.py b/jmetal/component/observer.py index 581776fc..49447104 100644 --- a/jmetal/component/observer.py +++ b/jmetal/component/observer.py @@ -1,6 +1,8 @@ import logging import os +from tqdm import tqdm + from jmetal.core.problem import Problem from jmetal.util.graphic import ScatterBokeh, ScatterMatplotlib from jmetal.util.observable import Observer @@ -9,6 +11,22 @@ logger = logging.getLogger(__name__) +class ProgressBarObserver(Observer): + + def __init__(self, step: int, max: int, desc: str='Progress') -> None: + self.progress_bar = tqdm(total=max, initial=step, ascii=True, desc=desc) + self.progress = step + self.step = step + self.maxx = max + + def update(self, *args, **kwargs): + self.progress_bar.update(self.step) + self.progress += self.step + + if self.progress >= self.maxx: + self.progress_bar.close() + + class BasicAlgorithmObserver(Observer): def __init__(self, frequency: float = 1.0) -> None: diff --git a/jmetal/core/algorithm.py b/jmetal/core/algorithm.py index 333da49e..e370f573 100644 --- a/jmetal/core/algorithm.py +++ b/jmetal/core/algorithm.py @@ -3,6 +3,8 @@ import time from typing import TypeVar, Generic, List +from tqdm import tqdm + from jmetal.component.evaluator import Evaluator, SequentialEvaluator from jmetal.core.solution import FloatSolution @@ -26,6 +28,7 @@ def __init__(self): threading.Thread.__init__(self) self.observable = None self.evaluations: int = 0 + self.max_evaluations: int = 100 self.start_computing_time: int = 0 self.total_computing_time: int = 0 @@ -42,7 +45,7 @@ def get_current_computing_time(self) -> float: class EvolutionaryAlgorithm(Algorithm[S, R]): def __init__(self, evaluator: Evaluator[S] = SequentialEvaluator[S]()): - super(EvolutionaryAlgorithm,self).__init__() + super(EvolutionaryAlgorithm, self).__init__() self.population = [] self.evaluator = evaluator diff --git a/jmetal/runner/multiobjective/nsgaii_standard_settings.py b/jmetal/runner/multiobjective/nsgaii_standard_settings.py index f875b192..ada9d0b7 100644 --- a/jmetal/runner/multiobjective/nsgaii_standard_settings.py +++ b/jmetal/runner/multiobjective/nsgaii_standard_settings.py @@ -1,6 +1,7 @@ import logging from jmetal.algorithm.multiobjective.nsgaii import NSGAII +from jmetal.component.observer import ProgressBarObserver from jmetal.operator.crossover import SBX from jmetal.operator.mutation import Polynomial from jmetal.operator.selection import BinaryTournament2Selection @@ -20,6 +21,9 @@ def main() -> None: selection=BinaryTournament2Selection([SolutionAttributeComparator('dominance_ranking'), SolutionAttributeComparator('crowding_distance', lowest_is_best=False)])) + progress_bar = ProgressBarObserver(step=100, max=25000) + algorithm.observable.register(progress_bar) + algorithm.run() print("Algorithm (continuous problem): " + algorithm.get_name()) diff --git a/jmetal/runner/multiobjective/smpso_standard_settings.py b/jmetal/runner/multiobjective/smpso_standard_settings.py index 6e59b57b..5e2d6e0d 100644 --- a/jmetal/runner/multiobjective/smpso_standard_settings.py +++ b/jmetal/runner/multiobjective/smpso_standard_settings.py @@ -1,5 +1,6 @@ import logging +from jmetal.component.observer import ProgressBarObserver from jmetal.problem.multiobjective.zdt import ZDT1 from jmetal.algorithm.multiobjective.smpso import SMPSO from jmetal.component.archive import CrowdingDistanceArchive @@ -17,6 +18,9 @@ def main() -> None: leaders=CrowdingDistanceArchive(100) ) + progress_bar = ProgressBarObserver(step=100, max=25000) + algorithm.observable.register(progress_bar) + algorithm.run() print("Algorithm (continuous problem): " + algorithm.get_name()) diff --git a/jmetal/runner/multiobjective/smpsorp_standard_settings.py b/jmetal/runner/multiobjective/smpsorp_standard_settings.py index d1a9c449..1a714984 100644 --- a/jmetal/runner/multiobjective/smpsorp_standard_settings.py +++ b/jmetal/runner/multiobjective/smpsorp_standard_settings.py @@ -2,7 +2,7 @@ from jmetal.algorithm.multiobjective.smpso import SMPSORP from jmetal.component.archive import CrowdingDistanceArchiveWithReferencePoint -from jmetal.component.observer import VisualizerObserver +from jmetal.component.observer import ProgressBarObserver from jmetal.operator.mutation import Polynomial from jmetal.problem.multiobjective.zdt import ZDT1 @@ -28,8 +28,8 @@ def main() -> None: leaders=archives_with_reference_points ) - observer = VisualizerObserver(problem) - algorithm.observable.register(observer=observer) + progress_bar = ProgressBarObserver(step=100, max=25000) + algorithm.observable.register(progress_bar) algorithm.run() diff --git a/requirements.txt b/requirements.txt index 09cc7145..23ed5e0e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +tqdm bokeh==0.12.16 pytest==3.1.2 PyHamcrest==1.9.0 From 22a5cc58239ed1ad165267df25df93b181653ced Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 5 Jul 2018 13:46:46 +0200 Subject: [PATCH 72/90] Major restructuring --- .../multiobjective/nsgaii_full_settings.py | 2 +- .../multiobjective/smpso_full_settings.py | 0 .../smpsorp_standard_settings.py | 2 +- .../elitist_evolution_strategy_binary.py | 0 .../elitist_evolution_strategy_float.py | 0 ..._evolution_strategy_running_as_a_thread.py | 0 .../non_elitist_evolution_strategy_binary.py | 0 .../non_elitist_evolution_strategy_float.py | 0 ..._evolution_strategy_running_as_a_thread.py | 0 .../generational_genetic_algorithm_binary.py | 4 +- .../generational_genetic_algorithm_float.py | 0 ...l_genetic_algorithm_running_as_a_thread.py | 0 ...onal_genetic_algorithm_stopping_by_time.py | 0 jmetal/algorithm/__init__.py | 7 +++ jmetal/algorithm/multiobjective/nsgaii.py | 8 +-- .../algorithm/multiobjective/randomSearch.py | 5 +- jmetal/algorithm/multiobjective/smpso.py | 32 +++++------ .../singleobjective/evolutionaryalgorithm.py | 32 +++++------ jmetal/component/archive.py | 24 ++++++--- jmetal/{util => component}/comparator.py | 0 jmetal/component/observer.py | 4 +- jmetal/{util => component}/ranking.py | 2 +- .../test/test_comparator.py | 2 +- .../{util => component}/test/test_ranking.py | 2 +- jmetal/core/algorithm.py | 26 ++++----- jmetal/{util => core}/observable.py | 31 +++++------ jmetal/core/operator.py | 16 ++++-- jmetal/core/problem.py | 2 +- jmetal/{util => core}/test/test_observable.py | 2 +- jmetal/core/test/test_problem.py | 2 - jmetal/core/test/test_solution.py | 14 ----- jmetal/operator/__init__.py | 9 ++++ jmetal/operator/crossover.py | 18 ++++--- jmetal/operator/mutation.py | 54 +++++++++++-------- jmetal/operator/selection.py | 27 +++++++--- jmetal/operator/test/test_crossover.py | 32 +++++------ jmetal/operator/test/test_mutation.py | 17 +----- jmetal/operator/test/test_selection.py | 13 ++--- jmetal/problem/__init__.py | 11 ++++ jmetal/problem/multiobjective/constrained.py | 12 ++--- jmetal/problem/multiobjective/dtlz.py | 4 +- .../multiobjective/test/test_unconstrained.py | 1 - .../problem/multiobjective/unconstrained.py | 24 ++++----- jmetal/problem/multiobjective/zdt.py | 6 +-- .../test/test_unconstrained.py | 19 +------ .../problem/singleobjective/unconstrained.py | 18 +++++-- jmetal/runner/__init__.py | 0 jmetal/runner/multiobjective/__init__.py | 0 .../nsgaii_standard_settings.py | 44 --------------- jmetal/runner/singleobjective/__init__.py | 0 .../evolution_strategy/__init__.py | 0 .../genetic_algorithm/__init__.py | 0 ...ational_genetic_algorithm_with_observer.py | 41 -------------- jmetal/util/front_file.py | 2 +- jmetal/util/graphic.py | 4 +- jmetal/util/laboratory.py | 43 +++++++++++++++ jmetal/util/solution_list_output.py | 11 +++- 57 files changed, 301 insertions(+), 328 deletions(-) rename {jmetal/runner => examples}/multiobjective/nsgaii_full_settings.py (96%) rename jmetal/runner/multiobjective/smpso_standard_settings.py => examples/multiobjective/smpso_full_settings.py (100%) rename {jmetal/runner => examples}/multiobjective/smpsorp_standard_settings.py (95%) rename {jmetal/runner => examples}/singleobjective/evolution_strategy/elitist_evolution_strategy_binary.py (100%) rename {jmetal/runner => examples}/singleobjective/evolution_strategy/elitist_evolution_strategy_float.py (100%) rename {jmetal/runner => examples}/singleobjective/evolution_strategy/elitist_evolution_strategy_running_as_a_thread.py (100%) rename {jmetal/runner => examples}/singleobjective/evolution_strategy/non_elitist_evolution_strategy_binary.py (100%) rename {jmetal/runner => examples}/singleobjective/evolution_strategy/non_elitist_evolution_strategy_float.py (100%) rename {jmetal/runner => examples}/singleobjective/evolution_strategy/non_elitist_evolution_strategy_running_as_a_thread.py (100%) rename {jmetal/runner => examples}/singleobjective/genetic_algorithm/generational_genetic_algorithm_binary.py (92%) rename {jmetal/runner => examples}/singleobjective/genetic_algorithm/generational_genetic_algorithm_float.py (100%) rename {jmetal/runner => examples}/singleobjective/genetic_algorithm/generational_genetic_algorithm_running_as_a_thread.py (100%) rename {jmetal/runner => examples}/singleobjective/genetic_algorithm/generational_genetic_algorithm_stopping_by_time.py (100%) rename jmetal/{util => component}/comparator.py (100%) rename jmetal/{util => component}/ranking.py (98%) rename jmetal/{util => component}/test/test_comparator.py (99%) rename jmetal/{util => component}/test/test_ranking.py (98%) rename jmetal/{util => core}/observable.py (98%) rename jmetal/{util => core}/test/test_observable.py (96%) delete mode 100644 jmetal/runner/__init__.py delete mode 100644 jmetal/runner/multiobjective/__init__.py delete mode 100644 jmetal/runner/multiobjective/nsgaii_standard_settings.py delete mode 100644 jmetal/runner/singleobjective/__init__.py delete mode 100644 jmetal/runner/singleobjective/evolution_strategy/__init__.py delete mode 100644 jmetal/runner/singleobjective/genetic_algorithm/__init__.py delete mode 100644 jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_with_observer.py create mode 100644 jmetal/util/laboratory.py diff --git a/jmetal/runner/multiobjective/nsgaii_full_settings.py b/examples/multiobjective/nsgaii_full_settings.py similarity index 96% rename from jmetal/runner/multiobjective/nsgaii_full_settings.py rename to examples/multiobjective/nsgaii_full_settings.py index b3b0e782..fe068809 100644 --- a/jmetal/runner/multiobjective/nsgaii_full_settings.py +++ b/examples/multiobjective/nsgaii_full_settings.py @@ -7,7 +7,7 @@ from jmetal.operator.mutation import Polynomial from jmetal.operator.selection import BinaryTournament2Selection from jmetal.problem.multiobjective.dtlz import DTLZ1 -from jmetal.util.comparator import SolutionAttributeComparator +from jmetal.component.comparator import SolutionAttributeComparator from jmetal.util.graphic import ScatterMatplotlib from jmetal.util.solution_list_output import SolutionList diff --git a/jmetal/runner/multiobjective/smpso_standard_settings.py b/examples/multiobjective/smpso_full_settings.py similarity index 100% rename from jmetal/runner/multiobjective/smpso_standard_settings.py rename to examples/multiobjective/smpso_full_settings.py diff --git a/jmetal/runner/multiobjective/smpsorp_standard_settings.py b/examples/multiobjective/smpsorp_standard_settings.py similarity index 95% rename from jmetal/runner/multiobjective/smpsorp_standard_settings.py rename to examples/multiobjective/smpsorp_standard_settings.py index 1a714984..86a6d2a2 100644 --- a/jmetal/runner/multiobjective/smpsorp_standard_settings.py +++ b/examples/multiobjective/smpsorp_standard_settings.py @@ -28,7 +28,7 @@ def main() -> None: leaders=archives_with_reference_points ) - progress_bar = ProgressBarObserver(step=100, max=25000) + progress_bar = ProgressBarObserver(step=swarm_size, max=25000) algorithm.observable.register(progress_bar) algorithm.run() diff --git a/jmetal/runner/singleobjective/evolution_strategy/elitist_evolution_strategy_binary.py b/examples/singleobjective/evolution_strategy/elitist_evolution_strategy_binary.py similarity index 100% rename from jmetal/runner/singleobjective/evolution_strategy/elitist_evolution_strategy_binary.py rename to examples/singleobjective/evolution_strategy/elitist_evolution_strategy_binary.py diff --git a/jmetal/runner/singleobjective/evolution_strategy/elitist_evolution_strategy_float.py b/examples/singleobjective/evolution_strategy/elitist_evolution_strategy_float.py similarity index 100% rename from jmetal/runner/singleobjective/evolution_strategy/elitist_evolution_strategy_float.py rename to examples/singleobjective/evolution_strategy/elitist_evolution_strategy_float.py diff --git a/jmetal/runner/singleobjective/evolution_strategy/elitist_evolution_strategy_running_as_a_thread.py b/examples/singleobjective/evolution_strategy/elitist_evolution_strategy_running_as_a_thread.py similarity index 100% rename from jmetal/runner/singleobjective/evolution_strategy/elitist_evolution_strategy_running_as_a_thread.py rename to examples/singleobjective/evolution_strategy/elitist_evolution_strategy_running_as_a_thread.py diff --git a/jmetal/runner/singleobjective/evolution_strategy/non_elitist_evolution_strategy_binary.py b/examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_binary.py similarity index 100% rename from jmetal/runner/singleobjective/evolution_strategy/non_elitist_evolution_strategy_binary.py rename to examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_binary.py diff --git a/jmetal/runner/singleobjective/evolution_strategy/non_elitist_evolution_strategy_float.py b/examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_float.py similarity index 100% rename from jmetal/runner/singleobjective/evolution_strategy/non_elitist_evolution_strategy_float.py rename to examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_float.py diff --git a/jmetal/runner/singleobjective/evolution_strategy/non_elitist_evolution_strategy_running_as_a_thread.py b/examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_running_as_a_thread.py similarity index 100% rename from jmetal/runner/singleobjective/evolution_strategy/non_elitist_evolution_strategy_running_as_a_thread.py rename to examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_running_as_a_thread.py diff --git a/jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_binary.py b/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_binary.py similarity index 92% rename from jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_binary.py rename to examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_binary.py index e998481c..ff7e4f5b 100644 --- a/jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_binary.py +++ b/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_binary.py @@ -2,7 +2,7 @@ from jmetal.algorithm.singleobjective.evolutionaryalgorithm import GenerationalGeneticAlgorithm from jmetal.core.solution import BinarySolution -from jmetal.operator.crossover import SinglePoint +from jmetal.operator.crossover import SP from jmetal.operator.mutation import BitFlip from jmetal.operator.selection import BinaryTournamentSelection from jmetal.problem.singleobjective.unconstrained import OneMax @@ -19,7 +19,7 @@ def main() -> None: population_size = 100, max_evaluations = 150000, mutation = BitFlip(1.0/bits), - crossover = SinglePoint(0.9), + crossover = SP(0.9), selection = BinaryTournamentSelection()) algorithm.run() diff --git a/jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_float.py b/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_float.py similarity index 100% rename from jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_float.py rename to examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_float.py diff --git a/jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_running_as_a_thread.py b/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_running_as_a_thread.py similarity index 100% rename from jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_running_as_a_thread.py rename to examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_running_as_a_thread.py diff --git a/jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_stopping_by_time.py b/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_stopping_by_time.py similarity index 100% rename from jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_stopping_by_time.py rename to examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_stopping_by_time.py diff --git a/jmetal/algorithm/__init__.py b/jmetal/algorithm/__init__.py index e69de29b..197a2912 100644 --- a/jmetal/algorithm/__init__.py +++ b/jmetal/algorithm/__init__.py @@ -0,0 +1,7 @@ +from .multiobjective.nsgaii import NSGAII +from .multiobjective.smpso import SMPSO, SMPSORP +from .singleobjective.evolutionaryalgorithm import ElitistEvolutionStrategy, NonElitistEvolutionStrategy + +__all__ = ['NSGAII', + 'SMPSO', 'SMPSORP', + 'ElitistEvolutionStrategy', 'NonElitistEvolutionStrategy'] \ No newline at end of file diff --git a/jmetal/algorithm/multiobjective/nsgaii.py b/jmetal/algorithm/multiobjective/nsgaii.py index 2567212c..7235e6de 100644 --- a/jmetal/algorithm/multiobjective/nsgaii.py +++ b/jmetal/algorithm/multiobjective/nsgaii.py @@ -5,7 +5,6 @@ from jmetal.core.operator import Mutation, Crossover, Selection from jmetal.core.problem import Problem from jmetal.operator.selection import RankingAndCrowdingDistanceSelection -from jmetal.util.observable import Observable, DefaultObservable S = TypeVar('S') R = TypeVar(List[S]) @@ -28,8 +27,7 @@ def __init__(self, mutation: Mutation[S], crossover: Crossover[S, S], selection: Selection[List[S], S], - evaluator: Evaluator[S] = SequentialEvaluator[S](), - observable: Observable = DefaultObservable()): + evaluator: Evaluator[S] = SequentialEvaluator[S]()): """ NSGA-II is a genetic algorithm (GA), i.e. it belongs to the evolutionary algorithms (EAs) family. The implementation of NSGA-II provided in jMetalPy follows the evolutionary algorithm template described in the algorithm templates section (:mod:`algorithm`) of the documentation. @@ -40,7 +38,6 @@ def __init__(self, :param mutation: :param crossover: :param selection: - :param observable: :param evaluator: An evaluator object to evaluate the solutions in the population. """ super(NSGAII, self).__init__( @@ -50,8 +47,7 @@ def __init__(self, mutation, crossover, selection, - evaluator, - observable) + evaluator) def replacement(self, population: List[S], offspring_population: List[S]) -> List[List[TypeVar('S')]]: """ This method joins the current and offspring populations to produce the population of the next generation diff --git a/jmetal/algorithm/multiobjective/randomSearch.py b/jmetal/algorithm/multiobjective/randomSearch.py index f2559946..e66e5302 100644 --- a/jmetal/algorithm/multiobjective/randomSearch.py +++ b/jmetal/algorithm/multiobjective/randomSearch.py @@ -15,7 +15,10 @@ class RandomSearch(Generic[S]): - def __init__(self, problem: Problem[S], max_evaluations: int): + + def __init__(self, + problem: Problem[S], + max_evaluations: int = 25000): self.problem = problem self.max_evaluations = max_evaluations self.archive = NonDominatedSolutionListArchive() diff --git a/jmetal/algorithm/multiobjective/smpso.py b/jmetal/algorithm/multiobjective/smpso.py index 13d70efb..5460d183 100644 --- a/jmetal/algorithm/multiobjective/smpso.py +++ b/jmetal/algorithm/multiobjective/smpso.py @@ -1,7 +1,7 @@ +from typing import TypeVar, List from copy import copy -import random from math import sqrt -from typing import TypeVar, List +import random import numpy @@ -11,8 +11,7 @@ from jmetal.core.operator import Mutation from jmetal.core.problem import FloatProblem from jmetal.core.solution import FloatSolution -from jmetal.util.comparator import DominanceComparator -from jmetal.util.observable import Observable, DefaultObservable +from jmetal.component.comparator import DominanceComparator R = TypeVar('R') @@ -32,23 +31,21 @@ def __init__(self, swarm_size: int, max_evaluations: int, mutation: Mutation[FloatSolution], - leaders: BoundedArchive[FloatSolution] or None, - observable: Observable = DefaultObservable(), + leaders: BoundedArchive[FloatSolution], evaluator: Evaluator[FloatSolution] = SequentialEvaluator[FloatSolution]()): - """ This class implements the SMPSO algorithm described in + """ This class implements the SMPSO algorithm as described in * SMPSO: A new PSO-based metaheuristic for multi-objective optimization * MCDM 2009. DOI: ``_. - The implementation of SMPSO provided in jMetalPy follows the - algorithm template described in the algorithm templates section of the documentation. + The implementation of SMPSO provided in jMetalPy follows the algorithm template described in the algorithm + templates section of the documentation. :param problem: The problem to solve. - :param swarm_size: - :param max_evaluations: - :param mutation: - :param leaders: - :param observable: + :param swarm_size: Swarm size. + :param max_evaluations: Maximum number of evaluations. + :param mutation: Mutation operator. + :param leaders: Archive for leaders. :param evaluator: An evaluator object to evaluate the solutions in the population. """ super().__init__() @@ -57,7 +54,6 @@ def __init__(self, self.max_evaluations = max_evaluations self.mutation = mutation self.leaders = leaders - self.observable = observable self.evaluator = evaluator self.evaluations = 0 @@ -220,13 +216,13 @@ def __constriction_coefficient(self, c1: float, c2: float) -> float: class SMPSORP(SMPSO): - def __init__(self, problem: FloatProblem, + def __init__(self, + problem: FloatProblem, swarm_size: int, max_evaluations: int, mutation: Mutation[FloatSolution], reference_points: List[List], leaders: List[BoundedArchive[FloatSolution]], - observable: Observable = DefaultObservable(), evaluator: Evaluator[FloatSolution] = SequentialEvaluator[FloatSolution]()): """ This class implements the SMPSORP algorithm. @@ -235,7 +231,6 @@ def __init__(self, problem: FloatProblem, :param max_evaluations: :param mutation: :param leaders: List of bounded archives. - :param observable: :param evaluator: An evaluator object to evaluate the solutions in the population. """ super().__init__( @@ -244,7 +239,6 @@ def __init__(self, problem: FloatProblem, max_evaluations, mutation, None, - observable, evaluator) self.reference_points = reference_points self.leaders = leaders diff --git a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py index c0c269a1..58b5d94d 100644 --- a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py +++ b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py @@ -1,19 +1,16 @@ from copy import copy from typing import TypeVar, List -from tqdm import tqdm - -from jmetal.component.evaluator import Evaluator, SequentialEvaluator +from jmetal.component.evaluator import Evaluator from jmetal.core.algorithm import EvolutionaryAlgorithm from jmetal.core.operator import Mutation, Crossover, Selection from jmetal.core.problem import Problem -from jmetal.util.observable import Observable, DefaultObservable S = TypeVar('S') R = TypeVar('R') """ -.. module:: evolutionaryalgorithm +.. module:: Evolutionary Algorithm (EA) :platform: Unix, Windows :synopsis: Implementation of Evolutionary Algorithms. @@ -51,15 +48,15 @@ def create_initial_population(self) -> List[S]: population.append(self.problem.create_solution()) return population - def evaluate_population(self, population: List[S]): + def evaluate_population(self, population: List[S]) -> List[S]: for solution in population: self.problem.evaluate(solution) return population - def selection(self, population: List[S]): + def selection(self, population: List[S]) -> List[S]: return population - def reproduction(self, population: List[S]): + def reproduction(self, population: List[S]) -> List[S]: offspring_population = [] for solution in population: for j in range((int)(self.lambd_a / self.mu)): @@ -83,7 +80,7 @@ def replacement(self, population: List[S], offspring_population: List[S]) -> Lis def get_result(self) -> R: return self.population[0] - def get_name(self): + def get_name(self) -> str: return "(" + str(self.mu) + "+" + str(self.lambd_a) + ")ES" @@ -91,14 +88,13 @@ class NonElitistEvolutionStrategy(ElitistEvolutionStrategy[S, R]): def __init__(self, problem: Problem[S], - mu: int, lambdA: int, + mu: int, + lambd_a: int, max_evaluations: int, mutation: Mutation[S]): - super(NonElitistEvolutionStrategy, self).__init__(problem, mu, lambdA, - max_evaluations, mutation) + super(NonElitistEvolutionStrategy, self).__init__(problem, mu, lambd_a, max_evaluations, mutation) - def replacement(self, population: List[S], offspring_population: List[S]) \ - -> List[S]: + def replacement(self, population: List[S], offspring_population: List[S]) -> List[S]: offspring_population.sort(key=lambda s: s.objectives[0]) new_population = [] @@ -120,17 +116,15 @@ def __init__(self, mutation: Mutation[S], crossover: Crossover[S, S], selection: Selection[List[S], S], - evaluator: Evaluator[S] = SequentialEvaluator[S](), - observable: Observable = DefaultObservable()): - super(GenerationalGeneticAlgorithm, self).__init__(evaluator) + evaluator: Evaluator[S]): + super(GenerationalGeneticAlgorithm, self).__init__() self.problem = problem self.population_size = population_size self.max_evaluations = max_evaluations self.mutation_operator = mutation self.crossover_operator = crossover self.selection_operator = selection - self.evaluations = 0 - self.observable = observable + self.evaluator = evaluator def init_progress(self): self.evaluations = self.population_size diff --git a/jmetal/component/archive.py b/jmetal/component/archive.py index 2cb024b3..f3591915 100644 --- a/jmetal/component/archive.py +++ b/jmetal/component/archive.py @@ -3,7 +3,7 @@ from typing import TypeVar, Generic, List from jmetal.component.density_estimator import CrowdingDistance, DensityEstimator -from jmetal.util.comparator import Comparator, DominanceComparator, EqualSolutionsComparator, SolutionAttributeComparator +from jmetal.component.comparator import Comparator, DominanceComparator, EqualSolutionsComparator, SolutionAttributeComparator S = TypeVar('S') @@ -24,7 +24,7 @@ def __init__(self): def add(self, solution: S) -> bool: pass - def get(self, index:int) -> S: + def get(self, index: int) -> S: return self.solution_list[index] def get_solution_list(self) -> List[S]: @@ -39,7 +39,10 @@ def get_comparator(self): class BoundedArchive(Archive[S]): - def __init__(self, maximum_size: int, comparator: Comparator[S]=None, density_estimator: DensityEstimator=None): + def __init__(self, + maximum_size: int, + comparator: Comparator[S]=None, + density_estimator: DensityEstimator=None): super(BoundedArchive, self).__init__() self.maximum_size = maximum_size self.comparator = comparator @@ -86,7 +89,7 @@ def __init__(self): super(NonDominatedSolutionListArchive, self).__init__() self.comparator = DominanceComparator() - def add(self, solution:S) -> bool: + def add(self, solution: S) -> bool: is_dominated = False is_contained = False @@ -122,7 +125,8 @@ def get_comparator(self): class CrowdingDistanceArchive(BoundedArchive[S]): - def __init__(self, maximum_size: int): + def __init__(self, + maximum_size: int): super(CrowdingDistanceArchive, self).__init__( maximum_size=maximum_size, comparator=SolutionAttributeComparator("crowding_distance", lowest_is_best=False), @@ -131,7 +135,11 @@ def __init__(self, maximum_size: int): class ArchiveWithReferencePoint(BoundedArchive[S]): - def __init__(self, maximum_size: int, reference_point: List[float], comparator: Comparator[S], density_estimator: DensityEstimator): + def __init__(self, + maximum_size: int, + reference_point: List[float], + comparator: Comparator[S], + density_estimator: DensityEstimator): super(ArchiveWithReferencePoint, self).__init__(maximum_size, comparator, density_estimator) self.__reference_point = reference_point self.__comparator = comparator @@ -195,7 +203,9 @@ def __dominance_test(self, solution1:S, solution2:S)->int: class CrowdingDistanceArchiveWithReferencePoint(ArchiveWithReferencePoint[S]): - def __init__(self, maximum_size: int, reference_point:List[float]): + def __init__(self, + maximum_size: int, + reference_point: List[float]): super(CrowdingDistanceArchiveWithReferencePoint, self).__init__( maximum_size=maximum_size, reference_point=reference_point, diff --git a/jmetal/util/comparator.py b/jmetal/component/comparator.py similarity index 100% rename from jmetal/util/comparator.py rename to jmetal/component/comparator.py diff --git a/jmetal/component/observer.py b/jmetal/component/observer.py index 49447104..51fdc6f1 100644 --- a/jmetal/component/observer.py +++ b/jmetal/component/observer.py @@ -4,8 +4,8 @@ from tqdm import tqdm from jmetal.core.problem import Problem -from jmetal.util.graphic import ScatterBokeh, ScatterMatplotlib -from jmetal.util.observable import Observer +from jmetal.util.graphic import ScatterMatplotlib +from jmetal.core.observable import Observer from jmetal.util.solution_list_output import SolutionList logger = logging.getLogger(__name__) diff --git a/jmetal/util/ranking.py b/jmetal/component/ranking.py similarity index 98% rename from jmetal/util/ranking.py rename to jmetal/component/ranking.py index ac770685..eccd275c 100644 --- a/jmetal/util/ranking.py +++ b/jmetal/component/ranking.py @@ -1,6 +1,6 @@ from typing import TypeVar, List -from jmetal.util.comparator import DominanceComparator +from jmetal.component.comparator import DominanceComparator S = TypeVar('S') diff --git a/jmetal/util/test/test_comparator.py b/jmetal/component/test/test_comparator.py similarity index 99% rename from jmetal/util/test/test_comparator.py rename to jmetal/component/test/test_comparator.py index 7c6ad6d6..423e9dff 100644 --- a/jmetal/util/test/test_comparator.py +++ b/jmetal/component/test/test_comparator.py @@ -1,7 +1,7 @@ import unittest from jmetal.core.solution import FloatSolution, Solution -from jmetal.util.comparator import DominanceComparator, SolutionAttributeComparator, \ +from jmetal.component.comparator import DominanceComparator, SolutionAttributeComparator, \ RankingAndCrowdingDistanceComparator diff --git a/jmetal/util/test/test_ranking.py b/jmetal/component/test/test_ranking.py similarity index 98% rename from jmetal/util/test/test_ranking.py rename to jmetal/component/test/test_ranking.py index f8fe24ea..6dc993b6 100644 --- a/jmetal/util/test/test_ranking.py +++ b/jmetal/component/test/test_ranking.py @@ -1,7 +1,7 @@ import unittest from jmetal.core.solution import Solution -from jmetal.util.ranking import FastNonDominatedRanking +from jmetal.component.ranking import FastNonDominatedRanking class FastNonDominatedRankingTestCases(unittest.TestCase): diff --git a/jmetal/core/algorithm.py b/jmetal/core/algorithm.py index e370f573..f744558c 100644 --- a/jmetal/core/algorithm.py +++ b/jmetal/core/algorithm.py @@ -3,10 +3,8 @@ import time from typing import TypeVar, Generic, List -from tqdm import tqdm - -from jmetal.component.evaluator import Evaluator, SequentialEvaluator from jmetal.core.solution import FloatSolution +from jmetal.core.observable import Observable, DefaultObservable logger = logging.getLogger(__name__) @@ -14,7 +12,7 @@ R = TypeVar('R') """ -.. module:: algorithm +.. module:: Algorithm :platform: Unix, Windows :synopsis: Templates for algorithms. @@ -26,28 +24,30 @@ class Algorithm(Generic[S, R], threading.Thread): def __init__(self): threading.Thread.__init__(self) - self.observable = None self.evaluations: int = 0 self.max_evaluations: int = 100 self.start_computing_time: int = 0 self.total_computing_time: int = 0 - - def get_name(self) -> str: - return type(self).__name__ + self.observable: Observable = DefaultObservable() def get_evaluations(self) -> int: return self.evaluations + def get_result(self) -> R: + pass + def get_current_computing_time(self) -> float: return time.time() - self.start_computing_time + def get_name(self) -> str: + return type(self).__name__ + class EvolutionaryAlgorithm(Algorithm[S, R]): - def __init__(self, evaluator: Evaluator[S] = SequentialEvaluator[S]()): + def __init__(self): super(EvolutionaryAlgorithm, self).__init__() self.population = [] - self.evaluator = evaluator def create_initial_population(self) -> List[S]: pass @@ -73,9 +73,6 @@ def replacement(self, population: List[S], offspring_population: List[S]) -> Lis def update_progress(self): pass - def get_result(self) -> R: - pass - def run(self): """* Step One: Generate the initial population of individuals randomly. (First generation) * Step Two: Evaluate the fitness of each individual in that population (time limit, sufficient fitness achieved, etc.) @@ -150,9 +147,6 @@ def update_global_best(self, swarm: List[FloatSolution]) -> None: def update_particle_best(self, swarm: List[FloatSolution]) -> None: pass - def get_result(self) -> R: - pass - def run(self): self.start_computing_time = time.time() diff --git a/jmetal/util/observable.py b/jmetal/core/observable.py similarity index 98% rename from jmetal/util/observable.py rename to jmetal/core/observable.py index 67a40b38..af322357 100644 --- a/jmetal/util/observable.py +++ b/jmetal/core/observable.py @@ -1,7 +1,7 @@ from abc import ABCMeta, abstractmethod """ -.. module:: observable +.. module:: Observable :platform: Unix, Windows :synopsis: Implementation of the observer-observable pattern. @@ -9,6 +9,21 @@ """ +class Observer(object): + + __metaclass__ = ABCMeta + + @abstractmethod + def update(self, *args, **kwargs): + """ Update method + + :param args: + :param kwargs: + :return: + """ + pass + + class Observable(object): def register(self, observer): @@ -24,20 +39,6 @@ def notify_all(self, *args, **kwargs): pass -class Observer(object): - __metaclass__ = ABCMeta - - @abstractmethod - def update(self, *args, **kwargs): - """ Update method - - :param args: - :param kwargs: - :return: - """ - pass - - class DefaultObservable(Observable): def __init__(self): diff --git a/jmetal/core/operator.py b/jmetal/core/operator.py index e3cf03c8..915edea2 100644 --- a/jmetal/core/operator.py +++ b/jmetal/core/operator.py @@ -1,10 +1,16 @@ from typing import TypeVar, Generic, List -__author__ = "Antonio J. Nebro" - S = TypeVar('S') R = TypeVar('R') +""" +.. module:: Operator + :platform: Unix, Windows + :synopsis: Templates for operators. + +.. moduleauthor:: Antonio J. Nebro +""" + class Operator(Generic[S, R]): """ Class representing operator """ @@ -17,7 +23,7 @@ def get_name(self): class Mutation(Operator[S, S]): - """ Class representing mutation operator """ + """ Class representing mutation operator. """ def __init__(self, probability: float): if probability > 1.0: @@ -32,6 +38,8 @@ def execute(self, source: S) -> S: class Crossover(Operator[List[S], List[R]]): + """ Class representing crossover operator. """ + def __init__(self, probability: float): if probability > 1.0: raise Exception("The probability is greater than one: " + str(probability)) @@ -48,6 +56,8 @@ def get_number_of_parents(self) -> int: class Selection(Operator[S, R]): + """ Class representing selection operator. """ + def __init__(self): pass diff --git a/jmetal/core/problem.py b/jmetal/core/problem.py index 1f98a704..4e59ec57 100644 --- a/jmetal/core/problem.py +++ b/jmetal/core/problem.py @@ -5,7 +5,7 @@ import random from jmetal.core.solution import BinarySolution, FloatSolution, IntegerSolution -from jmetal.util.front_file import walk_up_folder, read_front_from_file_as_solutions +from jmetal.util.front_file import read_front_from_file_as_solutions S = TypeVar('S') diff --git a/jmetal/util/test/test_observable.py b/jmetal/core/test/test_observable.py similarity index 96% rename from jmetal/util/test/test_observable.py rename to jmetal/core/test/test_observable.py index 4e4c8316..eb75c856 100644 --- a/jmetal/util/test/test_observable.py +++ b/jmetal/core/test/test_observable.py @@ -1,6 +1,6 @@ import unittest -from jmetal.util.observable import DefaultObservable, Observer +from jmetal.core.observable import DefaultObservable, Observer class ObservableTestCases(unittest.TestCase): diff --git a/jmetal/core/test/test_problem.py b/jmetal/core/test/test_problem.py index 1d7ac345..2dbced3f 100644 --- a/jmetal/core/test/test_problem.py +++ b/jmetal/core/test/test_problem.py @@ -2,8 +2,6 @@ from jmetal.core.problem import Problem, FloatProblem, IntegerProblem -__author__ = "Antonio J. Nebro" - class ProblemTestCases(unittest.TestCase): diff --git a/jmetal/core/test/test_solution.py b/jmetal/core/test/test_solution.py index f0f5a3d5..dd28c356 100644 --- a/jmetal/core/test/test_solution.py +++ b/jmetal/core/test/test_solution.py @@ -3,14 +3,9 @@ from jmetal.core.solution import BinarySolution, FloatSolution, Solution, IntegerSolution -__author__ = "Antonio J. Nebro" - class SolutionTestCase(unittest.TestCase): - def setUp(self) -> None: - pass - def test_should_constructor_create_a_non_null_object(self) -> None: solution = Solution[int](3, 2) self.assertIsNotNone(solution) @@ -34,9 +29,6 @@ def test_should_constructor_create_a_non_null_objective_list(self) -> None: class BinarySolutionTestCase(unittest.TestCase): - def setUp(self) -> None: - pass - def test_should_default_constructor_create_a_valid_solution(self) -> None: solution = BinarySolution(2, 3, 1) self.assertEqual(2, solution.number_of_variables) @@ -67,9 +59,6 @@ def test_should_get_total_number_of_bits_return_the_right_value(self) -> None: class FloatSolutionTestCase(unittest.TestCase): - def setUp(self) -> None: - pass - def test_should_constructor_create_a_non_null_object(self) -> None: solution = FloatSolution(3, 2, 0, [], []) self.assertIsNotNone(solution) @@ -106,9 +95,6 @@ def test_should_copy_work_properly(self) -> None: class IntegerSolutionTestCase(unittest.TestCase): - def setUp(self) -> None: - pass - def test_should_constructor_create_a_non_null_object(self) -> None: solution = IntegerSolution(3, 2, 0, [], []) self.assertIsNotNone(solution) diff --git a/jmetal/operator/__init__.py b/jmetal/operator/__init__.py index e69de29b..26e57f2f 100644 --- a/jmetal/operator/__init__.py +++ b/jmetal/operator/__init__.py @@ -0,0 +1,9 @@ +from .crossover import NullCrossover, SBX, SP +from .mutation import NullMutation, BitFlip, Polynomial, IntegerPolynomial, Uniform, SimpleRandom +from .selection import BestSolutionSelection, BinaryTournamentSelection, BinaryTournament2Selection, \ + RandomSolutionSelection, NaryRandomSolutionSelection, RankingAndCrowdingDistanceSelection + +__all__ = ['NullCrossover', 'SBX', 'SP', + 'NullMutation', 'BitFlip', 'Polynomial', 'IntegerPolynomial', 'Uniform', 'SimpleRandom', + 'BestSolutionSelection', 'BinaryTournamentSelection', 'BinaryTournament2Selection', 'RandomSolutionSelection', + 'NaryRandomSolutionSelection', 'RankingAndCrowdingDistanceSelection'] \ No newline at end of file diff --git a/jmetal/operator/crossover.py b/jmetal/operator/crossover.py index c1d228f2..0ef52c26 100644 --- a/jmetal/operator/crossover.py +++ b/jmetal/operator/crossover.py @@ -5,18 +5,24 @@ from jmetal.core.operator import Crossover from jmetal.core.solution import Solution, FloatSolution, BinarySolution -""" Class implementing the null crossover operator """ +""" +.. module:: Crossover operators + :platform: Unix, Windows + :synopsis: Module implementing crossover operators. +.. moduleauthor:: Antonio J. Nebro +""" -class Null(Crossover[Solution, Solution]): + +class NullCrossover(Crossover[Solution, Solution]): def __init__(self): - super(Null, self).__init__(probability=0) + super(NullCrossover, self).__init__(probability=0) def execute(self, parents: List[Solution]) -> List[Solution]: if len(parents) != 2: raise Exception("The number of parents is not two: " + str(len(parents))) - return [copy.deepcopy(parents[0]), copy.deepcopy(parents[1])] + return parents def get_number_of_parents(self): return 2 @@ -96,9 +102,9 @@ def get_number_of_parents(self): return 2 -class SinglePoint(Crossover[BinarySolution, BinarySolution]): +class SP(Crossover[BinarySolution, BinarySolution]): def __init__(self, probability: float): - super(SinglePoint, self).__init__(probability=probability) + super(SP, self).__init__(probability=probability) def execute(self, parents: List[BinarySolution]) -> List[BinarySolution]: if len(parents) != 2: diff --git a/jmetal/operator/mutation.py b/jmetal/operator/mutation.py index 1a5bbc85..06897cc5 100644 --- a/jmetal/operator/mutation.py +++ b/jmetal/operator/mutation.py @@ -3,8 +3,24 @@ from jmetal.core.operator import Mutation from jmetal.core.solution import BinarySolution, Solution, FloatSolution, IntegerSolution -""" Class implementing the binary BitFlip mutation operator """ -__author__ = "Antonio J. Nebro" +""" +.. module:: Mutation operators + :platform: Unix, Windows + :synopsis: Module implementing mutation operators. + +.. moduleauthor:: Antonio J. Nebro +""" + + +class NullMutation(Mutation[Solution]): + def __init__(self): + super(NullMutation, self).__init__(probability=0) + + def execute(self, solution: Solution) -> Solution: + return solution + + def get_name(self): + return "Null mutation" class BitFlip(Mutation[BinarySolution]): @@ -20,16 +36,8 @@ def execute(self, solution: BinarySolution) -> BinarySolution: return solution - -class Null(Mutation[Solution]): - def __init__(self): - super(Null, self).__init__(probability=0) - def get_name(self): - return "Null mutation" - - def execute(self, solution: Solution) -> Solution: - return solution + return "BitFlip mutation" class Polynomial(Mutation[FloatSolution]): @@ -37,9 +45,6 @@ def __init__(self, probability: float, distribution_index: float = 0.20): super(Polynomial, self).__init__(probability=probability) self.distribution_index = distribution_index - def get_name(self): - return "Polynomial mutation" - def execute(self, solution: FloatSolution) -> FloatSolution: for i in range(solution.number_of_variables): rand = random.random() @@ -74,15 +79,15 @@ def execute(self, solution: FloatSolution) -> FloatSolution: return solution + def get_name(self): + return "Polynomial mutation" + class IntegerPolynomial(Mutation[IntegerSolution]): def __init__(self, probability: float, distribution_index: float = 0.20): super(IntegerPolynomial, self).__init__(probability=probability) self.distribution_index = distribution_index - def get_name(self): - return "Polynomial mutation (Integer)" - def execute(self, solution: IntegerSolution) -> IntegerSolution: for i in range(solution.number_of_variables): if random.random() <= self.probability: @@ -114,14 +119,14 @@ def execute(self, solution: IntegerSolution) -> IntegerSolution: solution.variables[i] = int(round(y)) return solution + def get_name(self): + return "Polynomial mutation (Integer)" + class SimpleRandom(Mutation[FloatSolution]): def __init__(self, probability: float): super(SimpleRandom, self).__init__(probability=probability) - def get_name(self): - return "Simple random mutation" - def execute(self, solution: FloatSolution) -> FloatSolution: for i in range(solution.number_of_variables): rand = random.random() @@ -130,15 +135,15 @@ def execute(self, solution: FloatSolution) -> FloatSolution: (solution.upper_bound[i] - solution.lower_bound[i]) * random.random() return solution + def get_name(self): + return "Simple random mutation" + class Uniform(Mutation[FloatSolution]): def __init__(self, probability: float, perturbation: float = 0.5): super(Uniform, self).__init__(probability=probability) self.perturbation = perturbation - def get_name(self): - return "Uniform mutation" - def execute(self, solution: FloatSolution) -> FloatSolution: for i in range(solution.number_of_variables): rand = random.random() @@ -155,3 +160,6 @@ def execute(self, solution: FloatSolution) -> FloatSolution: solution.variables[i] = tmp return solution + + def get_name(self): + return "Uniform mutation" diff --git a/jmetal/operator/selection.py b/jmetal/operator/selection.py index e9e18a73..842e6b81 100644 --- a/jmetal/operator/selection.py +++ b/jmetal/operator/selection.py @@ -3,13 +3,19 @@ from jmetal.component.density_estimator import CrowdingDistance from jmetal.core.operator import Selection -from jmetal.util.comparator import Comparator, DominanceComparator -from jmetal.util.ranking import FastNonDominatedRanking - -""" Class implementing a best solution selection operator """ +from jmetal.component.comparator import Comparator, DominanceComparator +from jmetal.component.ranking import FastNonDominatedRanking S = TypeVar('S') +""" +.. module:: Selection operators + :platform: Unix, Windows + :synopsis: Module implementing selection operators. + +.. moduleauthor:: Antonio J. Nebro +""" + class BinaryTournamentSelection(Selection[List[S], S]): def __init__(self, comparator: Comparator = DominanceComparator()): @@ -45,6 +51,7 @@ def get_name(self) -> str: class BestSolutionSelection(Selection[List[S], S]): + def __init__(self): super(BestSolutionSelection, self).__init__() @@ -63,6 +70,7 @@ def execute(self, solution_list: List[S]) -> S: class NaryRandomSolutionSelection(Selection[List[S], S]): + def __init__(self, number_of_solutions_to_be_returned:int = 1): super(NaryRandomSolutionSelection, self).__init__() if number_of_solutions_to_be_returned < 0: @@ -75,7 +83,7 @@ def execute(self, solution_list: List[S]) -> S: raise Exception("The solution list is null") if len(solution_list) == 0: raise Exception("The solution is empty") - if len(solution_list) S: class RandomSolutionSelection(Selection[List[S], S]): + def __init__(self): super(RandomSolutionSelection, self).__init__() @@ -96,6 +105,7 @@ def execute(self, solution_list: List[S]) -> S: class RankingAndCrowdingDistanceSelection(Selection[List[S], List[S]]): + def __init__(self, max_population_size: int): super(RankingAndCrowdingDistanceSelection, self).__init__() self.max_population_size = max_population_size @@ -123,13 +133,11 @@ def execute(self, solution_list: List[S]) -> List[S]: class BinaryTournament2Selection(Selection[List[S], S]): + def __init__(self, comparator_list: List[Comparator]): super(BinaryTournament2Selection, self).__init__() self.comparator_list = comparator_list - def get_name(self): - return "Binary tournament selection (experimental)" - def execute(self, solution_list: List[S]) -> S: if solution_list is None: raise Exception("The solution list is null") @@ -169,3 +177,6 @@ def __winner(self, solution_list: List[S], comparator: Comparator): result = None return result + + def get_name(self): + return "Binary tournament selection (experimental)" diff --git a/jmetal/operator/test/test_crossover.py b/jmetal/operator/test/test_crossover.py index 305354f0..1a880985 100644 --- a/jmetal/operator/test/test_crossover.py +++ b/jmetal/operator/test/test_crossover.py @@ -2,24 +2,21 @@ from unittest import mock from jmetal.core.solution import BinarySolution -from jmetal.operator.crossover import Null, SinglePoint +from jmetal.operator.crossover import NullCrossover, SP class NullCrossoverTestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self): - solution = Null() + solution = NullCrossover() self.assertIsNotNone(solution) def test_should_constructor_create_a_valid_operator(self): - operator = Null() + operator = NullCrossover() self.assertEqual(0, operator.probability) def test_should_the_solution_remain_unchanged(self): - operator = Null() + operator = NullCrossover() solution1 = BinarySolution(number_of_variables=1, number_of_objectives=1) solution1.variables[0] = [True, False, False, True, True, False] solution2 = BinarySolution(number_of_variables=1, number_of_objectives=1) @@ -31,27 +28,25 @@ def test_should_the_solution_remain_unchanged(self): class SinglePointTestCases(unittest.TestCase): - def setUp(self): - pass def test_should_constructor_create_a_non_null_object(self): - solution = SinglePoint(1.0) + solution = SP(1.0) self.assertIsNotNone(solution) def test_should_constructor_create_a_valid_operator(self): - operator = SinglePoint(0.5) + operator = SP(0.5) self.assertEqual(0.5, operator.probability) def test_should_constructor_raise_an_exception_if_the_probability_is_greater_than_one(self): with self.assertRaises(Exception): - SinglePoint(2) + SP(2) def test_should_constructor_raise_an_exception_if_the_probability_is_lower_than_zero(self): with self.assertRaises(Exception): - SinglePoint(-12) + SP(-12) def test_should_the_solution_remain_unchanged_if_the_probability_is_zero(self): - operator = SinglePoint(0.0) + operator = SP(0.0) solution1 = BinarySolution(number_of_variables=1, number_of_objectives=1) solution1.variables[0] = [True, False, False, True, True, False] solution2 = BinarySolution(number_of_variables=1, number_of_objectives=1) @@ -63,7 +58,7 @@ def test_should_the_solution_remain_unchanged_if_the_probability_is_zero(self): @mock.patch('random.randrange') def test_should_the_operator_work_if_the_first_bit_is_selected(self, random_call): - operator = SinglePoint(1.0) + operator = SP(1.0) solution1 = BinarySolution(number_of_variables=1, number_of_objectives=1) solution1.variables[0] = [True, False, False, True, True, False] solution2 = BinarySolution(number_of_variables=1, number_of_objectives=1) @@ -76,7 +71,7 @@ def test_should_the_operator_work_if_the_first_bit_is_selected(self, random_call @mock.patch('random.randrange') def test_should_the_operator_work_if_the_last_bit_is_selected(self, random_call): - operator = SinglePoint(1.0) + operator = SP(1.0) solution1 = BinarySolution(number_of_variables=1, number_of_objectives=1) solution1.variables[0] = [True, False, False, True, True, False] solution2 = BinarySolution(number_of_variables=1, number_of_objectives=1) @@ -89,7 +84,7 @@ def test_should_the_operator_work_if_the_last_bit_is_selected(self, random_call) @mock.patch('random.randrange') def test_should_the_operator_work_if_the_third_bit_is_selected(self, random_call): - operator = SinglePoint(1.0) + operator = SP(1.0) solution1 = BinarySolution(number_of_variables=1, number_of_objectives=1) solution1.variables[0] = [True, False, False, True, True, False] solution2 = BinarySolution(number_of_variables=1, number_of_objectives=1) @@ -102,7 +97,7 @@ def test_should_the_operator_work_if_the_third_bit_is_selected(self, random_call @mock.patch('random.randrange') def test_should_the_operator_work_with_a_solution_with_three_binary_variables(self, random_call): - operator = SinglePoint(1.0) + operator = SP(1.0) solution1 = BinarySolution(number_of_variables=3, number_of_objectives=1) solution1.variables[0] = [True, False, False, True, True, False] solution1.variables[1] = [True, False, False, True, False, False] @@ -121,5 +116,6 @@ def test_should_the_operator_work_with_a_solution_with_three_binary_variables(se self.assertEqual([True, True, False, True, False, False], offspring[1].variables[1]) self.assertEqual([True, False, True, True, True, True], offspring[1].variables[2]) + if __name__ == '__main__': unittest.main() diff --git a/jmetal/operator/test/test_mutation.py b/jmetal/operator/test/test_mutation.py index 87c9021a..0dfd7c40 100644 --- a/jmetal/operator/test/test_mutation.py +++ b/jmetal/operator/test/test_mutation.py @@ -3,14 +3,9 @@ from jmetal.core.solution import BinarySolution, FloatSolution, IntegerSolution from jmetal.operator.mutation import BitFlip, Uniform, SimpleRandom, Polynomial, IntegerPolynomial -__author__ = "Antonio J. Nebro" - class PolynomialMutationTestMethods(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self): mutation = Polynomial(1.0) self.assertIsNotNone(mutation) @@ -50,9 +45,6 @@ def test_should_the_solution_change__if_the_probability_is_one(self): class BitFlipTestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self): solution = BitFlip(1.0) self.assertIsNotNone(solution) @@ -90,9 +82,6 @@ def test_should_the_solution_change_all_the_bits_if_the_probability_is_one(self) class UniformMutationTestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self): operator = Uniform(0.3) operator2 = Uniform(0.3, 0.7) @@ -141,9 +130,6 @@ def test_should_the_solution_change_between_max_and_min_value(self): class RandomMutationTestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self): operator = SimpleRandom(1.0) self.assertIsNotNone(operator) @@ -188,8 +174,6 @@ def test_should_the_solution_change_between_max_and_min_value(self): class IntegerPolynomialMutationTestCases(unittest.TestCase): - def setUp(self): - pass def test_should_constructor_create_a_non_null_object(self): operator = IntegerPolynomial(1.0) @@ -226,5 +210,6 @@ def test_should_the_solution_change__if_the_probability_is_one(self): self.assertNotEqual([1, 2, 3], mutated_solution.variables) self.assertEqual([True, True, True], [isinstance(x, int) for x in mutated_solution.variables]) + if __name__ == '__main__': unittest.main() diff --git a/jmetal/operator/test/test_selection.py b/jmetal/operator/test/test_selection.py index 6cad5383..5ff43b3b 100644 --- a/jmetal/operator/test/test_selection.py +++ b/jmetal/operator/test/test_selection.py @@ -4,14 +4,12 @@ from jmetal.core.solution import Solution from jmetal.operator.selection import BinaryTournamentSelection, BestSolutionSelection, RandomSolutionSelection, \ - NaryRandomSolutionSelection, \ - RankingAndCrowdingDistanceSelection, BinaryTournament2Selection -from jmetal.util.comparator import Comparator, SolutionAttributeComparator - -__author__ = "Antonio J. Nebro" + NaryRandomSolutionSelection, RankingAndCrowdingDistanceSelection, BinaryTournament2Selection +from jmetal.component.comparator import Comparator, SolutionAttributeComparator class BinaryTournamentTestCases(unittest.TestCase): + def setUp(self): self.selection = BinaryTournamentSelection[Solution]() @@ -56,6 +54,7 @@ def test_should_execute_work_if_the_solution_list_contains_two_solutions_and_one class BestSolutionSelectionTestCases(unittest.TestCase): + def setUp(self): self.selection = BestSolutionSelection[Solution]() @@ -178,9 +177,6 @@ def test_should_execute_work_if_the_solution_list_contains_five_solutions_and_on class NaryRandomSolutionSelectionTestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self): selection = NaryRandomSolutionSelection[Solution]() self.assertIsNotNone(selection) @@ -246,6 +242,7 @@ def test_should_execute_work_if_the_solution_list_contains_five_solutions_and_on class DominanceRankingTestCases(unittest.TestCase): + def setUp(self): self.ranking_and_crowding_selection = RankingAndCrowdingDistanceSelection(5) diff --git a/jmetal/problem/__init__.py b/jmetal/problem/__init__.py index e69de29b..f303cfbf 100644 --- a/jmetal/problem/__init__.py +++ b/jmetal/problem/__init__.py @@ -0,0 +1,11 @@ +from .multiobjective.constrained import Srinivas, Tanaka +from .multiobjective.unconstrained import Kursawe, Fonseca, Schaffer, Viennet2 +from .multiobjective.dtlz import DTLZ1, DTLZ2 +from .multiobjective.zdt import ZDT1, ZDT2, ZDT3, ZDT4, ZDT6 +from .singleobjective.unconstrained import OneMax, Sphere + +__all__ = ['Srinivas', 'Tanaka', + 'Kursawe', 'Fonseca', 'Schaffer', 'Viennet2', + 'DTLZ1', 'DTLZ2', + 'ZDT1', 'ZDT2', 'ZDT3', 'ZDT4', 'ZDT6', + 'OneMax', 'Sphere'] \ No newline at end of file diff --git a/jmetal/problem/multiobjective/constrained.py b/jmetal/problem/multiobjective/constrained.py index e22e86d4..ad4aa413 100644 --- a/jmetal/problem/multiobjective/constrained.py +++ b/jmetal/problem/multiobjective/constrained.py @@ -13,7 +13,7 @@ class Srinivas(FloatProblem): - """ Class representing problem Srinivas """ + """ Class representing problem Srinivas. """ def __init__(self): super().__init__() @@ -34,11 +34,8 @@ def evaluate(self, solution: FloatSolution): solution.objectives[0] = 2.0 + (x1 - 2.0) * (x1 - 2.0) + (x2 - 1.0) * (x2 - 1.0) solution.objectives[1] = 9.0 * x1 - (x2 - 1.0) * (x2 - 1.0) - def get_name(self): - return "Srinivas" - def evaluate_constraints(self, solution: FloatSolution) -> None: - constraints : [float] = [0.0 for _ in range(self.number_of_constraints)] + constraints = [0.0 for _ in range(self.number_of_constraints)] x1 = solution.variables[0] x2 = solution.variables[1] @@ -57,6 +54,9 @@ def evaluate_constraints(self, solution: FloatSolution) -> None: solution.attributes["overall_constraint_violation"] = overall_constraint_violation solution.attributes["number_of_violated_constraints"] = number_of_violated_constraints + def get_name(self): + return "Srinivas" + class Tanaka(FloatProblem): """ Class representing problem Tanaka """ @@ -78,7 +78,7 @@ def evaluate(self, solution: FloatSolution): solution.objectives[1] = solution.variables[1] def evaluate_constraints(self, solution: FloatSolution) -> None: - constraints : [float] = [0.0 for _ in range(self.number_of_constraints)] + constraints = [0.0 for _ in range(self.number_of_constraints)] x1 = solution.variables[0] x2 = solution.variables[1] diff --git a/jmetal/problem/multiobjective/dtlz.py b/jmetal/problem/multiobjective/dtlz.py index cacee429..b0469320 100644 --- a/jmetal/problem/multiobjective/dtlz.py +++ b/jmetal/problem/multiobjective/dtlz.py @@ -4,7 +4,7 @@ from jmetal.core.solution import FloatSolution """ -.. module:: `dtlz` +.. module:: DTLZ :platform: Unix, Windows :synopsis: DTLZ problem family of multi-objective problems. @@ -19,7 +19,7 @@ class DTLZ1(FloatProblem): """ def __init__(self, number_of_variables: int = 7, number_of_objectives=3): - """ :param number_of_variables: number of decision variables of the problem + """ :param number_of_variables: number of decision variables of the problem. """ super().__init__() self.number_of_variables = number_of_variables diff --git a/jmetal/problem/multiobjective/test/test_unconstrained.py b/jmetal/problem/multiobjective/test/test_unconstrained.py index f3e95b8b..c3aab297 100644 --- a/jmetal/problem/multiobjective/test/test_unconstrained.py +++ b/jmetal/problem/multiobjective/test/test_unconstrained.py @@ -3,7 +3,6 @@ from jmetal.problem.multiobjective.unconstrained import Kursawe, Fonseca, Schaffer, Viennet2 - class KursaweTestCases(unittest.TestCase): def test_should_constructor_create_a_non_null_object(self) -> None: diff --git a/jmetal/problem/multiobjective/unconstrained.py b/jmetal/problem/multiobjective/unconstrained.py index 6da24312..6169d815 100644 --- a/jmetal/problem/multiobjective/unconstrained.py +++ b/jmetal/problem/multiobjective/unconstrained.py @@ -27,9 +27,6 @@ def __init__(self, number_of_variables: int = 3): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def get_name(self): - return "Kursawe" - def evaluate(self, solution: FloatSolution): fx = [0.0 for _ in range(self.number_of_objectives)] for i in range(self.number_of_variables - 1): @@ -42,6 +39,9 @@ def evaluate(self, solution: FloatSolution): solution.objectives[0] = fx[0] solution.objectives[1] = fx[1] + def get_name(self): + return "Kursawe" + class Fonseca(FloatProblem): @@ -57,14 +57,14 @@ def __init__(self): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def get_name(self): - return "Fonseca" - def evaluate(self, solution: FloatSolution): n = self.number_of_variables solution.objectives[0] = 1 - exp(-sum([(x - 1.0 / n ** 0.5) ** 2 for x in solution.variables])) solution.objectives[1] = 1 - exp(-sum([(x + 1.0 / n ** 0.5) ** 2 for x in solution.variables])) + def get_name(self): + return "Fonseca" + class Schaffer(FloatProblem): @@ -80,15 +80,15 @@ def __init__(self): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def get_name(self): - return "Schaffer" - def evaluate(self, solution: FloatSolution): value = solution.variables[0] solution.objectives[0] = value ** 2 solution.objectives[1] = (value - 2) ** 2 + def get_name(self): + return "Schaffer" + class Viennet2(FloatProblem): @@ -104,9 +104,6 @@ def __init__(self): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def get_name(self): - return "Viennet2" - def evaluate(self, solution: FloatSolution): x0 = solution.variables[0] x1 = solution.variables[1] @@ -118,3 +115,6 @@ def evaluate(self, solution: FloatSolution): solution.objectives[0] = f1 solution.objectives[1] = f2 solution.objectives[2] = f3 + + def get_name(self): + return "Viennet2" diff --git a/jmetal/problem/multiobjective/zdt.py b/jmetal/problem/multiobjective/zdt.py index 87f59f3d..e591678f 100644 --- a/jmetal/problem/multiobjective/zdt.py +++ b/jmetal/problem/multiobjective/zdt.py @@ -4,7 +4,7 @@ from jmetal.core.solution import FloatSolution """ -.. module:: `zdt` +.. module:: ZDT :platform: Unix, Windows :synopsis: ZDT problem family of multi-objective problems. @@ -20,9 +20,7 @@ class ZDT1(FloatProblem): """ def __init__(self, number_of_variables: int = 30): - """Constructor - - :param number_of_variables: number of decision variables of the problem + """ :param number_of_variables: Number of decision variables of the problem. """ super().__init__() self.number_of_variables = number_of_variables diff --git a/jmetal/problem/singleobjective/test/test_unconstrained.py b/jmetal/problem/singleobjective/test/test_unconstrained.py index a3672045..2447b668 100644 --- a/jmetal/problem/singleobjective/test/test_unconstrained.py +++ b/jmetal/problem/singleobjective/test/test_unconstrained.py @@ -2,14 +2,9 @@ from jmetal.problem.singleobjective.unconstrained import OneMax, Sphere -__author__ = "Antonio J. Nebro" - class OneMaxTestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self) -> None: problem = OneMax() self.assertIsNotNone(problem) @@ -33,13 +28,6 @@ def test_should_create_solution_a_valid_binary_solution(self) -> None: solution = problem.create_solution() self.assertEqual(256, len(solution.variables[0])) - # def test_should_evaluate_work_properly_if_the_bitset_only_contains_ones(self) -> None: - # problem = OneMax(512) - # solution = problem.create_solution() - # solution.variables[0] = [True for i in range(problem.number_of_bits)] - # problem.evaluate(solution) - # self.assertEqual(512.0, solution.objectives[0]) - def test_should_evaluate_work_properly_if_the_bitset_only_contains_zeroes(self) -> None: problem = OneMax(512) solution = problem.create_solution() @@ -54,9 +42,6 @@ def test_should_get_name_return_the_right_name(self): class SphereTestCases(unittest.TestCase): - def setUp(self): - pass - def test_should_constructor_create_a_non_null_object(self): problem = Sphere(3) self.assertIsNotNone(problem) @@ -67,8 +52,8 @@ def test_should_constructor_create_a_valid_problem_with_default_settings(self): self.assertEqual(1, problem.number_of_objectives) self.assertEqual(0, problem.number_of_constraints) - self.assertEqual([-5.12 for i in range(10)], problem.lower_bound) - self.assertEqual([5.12 for i in range(10)], problem.upper_bound) + self.assertEqual([-5.12 for _ in range(10)], problem.lower_bound) + self.assertEqual([5.12 for _ in range(10)], problem.upper_bound) def test_should_constructor_create_a_valid_problem_with_5_variables(self): problem = Sphere(5) diff --git a/jmetal/problem/singleobjective/unconstrained.py b/jmetal/problem/singleobjective/unconstrained.py index 61c9523e..14769284 100644 --- a/jmetal/problem/singleobjective/unconstrained.py +++ b/jmetal/problem/singleobjective/unconstrained.py @@ -3,13 +3,20 @@ from jmetal.core.problem import BinaryProblem, FloatProblem from jmetal.core.solution import BinarySolution, FloatSolution -__author__ = "Antonio J. Nebro" +""" +.. module:: unconstrained + :platform: Unix, Windows + :synopsis: Unconstrained test problems for single-objective optimization + +.. moduleauthor:: Antonio J. Nebro +""" class OneMax(BinaryProblem): - """ Class representing problem Kursawe """ + """ Class representing problem Kursawe. """ def __init__(self, number_of_bits: int = 256): + super().__init__() self.number_of_bits = number_of_bits self.number_of_objectives = 1 self.number_of_variables = 1 @@ -26,7 +33,7 @@ def evaluate(self, solution: BinarySolution) -> None: def create_solution(self) -> BinarySolution: new_solution = BinarySolution(number_of_variables=1, number_of_objectives=1) new_solution.variables[0] = \ - [True if random.randint(0, 1) == 0 else False for i in range(self.number_of_bits)] + [True if random.randint(0, 1) == 0 else False for _ in range(self.number_of_bits)] return new_solution def get_name(self) -> str: @@ -35,12 +42,13 @@ def get_name(self) -> str: class Sphere(FloatProblem): def __init__(self, number_of_variables: int = 10): + super().__init__() self.number_of_objectives = 1 self.number_of_variables = number_of_variables self.number_of_constraints = 0 - self.lower_bound = [-5.12 for i in range(number_of_variables)] - self.upper_bound = [5.12 for i in range(number_of_variables)] + self.lower_bound = [-5.12 for _ in range(number_of_variables)] + self.upper_bound = [5.12 for _ in range(number_of_variables)] FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound diff --git a/jmetal/runner/__init__.py b/jmetal/runner/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/jmetal/runner/multiobjective/__init__.py b/jmetal/runner/multiobjective/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/jmetal/runner/multiobjective/nsgaii_standard_settings.py b/jmetal/runner/multiobjective/nsgaii_standard_settings.py deleted file mode 100644 index ada9d0b7..00000000 --- a/jmetal/runner/multiobjective/nsgaii_standard_settings.py +++ /dev/null @@ -1,44 +0,0 @@ -import logging - -from jmetal.algorithm.multiobjective.nsgaii import NSGAII -from jmetal.component.observer import ProgressBarObserver -from jmetal.operator.crossover import SBX -from jmetal.operator.mutation import Polynomial -from jmetal.operator.selection import BinaryTournament2Selection -from jmetal.problem.multiobjective.dtlz import DTLZ1 -from jmetal.util.comparator import SolutionAttributeComparator - - -def main() -> None: - problem = DTLZ1() - - algorithm = NSGAII( - problem=problem, - population_size=100, - max_evaluations=25000, - mutation=Polynomial(1.0 / problem.number_of_variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournament2Selection([SolutionAttributeComparator('dominance_ranking'), - SolutionAttributeComparator('crowding_distance', lowest_is_best=False)])) - - progress_bar = ProgressBarObserver(step=100, max=25000) - algorithm.observable.register(progress_bar) - - algorithm.run() - - print("Algorithm (continuous problem): " + algorithm.get_name()) - print("Problem: " + problem.get_name()) - print("Computing time: " + str(algorithm.total_computing_time)) - - -if __name__ == '__main__': - logging.basicConfig( - level=logging.INFO, - format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s", - handlers=[ - logging.FileHandler('jmetalpy.log'), - logging.StreamHandler() - ] - ) - - main() \ No newline at end of file diff --git a/jmetal/runner/singleobjective/__init__.py b/jmetal/runner/singleobjective/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/jmetal/runner/singleobjective/evolution_strategy/__init__.py b/jmetal/runner/singleobjective/evolution_strategy/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/jmetal/runner/singleobjective/genetic_algorithm/__init__.py b/jmetal/runner/singleobjective/genetic_algorithm/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_with_observer.py b/jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_with_observer.py deleted file mode 100644 index 53fd2243..00000000 --- a/jmetal/runner/singleobjective/genetic_algorithm/generational_genetic_algorithm_with_observer.py +++ /dev/null @@ -1,41 +0,0 @@ -import logging - -from jmetal.algorithm.singleobjective.evolutionaryalgorithm import GenerationalGeneticAlgorithm -from jmetal.component.observer import BasicAlgorithmObserver -from jmetal.core.solution import FloatSolution -from jmetal.operator.crossover import SBX -from jmetal.operator.mutation import Polynomial -from jmetal.operator.selection import BinaryTournamentSelection -from jmetal.problem.singleobjective.unconstrained import Sphere - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - - -def main() -> None: - variables = 10 - problem = Sphere(variables) - algorithm = GenerationalGeneticAlgorithm[FloatSolution, FloatSolution]( - problem, - population_size=100, - max_evaluations=25000, - mutation=Polynomial(1.0 / variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection()) - - observer = BasicAlgorithmObserver(2000) - - algorithm.observable.register(observer=observer) - - algorithm.start() - algorithm.join() - - result = algorithm.get_result() - logger.info("Algorithm: " + algorithm.get_name()) - logger.info("Problem: " + problem.get_name()) - logger.info("Solution: " + str(result.variables)) - logger.info("Fitness: " + str(result.objectives[0])) - - -if __name__ == '__main__': - main() diff --git a/jmetal/util/front_file.py b/jmetal/util/front_file.py index d1f8a2cd..21e62d94 100644 --- a/jmetal/util/front_file.py +++ b/jmetal/util/front_file.py @@ -3,7 +3,7 @@ from jmetal.core.solution import FloatSolution """ -.. module:: front_file +.. module:: Front file :platform: Unix, Windows :synopsis: Utils to read reference frontiers from files. diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index 1871b532..d5eb5a87 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -20,9 +20,9 @@ S = TypeVar('S') """ -.. module:: graphics +.. module:: Visualization :platform: Unix, Windows - :synopsis: Class for plotting solutions. + :synopsis: Classes for plotting solutions. .. moduleauthor:: Antonio Benítez-Hidalgo """ diff --git a/jmetal/util/laboratory.py b/jmetal/util/laboratory.py new file mode 100644 index 00000000..73a4c66e --- /dev/null +++ b/jmetal/util/laboratory.py @@ -0,0 +1,43 @@ +from typing import List, Type + +from jmetal.algorithm.multiobjective.nsgaii import NSGAII +from jmetal.algorithm.multiobjective.smpso import SMPSO +from jmetal.core.algorithm import Algorithm +from jmetal.core.problem import Problem +from jmetal.problem.multiobjective.zdt import ZDT1 +from jmetal.util.quality_indicator import HyperVolume + +""" +.. module:: laboratory + :platform: Unix, Windows + :synopsis: Run experiments. + +.. moduleauthor:: Antonio Benítez-Hidalgo +""" + + +def experiment(algorithm_list: List[Type[Algorithm]], problem_list: List[Type[Problem]], metric_list: list): + result = dict() + + for problem in problem_list: + if isinstance(problem, type): + problem = problem() + + for algorithm in algorithm_list: + if isinstance(algorithm, type): + algorithm = algorithm(problem=problem) + + algorithm.run() + solution_list = algorithm.get_result() + + result[algorithm.get_name()][problem.get_name()] = [metric.compute(solution_list) for metric in metric_list] + + print(result) + + +if __name__ == '__main__': + algorithm = [NSGAII, SMPSO] + problem = [ZDT1] + metric = [HyperVolume(referencePoint=[1, 1])] + + experiment(algorithm, problem, metric) diff --git a/jmetal/util/solution_list_output.py b/jmetal/util/solution_list_output.py index 141c8f6e..089cd7c7 100644 --- a/jmetal/util/solution_list_output.py +++ b/jmetal/util/solution_list_output.py @@ -1,9 +1,18 @@ import logging from typing import TypeVar, Generic -S = TypeVar('S') logger = logging.getLogger(__name__) +S = TypeVar('S') + +""" +.. module:: Solution list + :platform: Unix, Windows + :synopsis: Utils to print solutions. + +.. moduleauthor:: Antonio J. Nebro +""" + class SolutionList(Generic[S]): From 6bd1f5e9500b200f661db2f720a1ec472212eb3b Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 5 Jul 2018 13:47:20 +0200 Subject: [PATCH 73/90] WIP laboratory --- jmetal/util/laboratory.py | 43 --------------------------------------- 1 file changed, 43 deletions(-) diff --git a/jmetal/util/laboratory.py b/jmetal/util/laboratory.py index 73a4c66e..e69de29b 100644 --- a/jmetal/util/laboratory.py +++ b/jmetal/util/laboratory.py @@ -1,43 +0,0 @@ -from typing import List, Type - -from jmetal.algorithm.multiobjective.nsgaii import NSGAII -from jmetal.algorithm.multiobjective.smpso import SMPSO -from jmetal.core.algorithm import Algorithm -from jmetal.core.problem import Problem -from jmetal.problem.multiobjective.zdt import ZDT1 -from jmetal.util.quality_indicator import HyperVolume - -""" -.. module:: laboratory - :platform: Unix, Windows - :synopsis: Run experiments. - -.. moduleauthor:: Antonio Benítez-Hidalgo -""" - - -def experiment(algorithm_list: List[Type[Algorithm]], problem_list: List[Type[Problem]], metric_list: list): - result = dict() - - for problem in problem_list: - if isinstance(problem, type): - problem = problem() - - for algorithm in algorithm_list: - if isinstance(algorithm, type): - algorithm = algorithm(problem=problem) - - algorithm.run() - solution_list = algorithm.get_result() - - result[algorithm.get_name()][problem.get_name()] = [metric.compute(solution_list) for metric in metric_list] - - print(result) - - -if __name__ == '__main__': - algorithm = [NSGAII, SMPSO] - problem = [ZDT1] - metric = [HyperVolume(referencePoint=[1, 1])] - - experiment(algorithm, problem, metric) From 6edc4863519c9e3412e5ca78e048ab35dc6f073e Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 5 Jul 2018 13:47:55 +0200 Subject: [PATCH 74/90] Docs updated --- docs/source/api/jmetal.component.rst | 16 ++++++++++++++ docs/source/api/jmetal.core.rst | 8 +++++++ docs/source/api/jmetal.util.rst | 32 ++++------------------------ docs/source/conf.py | 5 +++-- docs/source/contributing.rst | 2 ++ docs/source/index.rst | 9 ++++---- docs/source/runner/nsgaii.rst | 6 +++--- docs/source/runner/observer.rst | 23 +++----------------- requirements.txt | 2 +- setup.py | 8 +++---- 10 files changed, 49 insertions(+), 62 deletions(-) create mode 100644 docs/source/contributing.rst diff --git a/docs/source/api/jmetal.component.rst b/docs/source/api/jmetal.component.rst index ba9777ba..b7a8ef1d 100644 --- a/docs/source/api/jmetal.component.rst +++ b/docs/source/api/jmetal.component.rst @@ -25,6 +25,22 @@ Evaluator :undoc-members: :show-inheritance: +Comparator +----------------------------- + +.. automodule:: jmetal.component.comparator + :members: + :undoc-members: + :show-inheritance: + +Ranking +-------------------------- + +.. automodule:: jmetal.component.ranking + :members: + :undoc-members: + :show-inheritance: + Observer -------------------------------- diff --git a/docs/source/api/jmetal.core.rst b/docs/source/api/jmetal.core.rst index cee0a8ba..fae7742e 100644 --- a/docs/source/api/jmetal.core.rst +++ b/docs/source/api/jmetal.core.rst @@ -34,3 +34,11 @@ Solution :members: :undoc-members: :show-inheritance: + +Observable +----------------------------- + +.. automodule:: jmetal.core.observable + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/docs/source/api/jmetal.util.rst b/docs/source/api/jmetal.util.rst index 8d5f7c5c..e82c68aa 100644 --- a/docs/source/api/jmetal.util.rst +++ b/docs/source/api/jmetal.util.rst @@ -1,18 +1,18 @@ Utils =================== -Quality indicator +Front file ----------------------------- -.. automodule:: jmetal.util.quality_indicator +.. automodule:: jmetal.util.front_file :members: :undoc-members: :show-inheritance: -Comparator +Quality indicator ----------------------------- -.. automodule:: jmetal.util.comparator +.. automodule:: jmetal.util.quality_indicator :members: :undoc-members: :show-inheritance: @@ -25,22 +25,6 @@ Graphic :undoc-members: :show-inheritance: -Observable ------------------------------ - -.. automodule:: jmetal.util.observable - :members: - :undoc-members: - :show-inheritance: - -Ranking --------------------------- - -.. automodule:: jmetal.util.ranking - :members: - :undoc-members: - :show-inheritance: - Solution list output ----------------------------------------- @@ -48,11 +32,3 @@ Solution list output :members: :undoc-members: :show-inheritance: - -Time ------------------------ - -.. automodule:: jmetal.util.time - :members: - :undoc-members: - :show-inheritance: \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index 9509e34c..3802a156 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -19,7 +19,8 @@ # http://blog.rtwilson.com/how-to-make-your-sphinx-documentation-compile-with-readthedocs-when-youre-using-numpy-and-scipy/ import mock -MOCK_MODULES = ['numpy', 'dask', 'dask.distributed', 'mpl_toolkits', 'mpl_toolkits.mplot3d', 'matplotlib', 'matplotlib.pyplot', 'matplotlib.axes'] +MOCK_MODULES = ['numpy', 'dask', 'dask.distributed', 'bokeh', 'tqdm', + 'mpl_toolkits', 'mpl_toolkits.mplot3d', 'matplotlib', 'matplotlib.pyplot', 'matplotlib.axes'] for mod_name in MOCK_MODULES: sys.modules[mod_name] = mock.Mock() @@ -30,7 +31,7 @@ author = 'Antonio J. Nebro' # The short X.Y version -version = '1.0.0' +version = '0.5.0' # The full version, including alpha/beta/rc tags release = '' diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst new file mode 100644 index 00000000..b4d056c9 --- /dev/null +++ b/docs/source/contributing.rst @@ -0,0 +1,2 @@ +Contributing +================================================ diff --git a/docs/source/index.rst b/docs/source/index.rst index 13329c29..7e37adad 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -6,7 +6,7 @@ jMetalPy: Python version of the jMetal framework ================================================ -.. warning:: Documentation is in process!! Some information may be missing. +.. warning:: Documentation is WIP!! Some information may be missing. .. toctree:: :maxdepth: 1 @@ -31,6 +31,7 @@ Via Github: $ git clone https://github.com/jMetal/jMetalPy.git $ pip install -r requirements.txt + $ python setup.py install Basic Usage ----------- @@ -42,9 +43,9 @@ Basic Usage problem=problem, population_size=100, max_evaluations=25000, - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())) + mutation=Polynomial(probability=1.0/problem.number_of_variables, distribution_index=20), + crossover=SBX(probability=1.0, distribution_index=20), + selection=BinaryTournamentSelection(comparator=RankingAndCrowdingDistanceComparator())) algorithm.run() result = algorithm.get_result() diff --git a/docs/source/runner/nsgaii.rst b/docs/source/runner/nsgaii.rst index 1b11886a..594bd5a4 100644 --- a/docs/source/runner/nsgaii.rst +++ b/docs/source/runner/nsgaii.rst @@ -22,9 +22,9 @@ NSGA-II with standard settings problem=problem, population_size=100, max_evaluations=25000, - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator()) + mutation=Polynomial(probability=1.0/problem.number_of_variables, distribution_index=20), + crossover=SBX(probability=1.0, distribution_index=20), + selection=BinaryTournamentSelection(comparator=RankingAndCrowdingDistanceComparator()) ) algorithm.run() diff --git a/docs/source/runner/observer.rst b/docs/source/runner/observer.rst index 74b22490..dad0ea72 100644 --- a/docs/source/runner/observer.rst +++ b/docs/source/runner/observer.rst @@ -7,25 +7,8 @@ For example, a basic algorithm observer will print the number of evaluations, th .. code-block:: python - observer = BasicAlgorithmObserver(frequency=1.0) - algorithm.observable.register(observer=observer) + basic = BasicAlgorithmObserver(frequency=1.0) + algorithm.observable.register(observer=basic) -Write Front To File ------------------------------------- -This observer will save each generation of individuals in files: - -.. code-block:: python - - observer = WriteFrontToFileObserver(output_directory="FUN") - algorithm.observable.register(observer=observer) - -Visualization ------------------------------------- - -This observer will plot in real-time the Pareto frontier (with a reference front, if any) in 2D or 3D depending on the number of objectives. - -.. code-block:: python - - observer = VisualizerObserver(frequency=1.0) - algorithm.observable.register(observer=observer) \ No newline at end of file +A full list of all available observers can be found :doc:`here `. \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 23ed5e0e..517d7f6a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ -tqdm +tqdm==4.23.4 bokeh==0.12.16 pytest==3.1.2 PyHamcrest==1.9.0 diff --git a/setup.py b/setup.py index 649051f1..578494e3 100644 --- a/setup.py +++ b/setup.py @@ -2,12 +2,12 @@ setup( name='jmetalpy', - version='1.0.0', + version='0.5.0', description='JMetalPy. Python version of the jMetal framework', author='Antonio J. Nebro', - author_email='ajnebro@uma.es', - maintainer='Antonio Nebro', - maintainer_email='ajnebro@uma.es', + author_email='antonio@lcc.uma.es', + maintainer='Antonio J. Nebro', + maintainer_email='antonio@lcc.uma.es', license='MIT', url='https://github.com/jMetal/jMetalPy', classifiers=[ From ad77d23b129521d456fa40d740bc8f05ae210c68 Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 5 Jul 2018 13:48:15 +0200 Subject: [PATCH 75/90] Examples of running algorithms --- .../multiobjective/nsgaii_full_settings.py | 29 +++++++++-------- .../multiobjective/smpso_full_settings.py | 22 ++++++++++--- .../smpsorp_standard_settings.py | 6 ++-- .../elitist_evolution_strategy_binary.py | 15 +++++---- .../elitist_evolution_strategy_float.py | 15 +++++---- ..._evolution_strategy_running_as_a_thread.py | 15 +++++---- .../non_elitist_evolution_strategy_binary.py | 12 +++++-- .../non_elitist_evolution_strategy_float.py | 11 +++++-- ..._evolution_strategy_running_as_a_thread.py | 10 ++++-- .../generational_genetic_algorithm_binary.py | 29 +++++++++-------- .../generational_genetic_algorithm_float.py | 25 +++++++-------- ...l_genetic_algorithm_running_as_a_thread.py | 31 +++++++++---------- ...onal_genetic_algorithm_stopping_by_time.py | 28 ++++++++--------- 13 files changed, 141 insertions(+), 107 deletions(-) diff --git a/examples/multiobjective/nsgaii_full_settings.py b/examples/multiobjective/nsgaii_full_settings.py index fe068809..16f13a01 100644 --- a/examples/multiobjective/nsgaii_full_settings.py +++ b/examples/multiobjective/nsgaii_full_settings.py @@ -1,13 +1,10 @@ import logging -from jmetal.algorithm.multiobjective.nsgaii import NSGAII -from jmetal.component.observer import VisualizerObserver -from jmetal.core.solution import FloatSolution -from jmetal.operator.crossover import SBX -from jmetal.operator.mutation import Polynomial -from jmetal.operator.selection import BinaryTournament2Selection -from jmetal.problem.multiobjective.dtlz import DTLZ1 -from jmetal.component.comparator import SolutionAttributeComparator +from jmetal.algorithm import NSGAII +from jmetal.component.observer import VisualizerObserver, ProgressBarObserver +from jmetal.component.comparator import RankingAndCrowdingDistanceComparator +from jmetal.problem import DTLZ1 +from jmetal.operator import SBX, Polynomial, BinaryTournamentSelection from jmetal.util.graphic import ScatterMatplotlib from jmetal.util.solution_list_output import SolutionList @@ -19,23 +16,25 @@ def main() -> None: problem=problem, population_size=100, max_evaluations=25000, - mutation=Polynomial(1.0 / problem.number_of_variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournament2Selection([SolutionAttributeComparator('dominance_ranking'), - SolutionAttributeComparator('crowding_distance', lowest_is_best=False)])) + mutation=Polynomial(probability=1.0 / problem.number_of_variables, distribution_index=20), + crossover=SBX(probability=1.0, distribution_index=20), + selection=BinaryTournamentSelection(comparator=RankingAndCrowdingDistanceComparator()) + ) observer = VisualizerObserver(problem) + progress_bar = ProgressBarObserver(step=100, max=25000) algorithm.observable.register(observer=observer) + algorithm.observable.register(observer=progress_bar) algorithm.run() result = algorithm.get_result() - # Plot frontier + # Plot frontier to file pareto_front = ScatterMatplotlib(plot_title='NSGAII for DTLZ1', number_of_objectives=problem.number_of_objectives) - pareto_front.plot(result, reference=problem.get_reference_front(), output='output2') + pareto_front.plot(result, reference=problem.get_reference_front(), output='NSGAII-DTLZ1', show=False) # Save variables to file - SolutionList[FloatSolution].print_function_values_to_file(result, 'NSGAII.' + problem.get_name()) + SolutionList.print_function_values_to_file(result, 'NSGAII.' + problem.get_name()) print("Algorithm (continuous problem): " + algorithm.get_name()) print("Problem: " + problem.get_name()) diff --git a/examples/multiobjective/smpso_full_settings.py b/examples/multiobjective/smpso_full_settings.py index 5e2d6e0d..3d7a8c2a 100644 --- a/examples/multiobjective/smpso_full_settings.py +++ b/examples/multiobjective/smpso_full_settings.py @@ -1,10 +1,12 @@ import logging -from jmetal.component.observer import ProgressBarObserver -from jmetal.problem.multiobjective.zdt import ZDT1 -from jmetal.algorithm.multiobjective.smpso import SMPSO +from jmetal.algorithm import SMPSO +from jmetal.component.observer import ProgressBarObserver, VisualizerObserver from jmetal.component.archive import CrowdingDistanceArchive -from jmetal.operator.mutation import Polynomial +from jmetal.problem import ZDT1 +from jmetal.operator import Polynomial +from jmetal.util.graphic import ScatterMatplotlib +from jmetal.util.solution_list_output import SolutionList def main() -> None: @@ -18,10 +20,20 @@ def main() -> None: leaders=CrowdingDistanceArchive(100) ) + observer = VisualizerObserver(problem) progress_bar = ProgressBarObserver(step=100, max=25000) - algorithm.observable.register(progress_bar) + algorithm.observable.register(observer=observer) + algorithm.observable.register(observer=progress_bar) algorithm.run() + result = algorithm.get_result() + + # Plot frontier to file + pareto_front = ScatterMatplotlib(plot_title='SMPSO for ZDT1', number_of_objectives=problem.number_of_objectives) + pareto_front.plot(result, reference=problem.get_reference_front(), output='SMPSO-ZDT1', show=False) + + # Save variables to file + SolutionList.print_function_values_to_file(result, 'SMPSO.ZDT1') print("Algorithm (continuous problem): " + algorithm.get_name()) print("Problem: " + problem.get_name()) diff --git a/examples/multiobjective/smpsorp_standard_settings.py b/examples/multiobjective/smpsorp_standard_settings.py index 86a6d2a2..56d0afa4 100644 --- a/examples/multiobjective/smpsorp_standard_settings.py +++ b/examples/multiobjective/smpsorp_standard_settings.py @@ -1,10 +1,10 @@ import logging -from jmetal.algorithm.multiobjective.smpso import SMPSORP +from jmetal.algorithm import SMPSORP from jmetal.component.archive import CrowdingDistanceArchiveWithReferencePoint from jmetal.component.observer import ProgressBarObserver -from jmetal.operator.mutation import Polynomial -from jmetal.problem.multiobjective.zdt import ZDT1 +from jmetal.problem import ZDT1 +from jmetal.operator import Polynomial def main() -> None: diff --git a/examples/singleobjective/evolution_strategy/elitist_evolution_strategy_binary.py b/examples/singleobjective/evolution_strategy/elitist_evolution_strategy_binary.py index cb26d66e..2a35bc50 100644 --- a/examples/singleobjective/evolution_strategy/elitist_evolution_strategy_binary.py +++ b/examples/singleobjective/evolution_strategy/elitist_evolution_strategy_binary.py @@ -7,15 +7,18 @@ def main() -> None: bits = 512 problem = OneMax(bits) - algorithm = ElitistEvolutionStrategy[BinarySolution, BinarySolution]\ - (problem, - mu=1, - lambdA=10, - max_evaluations=25000, - mutation=BitFlip(1.0/bits)) + + algorithm = ElitistEvolutionStrategy[BinarySolution, BinarySolution]( + problem=problem, + mu=1, + lambd_a=10, + max_evaluations=25000, + mutation=BitFlip(probability=1.0/bits) + ) algorithm.run() result = algorithm.get_result() + print("Algorithm: " + algorithm.get_name()) print("Problem: " + problem.get_name()) print("Solution: " + str(result.variables[0])) diff --git a/examples/singleobjective/evolution_strategy/elitist_evolution_strategy_float.py b/examples/singleobjective/evolution_strategy/elitist_evolution_strategy_float.py index 4908e6a7..9399387e 100644 --- a/examples/singleobjective/evolution_strategy/elitist_evolution_strategy_float.py +++ b/examples/singleobjective/evolution_strategy/elitist_evolution_strategy_float.py @@ -7,15 +7,18 @@ def main() -> None: variables = 10 problem = Sphere(variables) - algorithm = ElitistEvolutionStrategy[FloatSolution, FloatSolution]\ - (problem, - mu=10, - lambdA=10, - max_evaluations=50000, - mutation=Polynomial(1.0/variables)) + + algorithm = ElitistEvolutionStrategy[FloatSolution, FloatSolution]( + problem=problem, + mu=10, + lambd_a=10, + max_evaluations=50000, + mutation=Polynomial(probability=1.0/variables) + ) algorithm.run() result = algorithm.get_result() + print("Algorithm: " + algorithm.get_name()) print("Problem: " + problem.get_name()) print("Solution: " + str(result.variables)) diff --git a/examples/singleobjective/evolution_strategy/elitist_evolution_strategy_running_as_a_thread.py b/examples/singleobjective/evolution_strategy/elitist_evolution_strategy_running_as_a_thread.py index e0032e1e..ef32c2db 100644 --- a/examples/singleobjective/evolution_strategy/elitist_evolution_strategy_running_as_a_thread.py +++ b/examples/singleobjective/evolution_strategy/elitist_evolution_strategy_running_as_a_thread.py @@ -7,12 +7,14 @@ def main() -> None: variables = 10 problem = Sphere(variables) - algorithm = ElitistEvolutionStrategy[FloatSolution, FloatSolution]\ - (problem, - mu=10, - lambdA=10, - max_evaluations=50000, - mutation=Polynomial(1.0/variables)) + + algorithm = ElitistEvolutionStrategy[FloatSolution, FloatSolution]( + problem=problem, + mu=10, + lambd_a=10, + max_evaluations=50000, + mutation=Polynomial(probability=1.0/variables) + ) algorithm.start() print("Algorithm (running as a thread): " + algorithm.get_name()) @@ -20,6 +22,7 @@ def main() -> None: algorithm.join() result = algorithm.get_result() + print("Solution: " + str(result.variables)) print("Fitness: " + str(result.objectives[0])) print("Computing time: " + str(algorithm.total_computing_time)) diff --git a/examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_binary.py b/examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_binary.py index 6a9fbc15..29592da2 100644 --- a/examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_binary.py +++ b/examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_binary.py @@ -7,16 +7,24 @@ def main() -> None: bits = 512 problem = OneMax(bits) - algorithm = NonElitistEvolutionStrategy[BinarySolution, BinarySolution]\ - (problem, mu=1, lambdA=10, max_evaluations= 25000, mutation=BitFlip(1.0/bits)) + + algorithm = NonElitistEvolutionStrategy[BinarySolution, BinarySolution]( + problem=problem, + mu=1, + lambd_a=10, + max_evaluations= 25000, + mutation=BitFlip(probability=1.0/bits) + ) algorithm.run() result = algorithm.get_result() + print("Algorithm: " + algorithm.get_name()) print("Problem: " + problem.get_name()) print("Solution: " + str(result.variables[0])) print("Fitness: " + str(result.objectives[0])) print("Computing time: " + str(algorithm.total_computing_time)) + if __name__ == '__main__': main() diff --git a/examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_float.py b/examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_float.py index 1175954a..0ff5bb2c 100644 --- a/examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_float.py +++ b/examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_float.py @@ -7,11 +7,18 @@ def main() -> None: variables = 10 problem = Sphere(variables) - algorithm = NonElitistEvolutionStrategy[FloatSolution, FloatSolution]\ - (problem, mu=10, lambdA=10, max_evaluations= 50000, mutation=Polynomial(1.0/variables)) + + algorithm = NonElitistEvolutionStrategy[FloatSolution, FloatSolution]( + problem=problem, + mu=10, + lambd_a=10, + max_evaluations=50000, + mutation=Polynomial(probability=1.0/variables) + ) algorithm.run() result = algorithm.get_result() + print("Algorithm: " + algorithm.get_name()) print("Problem: " + problem.get_name()) print("Solution: " + str(result.variables)) diff --git a/examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_running_as_a_thread.py b/examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_running_as_a_thread.py index a23215ef..590f0c92 100644 --- a/examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_running_as_a_thread.py +++ b/examples/singleobjective/evolution_strategy/non_elitist_evolution_strategy_running_as_a_thread.py @@ -7,8 +7,14 @@ def main() -> None: variables = 10 problem = Sphere(variables) - algorithm = NonElitistEvolutionStrategy[FloatSolution, FloatSolution]\ - (problem, mu=10, lambdA=10, max_evaluations= 50000, mutation=Polynomial(1.0/variables)) + + algorithm = NonElitistEvolutionStrategy[FloatSolution, FloatSolution]( + problem=problem, + mu=10, + lambd_a=10, + max_evaluations=50000, + mutation=Polynomial(probability=1.0/variables) + ) algorithm.start() print("Algorithm (running as a thread): " + algorithm.get_name()) diff --git a/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_binary.py b/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_binary.py index ff7e4f5b..afd06659 100644 --- a/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_binary.py +++ b/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_binary.py @@ -1,5 +1,3 @@ -import logging - from jmetal.algorithm.singleobjective.evolutionaryalgorithm import GenerationalGeneticAlgorithm from jmetal.core.solution import BinarySolution from jmetal.operator.crossover import SP @@ -7,28 +5,29 @@ from jmetal.operator.selection import BinaryTournamentSelection from jmetal.problem.singleobjective.unconstrained import OneMax -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - def main() -> None: bits = 256 problem = OneMax(bits) + algorithm = GenerationalGeneticAlgorithm[BinarySolution, BinarySolution]( - problem, - population_size = 100, - max_evaluations = 150000, - mutation = BitFlip(1.0/bits), - crossover = SP(0.9), - selection = BinaryTournamentSelection()) + problem=problem, + population_size=100, + max_evaluations=150000, + mutation=BitFlip(1.0/bits), + crossover=SP(0.9), + selection=BinaryTournamentSelection() + ) algorithm.run() result = algorithm.get_result() - logger.info("Algorithm (binary problem): " + algorithm.get_name()) - logger.info("Problem: " + problem.get_name()) - logger.info("Solution: " + str(result.variables[0])) - logger.info("Fitness: " + str(result.objectives[0])) + print("Algorithm: " + algorithm.get_name()) + print("Problem: " + problem.get_name()) + print("Solution: " + str(result.variables)) + print("Fitness: " + str(result.objectives[0])) + print("Computing time: " + str(algorithm.total_computing_time)) + if __name__ == '__main__': main() diff --git a/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_float.py b/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_float.py index 97d260b8..cb212dfc 100644 --- a/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_float.py +++ b/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_float.py @@ -1,5 +1,3 @@ -import logging - from jmetal.algorithm.singleobjective.evolutionaryalgorithm import GenerationalGeneticAlgorithm from jmetal.core.solution import FloatSolution from jmetal.operator.crossover import SBX @@ -7,28 +5,29 @@ from jmetal.operator.selection import BinaryTournamentSelection from jmetal.problem.singleobjective.unconstrained import Sphere -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - def main() -> None: variables = 10 problem = Sphere(variables) + algorithm = GenerationalGeneticAlgorithm[FloatSolution, FloatSolution]( - problem, + problem=problem, population_size=100, max_evaluations=25000, - mutation=Polynomial(1.0/variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection()) + mutation=Polynomial(probability=1.0/variables, distribution_index=20), + crossover=SBX(probability=1.0, distribution_index=20), + selection=BinaryTournamentSelection() + ) algorithm.run() result = algorithm.get_result() - logger.info("Algorithm (continuous problem): " + algorithm.get_name()) - logger.info("Problem: " + problem.get_name()) - logger.info("Solution: " + str(result.variables)) - logger.info("Fitness: " + str(result.objectives[0])) + print("Algorithm: " + algorithm.get_name()) + print("Problem: " + problem.get_name()) + print("Solution: " + str(result.variables)) + print("Fitness: " + str(result.objectives[0])) + print("Computing time: " + str(algorithm.total_computing_time)) + if __name__ == '__main__': main() diff --git a/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_running_as_a_thread.py b/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_running_as_a_thread.py index fa751c12..11db7404 100644 --- a/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_running_as_a_thread.py +++ b/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_running_as_a_thread.py @@ -1,5 +1,3 @@ -import logging - from jmetal.algorithm.singleobjective.evolutionaryalgorithm import GenerationalGeneticAlgorithm from jmetal.core.solution import FloatSolution from jmetal.operator.crossover import SBX @@ -7,31 +5,30 @@ from jmetal.operator.selection import BinaryTournamentSelection from jmetal.problem.singleobjective.unconstrained import Sphere -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - def main() -> None: variables = 10 problem = Sphere(variables) + algorithm = GenerationalGeneticAlgorithm[FloatSolution, FloatSolution]( - problem, - population_size = 100, - max_evaluations = 25000, - mutation = Polynomial(1.0/variables, distribution_index=20), - crossover = SBX(1.0, distribution_index=20), - selection = BinaryTournamentSelection()) + problem=problem, + population_size=100, + max_evaluations=25000, + mutation=Polynomial(probability=1.0/variables, distribution_index=20), + crossover=SBX(probability=1.0, distribution_index=20), + selection=BinaryTournamentSelection() + ) algorithm.start() - logger.info("Algorithm (running as a thread): " + algorithm.get_name()) - logger.info("Problem: " + problem.get_name()) - + print("Algorithm (running as a thread): " + algorithm.get_name()) + print("Problem: " + problem.get_name()) algorithm.join() + result = algorithm.get_result() - logger.info("Solution: " + str(result.variables)) - logger.info("Fitness: " + str(result.objectives[0])) - logger.info("Computing time: " + str(algorithm.total_computing_time)) + print("Solution: " + str(result.variables)) + print("Fitness: " + str(result.objectives[0])) + print("Computing time: " + str(algorithm.total_computing_time)) if __name__ == '__main__': diff --git a/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_stopping_by_time.py b/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_stopping_by_time.py index 73fa150a..0b9ec4e0 100644 --- a/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_stopping_by_time.py +++ b/examples/singleobjective/genetic_algorithm/generational_genetic_algorithm_stopping_by_time.py @@ -1,5 +1,3 @@ -import logging - from jmetal.algorithm.singleobjective.evolutionaryalgorithm import GenerationalGeneticAlgorithm from jmetal.core.solution import FloatSolution from jmetal.operator.crossover import SBX @@ -7,9 +5,6 @@ from jmetal.operator.selection import BinaryTournamentSelection from jmetal.problem.singleobjective.unconstrained import Sphere -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - def main() -> None: class GGA2(GenerationalGeneticAlgorithm[FloatSolution, FloatSolution]): @@ -18,27 +13,30 @@ def is_stopping_condition_reached(self): reached = [False, True][self.get_current_computing_time() > 4] if reached: - logger.info("Stopping condition reached!") + print("Stopping condition reached!") return reached variables = 10 problem = Sphere(variables) + algorithm = GGA2( - problem, - population_size = 100, + problem=problem, + population_size=100, max_evaluations=0, - mutation = Polynomial(1.0/variables, distribution_index=20), - crossover = SBX(1.0, distribution_index=20), - selection = BinaryTournamentSelection()) + mutation=Polynomial(1.0/variables, distribution_index=20), + crossover=SBX(1.0, distribution_index=20), + selection=BinaryTournamentSelection() + ) algorithm.run() result = algorithm.get_result() - logger.info("Algorithm (stop for timeout): " + algorithm.get_name()) - logger.info("Problem: " + problem.get_name()) - logger.info("Solution: " + str(result.variables)) - logger.info("Fitness: " + str(result.objectives[0])) + print("Algorithm (stop for timeout): " + algorithm.get_name()) + print("Problem: " + problem.get_name()) + print("Solution: " + str(result.variables)) + print("Fitness: " + str(result.objectives[0])) + print("Computing time: " + str(algorithm.total_computing_time)) if __name__ == '__main__': From afcf5016b0ce0d74be2bad14b75b4cecc4e7353a Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 5 Jul 2018 14:01:39 +0200 Subject: [PATCH 76/90] Added docs --- docs/source/conf.py | 3 ++- docs/source/runner/observer.rst | 2 +- jmetal/algorithm/singleobjective/evolutionaryalgorithm.py | 2 +- jmetal/component/observer.py | 8 ++++++++ jmetal/core/algorithm.py | 3 ++- jmetal/operator/selection.py | 2 +- jmetal/util/solution_list_output.py | 2 +- 7 files changed, 16 insertions(+), 6 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 3802a156..40cf677f 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -19,7 +19,8 @@ # http://blog.rtwilson.com/how-to-make-your-sphinx-documentation-compile-with-readthedocs-when-youre-using-numpy-and-scipy/ import mock -MOCK_MODULES = ['numpy', 'dask', 'dask.distributed', 'bokeh', 'tqdm', +MOCK_MODULES = ['numpy', 'dask', 'dask.distributed', 'tqdm', 'bokeh', 'bokeh.embed', 'bokeh.resources', 'bokeh.client', + 'bokeh.io', 'bokeh.layouts','bokeh.models','bokeh.plotting', 'mpl_toolkits', 'mpl_toolkits.mplot3d', 'matplotlib', 'matplotlib.pyplot', 'matplotlib.axes'] for mod_name in MOCK_MODULES: sys.modules[mod_name] = mock.Mock() diff --git a/docs/source/runner/observer.rst b/docs/source/runner/observer.rst index dad0ea72..fec74f19 100644 --- a/docs/source/runner/observer.rst +++ b/docs/source/runner/observer.rst @@ -11,4 +11,4 @@ For example, a basic algorithm observer will print the number of evaluations, th algorithm.observable.register(observer=basic) -A full list of all available observers can be found :doc:`here `. \ No newline at end of file +A full list of all available observer can be found at :py:mod:`observer`. \ No newline at end of file diff --git a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py index 58b5d94d..3a8be66e 100644 --- a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py +++ b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py @@ -10,7 +10,7 @@ R = TypeVar('R') """ -.. module:: Evolutionary Algorithm (EA) +.. module:: evolutionary_algorithm :platform: Unix, Windows :synopsis: Implementation of Evolutionary Algorithms. diff --git a/jmetal/component/observer.py b/jmetal/component/observer.py index 51fdc6f1..81b96a70 100644 --- a/jmetal/component/observer.py +++ b/jmetal/component/observer.py @@ -10,6 +10,14 @@ logger = logging.getLogger(__name__) +""" +.. module:: observer + :platform: Unix, Windows + :synopsis: Implementation of algorithm's observers. + +.. moduleauthor:: Antonio J. Nebro +""" + class ProgressBarObserver(Observer): diff --git a/jmetal/core/algorithm.py b/jmetal/core/algorithm.py index f744558c..f4db5aa0 100644 --- a/jmetal/core/algorithm.py +++ b/jmetal/core/algorithm.py @@ -76,7 +76,8 @@ def update_progress(self): def run(self): """* Step One: Generate the initial population of individuals randomly. (First generation) * Step Two: Evaluate the fitness of each individual in that population (time limit, sufficient fitness achieved, etc.) - * Step Three: Repeat the following regenerational steps until termination: + * Step Three: Repeat the following regenerational steps until termination + 1. Select the best-fit individuals for reproduction. (Parents) 2. Breed new individuals through crossover and mutation operations to give birth to offspring. 3. Evaluate the individual fitness of new individuals. diff --git a/jmetal/operator/selection.py b/jmetal/operator/selection.py index 842e6b81..cc9b9560 100644 --- a/jmetal/operator/selection.py +++ b/jmetal/operator/selection.py @@ -9,7 +9,7 @@ S = TypeVar('S') """ -.. module:: Selection operators +.. module:: selection :platform: Unix, Windows :synopsis: Module implementing selection operators. diff --git a/jmetal/util/solution_list_output.py b/jmetal/util/solution_list_output.py index 089cd7c7..e2051056 100644 --- a/jmetal/util/solution_list_output.py +++ b/jmetal/util/solution_list_output.py @@ -6,7 +6,7 @@ S = TypeVar('S') """ -.. module:: Solution list +.. module:: solution_list :platform: Unix, Windows :synopsis: Utils to print solutions. From cc28a37c07f27e86d7176d3a0e8426251a90b518 Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 5 Jul 2018 14:23:54 +0200 Subject: [PATCH 77/90] Added docs --- docs/source/about.rst | 6 ++-- docs/source/api/jmetal.rst | 2 +- jmetal/algorithm/multiobjective/nsgaii.py | 34 ++++++++++++++--------- jmetal/core/algorithm.py | 2 +- jmetal/operator/crossover.py | 2 +- jmetal/operator/mutation.py | 2 +- 6 files changed, 28 insertions(+), 20 deletions(-) diff --git a/docs/source/about.rst b/docs/source/about.rst index 50c6671a..c5482847 100644 --- a/docs/source/about.rst +++ b/docs/source/about.rst @@ -1,10 +1,10 @@ About ============== -jMetalPy is being developed by `Antonio J. Nebro `_, associate professor at the University of Málaga, and `Antonio Benítez-Hidalgo `_. +jMetalPy is being developed by `Antonio J. Nebro `_, associate professor at the University of Málaga, and `Antonio Benítez-Hidalgo `_. References -------------------------------- -1. J.J. Durillo, A.J. Nebro jMetal: a Java Framework for Multi-Objective Optimization. Advances in Engineering Software 42 (2011) 760-771. -2. A.J. Nebro, J.J. Durillo, M. Vergne Redesigning the jMetal Multi-Objective Optimization Framework. GECCO (Companion) 2015, pp: 1093-1100. July 2015. \ No newline at end of file +1. J.J. Durillo, A.J. Nebro jMetal: a Java Framework for Multi-Objective Optimization. Advances in Engineering Software 42 (2011) 760-771. +2. A.J. Nebro, J.J. Durillo, M. Vergne Redesigning the jMetal Multi-Objective Optimization Framework. GECCO (Companion) 2015, pp: 1093-1100. July 2015. \ No newline at end of file diff --git a/docs/source/api/jmetal.rst b/docs/source/api/jmetal.rst index 886d0001..3693cd8e 100644 --- a/docs/source/api/jmetal.rst +++ b/docs/source/api/jmetal.rst @@ -1,5 +1,5 @@ User documentation -============== +===================================== .. toctree:: diff --git a/jmetal/algorithm/multiobjective/nsgaii.py b/jmetal/algorithm/multiobjective/nsgaii.py index 7235e6de..542c2015 100644 --- a/jmetal/algorithm/multiobjective/nsgaii.py +++ b/jmetal/algorithm/multiobjective/nsgaii.py @@ -12,7 +12,7 @@ """ .. module:: NSGA-II :platform: Unix, Windows - :synopsis: Implementation of NSGA-II. + :synopsis: NSGA-II (Non-dominance Sorting Genetic Algorithm II) implementation. .. moduleauthor:: Antonio J. Nebro """ @@ -28,17 +28,23 @@ def __init__(self, crossover: Crossover[S, S], selection: Selection[List[S], S], evaluator: Evaluator[S] = SequentialEvaluator[S]()): - """ NSGA-II is a genetic algorithm (GA), i.e. it belongs to the evolutionary algorithms (EAs) + """ NSGA-II implementation as described in + + * K. Deb, A. Pratap, S. Agarwal and T. Meyarivan, "A fast and elitist + multiobjective genetic algorithm: NSGA-II," in IEEE Transactions on Evolutionary Computation, + vol. 6, no. 2, pp. 182-197, Apr 2002. doi: 10.1109/4235.996017 + + NSGA-II is a genetic algorithm (GA), i.e. it belongs to the evolutionary algorithms (EAs) family. The implementation of NSGA-II provided in jMetalPy follows the evolutionary - algorithm template described in the algorithm templates section (:mod:`algorithm`) of the documentation. + algorithm template described in the algorithm module (:mod:`algorithm`). :param problem: The problem to solve. - :param population_size: - :param max_evaluations: - :param mutation: - :param crossover: - :param selection: - :param evaluator: An evaluator object to evaluate the solutions in the population. + :param population_size: Size of the population. + :param max_evaluations: Maximum number of evaluations/iterations. + :param mutation: Mutation operator (see :mod:`mutation`). + :param crossover: Crossover operator (see :mod:`crosover`). + :param selection: Selection operator (see :mod:`selection`). + :param evaluator: An evaluator object to evaluate the individuals of the population. """ super(NSGAII, self).__init__( problem, @@ -53,17 +59,19 @@ def replacement(self, population: List[S], offspring_population: List[S]) -> Lis """ This method joins the current and offspring populations to produce the population of the next generation by applying the ranking and crowding distance selection. - :param population: - :param offspring_population: - :return: New population. + :param population: Parent population. + :param offspring_population: Offspring population. + :return: New population after ranking and crowding distance selection is applied. """ join_population = population + offspring_population return RankingAndCrowdingDistanceSelection(self.population_size).execute(join_population) def get_result(self) -> R: - """:return: Population. + """ :return: Final population. """ return self.population def get_name(self) -> str: + """ :return: Name of the algorithm. + """ return 'NSGA-II' diff --git a/jmetal/core/algorithm.py b/jmetal/core/algorithm.py index f4db5aa0..3520a133 100644 --- a/jmetal/core/algorithm.py +++ b/jmetal/core/algorithm.py @@ -12,7 +12,7 @@ R = TypeVar('R') """ -.. module:: Algorithm +.. module:: algorithm :platform: Unix, Windows :synopsis: Templates for algorithms. diff --git a/jmetal/operator/crossover.py b/jmetal/operator/crossover.py index 0ef52c26..796617bc 100644 --- a/jmetal/operator/crossover.py +++ b/jmetal/operator/crossover.py @@ -6,7 +6,7 @@ from jmetal.core.solution import Solution, FloatSolution, BinarySolution """ -.. module:: Crossover operators +.. module:: crosover :platform: Unix, Windows :synopsis: Module implementing crossover operators. diff --git a/jmetal/operator/mutation.py b/jmetal/operator/mutation.py index 06897cc5..cec2c8c9 100644 --- a/jmetal/operator/mutation.py +++ b/jmetal/operator/mutation.py @@ -4,7 +4,7 @@ from jmetal.core.solution import BinarySolution, Solution, FloatSolution, IntegerSolution """ -.. module:: Mutation operators +.. module:: mutation :platform: Unix, Windows :synopsis: Module implementing mutation operators. From 3e33426a8ba3c43889f5011880f7533739a4f014 Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 5 Jul 2018 14:30:00 +0200 Subject: [PATCH 78/90] Fix docs --- jmetal/algorithm/multiobjective/nsgaii.py | 12 ++++++------ jmetal/util/quality_indicator.py | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/jmetal/algorithm/multiobjective/nsgaii.py b/jmetal/algorithm/multiobjective/nsgaii.py index 542c2015..27252033 100644 --- a/jmetal/algorithm/multiobjective/nsgaii.py +++ b/jmetal/algorithm/multiobjective/nsgaii.py @@ -31,19 +31,19 @@ def __init__(self, """ NSGA-II implementation as described in * K. Deb, A. Pratap, S. Agarwal and T. Meyarivan, "A fast and elitist - multiobjective genetic algorithm: NSGA-II," in IEEE Transactions on Evolutionary Computation, - vol. 6, no. 2, pp. 182-197, Apr 2002. doi: 10.1109/4235.996017 + multiobjective genetic algorithm: NSGA-II," in IEEE Transactions on Evolutionary Computation, + vol. 6, no. 2, pp. 182-197, Apr 2002. doi: 10.1109/4235.996017 NSGA-II is a genetic algorithm (GA), i.e. it belongs to the evolutionary algorithms (EAs) family. The implementation of NSGA-II provided in jMetalPy follows the evolutionary - algorithm template described in the algorithm module (:mod:`algorithm`). + algorithm template described in the algorithm module (:py:mod:`algorithm`). :param problem: The problem to solve. :param population_size: Size of the population. :param max_evaluations: Maximum number of evaluations/iterations. - :param mutation: Mutation operator (see :mod:`mutation`). - :param crossover: Crossover operator (see :mod:`crosover`). - :param selection: Selection operator (see :mod:`selection`). + :param mutation: Mutation operator (see :py:mod:`mutation`). + :param crossover: Crossover operator (see :py:mod:`crosover`). + :param selection: Selection operator (see :py:mod:`selection`). :param evaluator: An evaluator object to evaluate the individuals of the population. """ super(NSGAII, self).__init__( diff --git a/jmetal/util/quality_indicator.py b/jmetal/util/quality_indicator.py index 317d8f5d..16a260fe 100644 --- a/jmetal/util/quality_indicator.py +++ b/jmetal/util/quality_indicator.py @@ -28,8 +28,8 @@ class HyperVolume: """ Hypervolume computation based on variant 3 of the algorithm in the paper: * C. M. Fonseca, L. Paquete, and M. Lopez-Ibanez. An improved dimension-sweep - algorithm for the hypervolume indicator. In IEEE Congress on Evolutionary - Computation, pages 1157-1163, Vancouver, Canada, July 2006. + algorithm for the hypervolume indicator. In IEEE Congress on Evolutionary + Computation, pages 1157-1163, Vancouver, Canada, July 2006. Minimization is implicitly assumed here! """ From b0990bc9cfa16723ed729b22d5e9fd3022a7d5b6 Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 10 Jul 2018 14:00:27 +0200 Subject: [PATCH 79/90] Change default logger and some syntax changes --- .travis.yml | 16 +- .../multiobjective/nsgaii_full_settings.ipynb | 42 ++++ .../multiobjective/nsgaii_full_settings.py | 33 +-- .../multiobjective/smpso_full_settings.py | 29 +-- .../smpsorp_standard_settings.py | 23 +- jmetal/__init__.py | 21 +- jmetal/algorithm/multiobjective/nsgaii.py | 4 - jmetal/algorithm/multiobjective/smpso.py | 8 +- jmetal/component/comparator.py | 4 + jmetal/component/density_estimator.py | 36 +-- jmetal/component/evaluator.py | 7 +- jmetal/component/observer.py | 36 +-- .../{util => component}/quality_indicator.py | 211 +++++++++--------- jmetal/component/ranking.py | 14 +- jmetal/component/test/test_archive.py | 8 +- jmetal/component/test/test_evaluator.py | 4 +- .../test/test_quality_indicator.py | 17 +- jmetal/core/algorithm.py | 7 +- jmetal/core/operator.py | 8 +- jmetal/core/problem.py | 14 +- jmetal/core/solution.py | 6 +- jmetal/operator/crossover.py | 41 ++-- jmetal/operator/mutation.py | 24 +- jmetal/operator/selection.py | 108 ++++----- jmetal/problem/{resources => front}/DTLZ1.pf | 0 jmetal/problem/{resources => front}/ZDT1.pf | 0 jmetal/problem/{resources => front}/ZDT2.pf | 0 jmetal/problem/{resources => front}/ZDT3.pf | 0 jmetal/problem/{resources => front}/ZDT4.pf | 0 jmetal/problem/{resources => front}/ZDT6.pf | 0 jmetal/problem/multiobjective/dtlz.py | 8 +- .../problem/multiobjective/unconstrained.py | 16 +- jmetal/problem/multiobjective/zdt.py | 23 +- .../problem/singleobjective/unconstrained.py | 4 +- jmetal/util/graphic.py | 76 +++---- sonar-project.properties | 9 - 36 files changed, 464 insertions(+), 393 deletions(-) create mode 100644 examples/multiobjective/nsgaii_full_settings.ipynb rename jmetal/{util => component}/quality_indicator.py (51%) rename jmetal/{util => component}/test/test_quality_indicator.py (58%) rename jmetal/problem/{resources => front}/DTLZ1.pf (100%) rename jmetal/problem/{resources => front}/ZDT1.pf (100%) rename jmetal/problem/{resources => front}/ZDT2.pf (100%) rename jmetal/problem/{resources => front}/ZDT3.pf (100%) rename jmetal/problem/{resources => front}/ZDT4.pf (100%) rename jmetal/problem/{resources => front}/ZDT6.pf (100%) delete mode 100644 sonar-project.properties diff --git a/.travis.yml b/.travis.yml index 9d089652..4e90f15c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,11 +7,11 @@ branches: - master - /.*/ deploy: - provider: pypi - skip_cleanup: true - user: ajnebro - distributions: sdist bdist_wheel - password: - secure: "pJhh2ZwuDaMELZO7kmNGWa7sRaUi6s4By4GdBxf1hPjIBkB0GkOGHKxuivnWitAYLbmzpSoMcp2rHETcRiSqYTPlyovLA8A7YpY1HXIcNBrrmqnOpzc9bN3Ka90HMu0ySw2uYZgaQ2neFMm5CvD6W47IG0UUaFPYl68aZ8lEe8t7Tea7kFLU4UgXZxp3BXLTHF7xx7V29Ba5aKv2" - on: - branch: master + provider: pypi + skip_cleanup: true + user: ajnebro + distributions: sdist bdist_wheel + password: + secure: "pJhh2ZwuDaMELZO7kmNGWa7sRaUi6s4By4GdBxf1hPjIBkB0GkOGHKxuivnWitAYLbmzpSoMcp2rHETcRiSqYTPlyovLA8A7YpY1HXIcNBrrmqnOpzc9bN3Ka90HMu0ySw2uYZgaQ2neFMm5CvD6W47IG0UUaFPYl68aZ8lEe8t7Tea7kFLU4UgXZxp3BXLTHF7xx7V29Ba5aKv2" + on: + branch: master diff --git a/examples/multiobjective/nsgaii_full_settings.ipynb b/examples/multiobjective/nsgaii_full_settings.ipynb new file mode 100644 index 00000000..b360d7c2 --- /dev/null +++ b/examples/multiobjective/nsgaii_full_settings.ipynb @@ -0,0 +1,42 @@ +{ + "cells": [ + { + "cell_type": "heading", + "metadata": { + "collapsed": true + }, + "level": 1, + "source": [ + "NSGAII with full settings" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/examples/multiobjective/nsgaii_full_settings.py b/examples/multiobjective/nsgaii_full_settings.py index 16f13a01..b5ad9812 100644 --- a/examples/multiobjective/nsgaii_full_settings.py +++ b/examples/multiobjective/nsgaii_full_settings.py @@ -1,5 +1,3 @@ -import logging - from jmetal.algorithm import NSGAII from jmetal.component.observer import VisualizerObserver, ProgressBarObserver from jmetal.component.comparator import RankingAndCrowdingDistanceComparator @@ -9,7 +7,7 @@ from jmetal.util.solution_list_output import SolutionList -def main() -> None: +if __name__ == '__main__': problem = DTLZ1() algorithm = NSGAII( @@ -21,34 +19,21 @@ def main() -> None: selection=BinaryTournamentSelection(comparator=RankingAndCrowdingDistanceComparator()) ) - observer = VisualizerObserver(problem) + visualizer = VisualizerObserver(problem) progress_bar = ProgressBarObserver(step=100, max=25000) - algorithm.observable.register(observer=observer) + algorithm.observable.register(observer=visualizer) algorithm.observable.register(observer=progress_bar) algorithm.run() - result = algorithm.get_result() + front = algorithm.get_result() # Plot frontier to file pareto_front = ScatterMatplotlib(plot_title='NSGAII for DTLZ1', number_of_objectives=problem.number_of_objectives) - pareto_front.plot(result, reference=problem.get_reference_front(), output='NSGAII-DTLZ1', show=False) + pareto_front.plot(front, reference=problem.get_reference_front(), output='NSGAII-DTLZ1', show=False) # Save variables to file - SolutionList.print_function_values_to_file(result, 'NSGAII.' + problem.get_name()) - - print("Algorithm (continuous problem): " + algorithm.get_name()) - print("Problem: " + problem.get_name()) - print("Computing time: " + str(algorithm.total_computing_time)) - - -if __name__ == '__main__': - logging.basicConfig( - level=logging.INFO, - format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s", - handlers=[ - logging.FileHandler('jmetalpy.log'), - logging.StreamHandler() - ] - ) + SolutionList.print_function_values_to_file(front, 'NSGAII.' + problem.get_name()) - main() \ No newline at end of file + print('Algorithm (continuous problem): ' + algorithm.get_name()) + print('Problem: ' + problem.get_name()) + print('Computing time: ' + str(algorithm.total_computing_time)) \ No newline at end of file diff --git a/examples/multiobjective/smpso_full_settings.py b/examples/multiobjective/smpso_full_settings.py index 3d7a8c2a..75590f9a 100644 --- a/examples/multiobjective/smpso_full_settings.py +++ b/examples/multiobjective/smpso_full_settings.py @@ -1,5 +1,3 @@ -import logging - from jmetal.algorithm import SMPSO from jmetal.component.observer import ProgressBarObserver, VisualizerObserver from jmetal.component.archive import CrowdingDistanceArchive @@ -9,7 +7,7 @@ from jmetal.util.solution_list_output import SolutionList -def main() -> None: +if __name__ == '__main__': problem = ZDT1() algorithm = SMPSO( @@ -26,28 +24,15 @@ def main() -> None: algorithm.observable.register(observer=progress_bar) algorithm.run() - result = algorithm.get_result() + front = algorithm.get_result() # Plot frontier to file pareto_front = ScatterMatplotlib(plot_title='SMPSO for ZDT1', number_of_objectives=problem.number_of_objectives) - pareto_front.plot(result, reference=problem.get_reference_front(), output='SMPSO-ZDT1', show=False) + pareto_front.plot(front, reference=problem.get_reference_front(), output='SMPSO-ZDT1', show=False) # Save variables to file - SolutionList.print_function_values_to_file(result, 'SMPSO.ZDT1') - - print("Algorithm (continuous problem): " + algorithm.get_name()) - print("Problem: " + problem.get_name()) - print("Computing time: " + str(algorithm.total_computing_time)) - - -if __name__ == '__main__': - logging.basicConfig( - level=logging.INFO, - format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s", - handlers=[ - logging.FileHandler('jmetalpy.log'), - logging.StreamHandler() - ] - ) + SolutionList.print_function_values_to_file(front, 'SMPSO.ZDT1') - main() \ No newline at end of file + print('Algorithm (continuous problem): ' + algorithm.get_name()) + print('Problem: ' + problem.get_name()) + print('Computing time: ' + str(algorithm.total_computing_time)) diff --git a/examples/multiobjective/smpsorp_standard_settings.py b/examples/multiobjective/smpsorp_standard_settings.py index 56d0afa4..4db454ca 100644 --- a/examples/multiobjective/smpsorp_standard_settings.py +++ b/examples/multiobjective/smpsorp_standard_settings.py @@ -1,5 +1,3 @@ -import logging - from jmetal.algorithm import SMPSORP from jmetal.component.archive import CrowdingDistanceArchiveWithReferencePoint from jmetal.component.observer import ProgressBarObserver @@ -7,7 +5,7 @@ from jmetal.operator import Polynomial -def main() -> None: +if __name__ == '__main__': problem = ZDT1() swarm_size = 100 @@ -33,19 +31,6 @@ def main() -> None: algorithm.run() - print("Algorithm (continuous problem): " + algorithm.get_name()) - print("Problem: " + problem.get_name()) - print("Computing time: " + str(algorithm.total_computing_time)) - - -if __name__ == '__main__': - logging.basicConfig( - level=logging.INFO, - format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s", - handlers=[ - logging.FileHandler('jmetalpy.log'), - logging.StreamHandler() - ] - ) - - main() \ No newline at end of file + print('Algorithm (continuous problem): ' + algorithm.get_name()) + print('Problem: ' + problem.get_name()) + print('Computing time: ' + str(algorithm.total_computing_time)) diff --git a/jmetal/__init__.py b/jmetal/__init__.py index b5bfb0c6..df1d671d 100644 --- a/jmetal/__init__.py +++ b/jmetal/__init__.py @@ -1,8 +1,25 @@ +import logging + from jmetal import algorithm from jmetal import core from jmetal import operator from jmetal import problem __all__ = ['core', 'algorithm', 'operator', 'problem'] -__version__ = '1.0' -__author__ = 'Antonio J. Nebro ' + +logger = logging.getLogger('jMetalPy') +logger.setLevel(logging.DEBUG) + +# create a file handler +file_handler = logging.FileHandler('jmetalpy.log') +file_handler.setLevel(logging.INFO) +stream_handler = logging.StreamHandler() + +# create a logging format +formatter = logging.Formatter('%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s') +file_handler.setFormatter(formatter) +stream_handler.setFormatter(formatter) + +# add the handlers to the logger +logger.addHandler(file_handler) +logger.addHandler(stream_handler) \ No newline at end of file diff --git a/jmetal/algorithm/multiobjective/nsgaii.py b/jmetal/algorithm/multiobjective/nsgaii.py index 27252033..9420af5e 100644 --- a/jmetal/algorithm/multiobjective/nsgaii.py +++ b/jmetal/algorithm/multiobjective/nsgaii.py @@ -67,11 +67,7 @@ def replacement(self, population: List[S], offspring_population: List[S]) -> Lis return RankingAndCrowdingDistanceSelection(self.population_size).execute(join_population) def get_result(self) -> R: - """ :return: Final population. - """ return self.population def get_name(self) -> str: - """ :return: Name of the algorithm. - """ return 'NSGA-II' diff --git a/jmetal/algorithm/multiobjective/smpso.py b/jmetal/algorithm/multiobjective/smpso.py index 5460d183..8e37eb4c 100644 --- a/jmetal/algorithm/multiobjective/smpso.py +++ b/jmetal/algorithm/multiobjective/smpso.py @@ -114,14 +114,14 @@ def initialize_global_best(self, swarm: List[FloatSolution]) -> None: def initialize_particle_best(self, swarm: List[FloatSolution]) -> None: for particle in swarm: - particle.attributes["local_best"] = copy(particle) + particle.attributes['local_best'] = copy(particle) def initialize_velocity(self, swarm: List[FloatSolution]) -> None: pass # Velocity initialized in the constructor def update_velocity(self, swarm: List[FloatSolution]) -> None: for i in range(self.swarm_size): - best_particle = copy(swarm[i].attributes["local_best"]) + best_particle = copy(swarm[i].attributes['local_best']) best_global = self.select_global_best() r1 = round(random.uniform(self.r1_min, self.r1_max), 1) @@ -170,9 +170,9 @@ def update_particle_best(self, swarm: List[FloatSolution]) -> None: for i in range(self.swarm_size): flag = self.dominance_comparator.compare( swarm[i], - swarm[i].attributes["local_best"]) + swarm[i].attributes['local_best']) if flag != 1: - swarm[i].attributes["local_best"] = copy(swarm[i]) + swarm[i].attributes['local_best'] = copy(swarm[i]) def get_result(self) -> List[FloatSolution]: return self.leaders.solution_list diff --git a/jmetal/component/comparator.py b/jmetal/component/comparator.py index bd38d9ed..20f83dfc 100644 --- a/jmetal/component/comparator.py +++ b/jmetal/component/comparator.py @@ -6,11 +6,13 @@ class Comparator(Generic[S]): + def compare(self, object1: S, object2: S) -> int: pass class EqualSolutionsComparator(Comparator): + def compare(self, solution1: Solution, solution2: Solution) -> int: if solution1 is None: return 1 @@ -45,6 +47,7 @@ def compare(self, solution1: Solution, solution2: Solution) -> int: class SolutionAttributeComparator(Comparator): + def __init__(self, key: str, lowest_is_best: bool = True): self.key = key self.lowest_is_best = lowest_is_best @@ -87,6 +90,7 @@ def compare(self, solution1: Solution, solution2: Solution) -> int: class DominanceComparator(Comparator): + def __init__(self, constraint_comparator = SolutionAttributeComparator("overall_constraint_violation", lowest_is_best=False)): self.constraint_comparator = constraint_comparator diff --git a/jmetal/component/density_estimator.py b/jmetal/component/density_estimator.py index 41651fb0..50960072 100644 --- a/jmetal/component/density_estimator.py +++ b/jmetal/component/density_estimator.py @@ -27,49 +27,49 @@ class CrowdingDistance(DensityEstimator[List[S]]): In consequence, the main method of this class is :func:`compute_density_estimator`. """ - def compute_density_estimator(self, solution_list: List[S]): + def compute_density_estimator(self, front: List[S]): """This function performs the computation of the crowding density estimation over the solution list. .. note:: This method assign the distance in the inner elements of the solution list. - :param solution_list: The list of solutions. + :param front: The list of solutions. """ - size = len(solution_list) + size = len(front) if size is 0: return elif size is 1: - solution_list[0].attributes["crowding_distance"] = float("inf") + front[0].attributes['crowding_distance'] = float("inf") return elif size is 2: - solution_list[0].attributes["crowding_distance"] = float("inf") - solution_list[1].attributes["crowding_distance"] = float("inf") + front[0].attributes['crowding_distance'] = float("inf") + front[1].attributes['crowding_distance'] = float("inf") return - for i in range(len(solution_list)): - solution_list[i].attributes["crowding_distance"] = 0.0 + for i in range(len(front)): + front[i].attributes['crowding_distance'] = 0.0 - number_of_objectives = solution_list[0].number_of_objectives + number_of_objectives = front[0].number_of_objectives for i in range(number_of_objectives): # Sort the population by Obj n - solution_list = sorted(solution_list, key=lambda x: x.objectives[i]) - objective_minn = solution_list[0].objectives[i] - objective_maxn = solution_list[len(solution_list) - 1].objectives[i] + front = sorted(front, key=lambda x: x.objectives[i]) + objective_minn = front[0].objectives[i] + objective_maxn = front[len(front) - 1].objectives[i] # Set de crowding distance - solution_list[0].attributes["crowding_distance"] = float("inf") - solution_list[size - 1].attributes["crowding_distance"] = float("inf") + front[0].attributes['crowding_distance'] = float('inf') + front[size - 1].attributes['crowding_distance'] = float('inf') for j in range(1, size - 1): - distance = solution_list[j + 1].objectives[i] - solution_list[j - 1].objectives[i] + distance = front[j + 1].objectives[i] - front[j - 1].objectives[i] # Check if minimum and maximum are the same (in which case do nothing) if objective_maxn - objective_minn == 0: - logger.warning("Minimum and maximum are the same!") + logger.warning('Minimum and maximum are the same!') else: distance = distance / (objective_maxn - objective_minn) - distance += solution_list[j].attributes["crowding_distance"] - solution_list[j].attributes["crowding_distance"] = distance + distance += front[j].attributes['crowding_distance'] + front[j].attributes['crowding_distance'] = distance diff --git a/jmetal/component/evaluator.py b/jmetal/component/evaluator.py index def59202..a46d2eaf 100644 --- a/jmetal/component/evaluator.py +++ b/jmetal/component/evaluator.py @@ -29,7 +29,7 @@ def evaluate(self, solution_list: List[S], problem: Problem) -> List[S]: return solution_list -class ParallelEvaluator(Evaluator[S]): +class MapEvaluator(Evaluator[S]): def __init__(self, processes=None): self.pool = ThreadPool(processes) @@ -40,10 +40,11 @@ def evaluate(self, solution_list: List[S], problem: Problem) -> List[S]: return solution_list -class DaskMultithreadedEvaluator(Evaluator[S]): +class MultithreadedEvaluator(Evaluator[S]): def __init__(self, n_workers: int, processes: bool=True): - """ :param n_workers: Number of workers to start. + """ + :param n_workers: Number of workers to start. :param processes: Whether to use processes (True) or threads (False). """ cluster = LocalCluster(n_workers=n_workers, processes=processes) diff --git a/jmetal/component/observer.py b/jmetal/component/observer.py index 81b96a70..bff58ef1 100644 --- a/jmetal/component/observer.py +++ b/jmetal/component/observer.py @@ -8,7 +8,7 @@ from jmetal.core.observable import Observer from jmetal.util.solution_list_output import SolutionList -logger = logging.getLogger(__name__) +jMetalPyLogger = logging.getLogger('jMetalPy') """ .. module:: observer @@ -41,12 +41,16 @@ def __init__(self, frequency: float = 1.0) -> None: self.display_frequency = frequency def update(self, *args, **kwargs): - evaluations = kwargs["evaluations"] + computing_time = kwargs['computing time'] + evaluations = kwargs['evaluations'] + front = kwargs['population'] if (evaluations % self.display_frequency) == 0: - logger.debug("Evaluations: " + str(evaluations) + - ". Best fitness: " + str(kwargs["population"][0].objectives) + - ". Computing time: " + str(kwargs["computing time"])) + jMetalPyLogger.debug( + 'Evaluations: {0} \n Best fitness: {1} \n Computing time: {2}'.format( + evaluations, front[0].objectives, computing_time + ) + ) class WriteFrontToFileObserver(Observer): @@ -56,17 +60,17 @@ def __init__(self, output_directory) -> None: self.directory = output_directory if os.path.isdir(self.directory): - logger.warning("Directory " + self.directory + " exists. Removing contents.") + jMetalPyLogger.warning('Directory {0} exists. Removing contents.'.format(self.directory)) for file in os.listdir(self.directory): - os.remove(self.directory + "/" + file) + os.remove('{0}/{1}'.format(self.directory, file)) else: - logger.warning("Directory " + self.directory + " does not exist. Creating it.") + jMetalPyLogger.warning('Directory {0} does not exist. Creating it.'.format(self.directory)) os.mkdir(self.directory) def update(self, *args, **kwargs): - SolutionList.print_function_values_to_file( - kwargs["population"], self.directory + "/FUN." + str(self.counter)) + front = kwargs['population'] + SolutionList.print_function_values_to_file(front, '{0}/FUN.{1}'.format(self.directory, self.counter)) self.counter += 1 @@ -76,14 +80,14 @@ def __init__(self, problem: Problem, replace: bool=True) -> None: self.display_frequency = 1.0 self.replace = replace self.reference = problem.get_reference_front() - self.plot = ScatterMatplotlib('VisualizerObserver', problem.number_of_objectives) + self.plot = ScatterMatplotlib('jMetalPy', problem.number_of_objectives) def update(self, *args, **kwargs): - evaluations = kwargs["evaluations"] - computing_time = kwargs["computing time"] - solution_list = kwargs["population"] + computing_time = kwargs['computing time'] + evaluations = kwargs['evaluations'] + front = kwargs['population'] - title = '{0}, Eval: {1}, Time: {2}'.format("VisualizerObserver", evaluations, computing_time) + title = '{0}, Eval: {1}, Time: {2}'.format('VisualizerObserver', evaluations, computing_time) if (evaluations % self.display_frequency) == 0: - self.plot.update(solution_list, self.reference, new_title=title, persistence=self.replace) + self.plot.update(front, self.reference, new_title=title, persistence=self.replace) diff --git a/jmetal/util/quality_indicator.py b/jmetal/component/quality_indicator.py similarity index 51% rename from jmetal/util/quality_indicator.py rename to jmetal/component/quality_indicator.py index 16a260fe..56afa66e 100644 --- a/jmetal/util/quality_indicator.py +++ b/jmetal/component/quality_indicator.py @@ -1,30 +1,25 @@ -# Copyright (C) 2010 Simon Wessing -# TU Dortmund University -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +from typing import List, TypeVar +from jmetal.core.solution import Solution """ -.. module:: HyperVolume +.. module:: indicators :platform: Unix, Windows - :synopsis: Hypervolume implementation. + :synopsis: Quality indicators implementation. -.. moduleauthor:: Simon Wessing +.. moduleauthor:: Antonio Benítez-Hidalgo , Simon Wessing """ +S = TypeVar('S') -class HyperVolume: + +class Metric: + + def get_name(self) -> str: + return self.__class__.__name__ + + +class HyperVolume(Metric): """ Hypervolume computation based on variant 3 of the algorithm in the paper: * C. M. Fonseca, L. Paquete, and M. Lopez-Ibanez. An improved dimension-sweep @@ -34,43 +29,51 @@ class HyperVolume: Minimization is implicitly assumed here! """ - def __init__(self, referencePoint): + def __init__(self, reference_point: list): """Constructor.""" - self.referencePoint = referencePoint + self.referencePoint = reference_point self.list: MultiList = [] - def compute(self, front): + def compute(self, front: List[Solution]): """Before the HV computation, front and reference point are translated, so that the reference point is [0, ..., 0]. :return: The hypervolume that is dominated by a non-dominated front. """ + def get_variables(front: List[Solution]) -> list: + result = [] + for solution in front: + result.append(solution.objectives) - def weaklyDominates(point, other): + return result + + front = get_variables(front) + + def weakly_dominates(point, other): for i in range(len(point)): if point[i] > other[i]: return False return True - relevantPoints = [] - referencePoint = self.referencePoint - dimensions = len(referencePoint) + relevant_points = [] + reference_point = self.referencePoint + dimensions = len(reference_point) for point in front: # only consider points that dominate the reference point - if weaklyDominates(point, referencePoint): - relevantPoints.append(point) - if any(referencePoint): - # shift points so that referencePoint == [0, ..., 0] + if weakly_dominates(point, reference_point): + relevant_points.append(point) + if any(reference_point): + # shift points so that reference_point == [0, ..., 0] # this way the reference point doesn't have to be explicitly used # in the HV computation - for j in range(len(relevantPoints)): - relevantPoints[j] = [relevantPoints[j][i] - referencePoint[i] for i in range(dimensions)] - self.preProcess(relevantPoints) + for j in range(len(relevant_points)): + relevant_points[j] = [relevant_points[j][i] - reference_point[i] for i in range(dimensions)] + self._pre_process(relevant_points) bounds = [-1.0e308] * dimensions - hyperVolume = self.hvRecursive(dimensions - 1, len(relevantPoints), bounds) - return hyperVolume - def hvRecursive(self, dimIndex, length, bounds): + return self._hv_recursive(dimensions - 1, len(relevant_points), bounds) + + def _hv_recursive(self, dim_index: int, length: int, bounds: list): """Recursive call to hypervolume calculation. In contrast to the paper, the code assumes that the reference point @@ -80,11 +83,11 @@ def hvRecursive(self, dimIndex, length, bounds): sentinel = self.list.sentinel if length == 0: return hvol - elif dimIndex == 0: + elif dim_index == 0: # special case: only one dimension # why using hypervolume at all? return -sentinel.next[0].cargo[0] - elif dimIndex == 1: + elif dim_index == 1: # special case: two dimensions, end recursion q = sentinel.next[1] h = q.cargo[0] @@ -101,65 +104,65 @@ def hvRecursive(self, dimIndex, length, bounds): else: remove = self.list.remove reinsert = self.list.reinsert - hvRecursive = self.hvRecursive + hv_recursive = self._hv_recursive p = sentinel - q = p.prev[dimIndex] + q = p.prev[dim_index] while q.cargo != None: - if q.ignore < dimIndex: + if q.ignore < dim_index: q.ignore = 0 - q = q.prev[dimIndex] - q = p.prev[dimIndex] + q = q.prev[dim_index] + q = p.prev[dim_index] while length > 1 and ( - q.cargo[dimIndex] > bounds[dimIndex] or q.prev[dimIndex].cargo[dimIndex] >= bounds[dimIndex]): + q.cargo[dim_index] > bounds[dim_index] or q.prev[dim_index].cargo[dim_index] >= bounds[dim_index]): p = q - remove(p, dimIndex, bounds) - q = p.prev[dimIndex] + remove(p, dim_index, bounds) + q = p.prev[dim_index] length -= 1 - qArea = q.area - qCargo = q.cargo - qPrevDimIndex = q.prev[dimIndex] + q_area = q.area + q_cargo = q.cargo + q_prev_dim_index = q.prev[dim_index] if length > 1: - hvol = qPrevDimIndex.volume[dimIndex] + qPrevDimIndex.area[dimIndex] * ( - qCargo[dimIndex] - qPrevDimIndex.cargo[dimIndex]) + hvol = q_prev_dim_index.volume[dim_index] + q_prev_dim_index.area[dim_index] * ( + q_cargo[dim_index] - q_prev_dim_index.cargo[dim_index]) else: - qArea[0] = 1 - qArea[1:dimIndex + 1] = [qArea[i] * -qCargo[i] for i in range(dimIndex)] - q.volume[dimIndex] = hvol - if q.ignore >= dimIndex: - qArea[dimIndex] = qPrevDimIndex.area[dimIndex] + q_area[0] = 1 + q_area[1:dim_index + 1] = [q_area[i] * -q_cargo[i] for i in range(dim_index)] + q.volume[dim_index] = hvol + if q.ignore >= dim_index: + q_area[dim_index] = q_prev_dim_index.area[dim_index] else: - qArea[dimIndex] = hvRecursive(dimIndex - 1, length, bounds) - if qArea[dimIndex] <= qPrevDimIndex.area[dimIndex]: - q.ignore = dimIndex + q_area[dim_index] = hv_recursive(dim_index - 1, length, bounds) + if q_area[dim_index] <= q_prev_dim_index.area[dim_index]: + q.ignore = dim_index while p is not sentinel: - pCargoDimIndex = p.cargo[dimIndex] - hvol += q.area[dimIndex] * (pCargoDimIndex - q.cargo[dimIndex]) - bounds[dimIndex] = pCargoDimIndex - reinsert(p, dimIndex, bounds) + pCargoDimIndex = p.cargo[dim_index] + hvol += q.area[dim_index] * (pCargoDimIndex - q.cargo[dim_index]) + bounds[dim_index] = pCargoDimIndex + reinsert(p, dim_index, bounds) length += 1 q = p - p = p.next[dimIndex] - q.volume[dimIndex] = hvol - if q.ignore >= dimIndex: - q.area[dimIndex] = q.prev[dimIndex].area[dimIndex] + p = p.next[dim_index] + q.volume[dim_index] = hvol + if q.ignore >= dim_index: + q.area[dim_index] = q.prev[dim_index].area[dim_index] else: - q.area[dimIndex] = hvRecursive(dimIndex - 1, length, bounds) - if q.area[dimIndex] <= q.prev[dimIndex].area[dimIndex]: - q.ignore = dimIndex - hvol -= q.area[dimIndex] * q.cargo[dimIndex] + q.area[dim_index] = hv_recursive(dim_index - 1, length, bounds) + if q.area[dim_index] <= q.prev[dim_index].area[dim_index]: + q.ignore = dim_index + hvol -= q.area[dim_index] * q.cargo[dim_index] return hvol - def preProcess(self, front): - """Sets up the list resources structure needed for calculation.""" + def _pre_process(self, front): + """Sets up the list front structure needed for calculation.""" dimensions = len(self.referencePoint) - nodeList = MultiList(dimensions) + node_list = MultiList(dimensions) nodes = [MultiList.Node(dimensions, point) for point in front] for i in range(dimensions): - self.sortByDimension(nodes, i) - nodeList.extend(nodes, i) - self.list = nodeList + self._sort_by_dimension(nodes, i) + node_list.extend(nodes, i) + self.list = node_list - def sortByDimension(self, nodes, i): + def _sort_by_dimension(self, nodes, i): """Sorts the list of nodes by the i-th value of the contained points.""" # build a list of tuples of (point[i], node) decorated = [(node.cargo[i], node) for node in nodes] @@ -170,7 +173,7 @@ def sortByDimension(self, nodes, i): class MultiList: - """A special resources structure needed by FonsecaHyperVolume. + """A special front structure needed by FonsecaHyperVolume. It consists of several doubly linked lists that share common nodes. So, every node has multiple predecessors and successors, one in every list. @@ -178,44 +181,44 @@ class MultiList: class Node: - def __init__(self, numberLists, cargo=None): + def __init__(self, number_lists, cargo=None): self.cargo = cargo - self.next = [None] * numberLists - self.prev = [None] * numberLists + self.next = [None] * number_lists + self.prev = [None] * number_lists self.ignore = 0 - self.area = [0.0] * numberLists - self.volume = [0.0] * numberLists + self.area = [0.0] * number_lists + self.volume = [0.0] * number_lists def __str__(self): return str(self.cargo) - def __init__(self, numberLists): + def __init__(self, number_lists): """ Builds 'numberLists' doubly linked lists. """ - self.numberLists = numberLists - self.sentinel = MultiList.Node(numberLists) - self.sentinel.next = [self.sentinel] * numberLists - self.sentinel.prev = [self.sentinel] * numberLists + self.number_lists = number_lists + self.sentinel = MultiList.Node(number_lists) + self.sentinel.next = [self.sentinel] * number_lists + self.sentinel.prev = [self.sentinel] * number_lists def __str__(self): strings = [] - for i in range(self.numberLists): - currentList = [] + for i in range(self.number_lists): + current_list = [] node = self.sentinel.next[i] while node != self.sentinel: - currentList.append(str(node)) + current_list.append(str(node)) node = node.next[i] - strings.append(str(currentList)) - stringRepr = "" + strings.append(str(current_list)) + string_repr = "" for string in strings: - stringRepr += string + "\n" - return stringRepr + string_repr += string + "\n" + return string_repr def __len__(self): """Returns the number of lists that are included in this MultiList.""" - return self.numberLists + return self.number_lists - def getLength(self, i): + def get_length(self, i): """Returns the length of the i-th list.""" length = 0 sentinel = self.sentinel @@ -227,23 +230,23 @@ def getLength(self, i): def append(self, node, index): """ Appends a node to the end of the list at the given index.""" - lastButOne = self.sentinel.prev[index] + last_but_one = self.sentinel.prev[index] node.next[index] = self.sentinel - node.prev[index] = lastButOne + node.prev[index] = last_but_one # set the last element as the new one self.sentinel.prev[index] = node - lastButOne.next[index] = node + last_but_one.next[index] = node def extend(self, nodes, index): """ Extends the list at the given index with the nodes.""" sentinel = self.sentinel for node in nodes: - lastButOne = sentinel.prev[index] + last_but_one = sentinel.prev[index] node.next[index] = sentinel - node.prev[index] = lastButOne + node.prev[index] = last_but_one # set the last element as the new one sentinel.prev[index] = node - lastButOne.next[index] = node + last_but_one.next[index] = node def remove(self, node, index, bounds): """ Removes and returns 'node' from all lists in [0, 'index'[.""" diff --git a/jmetal/component/ranking.py b/jmetal/component/ranking.py index eccd275c..dfd6a7fb 100644 --- a/jmetal/component/ranking.py +++ b/jmetal/component/ranking.py @@ -17,7 +17,7 @@ def compute_ranking(self, solution_list: List[S]): def get_subfront(self, rank: int): if rank >= len(self.ranked_sublists): - raise Exception("Invalid rank: " + str(rank) + ". Max rank = " + str(len(self.ranked_sublists) -1)) + raise Exception('Invalid rank: {0}. Max rank: {1}'.format(rank, len(self.ranked_sublists) - 1)) return self.ranked_sublists[rank] def get_number_of_subfronts(self): @@ -35,13 +35,13 @@ def __init__(self): def compute_ranking(self, solution_list: List[S]): # number of solutions dominating solution ith - dominate_me = [0 for i in range(len(solution_list))] + dominate_me = [0 for _ in range(len(solution_list))] # list of solutions dominated by solution ith - i_dominate = [[] for i in range(len(solution_list))] + i_dominate = [[] for _ in range(len(solution_list))] # front[i] contains the list of solutions belonging to front i - front = [[] for i in range(len(solution_list) + 1)] + front = [[] for _ in range(len(solution_list) + 1)] for p in range(len(solution_list) - 1): for q in range(p + 1, len(solution_list)): @@ -57,7 +57,7 @@ def compute_ranking(self, solution_list: List[S]): for i in range(len(solution_list)): if dominate_me[i] is 0: front[0].append(i) - solution_list[i].attributes["dominance_ranking"] = 0 + solution_list[i].attributes['dominance_ranking'] = 0 i = 0 while len(front[i]) != 0: @@ -69,7 +69,7 @@ def compute_ranking(self, solution_list: List[S]): dominate_me[index] -= 1 if dominate_me[index] is 0: front[i].append(index) - solution_list[index].attributes["dominance_ranking"] = i + solution_list[index].attributes['dominance_ranking'] = i self.ranked_sublists = [[]] * i for j in range(i): @@ -88,5 +88,5 @@ def __init__(self): super(EfficientNonDominatedRanking, self).__init__() def compute_ranking(self, solution_list: List[S]): - #todo + # todo return self.ranked_sublists diff --git a/jmetal/component/test/test_archive.py b/jmetal/component/test/test_archive.py index 808ea35a..c45ac372 100644 --- a/jmetal/component/test/test_archive.py +++ b/jmetal/component/test/test_archive.py @@ -43,11 +43,11 @@ def test_should_adding_one_solution_work_properly(self): self.assertEqual(solution, self.archive.get_solution_list()[0]) def test_should_adding_two_solutions_work_properly_if_one_is_dominated(self): - dominated_solution = Solution(1,2) - dominated_solution.objectives = [2.0,2.0] + dominated_solution = Solution(1 ,2) + dominated_solution.objectives = [2.0, 2.0] - dominant_solution = Solution(1,2) - dominant_solution.objectives = [1.0,1.0] + dominant_solution = Solution(1, 2) + dominant_solution.objectives = [1.0 ,1.0] self.archive.add(dominated_solution) self.archive.add(dominant_solution) diff --git a/jmetal/component/test/test_evaluator.py b/jmetal/component/test/test_evaluator.py index 3e6dd4e3..534cf66a 100644 --- a/jmetal/component/test/test_evaluator.py +++ b/jmetal/component/test/test_evaluator.py @@ -1,6 +1,6 @@ import unittest -from jmetal.component.evaluator import SequentialEvaluator, ParallelEvaluator +from jmetal.component.evaluator import SequentialEvaluator, MapEvaluator from jmetal.core.problem import FloatProblem from jmetal.core.solution import FloatSolution @@ -56,7 +56,7 @@ def test_should_evaluate_a_list_of_problem_work_properly(self): class ParallelEvaluatorTestCases(unittest.TestCase): def setUp(self): - self.evaluator = ParallelEvaluator() + self.evaluator = MapEvaluator() self.problem = MockedProblem() def test_should_constructor_create_a_non_null_object(self): diff --git a/jmetal/util/test/test_quality_indicator.py b/jmetal/component/test/test_quality_indicator.py similarity index 58% rename from jmetal/util/test/test_quality_indicator.py rename to jmetal/component/test/test_quality_indicator.py index 43c24821..ebb584b5 100644 --- a/jmetal/util/test/test_quality_indicator.py +++ b/jmetal/component/test/test_quality_indicator.py @@ -1,8 +1,9 @@ from os.path import dirname, join import unittest -from jmetal.util.front_file import read_front_from_file, walk_up_folder -from jmetal.util.quality_indicator import HyperVolume +from jmetal.core.solution import Solution +from jmetal.util.front_file import read_front_from_file_as_solutions, walk_up_folder +from jmetal.component.quality_indicator import HyperVolume class HyperVolumeTestCases(unittest.TestCase): @@ -12,7 +13,14 @@ def setUp(self): def test_should_hypervolume_return_5_0(self): reference_point = [2, 2, 2] - front = [[1, 0, 1], [0, 1, 0]] + + solution1 = Solution(1, 3) + solution1.objectives = [1, 0, 1] + + solution2 = Solution(1, 3) + solution2.objectives = [0, 1, 0] + + front = [solution1, solution2] hv = HyperVolume(reference_point) value = hv.compute(front) @@ -21,7 +29,8 @@ def test_should_hypervolume_return_5_0(self): def test_should_hypervolume_return_the_correct_value_when_applied_to_the_ZDT1_reference_front(self): reference_point = [1, 1] - front = read_front_from_file(join(walk_up_folder(self.file_path, 2), 'problem/resources/ZDT1.pf')) + front = read_front_from_file_as_solutions(join(walk_up_folder(self.file_path, 2), 'problem/front/ZDT1.pf')) + hv = HyperVolume(reference_point) value = hv.compute(front) diff --git a/jmetal/core/algorithm.py b/jmetal/core/algorithm.py index 3520a133..b531583b 100644 --- a/jmetal/core/algorithm.py +++ b/jmetal/core/algorithm.py @@ -1,4 +1,3 @@ -import logging import threading import time from typing import TypeVar, Generic, List @@ -6,8 +5,6 @@ from jmetal.core.solution import FloatSolution from jmetal.core.observable import Observable, DefaultObservable -logger = logging.getLogger(__name__) - S = TypeVar('S') R = TypeVar('R') @@ -34,12 +31,16 @@ def get_evaluations(self) -> int: return self.evaluations def get_result(self) -> R: + """ :return: Final population. + """ pass def get_current_computing_time(self) -> float: return time.time() - self.start_computing_time def get_name(self) -> str: + """ :return: Name of the algorithm. + """ return type(self).__name__ diff --git a/jmetal/core/operator.py b/jmetal/core/operator.py index 915edea2..f745d839 100644 --- a/jmetal/core/operator.py +++ b/jmetal/core/operator.py @@ -27,9 +27,9 @@ class Mutation(Operator[S, S]): def __init__(self, probability: float): if probability > 1.0: - raise Exception("The probability is greater than one: " + str(probability)) + raise Exception('The probability is greater than one: {}'.format(probability)) elif probability < 0.0: - raise Exception("The probability is lower than zero: " + str(probability)) + raise Exception('The probability is lower than zero: {}'.format(probability)) self.probability = probability @@ -42,9 +42,9 @@ class Crossover(Operator[List[S], List[R]]): def __init__(self, probability: float): if probability > 1.0: - raise Exception("The probability is greater than one: " + str(probability)) + raise Exception('The probability is greater than one: {}'.format(probability)) elif probability < 0.0: - raise Exception("The probability is lower than zero: " + str(probability)) + raise Exception('The probability is lower than zero: {}'.format(probability)) self.probability = probability diff --git a/jmetal/core/problem.py b/jmetal/core/problem.py index 4e59ec57..67f30dff 100644 --- a/jmetal/core/problem.py +++ b/jmetal/core/problem.py @@ -1,4 +1,3 @@ -import os from os.path import dirname, join from pathlib import Path from typing import Generic, TypeVar @@ -13,11 +12,14 @@ class Problem(Generic[S]): """ Class representing problems. """ + MINIMIZE = -1 + MAXIMIZE = 1 + def __init__(self): self.number_of_variables: int = None self.number_of_objectives: int = None self.number_of_constraints: int = None - self.reference_front_path: str = 'problem/resources/{0}.pf'.format(self.get_name()) + self.obj_directions: list = [] def evaluate(self, solution: S) -> S: raise NotImplemented @@ -29,9 +31,11 @@ def create_solution(self) -> S: raise NotImplemented def get_reference_front(self) -> list: + reference_front_path = 'problem/front/{0}.pf'.format(self.get_name()) + front = [] file_path = dirname(join(dirname(__file__))) - computed_path = join(file_path, self.reference_front_path) + computed_path = join(file_path, reference_front_path) if Path(computed_path).is_file(): front = read_front_from_file_as_solutions(computed_path) @@ -74,8 +78,8 @@ class IntegerProblem(Problem[IntegerSolution]): def __init__(self): super().__init__() - self.lower_bound : [] = None - self.upper_bound : [] = None + self.lower_bound: [] = None + self.upper_bound: [] = None def create_solution(self) -> IntegerSolution: new_solution = IntegerSolution( diff --git a/jmetal/core/solution.py b/jmetal/core/solution.py index 7b5ae5c0..9f8ff539 100644 --- a/jmetal/core/solution.py +++ b/jmetal/core/solution.py @@ -16,11 +16,11 @@ def __init__(self, number_of_variables: int, number_of_objectives: int, number_o self.attributes = {} def __str__(self) -> str: - solution = "number_of_objectives: {0} \nnumber_of_variables: {1} \nnumber_of_constraints: {2} \n".format( + solution = 'number_of_objectives: {0} \nnumber_of_variables: {1} \nnumber_of_constraints: {2} \n'.format( self.number_of_objectives, self.number_of_variables, self.number_of_constraints ) - solution += "objectives: \n {0} \n".format(self.objectives) - solution += "variables: \n {0}".format(self.variables) + solution += 'objectives: \n {0} \n'.format(self.objectives) + solution += 'variables: \n {0}'.format(self.variables) return solution diff --git a/jmetal/operator/crossover.py b/jmetal/operator/crossover.py index 796617bc..5967d125 100644 --- a/jmetal/operator/crossover.py +++ b/jmetal/operator/crossover.py @@ -15,18 +15,22 @@ class NullCrossover(Crossover[Solution, Solution]): + def __init__(self): super(NullCrossover, self).__init__(probability=0) def execute(self, parents: List[Solution]) -> List[Solution]: if len(parents) != 2: - raise Exception("The number of parents is not two: " + str(len(parents))) + raise Exception('The number of parents is not two: {}'.format(len(parents))) return parents def get_number_of_parents(self): return 2 - + + def get_name(self): + return 'Null crossover' + class SBX(Crossover[FloatSolution, FloatSolution]): __EPS = 1.0e-14 @@ -37,7 +41,7 @@ def __init__(self, probability: float, distribution_index: float = 20.0): def execute(self, parents: List[FloatSolution]) -> List[FloatSolution]: if len(parents) != 2: - raise Exception("The number of parents is not two: " + str(len(parents))) + raise Exception('The number of parents is not two: {}'.format(len(parents))) offspring = [copy.copy(parents[0]), copy.copy(parents[1])] rand = random.random() @@ -53,9 +57,9 @@ def execute(self, parents: List[FloatSolution]) -> List[FloatSolution]: else: y1, y2 = value_x2, value_x1 - lowerBound, upperBound = parents[0].lower_bound[i], parents[1].upper_bound[i] + lower_bound, upper_bound = parents[0].lower_bound[i], parents[1].upper_bound[i] - beta = 1.0 + (2.0 * (y1 - lowerBound) / (y2 - y1)) + beta = 1.0 + (2.0 * (y1 - lower_bound) / (y2 - y1)) alpha = 2.0 - pow(beta, -(self.distribution_index + 1.0)) rand = random.random() @@ -65,7 +69,7 @@ def execute(self, parents: List[FloatSolution]) -> List[FloatSolution]: betaq = pow(1.0 / (2.0 - rand * alpha), 1.0 / (self.distribution_index + 1.0)) c1 = 0.5 * (y1 + y2 - betaq * (y2 - y1)) - beta = 1.0 + (2.0 * (upperBound - y2) / (y2 - y1)) + beta = 1.0 + (2.0 * (upper_bound - y2) / (y2 - y1)) alpha = 2.0 - pow(beta, -(self.distribution_index + 1.0)) if rand <= (1.0 / alpha): @@ -75,14 +79,14 @@ def execute(self, parents: List[FloatSolution]) -> List[FloatSolution]: c2 = 0.5 * (y1 + y2 + betaq * (y2 - y1)) - if c1 < lowerBound: - c1 = lowerBound - if c2 < lowerBound: - c2 = lowerBound - if c1 > upperBound: - c1 = upperBound - if c2 > upperBound: - c2 = upperBound + if c1 < lower_bound: + c1 = lower_bound + if c2 < lower_bound: + c2 = lower_bound + if c1 > upper_bound: + c1 = upper_bound + if c2 > upper_bound: + c2 = upper_bound if random.random() <= 0.5: offspring[0].variables[i] = c2 @@ -101,14 +105,18 @@ def execute(self, parents: List[FloatSolution]) -> List[FloatSolution]: def get_number_of_parents(self): return 2 + def get_name(self): + return 'SBX crossover' + class SP(Crossover[BinarySolution, BinarySolution]): + def __init__(self, probability: float): super(SP, self).__init__(probability=probability) def execute(self, parents: List[BinarySolution]) -> List[BinarySolution]: if len(parents) != 2: - raise Exception("The number of parents is not two: " + str(len(parents))) + raise Exception('The number of parents is not two: {}'.format(len(parents))) offspring = [copy.copy(parents[0]), copy.copy(parents[1])] rand = random.random() @@ -152,3 +160,6 @@ def execute(self, parents: List[BinarySolution]) -> List[BinarySolution]: def get_number_of_parents(self): return 2 + + def get_name(self): + return 'Single point crossover' diff --git a/jmetal/operator/mutation.py b/jmetal/operator/mutation.py index cec2c8c9..513e8520 100644 --- a/jmetal/operator/mutation.py +++ b/jmetal/operator/mutation.py @@ -13,6 +13,7 @@ class NullMutation(Mutation[Solution]): + def __init__(self): super(NullMutation, self).__init__(probability=0) @@ -24,6 +25,7 @@ def get_name(self): class BitFlip(Mutation[BinarySolution]): + def __init__(self, probability: float): super(BitFlip, self).__init__(probability=probability) @@ -32,15 +34,16 @@ def execute(self, solution: BinarySolution) -> BinarySolution: for j in range(len(solution.variables[i])): rand = random.random() if rand <= self.probability: - solution.variables[i][j] = True if solution.variables[i][j] == False else False + solution.variables[i][j] = True if solution.variables[i][j] is False else False return solution def get_name(self): - return "BitFlip mutation" + return 'BitFlip mutation' class Polynomial(Mutation[FloatSolution]): + def __init__(self, probability: float, distribution_index: float = 0.20): super(Polynomial, self).__init__(probability=probability) self.distribution_index = distribution_index @@ -80,10 +83,11 @@ def execute(self, solution: FloatSolution) -> FloatSolution: return solution def get_name(self): - return "Polynomial mutation" + return 'Polynomial mutation' class IntegerPolynomial(Mutation[IntegerSolution]): + def __init__(self, probability: float, distribution_index: float = 0.20): super(IntegerPolynomial, self).__init__(probability=probability) self.distribution_index = distribution_index @@ -99,16 +103,16 @@ def execute(self, solution: IntegerSolution) -> IntegerSolution: else: delta1 = (y - yl) / (yu - yl) delta2 = (yu - y) / (yu - yl) - mutPow = 1.0 / (self.distribution_index + 1.0) + mut_pow = 1.0 / (self.distribution_index + 1.0) rnd = random.random() if rnd <= 0.5: xy = 1.0 - delta1 val = 2.0 * rnd + (1.0 - 2.0 * rnd) * (xy ** (self.distribution_index + 1.0)) - deltaq = val ** mutPow - 1.0 + deltaq = val ** mut_pow - 1.0 else: xy = 1.0 - delta2 val = 2.0 * (1.0 - rnd) + 2.0 * (rnd - 0.5) * (xy ** (self.distribution_index + 1.0)) - deltaq = 1.0 - val ** mutPow + deltaq = 1.0 - val ** mut_pow y += deltaq * (yu - yl) if y < solution.lower_bound[i]: @@ -120,10 +124,11 @@ def execute(self, solution: IntegerSolution) -> IntegerSolution: return solution def get_name(self): - return "Polynomial mutation (Integer)" + return 'Polynomial mutation (Integer)' class SimpleRandom(Mutation[FloatSolution]): + def __init__(self, probability: float): super(SimpleRandom, self).__init__(probability=probability) @@ -136,10 +141,11 @@ def execute(self, solution: FloatSolution) -> FloatSolution: return solution def get_name(self): - return "Simple random mutation" + return 'Simple random mutation' class Uniform(Mutation[FloatSolution]): + def __init__(self, probability: float, perturbation: float = 0.5): super(Uniform, self).__init__(probability=probability) self.perturbation = perturbation @@ -162,4 +168,4 @@ def execute(self, solution: FloatSolution) -> FloatSolution: return solution def get_name(self): - return "Uniform mutation" + return 'Uniform mutation' diff --git a/jmetal/operator/selection.py b/jmetal/operator/selection.py index cc9b9560..3c87a74a 100644 --- a/jmetal/operator/selection.py +++ b/jmetal/operator/selection.py @@ -18,22 +18,24 @@ class BinaryTournamentSelection(Selection[List[S], S]): + def __init__(self, comparator: Comparator = DominanceComparator()): super(BinaryTournamentSelection, self).__init__() self.comparator = comparator - def execute(self, solution_list: List[S]) -> S: - if solution_list is None: - raise Exception("The solution list is null") - elif len(solution_list) == 0: - raise Exception("The solution is empty") + def execute(self, front: List[S]) -> S: + if front is None: + raise Exception('The front is null') + elif len(front) == 0: + raise Exception('The front is empty') - if len(solution_list) == 1: - result = solution_list[0] + if len(front) == 1: + result = front[0] else: - i, j = random.sample(range(0, len(solution_list)), 2) # sampling without replacement - solution1 = solution_list[i] - solution2 = solution_list[j] + # Sampling without replacement + i, j = random.sample(range(0, len(front)), 2) + solution1 = front[i] + solution2 = front[j] flag = self.comparator.compare(solution1, solution2) @@ -47,7 +49,7 @@ def execute(self, solution_list: List[S]) -> S: return result def get_name(self) -> str: - return "Binary tournament selection" + return 'Binary tournament selection' class BestSolutionSelection(Selection[List[S], S]): @@ -55,14 +57,14 @@ class BestSolutionSelection(Selection[List[S], S]): def __init__(self): super(BestSolutionSelection, self).__init__() - def execute(self, solution_list: List[S]) -> S: - if solution_list is None: - raise Exception("The solution list is null") - elif len(solution_list) == 0: - raise Exception("The solution is empty") + def execute(self, front: List[S]) -> S: + if front is None: + raise Exception('The front is null') + elif len(front) == 0: + raise Exception('The front is empty') - result = solution_list[0] - for solution in solution_list[1:]: + result = front[0] + for solution in front[1:]: if DominanceComparator().compare(solution, result) < 0: result = solution @@ -74,20 +76,20 @@ class NaryRandomSolutionSelection(Selection[List[S], S]): def __init__(self, number_of_solutions_to_be_returned:int = 1): super(NaryRandomSolutionSelection, self).__init__() if number_of_solutions_to_be_returned < 0: - raise Exception("The number of solutions to be returned must be positive integer") + raise Exception('The number of solutions to be returned must be positive integer') self.number_of_solutions_to_be_returned = number_of_solutions_to_be_returned - def execute(self, solution_list: List[S]) -> S: - if solution_list is None: - raise Exception("The solution list is null") - if len(solution_list) == 0: - raise Exception("The solution is empty") - if len(solution_list) < self.number_of_solutions_to_be_returned: - raise Exception("The solution list contains less elements then requred") + def execute(self, front: List[S]) -> S: + if front is None: + raise Exception('The front is null') + if len(front) == 0: + raise Exception('The front is empty') + if len(front) < self.number_of_solutions_to_be_returned: + raise Exception('The front contains less elements than required') # random sampling without replacement - return random.sample(solution_list, self.number_of_solutions_to_be_returned) + return random.sample(front, self.number_of_solutions_to_be_returned) class RandomSolutionSelection(Selection[List[S], S]): @@ -95,13 +97,13 @@ class RandomSolutionSelection(Selection[List[S], S]): def __init__(self): super(RandomSolutionSelection, self).__init__() - def execute(self, solution_list: List[S]) -> S: - if solution_list is None: - raise Exception("The solution list is null") - elif len(solution_list) == 0: - raise Exception("The solution is empty") + def execute(self, front: List[S]) -> S: + if front is None: + raise Exception('The front is null') + elif len(front) == 0: + raise Exception('The front is empty') - return random.choice(solution_list) + return random.choice(front) class RankingAndCrowdingDistanceSelection(Selection[List[S], List[S]]): @@ -110,10 +112,10 @@ def __init__(self, max_population_size: int): super(RankingAndCrowdingDistanceSelection, self).__init__() self.max_population_size = max_population_size - def execute(self, solution_list: List[S]) -> List[S]: + def execute(self, front: List[S]) -> List[S]: ranking = FastNonDominatedRanking() crowding_distance = CrowdingDistance() - ranking.compute_ranking(solution_list) + ranking.compute_ranking(front) ranking_index = 0 new_solution_list = [] @@ -125,7 +127,7 @@ def execute(self, solution_list: List[S]) -> List[S]: else: subfront = ranking.get_subfront(ranking_index) crowding_distance.compute_density_estimator(subfront) - sorted_subfront = sorted(subfront, key=lambda x: x.attributes["crowding_distance"], reverse=True) + sorted_subfront = sorted(subfront, key=lambda x: x.attributes['crowding_distance'], reverse=True) for i in range((self.max_population_size - len(new_solution_list))): new_solution_list.append(sorted_subfront[i]) @@ -138,34 +140,36 @@ def __init__(self, comparator_list: List[Comparator]): super(BinaryTournament2Selection, self).__init__() self.comparator_list = comparator_list - def execute(self, solution_list: List[S]) -> S: - if solution_list is None: - raise Exception("The solution list is null") - elif len(solution_list) == 0: - raise Exception("The solution is empty") + def execute(self, front: List[S]) -> S: + if front is None: + raise Exception('The front is null') + elif len(front) == 0: + raise Exception('The front is empty') elif not self.comparator_list: - raise Exception("The list of comparators is empty") + raise Exception('The comparators\' list is empty') winner = None - if len(solution_list) == 1: - winner = solution_list[0] + if len(front) == 1: + winner = front[0] else: for comparator in self.comparator_list: - winner = self.__winner(solution_list, comparator) + winner = self.__winner(front, comparator) if winner is not None: break if not winner: - i = random.randrange(0, len(solution_list)) - winner = solution_list[i] + i = random.randrange(0, len(front)) + winner = front[i] return winner - def __winner(self, solution_list: List[S], comparator: Comparator): - i, j = random.sample(range(0, len(solution_list)), 2) # sampling without replacement - solution1 = solution_list[i] - solution2 = solution_list[j] + def __winner(self, front: List[S], comparator: Comparator): + # Sampling without replacement + i, j = random.sample(range(0, len(front)), 2) + + solution1 = front[i] + solution2 = front[j] flag = comparator.compare(solution1, solution2) @@ -179,4 +183,4 @@ def __winner(self, solution_list: List[S], comparator: Comparator): return result def get_name(self): - return "Binary tournament selection (experimental)" + return 'Binary tournament selection (experimental)' diff --git a/jmetal/problem/resources/DTLZ1.pf b/jmetal/problem/front/DTLZ1.pf similarity index 100% rename from jmetal/problem/resources/DTLZ1.pf rename to jmetal/problem/front/DTLZ1.pf diff --git a/jmetal/problem/resources/ZDT1.pf b/jmetal/problem/front/ZDT1.pf similarity index 100% rename from jmetal/problem/resources/ZDT1.pf rename to jmetal/problem/front/ZDT1.pf diff --git a/jmetal/problem/resources/ZDT2.pf b/jmetal/problem/front/ZDT2.pf similarity index 100% rename from jmetal/problem/resources/ZDT2.pf rename to jmetal/problem/front/ZDT2.pf diff --git a/jmetal/problem/resources/ZDT3.pf b/jmetal/problem/front/ZDT3.pf similarity index 100% rename from jmetal/problem/resources/ZDT3.pf rename to jmetal/problem/front/ZDT3.pf diff --git a/jmetal/problem/resources/ZDT4.pf b/jmetal/problem/front/ZDT4.pf similarity index 100% rename from jmetal/problem/resources/ZDT4.pf rename to jmetal/problem/front/ZDT4.pf diff --git a/jmetal/problem/resources/ZDT6.pf b/jmetal/problem/front/ZDT6.pf similarity index 100% rename from jmetal/problem/resources/ZDT6.pf rename to jmetal/problem/front/ZDT6.pf diff --git a/jmetal/problem/multiobjective/dtlz.py b/jmetal/problem/multiobjective/dtlz.py index b0469320..89b4dd44 100644 --- a/jmetal/problem/multiobjective/dtlz.py +++ b/jmetal/problem/multiobjective/dtlz.py @@ -26,6 +26,8 @@ def __init__(self, number_of_variables: int = 7, number_of_objectives=3): self.number_of_objectives = number_of_objectives self.number_of_constraints = 0 + self.obj_directions = [self.MINIMIZE] * number_of_objectives + self.lower_bound = self.number_of_variables * [0.0] self.upper_bound = self.number_of_variables * [1.0] @@ -50,7 +52,7 @@ def evaluate(self, solution: FloatSolution): solution.objectives[i] *= 1 - solution.variables[self.number_of_objectives - (i + 1)] def get_name(self): - return "DTLZ1" + return 'DTLZ1' class DTLZ2(FloatProblem): @@ -67,6 +69,8 @@ def __init__(self, number_of_variables: int = 12, number_of_objectives=3): self.number_of_objectives = number_of_objectives self.number_of_constraints = 0 + self.obj_directions = [self.MINIMIZE] * number_of_objectives + self.lower_bound = self.number_of_variables * [0.0] self.upper_bound = self.number_of_variables * [1.0] @@ -88,4 +92,4 @@ def evaluate(self, solution: FloatSolution): solution.objectives[i] *= sin(0.5 * pi * solution.variables[self.number_of_objectives - (i + 1)]) def get_name(self): - return "DTLZ2" + return 'DTLZ2' diff --git a/jmetal/problem/multiobjective/unconstrained.py b/jmetal/problem/multiobjective/unconstrained.py index 6169d815..68581e7f 100644 --- a/jmetal/problem/multiobjective/unconstrained.py +++ b/jmetal/problem/multiobjective/unconstrained.py @@ -21,6 +21,8 @@ def __init__(self, number_of_variables: int = 3): self.number_of_variables = number_of_variables self.number_of_constraints = 0 + self.obj_directions = [self.MINIMIZE, self.MINIMIZE] + self.lower_bound = [-5.0 for _ in range(number_of_variables)] self.upper_bound = [5.0 for _ in range(number_of_variables)] @@ -40,7 +42,7 @@ def evaluate(self, solution: FloatSolution): solution.objectives[1] = fx[1] def get_name(self): - return "Kursawe" + return 'Kursawe' class Fonseca(FloatProblem): @@ -51,6 +53,8 @@ def __init__(self): self.number_of_objectives = 2 self.number_of_constraints = 0 + self.obj_directions = [self.MINIMIZE, self.MINIMIZE] + self.lower_bound = self.number_of_variables * [-4] self.upper_bound = self.number_of_variables * [ 4] @@ -63,7 +67,7 @@ def evaluate(self, solution: FloatSolution): solution.objectives[1] = 1 - exp(-sum([(x + 1.0 / n ** 0.5) ** 2 for x in solution.variables])) def get_name(self): - return "Fonseca" + return 'Fonseca' class Schaffer(FloatProblem): @@ -74,6 +78,8 @@ def __init__(self): self.number_of_objectives = 2 self.number_of_constraints = 0 + self.obj_directions = [self.MINIMIZE, self.MINIMIZE] + self.lower_bound = [-100000] self.upper_bound = [100000] @@ -87,7 +93,7 @@ def evaluate(self, solution: FloatSolution): solution.objectives[1] = (value - 2) ** 2 def get_name(self): - return "Schaffer" + return 'Schaffer' class Viennet2(FloatProblem): @@ -98,6 +104,8 @@ def __init__(self): self.number_of_objectives = 3 self.number_of_constraints = 0 + self.obj_directions = [self.MINIMIZE, self.MINIMIZE, self.MINIMIZE] + self.lower_bound = self.number_of_variables * [-4] self.upper_bound = self.number_of_variables * [4] @@ -117,4 +125,4 @@ def evaluate(self, solution: FloatSolution): solution.objectives[2] = f3 def get_name(self): - return "Viennet2" + return 'Viennet2' diff --git a/jmetal/problem/multiobjective/zdt.py b/jmetal/problem/multiobjective/zdt.py index e591678f..2dbf7622 100644 --- a/jmetal/problem/multiobjective/zdt.py +++ b/jmetal/problem/multiobjective/zdt.py @@ -20,13 +20,16 @@ class ZDT1(FloatProblem): """ def __init__(self, number_of_variables: int = 30): - """ :param number_of_variables: Number of decision variables of the problem. + """ + :param number_of_variables: Number of decision variables of the problem. """ super().__init__() self.number_of_variables = number_of_variables self.number_of_objectives = 2 self.number_of_constraints = 0 + self.obj_directions = [self.MINIMIZE, self.MINIMIZE] + self.lower_bound = self.number_of_variables * [0.0] self.upper_bound = self.number_of_variables * [1.0] @@ -52,7 +55,7 @@ def __eval_h(self, f: float, g: float) -> float: return 1.0 - sqrt(f / g) def get_name(self): - return "ZDT1" + return 'ZDT1' class ZDT2(FloatProblem): @@ -68,6 +71,8 @@ def __init__(self, number_of_variables: int = 30): self.number_of_objectives = 2 self.number_of_constraints = 0 + self.obj_directions = [self.MINIMIZE, self.MINIMIZE] + self.lower_bound = self.number_of_variables * [0.0] self.upper_bound = self.number_of_variables * [1.0] @@ -93,7 +98,7 @@ def __eval_h(self, f: float, g: float) -> float: return 1.0 - pow(f / g, 2.0) def get_name(self): - return "ZDT2" + return 'ZDT2' class ZDT3(FloatProblem): @@ -109,6 +114,8 @@ def __init__(self, number_of_variables: int = 30): self.number_of_objectives = 2 self.number_of_constraints = 0 + self.obj_directions = [self.MINIMIZE, self.MINIMIZE] + self.lower_bound = self.number_of_variables * [0.0] self.upper_bound = self.number_of_variables * [1.0] @@ -134,7 +141,7 @@ def __eval_h(self, f: float, g: float) -> float: return 1.0 - sqrt(f / g) - (f / g) * sin(10.0 * f * pi) def get_name(self): - return "ZDT3" + return 'ZDT3' class ZDT4(FloatProblem): @@ -150,6 +157,8 @@ def __init__(self, number_of_variables: int = 10): self.number_of_objectives = 2 self.number_of_constraints = 0 + self.obj_directions = [self.MINIMIZE, self.MINIMIZE] + self.lower_bound = self.number_of_variables * [-5.0] self.upper_bound = self.number_of_variables * [5.0] self.lower_bound[0] = 0.0 @@ -179,7 +188,7 @@ def __eval_h(self, f: float, g: float) -> float: return 1.0 - sqrt(f / g) def get_name(self): - return "ZDT4" + return 'ZDT4' class ZDT6(FloatProblem): @@ -195,6 +204,8 @@ def __init__(self, number_of_variables: int = 10): self.number_of_objectives = 2 self.number_of_constraints = 0 + self.obj_directions = [self.MINIMIZE, self.MINIMIZE] + self.lower_bound = self.number_of_variables * [0.0] self.upper_bound = self.number_of_variables * [1.0] @@ -221,4 +232,4 @@ def __eval_h(self, f: float, g: float) -> float: return 1.0 - pow(f / g, 2.0) def get_name(self): - return "ZDT6" + return 'ZDT6' diff --git a/jmetal/problem/singleobjective/unconstrained.py b/jmetal/problem/singleobjective/unconstrained.py index 14769284..56a66c11 100644 --- a/jmetal/problem/singleobjective/unconstrained.py +++ b/jmetal/problem/singleobjective/unconstrained.py @@ -37,7 +37,7 @@ def create_solution(self) -> BinarySolution: return new_solution def get_name(self) -> str: - return "OneMax" + return 'OneMax' class Sphere(FloatProblem): @@ -61,4 +61,4 @@ def evaluate(self, solution: FloatSolution): solution.objectives[0] = total def get_name(self) -> str: - return "Sphere" + return 'Sphere' diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index d5eb5a87..91ab0642 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -16,7 +16,7 @@ warnings.filterwarnings("ignore", ".*GUI is implemented.*") -logger = logging.getLogger(__name__) +jMetalPyLogger = logging.getLogger('jMetalPy') S = TypeVar('S') """ @@ -39,11 +39,11 @@ def __init__(self, plot_title: str, number_of_objectives: int, self.yaxis_label = yaxis_label self.zaxis_label = zaxis_label - def get_objectives(self, solution_list: List[S]) -> Tuple[list, list, list]: - if solution_list is None: - raise Exception("Solution list is none!") + def get_objectives(self, front: List[S]) -> Tuple[list, list, list]: + if front is None: + raise Exception('Front is none!') - points = list(solution.objectives for solution in solution_list) + points = list(solution.objectives for solution in front) x_values, y_values = [point[0] for point in points], [point[1] for point in points] @@ -74,7 +74,7 @@ def __init__(self, plot_title: str, number_of_objectives: int): def __initialize(self) -> None: """ Initialize the scatter plot for the first time. """ - logger.info("Generating plot...") + jMetalPyLogger.info("Generating plot...") # Initialize a plot self.fig.canvas.set_window_title('jMetalPy') @@ -98,7 +98,7 @@ def __initialize(self) -> None: self.axis.grid(color='#f0f0f5', linestyle='-', linewidth=1, alpha=0.5) self.fig.suptitle(self.plot_title, fontsize=13) - logger.info("Plot initialized") + jMetalPyLogger.info("Plot initialized") def __plot(self, x_values, y_values, z_values, color: str = '#98FB98', marker: str = 'o', msize: int = 3): if self.number_of_objectives == 2: @@ -108,27 +108,27 @@ def __plot(self, x_values, y_values, z_values, color: str = '#98FB98', marker: s self.sc, = self.axis.plot(x_values, y_values, z_values, color=color, marker=marker, markersize=msize, ls='None', picker=10) - def plot(self, solution_list: List[S], reference: List[S], output: str='', show: bool=True) -> None: + def plot(self, front: List[S], reference: List[S], output: str= '', show: bool=True) -> None: if reference: - logger.info("Reference front found") + jMetalPyLogger.info('Reference front found') ref_x_values, ref_y_values, ref_z_values = self.get_objectives(reference) self.__plot(ref_x_values, ref_y_values, ref_z_values, color='#323232', marker='*') - x_values, y_values, z_values = self.get_objectives(solution_list) + x_values, y_values, z_values = self.get_objectives(front) self.__plot(x_values, y_values, z_values) if output: self.__save(output) if show: - self.fig.canvas.mpl_connect('pick_event', lambda event: self.__pick_handler(event, solution_list)) + self.fig.canvas.mpl_connect('pick_event', lambda event: self.__pick_handler(event, front)) plt.show() - def update(self, solution_list: List[S], reference: List[S], new_title: str='', persistence: bool=True) -> None: + def update(self, front: List[S], reference: List[S], new_title: str= '', persistence: bool=True) -> None: if self.sc is None: - logger.warning("Plot is none! Generating first plot...") - self.plot(solution_list, reference, show=False) + jMetalPyLogger.warning("Plot is none! Generating first plot...") + self.plot(front, reference, show=False) - x_values, y_values, z_values = self.get_objectives(solution_list) + x_values, y_values, z_values = self.get_objectives(front) if persistence: # Replace with new points @@ -142,7 +142,7 @@ def update(self, solution_list: List[S], reference: List[S], new_title: str='', # Also, add event handler event_handler = \ - self.fig.canvas.mpl_connect('pick_event', lambda event: self.__pick_handler(event, solution_list)) + self.fig.canvas.mpl_connect('pick_event', lambda event: self.__pick_handler(event, front)) # Update title with new times and evaluations self.fig.suptitle(new_title, fontsize=13) @@ -163,30 +163,30 @@ def __save(self, file_name: str, fmt: str = 'png', dpi: int = 200): "raw", "rgba", "svg", "svgz", "tif", "tiff"] if fmt not in supported_formats: - raise Exception("{0} is not a valid format! Use one of these instead: {0}".format(fmt, supported_formats)) + raise Exception('{0} is not a valid format! Use one of these instead: {0}'.format(fmt, supported_formats)) self.fig.savefig(file_name + '.' + fmt, format=fmt, dpi=dpi) def __retrieve_info(self, x_val: float, y_val: float, solution: Solution) -> None: - logger.info("Output file: " + '{0}-{1}'.format(x_val, y_val)) + jMetalPyLogger.info("Output file: " + '{0}-{1}'.format(x_val, y_val)) with open('{0}-{1}'.format(x_val, y_val), 'w') as of: of.write(solution.__str__()) - def __pick_handler(self, event, solution_list: List[S]): + def __pick_handler(self, event, front: List[S]): """ Handler for picking points from the plot. """ line, ind = event.artist, event.ind[0] x, y = line.get_xdata(), line.get_ydata() - logger.debug('Selected resources point ({0}): ({1}, {2})'.format(ind, x[ind], y[ind])) + jMetalPyLogger.debug('Selected front point ({0}): ({1}, {2})'.format(ind, x[ind], y[ind])) - sol = next((solution for solution in solution_list + sol = next((solution for solution in front if solution.objectives[0] == x[ind] and solution.objectives[1] == y[ind]), None) if sol is not None: self.__retrieve_info(x[ind], y[ind], sol) else: - logger.warning("Solution is none.") + jMetalPyLogger.warning('Solution is none') return True @@ -202,7 +202,7 @@ def __init__(self, plot_title: str, number_of_objectives: int, ws_url: str='loca else: raise Exception('Wrong number of objectives: {0}'.format(number_of_objectives)) - self.client = ClientSession(websocket_url="ws://{0}/ws".format(ws_url)) + self.client = ClientSession(websocket_url='ws://{0}/ws'.format(ws_url)) self.doc = curdoc() self.doc.title = plot_title self.figure_xy = None @@ -215,16 +215,16 @@ def __initialize(self) -> None: """ Set-up tools for plot. """ code = ''' selected = source.selected['1d']['indices'][0] - var str = source.resources.str[selected] + var str = source.front.str[selected] alert(str) ''' callback = CustomJS(args=dict(source=self.source), code=code) self.plot_tools = [TapTool(callback=callback), WheelZoomTool(), 'save', 'pan', - HoverTool(tooltips=[("index", "$index"), ("(x,y)", "($x, $y)")])] + HoverTool(tooltips=[('index', '$index'), ('(x,y)', '($x, $y)')])] - def plot(self, solution_list: List[S], reference: List[S]=None, output: str='', show: bool=True) -> None: - # This is important to purge resources (if any) between calls + def plot(self, front: List[S], reference: List[S]=None, output: str= '', show: bool=True) -> None: + # This is important to purge front (if any) between calls reset_output() # Set up figure @@ -233,7 +233,7 @@ def plot(self, solution_list: List[S], reference: List[S]=None, output: str='', self.figure_xy.xaxis.axis_label = self.xaxis_label self.figure_xy.yaxis.axis_label = self.yaxis_label - x_values, y_values, z_values = self.get_objectives(solution_list) + x_values, y_values, z_values = self.get_objectives(front) if self.number_of_objectives == 2: # Plot reference solution list (if any) @@ -241,8 +241,8 @@ def plot(self, solution_list: List[S], reference: List[S]=None, output: str='', ref_x_values, ref_y_values, _ = self.get_objectives(reference) self.figure_xy.line(x=ref_x_values, y=ref_y_values, legend='reference', color='green') - # Push resources to server - self.source.stream({'x': x_values, 'y': y_values, 'str': [s.__str__() for s in solution_list]}) + # Push front to server + self.source.stream({'x': x_values, 'y': y_values, 'str': [s.__str__() for s in front]}) self.doc.add_root(column(self.figure_xy)) else: # Add new figures for each axis @@ -263,8 +263,8 @@ def plot(self, solution_list: List[S], reference: List[S]=None, output: str='', self.figure_xz.line(x=ref_x_values, y=ref_z_values, legend='reference', color='green') self.figure_yz.line(x=ref_y_values, y=ref_z_values, legend='reference', color='green') - # Push resources to server - self.source.stream({'x': x_values, 'y': y_values, 'z': z_values, 'str': [s.__str__() for s in solution_list]}) + # Push front to server + self.source.stream({'x': x_values, 'y': y_values, 'z': z_values, 'str': [s.__str__() for s in front]}) self.doc.add_root(row(self.figure_xy, self.figure_xz, self.figure_yz)) self.client.push(self.doc) @@ -274,24 +274,24 @@ def plot(self, solution_list: List[S], reference: List[S]=None, output: str='', if show: self.client.show() - def update(self, solution_list: List[S], reference: List[S], new_title: str='', persistence: bool=False) -> None: + def update(self, front: List[S], reference: List[S], new_title: str= '', persistence: bool=False) -> None: # Check if plot has not been initialized first if self.figure_xy is None: - self.plot(solution_list, reference) + self.plot(front, reference) if not persistence: - rollover = len(solution_list) + rollover = len(front) else: rollover = None self.figure_xy.title.text = new_title - x_values, y_values, z_values = self.get_objectives(solution_list) + x_values, y_values, z_values = self.get_objectives(front) if self.number_of_objectives == 2: - self.source.stream({'x': x_values, 'y': y_values, 'str': [s.__str__() for s in solution_list]}, + self.source.stream({'x': x_values, 'y': y_values, 'str': [s.__str__() for s in front]}, rollover=rollover) else: - self.source.stream({'x': x_values, 'y': y_values, 'z': z_values, 'str': [s.__str__() for s in solution_list]}, + self.source.stream({'x': x_values, 'y': y_values, 'z': z_values, 'str': [s.__str__() for s in front]}, rollover=rollover) def __save(self, file_name: str): diff --git a/sonar-project.properties b/sonar-project.properties deleted file mode 100644 index f41b87cc..00000000 --- a/sonar-project.properties +++ /dev/null @@ -1,9 +0,0 @@ -# Required metadata -sonar.projectKey=jmetalpy -sonar.projectName=jmetalpy -sonar.projectVersion=1.0.0 -sonar.language=py -sonar.sources=jmetal/ -sonar.binaries=dist/ -sonar.projectBaseDir=./jMetalPy/ -sonar.python.coverage.reportPath=coverage.xml \ No newline at end of file From fadb0707713411d65149d75cbc670c6aa2dc03c5 Mon Sep 17 00:00:00 2001 From: benhid Date: Tue, 10 Jul 2018 14:01:01 +0200 Subject: [PATCH 80/90] WIP experiments --- docs/source/conf.py | 2 +- examples/experiment/NSGAII-SMPSO for ZDT1.py | 21 +++++++ examples/experiment/__init__.py | 0 jmetal/util/laboratory.py | 60 ++++++++++++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 examples/experiment/NSGAII-SMPSO for ZDT1.py create mode 100644 examples/experiment/__init__.py diff --git a/docs/source/conf.py b/docs/source/conf.py index 40cf677f..a5e2a9c3 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -19,7 +19,7 @@ # http://blog.rtwilson.com/how-to-make-your-sphinx-documentation-compile-with-readthedocs-when-youre-using-numpy-and-scipy/ import mock -MOCK_MODULES = ['numpy', 'dask', 'dask.distributed', 'tqdm', 'bokeh', 'bokeh.embed', 'bokeh.resources', 'bokeh.client', +MOCK_MODULES = ['numpy', 'dask', 'dask.distributed', 'tqdm', 'bokeh', 'bokeh.embed', 'bokeh.front', 'bokeh.client', 'bokeh.io', 'bokeh.layouts','bokeh.models','bokeh.plotting', 'mpl_toolkits', 'mpl_toolkits.mplot3d', 'matplotlib', 'matplotlib.pyplot', 'matplotlib.axes'] for mod_name in MOCK_MODULES: diff --git a/examples/experiment/NSGAII-SMPSO for ZDT1.py b/examples/experiment/NSGAII-SMPSO for ZDT1.py new file mode 100644 index 00000000..17697176 --- /dev/null +++ b/examples/experiment/NSGAII-SMPSO for ZDT1.py @@ -0,0 +1,21 @@ +from jmetal.algorithm import NSGAII, SMPSO +from jmetal.component.archive import CrowdingDistanceArchive +from jmetal.component.comparator import RankingAndCrowdingDistanceComparator +from jmetal.operator import NullMutation, SBX, BinaryTournamentSelection +from jmetal.problem import ZDT1, ZDT2 +from jmetal.component.quality_indicator import HyperVolume +from jmetal.util.laboratory import experiment, display + +algorithm = [ + (NSGAII, {'population_size': 100, 'max_evaluations': 25000, 'mutation': NullMutation(), 'crossover': SBX(1.0, 20), + 'selection': BinaryTournamentSelection(RankingAndCrowdingDistanceComparator())}), + (NSGAII(population_size=100, max_evaluations=25000, mutation=NullMutation(), crossover=SBX(1.0, 20), + selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator()), problem=ZDT1()), {}), + (SMPSO, {'swarm_size': 100, 'max_evaluations': 25000, 'mutation': NullMutation(), + 'leaders': CrowdingDistanceArchive(100)}) +] +metric = [HyperVolume(reference_point=[1, 1])] +problem = [(ZDT1, {}), (ZDT2, {})] + +results = experiment(algorithm, metric, problem) +display(results) \ No newline at end of file diff --git a/examples/experiment/__init__.py b/examples/experiment/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/jmetal/util/laboratory.py b/jmetal/util/laboratory.py index e69de29b..29dc3abf 100644 --- a/jmetal/util/laboratory.py +++ b/jmetal/util/laboratory.py @@ -0,0 +1,60 @@ +import logging +from concurrent.futures import ProcessPoolExecutor + +jMetalPyLogger = logging.getLogger('jMetalPy') + +""" +.. module:: laboratory + :platform: Unix, Windows + :synopsis: Run experiments. + +.. moduleauthor:: Antonio Benítez-Hidalgo +""" + + +def experiment(algorithm_list: list, metric_list: list, problem_list: list, g_params: dict=None, m_workers: int=3): + """ :param algorithm_list: List of algorithms as Tuple(Algorithm, dic() with parameters). + :param metric_list: List of metrics. + :param problem_list: List of problems as Tuple(Problem, dic() with parameters). + :param g_params: Global parameters (will override those from algorithm_list). + :param m_workers: Maximum number of workers for ProcessPoolExecutor. + :return: Stats. + """ + + with ProcessPoolExecutor(max_workers=m_workers) as pool: + result = dict() + + for p_index, (problem, problem_params) in enumerate(problem_list): + if isinstance(problem, type): + jMetalPyLogger.debug('Problem is not instantiated by default') + problem = problem(**problem_params) + + for a_index, (algorithm, algorithm_params) in enumerate(algorithm_list): + if isinstance(algorithm, type): + jMetalPyLogger.debug('Algorithm {} is not instantiated by default'.format(algorithm)) + algorithm_list[a_index] = (algorithm(problem=problem, **algorithm_params), {}) + + jMetalPyLogger.info('Running experiment: problem {0}, algorithm {1}'.format(problem, algorithm)) + + pool.submit(algorithm_list[a_index][0].run()) + + jMetalPyLogger.debug('Waiting') + + # Wait until all computation is done for this problem + pool.shutdown(wait=True) + + for algorithm, _ in algorithm_list: + front = algorithm.get_result() + result[algorithm.get_name()] = {'front': front, + 'problem': algorithm.problem.get_name(), + 'time': algorithm.total_computing_time} + + for metric in metric_list: + result[algorithm.get_name()].setdefault('metric', dict()).update({metric.get_name(): metric.compute(front)}) + + return result + + +def display(table: dict): + for k, v in table.items(): + print('{0}: {1}'.format(k, v['metric'])) From 891335f1370247c8187abc97a3c8ca5d8beed936 Mon Sep 17 00:00:00 2001 From: benhid Date: Wed, 11 Jul 2018 14:17:20 +0200 Subject: [PATCH 81/90] Code inspection --- .../multiobjective/nsgaii_full_settings.py | 2 +- .../multiobjective/smpso_full_settings.py | 2 +- .../smpsorp_standard_settings.py | 2 +- jmetal/__init__.py | 2 +- jmetal/algorithm/__init__.py | 8 +- jmetal/algorithm/multiobjective/nsgaii.py | 4 +- .../algorithm/multiobjective/randomSearch.py | 5 +- jmetal/algorithm/multiobjective/smpso.py | 26 +++--- .../algorithm/multiobjective/test/__init__.py | 0 .../multiobjective/test/test_smpo.py | 54 ----------- .../singleobjective/evolutionaryalgorithm.py | 6 +- jmetal/component/archive.py | 45 ++++----- jmetal/component/comparator.py | 13 ++- jmetal/component/density_estimator.py | 4 + jmetal/component/evaluator.py | 7 ++ jmetal/component/observer.py | 6 +- jmetal/component/quality_indicator.py | 13 ++- jmetal/component/ranking.py | 39 ++++---- jmetal/component/test/test_archive.py | 92 ++++++++++--------- jmetal/component/test/test_comparator.py | 10 +- .../component/test/test_density_estimator.py | 2 +- jmetal/component/test/test_evaluator.py | 2 +- .../component/test/test_quality_indicator.py | 6 +- jmetal/core/algorithm.py | 57 +++++++++--- jmetal/core/observable.py | 10 +- jmetal/core/operator.py | 33 ++++++- jmetal/core/problem.py | 67 ++++++++++---- jmetal/core/solution.py | 6 +- jmetal/core/test/test_problem.py | 38 ++++---- jmetal/operator/__init__.py | 10 +- jmetal/operator/mutation.py | 4 +- jmetal/operator/selection.py | 16 +++- jmetal/operator/test/test_mutation.py | 2 +- jmetal/operator/test/test_selection.py | 4 +- jmetal/problem/__init__.py | 12 ++- jmetal/problem/multiobjective/constrained.py | 24 +++-- jmetal/problem/multiobjective/dtlz.py | 12 ++- .../multiobjective/test/test_unconstrained.py | 8 +- .../problem/multiobjective/unconstrained.py | 26 ++++-- jmetal/problem/multiobjective/zdt.py | 32 +++++-- .../{front => reference_front}/DTLZ1.pf | 0 .../{front => reference_front}/ZDT1.pf | 0 .../{front => reference_front}/ZDT2.pf | 0 .../{front => reference_front}/ZDT3.pf | 0 .../{front => reference_front}/ZDT4.pf | 0 .../{front => reference_front}/ZDT6.pf | 0 .../test/test_unconstrained.py | 2 +- .../problem/singleobjective/unconstrained.py | 14 ++- jmetal/util/front_file.py | 4 +- jmetal/util/graphic.py | 18 +++- 50 files changed, 432 insertions(+), 317 deletions(-) delete mode 100644 jmetal/algorithm/multiobjective/test/__init__.py delete mode 100644 jmetal/algorithm/multiobjective/test/test_smpo.py rename jmetal/problem/{front => reference_front}/DTLZ1.pf (100%) rename jmetal/problem/{front => reference_front}/ZDT1.pf (100%) rename jmetal/problem/{front => reference_front}/ZDT2.pf (100%) rename jmetal/problem/{front => reference_front}/ZDT3.pf (100%) rename jmetal/problem/{front => reference_front}/ZDT4.pf (100%) rename jmetal/problem/{front => reference_front}/ZDT6.pf (100%) diff --git a/examples/multiobjective/nsgaii_full_settings.py b/examples/multiobjective/nsgaii_full_settings.py index b5ad9812..97e6cc99 100644 --- a/examples/multiobjective/nsgaii_full_settings.py +++ b/examples/multiobjective/nsgaii_full_settings.py @@ -20,7 +20,7 @@ ) visualizer = VisualizerObserver(problem) - progress_bar = ProgressBarObserver(step=100, max=25000) + progress_bar = ProgressBarObserver(step=100, maximum=25000) algorithm.observable.register(observer=visualizer) algorithm.observable.register(observer=progress_bar) diff --git a/examples/multiobjective/smpso_full_settings.py b/examples/multiobjective/smpso_full_settings.py index 75590f9a..6626d0e8 100644 --- a/examples/multiobjective/smpso_full_settings.py +++ b/examples/multiobjective/smpso_full_settings.py @@ -19,7 +19,7 @@ ) observer = VisualizerObserver(problem) - progress_bar = ProgressBarObserver(step=100, max=25000) + progress_bar = ProgressBarObserver(step=100, maximum=25000) algorithm.observable.register(observer=observer) algorithm.observable.register(observer=progress_bar) diff --git a/examples/multiobjective/smpsorp_standard_settings.py b/examples/multiobjective/smpsorp_standard_settings.py index 4db454ca..8d485365 100644 --- a/examples/multiobjective/smpsorp_standard_settings.py +++ b/examples/multiobjective/smpsorp_standard_settings.py @@ -26,7 +26,7 @@ leaders=archives_with_reference_points ) - progress_bar = ProgressBarObserver(step=swarm_size, max=25000) + progress_bar = ProgressBarObserver(step=swarm_size, maximum=25000) algorithm.observable.register(progress_bar) algorithm.run() diff --git a/jmetal/__init__.py b/jmetal/__init__.py index df1d671d..12d3f66d 100644 --- a/jmetal/__init__.py +++ b/jmetal/__init__.py @@ -22,4 +22,4 @@ # add the handlers to the logger logger.addHandler(file_handler) -logger.addHandler(stream_handler) \ No newline at end of file +logger.addHandler(stream_handler) diff --git a/jmetal/algorithm/__init__.py b/jmetal/algorithm/__init__.py index 197a2912..33004dae 100644 --- a/jmetal/algorithm/__init__.py +++ b/jmetal/algorithm/__init__.py @@ -2,6 +2,8 @@ from .multiobjective.smpso import SMPSO, SMPSORP from .singleobjective.evolutionaryalgorithm import ElitistEvolutionStrategy, NonElitistEvolutionStrategy -__all__ = ['NSGAII', - 'SMPSO', 'SMPSORP', - 'ElitistEvolutionStrategy', 'NonElitistEvolutionStrategy'] \ No newline at end of file +__all__ = [ + 'NSGAII', + 'SMPSO', 'SMPSORP', + 'ElitistEvolutionStrategy', 'NonElitistEvolutionStrategy' +] \ No newline at end of file diff --git a/jmetal/algorithm/multiobjective/nsgaii.py b/jmetal/algorithm/multiobjective/nsgaii.py index 9420af5e..5f8d99cc 100644 --- a/jmetal/algorithm/multiobjective/nsgaii.py +++ b/jmetal/algorithm/multiobjective/nsgaii.py @@ -55,7 +55,7 @@ def __init__(self, selection, evaluator) - def replacement(self, population: List[S], offspring_population: List[S]) -> List[List[TypeVar('S')]]: + def replacement(self, population: List[S], offspring_population: List[S]) -> List[List[S]]: """ This method joins the current and offspring populations to produce the population of the next generation by applying the ranking and crowding distance selection. @@ -70,4 +70,4 @@ def get_result(self) -> R: return self.population def get_name(self) -> str: - return 'NSGA-II' + return 'Non-dominated Sorting Genetic Algorithm II' diff --git a/jmetal/algorithm/multiobjective/randomSearch.py b/jmetal/algorithm/multiobjective/randomSearch.py index e66e5302..13fa5573 100644 --- a/jmetal/algorithm/multiobjective/randomSearch.py +++ b/jmetal/algorithm/multiobjective/randomSearch.py @@ -30,7 +30,8 @@ def run(self) -> None: self.archive.add(new_solution) def get_result(self) -> List[S]: - return self.archive.get_solution_list() + return self.archive.solution_list - def get_name(self) -> str: + @staticmethod + def get_name() -> str: return 'Random Search Algorithm' diff --git a/jmetal/algorithm/multiobjective/smpso.py b/jmetal/algorithm/multiobjective/smpso.py index 8e37eb4c..1401eef2 100644 --- a/jmetal/algorithm/multiobjective/smpso.py +++ b/jmetal/algorithm/multiobjective/smpso.py @@ -48,7 +48,7 @@ def __init__(self, :param leaders: Archive for leaders. :param evaluator: An evaluator object to evaluate the solutions in the population. """ - super().__init__() + super(SMPSO, self).__init__() self.problem = problem self.swarm_size = swarm_size self.max_evaluations = max_evaluations @@ -75,7 +75,7 @@ def __init__(self, self.dominance_comparator = DominanceComparator() self.speed = numpy.zeros((self.swarm_size, self.problem.number_of_variables), dtype=float) - self.delta_max, self.delta_min = numpy.empty(problem.number_of_variables), \ + self.delta_max, self.delta_min = numpy.empty(problem.number_of_variables),\ numpy.empty(problem.number_of_variables) for i in range(problem.number_of_variables): self.delta_max[i] = (self.problem.upper_bound[i] - self.problem.lower_bound[i]) / 2.0 @@ -183,7 +183,7 @@ def select_global_best(self) -> FloatSolution: if len(leaders) > 2: particles = random.sample(leaders, 2) - if self.leaders.get_comparator().compare(particles[0], particles[1]) < 1: + if self.leaders.comparator.compare(particles[0], particles[1]) < 1: best_global = copy(particles[0]) else: best_global = copy(particles[1]) @@ -221,7 +221,7 @@ def __init__(self, swarm_size: int, max_evaluations: int, mutation: Mutation[FloatSolution], - reference_points: List[List], + reference_points: List[List[float]], leaders: List[BoundedArchive[FloatSolution]], evaluator: Evaluator[FloatSolution] = SequentialEvaluator[FloatSolution]()): """ This class implements the SMPSORP algorithm. @@ -233,13 +233,13 @@ def __init__(self, :param leaders: List of bounded archives. :param evaluator: An evaluator object to evaluate the solutions in the population. """ - super().__init__( - problem, - swarm_size, - max_evaluations, - mutation, - None, - evaluator) + super(SMPSORP, self).__init__( + problem=problem, + swarm_size=swarm_size, + max_evaluations=max_evaluations, + mutation=mutation, + leaders=None, + evaluator=evaluator) self.reference_points = reference_points self.leaders = leaders @@ -281,7 +281,7 @@ def get_result(self) -> List[FloatSolution]: result = [] for leader in self.leaders: - for solution in leader.get_solution_list(): + for solution in leader.solution_list: result.append(solution) return result @@ -300,7 +300,7 @@ def select_global_best(self) -> FloatSolution: if len(leaders) > 2: particles = random.sample(leaders, 2) - if self.leaders[selected_swarm_index].get_comparator().compare(particles[0], particles[1]) < 1: + if self.leaders[selected_swarm_index].comparator.compare(particles[0], particles[1]) < 1: best_global = copy(particles[0]) else: best_global = copy(particles[1]) diff --git a/jmetal/algorithm/multiobjective/test/__init__.py b/jmetal/algorithm/multiobjective/test/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/jmetal/algorithm/multiobjective/test/test_smpo.py b/jmetal/algorithm/multiobjective/test/test_smpo.py deleted file mode 100644 index d7583835..00000000 --- a/jmetal/algorithm/multiobjective/test/test_smpo.py +++ /dev/null @@ -1,54 +0,0 @@ -import unittest - -import numpy - -from jmetal.algorithm.multiobjective.smpso import SMPSO -from jmetal.component.archive import BoundedArchive -from jmetal.core.problem import Problem -from jmetal.core.solution import FloatSolution -from jmetal.operator.mutation import Polynomial - - -class SMPSOTestCases(unittest.TestCase): - - def test_should_constructor_create_a_valid_object(self): - problem = self.__DummyFloatProblem() - algorithm = SMPSO( - problem=problem, - swarm_size=100, - max_evaluations=200, - mutation=Polynomial(probability=1.0/problem.number_of_variables), - leaders=BoundedArchive[FloatSolution](100) - ) - - self.assertEqual(1.5, algorithm.c1_min) - self.assertEqual(2.5, algorithm.c1_max) - self.assertEqual(1.5, algorithm.c2_min) - self.assertEqual(2.5, algorithm.c2_max) - self.assertEqual(0.1, algorithm.min_weight) - self.assertEqual(0.1, algorithm.max_weight) - self.assertEqual(-1.0, algorithm.change_velocity1) - self.assertEqual(-1.0, algorithm.change_velocity2) - self.assertEqual(200, algorithm.max_evaluations) - self.assertEqual((100, 2), algorithm.speed.shape) - - numpy.testing.assert_array_almost_equal(numpy.array([2.0, 2.0]), algorithm.delta_max) - numpy.testing.assert_array_almost_equal(algorithm.delta_max * -1.0, algorithm.delta_min) - - class __DummyFloatProblem(Problem[FloatSolution]): - def __init__(self): - super().__init__() - self.number_of_variables = 2 - self.number_of_objectives = 2 - self.number_of_constraints = 0 - - self.lower_bound = [-2.0 for _ in range(self.number_of_variables)] - self.upper_bound = [2.0 for _ in range(self.number_of_variables)] - - FloatSolution.lower_bound = self.lower_bound - FloatSolution.upper_bound = self.upper_bound - - -if __name__ == '__main__': - unittest.main() - diff --git a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py index 3a8be66e..09e70b6d 100644 --- a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py +++ b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py @@ -59,7 +59,7 @@ def selection(self, population: List[S]) -> List[S]: def reproduction(self, population: List[S]) -> List[S]: offspring_population = [] for solution in population: - for j in range((int)(self.lambd_a / self.mu)): + for j in range(int(self.lambd_a / self.mu)): new_solution = copy(solution) offspring_population.append(self.mutation.execute(new_solution)) @@ -81,7 +81,7 @@ def get_result(self) -> R: return self.population[0] def get_name(self) -> str: - return "(" + str(self.mu) + "+" + str(self.lambd_a) + ")ES" + return 'Elitist evolution Strategy' class NonElitistEvolutionStrategy(ElitistEvolutionStrategy[S, R]): @@ -104,7 +104,7 @@ def replacement(self, population: List[S], offspring_population: List[S]) -> Lis return new_population def get_name(self) -> str: - return "(" + str(self.mu) + "," + str(self.lambd_a) + ")ES" + return 'Non-Elitist evolution Strategy' class GenerationalGeneticAlgorithm(EvolutionaryAlgorithm[S, R]): diff --git a/jmetal/component/archive.py b/jmetal/component/archive.py index f3591915..8236d02b 100644 --- a/jmetal/component/archive.py +++ b/jmetal/component/archive.py @@ -1,9 +1,11 @@ import random import copy +from abc import ABCMeta, abstractmethod from typing import TypeVar, Generic, List from jmetal.component.density_estimator import CrowdingDistance, DensityEstimator -from jmetal.component.comparator import Comparator, DominanceComparator, EqualSolutionsComparator, SolutionAttributeComparator +from jmetal.component.comparator import Comparator, DominanceComparator, EqualSolutionsComparator, \ + SolutionAttributeComparator S = TypeVar('S') @@ -18,23 +20,23 @@ class Archive(Generic[S]): + __metaclass__ = ABCMeta + def __init__(self): self.solution_list: List[S] = [] + @abstractmethod def add(self, solution: S) -> bool: pass def get(self, index: int) -> S: return self.solution_list[index] - def get_solution_list(self) -> List[S]: - return self.solution_list - def size(self) -> int: return len(self.solution_list) - def get_comparator(self): - pass + def get_name(self) -> str: + return self.__class__.__name__ class BoundedArchive(Archive[S]): @@ -48,21 +50,18 @@ def __init__(self, self.comparator = comparator self.density_estimator = density_estimator self.non_dominated_solution_archive = NonDominatedSolutionListArchive() - self.solution_list = self.non_dominated_solution_archive.get_solution_list() - - def get_max_size(self) -> int: - return self.maximum_size + self.solution_list = self.non_dominated_solution_archive.solution_list def compute_density_estimator(self): - self.density_estimator.compute_density_estimator(self.get_solution_list()) + self.density_estimator.compute_density_estimator(self.solution_list) def add(self, solution: S) -> bool: - success: bool = self.non_dominated_solution_archive.add(solution) + success = self.non_dominated_solution_archive.add(solution) if success: - if self.size() > self.get_max_size(): + if self.size() > self.maximum_size: self.compute_density_estimator() - worst_solution = self.__find_worst_solution(self.get_solution_list()) - self.get_solution_list().remove(worst_solution) + worst_solution = self.__find_worst_solution(self.solution_list) + self.solution_list.remove(worst_solution) return success @@ -79,9 +78,6 @@ def __find_worst_solution(self, solution_list: List[S]) -> S: return worst_solution - def get_comparator(self): - return self.comparator - class NonDominatedSolutionListArchive(Archive[S]): @@ -119,9 +115,6 @@ def add(self, solution: S) -> bool: return False - def get_comparator(self): - return self.comparator - class CrowdingDistanceArchive(BoundedArchive[S]): @@ -155,7 +148,7 @@ def add(self, solution: S) -> bool: dominated_solution = None if self.__dominance_test(solution, self.__reference_point_solution) == 0: - if len(self.get_solution_list()) == 0: + if len(self.solution_list) == 0: result = True else: if random.uniform(0.0, 1.0) < 0.05: @@ -169,10 +162,10 @@ def add(self, solution: S) -> bool: if result: result = super(ArchiveWithReferencePoint, self).add(solution) - if result and dominated_solution is not None and len(self.get_solution_list()) > 1: - self.get_solution_list().remove(dominated_solution) + if result and dominated_solution is not None and len(self.solution_list) > 1: + self.solution_list.remove(dominated_solution) - if result and len(self.get_solution_list()) > self.maximum_size: + if result and len(self.solution_list) > self.maximum_size: self.compute_density_estimator() return result @@ -180,7 +173,7 @@ def add(self, solution: S) -> bool: def get_reference_point(self)->List[float]: return self.__reference_point - def __dominance_test(self, solution1:S, solution2:S)->int: + def __dominance_test(self, solution1: S, solution2: S) -> int: best_is_one = 0 best_is_two = 0 diff --git a/jmetal/component/comparator.py b/jmetal/component/comparator.py index 20f83dfc..3861355e 100644 --- a/jmetal/component/comparator.py +++ b/jmetal/component/comparator.py @@ -1,3 +1,4 @@ +from abc import ABCMeta, abstractmethod from typing import TypeVar, Generic from jmetal.core.solution import Solution @@ -7,9 +8,15 @@ class Comparator(Generic[S]): - def compare(self, object1: S, object2: S) -> int: + __metaclass__ = ABCMeta + + @abstractmethod + def compare(self, solution1: S, solution2: S) -> int: pass + def get_name(self) -> str: + return self.__class__.__name__ + class EqualSolutionsComparator(Comparator): @@ -91,7 +98,7 @@ def compare(self, solution1: Solution, solution2: Solution) -> int: class DominanceComparator(Comparator): - def __init__(self, constraint_comparator = SolutionAttributeComparator("overall_constraint_violation", lowest_is_best=False)): + def __init__(self, constraint_comparator=SolutionAttributeComparator("overall_constraint_violation", False)): self.constraint_comparator = constraint_comparator def compare(self, solution1: Solution, solution2: Solution) -> int: @@ -108,7 +115,7 @@ def compare(self, solution1: Solution, solution2: Solution) -> int: return result - def __dominance_test(self, solution1, solution2) -> float: + def __dominance_test(self, solution1: Solution, solution2: Solution) -> float: best_is_one = 0 best_is_two = 0 diff --git a/jmetal/component/density_estimator.py b/jmetal/component/density_estimator.py index 50960072..31c3b86a 100644 --- a/jmetal/component/density_estimator.py +++ b/jmetal/component/density_estimator.py @@ -1,4 +1,5 @@ import logging +from abc import ABCMeta, abstractmethod from typing import TypeVar, List logger = logging.getLogger(__name__) @@ -18,6 +19,9 @@ class DensityEstimator(List[S]): """This is the interface of any density estimator algorithm. """ + __metaclass__ = ABCMeta + + @abstractmethod def compute_density_estimator(self, solution_list: List[S]) -> float: pass diff --git a/jmetal/component/evaluator.py b/jmetal/component/evaluator.py index a46d2eaf..dcb96bba 100644 --- a/jmetal/component/evaluator.py +++ b/jmetal/component/evaluator.py @@ -1,3 +1,4 @@ +from abc import ABCMeta, abstractmethod from multiprocessing.pool import ThreadPool from typing import TypeVar, List, Generic @@ -10,6 +11,9 @@ class Evaluator(Generic[S]): + __metaclass__ = ABCMeta + + @abstractmethod def evaluate(self, solution_list: List[S], problem: Problem) -> List[S]: pass @@ -19,6 +23,9 @@ def evaluate_solution(solution: S, problem: Problem) -> None: if problem.number_of_constraints > 0: problem.evaluate_constraints(solution) + def get_name(self) -> str: + return self.__class__.__name__ + class SequentialEvaluator(Evaluator[S]): diff --git a/jmetal/component/observer.py b/jmetal/component/observer.py index bff58ef1..5a8ff12e 100644 --- a/jmetal/component/observer.py +++ b/jmetal/component/observer.py @@ -21,11 +21,11 @@ class ProgressBarObserver(Observer): - def __init__(self, step: int, max: int, desc: str='Progress') -> None: - self.progress_bar = tqdm(total=max, initial=step, ascii=True, desc=desc) + def __init__(self, step: int, maximum: int, desc: str= 'Progress') -> None: + self.progress_bar = tqdm(total=maximum, initial=step, ascii=True, desc=desc) self.progress = step self.step = step - self.maxx = max + self.maxx = maximum def update(self, *args, **kwargs): self.progress_bar.update(self.step) diff --git a/jmetal/component/quality_indicator.py b/jmetal/component/quality_indicator.py index 56afa66e..7a9bfb8d 100644 --- a/jmetal/component/quality_indicator.py +++ b/jmetal/component/quality_indicator.py @@ -1,3 +1,4 @@ +from abc import ABCMeta, abstractmethod from typing import List, TypeVar from jmetal.core.solution import Solution @@ -15,6 +16,9 @@ class Metric: + __metaclass__ = ABCMeta + + @abstractmethod def get_name(self) -> str: return self.__class__.__name__ @@ -40,14 +44,14 @@ def compute(self, front: List[Solution]): :return: The hypervolume that is dominated by a non-dominated front. """ - def get_variables(front: List[Solution]) -> list: + def get_variables() -> list: result = [] for solution in front: result.append(solution.objectives) return result - front = get_variables(front) + front = get_variables() def weakly_dominates(point, other): for i in range(len(point)): @@ -107,7 +111,7 @@ def _hv_recursive(self, dim_index: int, length: int, bounds: list): hv_recursive = self._hv_recursive p = sentinel q = p.prev[dim_index] - while q.cargo != None: + while q.cargo is not None: if q.ignore < dim_index: q.ignore = 0 q = q.prev[dim_index] @@ -171,6 +175,9 @@ def _sort_by_dimension(self, nodes, i): # write back to original list nodes[:] = [node for (_, node) in decorated] + def get_name(self) -> str: + return 'Hypervolume' + class MultiList: """A special front structure needed by FonsecaHyperVolume. diff --git a/jmetal/component/ranking.py b/jmetal/component/ranking.py index dfd6a7fb..24b2007f 100644 --- a/jmetal/component/ranking.py +++ b/jmetal/component/ranking.py @@ -1,3 +1,4 @@ +from abc import ABCMeta, abstractmethod from typing import TypeVar, List from jmetal.component.comparator import DominanceComparator @@ -7,11 +8,14 @@ class Ranking(List[S]): + __metaclass__ = ABCMeta + def __init__(self): - super().__init__() + super(Ranking, self).__init__() self.number_of_comparisons = 0 self.ranked_sublists = [] + @abstractmethod def compute_ranking(self, solution_list: List[S]): pass @@ -23,9 +27,6 @@ def get_subfront(self, rank: int): def get_number_of_subfronts(self): return len(self.ranked_sublists) - def number_of_comparisons(self) -> int: - return self.number_of_comparisons - class FastNonDominatedRanking(Ranking[List[S]]): """ Class implementing the non-dominated ranking of NSGA-II. """ @@ -35,10 +36,10 @@ def __init__(self): def compute_ranking(self, solution_list: List[S]): # number of solutions dominating solution ith - dominate_me = [0 for _ in range(len(solution_list))] + dominating_ith = [0 for _ in range(len(solution_list))] # list of solutions dominated by solution ith - i_dominate = [[] for _ in range(len(solution_list))] + ith_dominated = [[] for _ in range(len(solution_list))] # front[i] contains the list of solutions belonging to front i front = [[] for _ in range(len(solution_list) + 1)] @@ -47,15 +48,16 @@ def compute_ranking(self, solution_list: List[S]): for q in range(p + 1, len(solution_list)): dominance_test_result = DominanceComparator().compare(solution_list[p], solution_list[q]) self.number_of_comparisons += 1 - if dominance_test_result is -1: - i_dominate[p].append(q) - dominate_me[q] += 1 + + if dominance_test_result == -1: + ith_dominated[p].append(q) + dominating_ith[q] += 1 elif dominance_test_result is 1: - i_dominate[q].append(p) - dominate_me[p] += 1 + ith_dominated[q].append(p) + dominating_ith[p] += 1 for i in range(len(solution_list)): - if dominate_me[i] is 0: + if dominating_ith[i] is 0: front[0].append(i) solution_list[i].attributes['dominance_ranking'] = 0 @@ -63,13 +65,12 @@ def compute_ranking(self, solution_list: List[S]): while len(front[i]) != 0: i += 1 for p in front[i - 1]: - if p <= len(i_dominate): - for q in i_dominate[p]: - index = q - dominate_me[index] -= 1 - if dominate_me[index] is 0: - front[i].append(index) - solution_list[index].attributes['dominance_ranking'] = i + if p <= len(ith_dominated): + for q in ith_dominated[p]: + dominating_ith[q] -= 1 + if dominating_ith[q] is 0: + front[i].append(q) + solution_list[q].attributes['dominance_ranking'] = i self.ranked_sublists = [[]] * i for j in range(i): diff --git a/jmetal/component/test/test_archive.py b/jmetal/component/test/test_archive.py index c45ac372..47c86043 100644 --- a/jmetal/component/test/test_archive.py +++ b/jmetal/component/test/test_archive.py @@ -5,15 +5,19 @@ class ArchiveTestCases(unittest.TestCase): + class DummyArchive(Archive): + + def add(self, solution) -> bool: + pass def setUp(self): - self.archive = Archive() + self.archive = self.DummyArchive() def test_should_constructor_create_a_non_null_object(self): self.assertIsNotNone(self.archive) def test_should_constructor_create_an_empty_list(self): - self.assertEqual(0, len(self.archive.get_solution_list())) + self.assertEqual(0, len(self.archive.solution_list)) class BoundedArchiveTestCases(unittest.TestCase): @@ -25,7 +29,7 @@ def test_should_constructor_create_a_non_null_object(self): self.assertIsNotNone(self.archive) def test_should_constructor_set_the_max_size(self): - self.assertEqual(5, self.archive.get_max_size()) + self.assertEqual(5, self.archive.maximum_size) class NonDominatedSolutionListArchiveTestCases(unittest.TestCase): @@ -37,23 +41,23 @@ def test_should_constructor_create_a_non_null_object(self): self.assertIsNotNone(self.archive) def test_should_adding_one_solution_work_properly(self): - solution = Solution(1,1) + solution = Solution(1, 1) self.archive.add(solution) self.assertEqual(1, self.archive.size()) - self.assertEqual(solution, self.archive.get_solution_list()[0]) + self.assertEqual(solution, self.archive.solution_list[0]) def test_should_adding_two_solutions_work_properly_if_one_is_dominated(self): - dominated_solution = Solution(1 ,2) + dominated_solution = Solution(1, 2) dominated_solution.objectives = [2.0, 2.0] dominant_solution = Solution(1, 2) - dominant_solution.objectives = [1.0 ,1.0] + dominant_solution.objectives = [1.0, 1.0] self.archive.add(dominated_solution) self.archive.add(dominant_solution) self.assertEqual(1, self.archive.size()) - self.assertEqual(dominant_solution, self.archive.get_solution_list()[0]) + self.assertEqual(dominant_solution, self.archive.solution_list[0]) def test_should_adding_two_solutions_work_properly_if_both_are_non_dominated(self): solution1 = Solution(1, 2) @@ -66,8 +70,8 @@ def test_should_adding_two_solutions_work_properly_if_both_are_non_dominated(sel self.archive.add(solution2) self.assertEqual(2, self.archive.size()) - self.assertTrue(solution1 in self.archive.get_solution_list() and - solution2 in self.archive.get_solution_list()) + self.assertTrue(solution1 in self.archive.solution_list and + solution2 in self.archive.solution_list) def test_should_adding_four_solutions_work_properly_if_one_dominates_the_others(self): solution1 = Solution(1, 2) @@ -88,7 +92,7 @@ def test_should_adding_four_solutions_work_properly_if_one_dominates_the_others( self.archive.add(solution4) self.assertEqual(1, self.archive.size()) - self.assertEqual(solution4, self.archive.get_solution_list()[0]) + self.assertEqual(solution4, self.archive.solution_list[0]) def test_should_adding_three_solutions_work_properly_if_two_of_them_are_equal(self): solution1 = Solution(1, 2) @@ -106,8 +110,8 @@ def test_should_adding_three_solutions_work_properly_if_two_of_them_are_equal(se self.assertEqual(2, self.archive.size()) self.assertFalse(result) - self.assertTrue(solution1 in self.archive.get_solution_list() - or solution3 in self.archive.get_solution_list()) + self.assertTrue(solution1 in self.archive.solution_list + or solution3 in self.archive.solution_list) class CrowdingDistanceArchiveTestCases(unittest.TestCase): @@ -119,7 +123,7 @@ def test_should_constructor_create_a_non_null_object(self): self.assertIsNotNone(self.archive) def test_should_constructor_set_the_max_size(self): - self.assertEqual(5, self.archive.get_max_size()) + self.assertEqual(5, self.archive.maximum_size) def test_should_constructor_create_an_empty_archive(self): self.assertEqual(0, self.archive.size()) @@ -131,7 +135,7 @@ def test_should_add_a_solution_when_the_archive_is_empty_work_properly(self): self.assertEqual(1, self.archive.size()) self.assertEqual(solution, self.archive.get(0)) - def test_should_add_work_properly_case1(self) : + def test_should_add_work_properly_case1(self): """ Case 1: add a dominated solution when the archive size is 1 must not include the solution. """ solution1 = Solution(2, 2) @@ -145,7 +149,7 @@ def test_should_add_work_properly_case1(self) : self.assertEqual(1, self.archive.size()) self.assertEqual(solution1, self.archive.get(0)) - def test_should_add_work_properly_case2(self) : + def test_should_add_work_properly_case2(self): """ Case 2: add a non-dominated solution when the archive size is 1 must include the solution. """ solution1 = Solution(2, 2) @@ -157,10 +161,10 @@ def test_should_add_work_properly_case2(self) : self.archive.add(solution2) self.assertEqual(2, self.archive.size()) - self.assertTrue(solution1 in self.archive.get_solution_list()) - self.assertTrue(solution2 in self.archive.get_solution_list()) + self.assertTrue(solution1 in self.archive.solution_list) + self.assertTrue(solution2 in self.archive.solution_list) - def test_should_add_work_properly_case3(self) : + def test_should_add_work_properly_case3(self): """ Case 3: add a non-dominated solution when the archive size is 3 must include the solution. """ solution1 = Solution(2, 2) @@ -168,7 +172,7 @@ def test_should_add_work_properly_case3(self) : solution2 = Solution(2, 2) solution2.objectives = [0.0, 4.0] solution3 = Solution(2, 2) - solution3.objectives = [1.5, 1.5 ] + solution3.objectives = [1.5, 1.5] solution4 = Solution(2, 2) solution4.objectives = [1.6, 1.2] @@ -178,12 +182,12 @@ def test_should_add_work_properly_case3(self) : self.archive.add(solution4) self.assertEqual(4, self.archive.size()) - self.assertTrue(solution1 in self.archive.get_solution_list()) - self.assertTrue(solution2 in self.archive.get_solution_list()) - self.assertTrue(solution3 in self.archive.get_solution_list()) - self.assertTrue(solution4 in self.archive.get_solution_list()) + self.assertTrue(solution1 in self.archive.solution_list) + self.assertTrue(solution2 in self.archive.solution_list) + self.assertTrue(solution3 in self.archive.solution_list) + self.assertTrue(solution4 in self.archive.solution_list) - def test_should_add_work_properly_case4(self) : + def test_should_add_work_properly_case4(self): """ Case 4: add a dominated solution when the archive size is 3 must not include the solution. """ solution1 = Solution(2, 2) @@ -191,7 +195,7 @@ def test_should_add_work_properly_case4(self) : solution2 = Solution(2, 2) solution2.objectives = [0.0, 4.0] solution3 = Solution(2, 2) - solution3.objectives = [1.5, 1.5 ] + solution3.objectives = [1.5, 1.5] solution4 = Solution(2, 2) solution4.objectives = [5.0, 6.0] @@ -201,11 +205,11 @@ def test_should_add_work_properly_case4(self) : self.archive.add(solution4) self.assertEqual(3, self.archive.size()) - self.assertTrue(solution1 in self.archive.get_solution_list()) - self.assertTrue(solution2 in self.archive.get_solution_list()) - self.assertTrue(solution3 in self.archive.get_solution_list()) + self.assertTrue(solution1 in self.archive.solution_list) + self.assertTrue(solution2 in self.archive.solution_list) + self.assertTrue(solution3 in self.archive.solution_list) - def test_should_add_work_properly_case5(self) : + def test_should_add_work_properly_case5(self): """ Case 5: add a dominated solution when the archive is full should not include the solution. """ solution1 = Solution(2, 2) @@ -213,7 +217,7 @@ def test_should_add_work_properly_case5(self) : solution2 = Solution(2, 2) solution2.objectives = [0.0, 4.0] solution3 = Solution(2, 2) - solution3.objectives = [1.5, 1.5 ] + solution3.objectives = [1.5, 1.5] solution4 = Solution(2, 2) solution4.objectives = [5.0, 6.0] @@ -223,11 +227,11 @@ def test_should_add_work_properly_case5(self) : self.archive.add(solution4) self.assertEqual(3, self.archive.size()) - self.assertTrue(solution1 in self.archive.get_solution_list()) - self.assertTrue(solution2 in self.archive.get_solution_list()) - self.assertTrue(solution3 in self.archive.get_solution_list()) + self.assertTrue(solution1 in self.archive.solution_list) + self.assertTrue(solution2 in self.archive.solution_list) + self.assertTrue(solution3 in self.archive.solution_list) - def test_should_add_work_properly_case6(self) : + def test_should_add_work_properly_case6(self): """ Case 6: add a non-dominated solution when the archive is full should not include the solution if it has the highest distance crowding value. """ @@ -238,7 +242,7 @@ def test_should_add_work_properly_case6(self) : solution2 = Solution(2, 2) solution2.objectives = [1.0, 2.0] solution3 = Solution(2, 2) - solution3.objectives = [2.0, 1.5 ] + solution3.objectives = [2.0, 1.5] solution4 = Solution(2, 2) solution4.objectives = [3.0, 0.0] @@ -252,9 +256,9 @@ def test_should_add_work_properly_case6(self) : archive.add(new_solution) self.assertEqual(4, archive.size()) - self.assertTrue(new_solution not in archive.get_solution_list()) + self.assertTrue(new_solution not in archive.solution_list) - def test_should_add_work_properly_case7(self) : + def test_should_add_work_properly_case7(self): """ Case 7: add a non-dominated solution when the archive is full should remove all the dominated solutions. """ archive = CrowdingDistanceArchive(4) @@ -264,7 +268,7 @@ def test_should_add_work_properly_case7(self) : solution2 = Solution(2, 2) solution2.objectives = [1.0, 2.0] solution3 = Solution(2, 2) - solution3.objectives = [2.0, 1.5 ] + solution3.objectives = [2.0, 1.5] solution4 = Solution(2, 2) solution4.objectives = [3.0, 0.0] @@ -278,9 +282,9 @@ def test_should_add_work_properly_case7(self) : archive.add(new_solution) self.assertEqual(1, archive.size()) - self.assertTrue(new_solution in archive.get_solution_list()) + self.assertTrue(new_solution in archive.solution_list) - def test_should_compute_density_estimator_work_properly_case1(self) : + def test_should_compute_density_estimator_work_properly_case1(self): """ Case 1: The archive contains one solution. """ archive = CrowdingDistanceArchive(4) @@ -294,7 +298,7 @@ def test_should_compute_density_estimator_work_properly_case1(self) : self.assertEqual(1, archive.size()) self.assertEqual(float("inf"), solution1.attributes["crowding_distance"]) - def test_should_compute_density_estimator_work_properly_case2(self) : + def test_should_compute_density_estimator_work_properly_case2(self): """ Case 2: The archive contains two solutions. """ archive = CrowdingDistanceArchive(4) @@ -313,7 +317,7 @@ def test_should_compute_density_estimator_work_properly_case2(self) : self.assertEqual(float("inf"), solution1.attributes["crowding_distance"]) self.assertEqual(float("inf"), solution2.attributes["crowding_distance"]) - def test_should_compute_density_estimator_work_properly_case3(self) : + def test_should_compute_density_estimator_work_properly_case3(self): """ Case 3: The archive contains two solutions. """ archive = CrowdingDistanceArchive(4) @@ -323,7 +327,7 @@ def test_should_compute_density_estimator_work_properly_case3(self) : solution2 = Solution(2, 2) solution2.objectives = [1.0, 2.0] solution3 = Solution(2, 2) - solution3.objectives = [2.0, 1.5 ] + solution3.objectives = [2.0, 1.5] archive.add(solution1) archive.add(solution2) diff --git a/jmetal/component/test/test_comparator.py b/jmetal/component/test/test_comparator.py index 423e9dff..0daddbb9 100644 --- a/jmetal/component/test/test_comparator.py +++ b/jmetal/component/test/test_comparator.py @@ -22,14 +22,6 @@ def test_should_dominance_comparator_raise_an_exception_if_the_second_solution_i with self.assertRaises(Exception): self.comparator.compare(solution, solution2) - """ - def test_should_dominance_comparator_raise_an_exception_if_the_solutions_have_not_the_same_number_of_objectives(self): - solution = FloatSolution(3, 2, 0, [], []) - solution2 = FloatSolution(3, 5, 0, [], []) - with self.assertRaises(Exception): - self.comparator.compare(solution, solution2) - """ - def test_should_dominance_comparator_return_zero_if_the_two_solutions_have_one_objective_with_the_same_value(self): solution = FloatSolution(3, 1, 0, [], []) solution2 = FloatSolution(3, 1, 0, [], []) @@ -94,7 +86,7 @@ def test_should_dominance_comparator_work_properly_case_d(self): """ Case d: solution1 has objectives [-1.0, 5.0, 9.0] and solution2 has [-1.0, 5.0, 8.0] """ solution = FloatSolution(3, 3, 0, [], []) - solution2 = FloatSolution(3, 3, 0 , [], []) + solution2 = FloatSolution(3, 3, 0, [], []) solution.objectives = [-1.0, 5.0, 9.0] solution2.objectives = [-1.0, 5.0, 8.0] diff --git a/jmetal/component/test/test_density_estimator.py b/jmetal/component/test/test_density_estimator.py index eb096372..e34ff1d6 100644 --- a/jmetal/component/test/test_density_estimator.py +++ b/jmetal/component/test/test_density_estimator.py @@ -88,4 +88,4 @@ def test_should_the_crowding_distance_of_four_solutions_correctly_assigned(self) if __name__ == "__main__": - unittest.main() \ No newline at end of file + unittest.main() diff --git a/jmetal/component/test/test_evaluator.py b/jmetal/component/test/test_evaluator.py index 534cf66a..f091894c 100644 --- a/jmetal/component/test/test_evaluator.py +++ b/jmetal/component/test/test_evaluator.py @@ -8,7 +8,7 @@ class MockedProblem(FloatProblem): def __init__(self, number_of_variables: int = 3): - super().__init__() + super(MockedProblem, self).__init__() self.number_of_objectives = 2 self.number_of_variables = number_of_variables self.number_of_constraints = 0 diff --git a/jmetal/component/test/test_quality_indicator.py b/jmetal/component/test/test_quality_indicator.py index ebb584b5..1874f4c3 100644 --- a/jmetal/component/test/test_quality_indicator.py +++ b/jmetal/component/test/test_quality_indicator.py @@ -2,7 +2,7 @@ import unittest from jmetal.core.solution import Solution -from jmetal.util.front_file import read_front_from_file_as_solutions, walk_up_folder +from jmetal.problem import ZDT1 from jmetal.component.quality_indicator import HyperVolume @@ -28,11 +28,11 @@ def test_should_hypervolume_return_5_0(self): self.assertEqual(5.0, value) def test_should_hypervolume_return_the_correct_value_when_applied_to_the_ZDT1_reference_front(self): + problem = ZDT1() reference_point = [1, 1] - front = read_front_from_file_as_solutions(join(walk_up_folder(self.file_path, 2), 'problem/front/ZDT1.pf')) hv = HyperVolume(reference_point) - value = hv.compute(front) + value = hv.compute(problem.get_reference_front()) self.assertAlmostEqual(0.666, value, delta=0.001) diff --git a/jmetal/core/algorithm.py b/jmetal/core/algorithm.py index b531583b..99b1e5ce 100644 --- a/jmetal/core/algorithm.py +++ b/jmetal/core/algorithm.py @@ -1,9 +1,10 @@ import threading import time +from abc import ABCMeta, abstractmethod from typing import TypeVar, Generic, List from jmetal.core.solution import FloatSolution -from jmetal.core.observable import Observable, DefaultObservable +from jmetal.core.observable import DefaultObservable S = TypeVar('S') R = TypeVar('R') @@ -19,64 +20,75 @@ class Algorithm(Generic[S, R], threading.Thread): + __metaclass__ = ABCMeta + def __init__(self): threading.Thread.__init__(self) - self.evaluations: int = 0 - self.max_evaluations: int = 100 - self.start_computing_time: int = 0 - self.total_computing_time: int = 0 - self.observable: Observable = DefaultObservable() + self.evaluations = 0 + self.max_evaluations = 100 + self.start_computing_time = 0 + self.total_computing_time = 0 + self.observable = DefaultObservable() def get_evaluations(self) -> int: return self.evaluations + def get_current_computing_time(self) -> float: + return time.time() - self.start_computing_time + + @abstractmethod def get_result(self) -> R: """ :return: Final population. """ pass - def get_current_computing_time(self) -> float: - return time.time() - self.start_computing_time - def get_name(self) -> str: - """ :return: Name of the algorithm. - """ - return type(self).__name__ + return self.__class__.__name__ class EvolutionaryAlgorithm(Algorithm[S, R]): + __metaclass__ = ABCMeta + def __init__(self): super(EvolutionaryAlgorithm, self).__init__() self.population = [] + @abstractmethod def create_initial_population(self) -> List[S]: pass + @abstractmethod def evaluate_population(self, population: List[S]) -> List[S]: pass + @abstractmethod def init_progress(self) -> None: pass + @abstractmethod def is_stopping_condition_reached(self) -> bool: pass + @abstractmethod def selection(self, population: List[S]) -> List[S]: pass + @abstractmethod def reproduction(self, population: List[S]) -> List[S]: pass + @abstractmethod def replacement(self, population: List[S], offspring_population: List[S]) -> List[S]: pass + @abstractmethod def update_progress(self): pass def run(self): """* Step One: Generate the initial population of individuals randomly. (First generation) - * Step Two: Evaluate the fitness of each individual in that population (time limit, sufficient fitness achieved, etc.) + * Step Two: Evaluate the fitness of each individual in that population * Step Three: Repeat the following regenerational steps until termination 1. Select the best-fit individuals for reproduction. (Parents) @@ -106,46 +118,61 @@ def run(self): class ParticleSwarmOptimization(Algorithm[FloatSolution, List[FloatSolution]]): + __metaclass__ = ABCMeta + def __init__(self): super(ParticleSwarmOptimization, self).__init__() self.swarm = [] - def init_progress(self) -> None : + @abstractmethod + def init_progress(self) -> None: pass - def update_progress(self) -> None : + @abstractmethod + def update_progress(self) -> None: pass + @abstractmethod def is_stopping_condition_reached(self) -> bool: pass + @abstractmethod def create_initial_swarm(self) -> List[FloatSolution]: pass + @abstractmethod def evaluate_swarm(self, swarm: List[FloatSolution]) -> List[FloatSolution]: pass + @abstractmethod def initialize_global_best(self, swarm: List[FloatSolution]) -> None: pass + @abstractmethod def initialize_particle_best(self, swarm: List[FloatSolution]) -> None: pass + @abstractmethod def initialize_velocity(self, swarm: List[FloatSolution]) -> None: pass + @abstractmethod def update_velocity(self, swarm: List[FloatSolution]) -> None: pass + @abstractmethod def update_position(self, swarm: List[FloatSolution]) -> None: pass + @abstractmethod def perturbation(self, swarm: List[FloatSolution]) -> None: pass + @abstractmethod def update_global_best(self, swarm: List[FloatSolution]) -> None: pass + @abstractmethod def update_particle_best(self, swarm: List[FloatSolution]) -> None: pass diff --git a/jmetal/core/observable.py b/jmetal/core/observable.py index af322357..dd901044 100644 --- a/jmetal/core/observable.py +++ b/jmetal/core/observable.py @@ -9,7 +9,7 @@ """ -class Observer(object): +class Observer: __metaclass__ = ABCMeta @@ -24,17 +24,23 @@ def update(self, *args, **kwargs): pass -class Observable(object): +class Observable: + __metaclass__ = ABCMeta + + @abstractmethod def register(self, observer): pass + @abstractmethod def deregister(self, observer): pass + @abstractmethod def deregister_all(self): pass + @abstractmethod def notify_all(self, *args, **kwargs): pass diff --git a/jmetal/core/operator.py b/jmetal/core/operator.py index f745d839..837ecef3 100644 --- a/jmetal/core/operator.py +++ b/jmetal/core/operator.py @@ -1,3 +1,4 @@ +from abc import ABCMeta, abstractmethod from typing import TypeVar, Generic, List S = TypeVar('S') @@ -15,16 +16,22 @@ class Operator(Generic[S, R]): """ Class representing operator """ + __metaclass__ = ABCMeta + + @abstractmethod def execute(self, source: S) -> R: pass - def get_name(self): + @abstractmethod + def get_name(self) -> str: pass class Mutation(Operator[S, S]): """ Class representing mutation operator. """ + __metaclass__ = ABCMeta + def __init__(self, probability: float): if probability > 1.0: raise Exception('The probability is greater than one: {}'.format(probability)) @@ -33,13 +40,20 @@ def __init__(self, probability: float): self.probability = probability - def execute(self, source: S) -> S: + @abstractmethod + def execute(self, source: S) -> R: + pass + + @abstractmethod + def get_name(self) -> str: pass class Crossover(Operator[List[S], List[R]]): """ Class representing crossover operator. """ + __metaclass__ = ABCMeta + def __init__(self, probability: float): if probability > 1.0: raise Exception('The probability is greater than one: {}'.format(probability)) @@ -48,18 +62,31 @@ def __init__(self, probability: float): self.probability = probability + @abstractmethod + def get_number_of_parents(self): + pass + + @abstractmethod def execute(self, source: S) -> R: pass - def get_number_of_parents(self) -> int: + @abstractmethod + def get_name(self) -> str: pass class Selection(Operator[S, R]): """ Class representing selection operator. """ + __metaclass__ = ABCMeta + def __init__(self): pass + @abstractmethod def execute(self, source: S) -> R: pass + + @abstractmethod + def get_name(self) -> str: + pass diff --git a/jmetal/core/problem.py b/jmetal/core/problem.py index 67f30dff..da10044b 100644 --- a/jmetal/core/problem.py +++ b/jmetal/core/problem.py @@ -1,3 +1,4 @@ +from abc import ABCMeta, abstractmethod from os.path import dirname, join from pathlib import Path from typing import Generic, TypeVar @@ -12,26 +13,41 @@ class Problem(Generic[S]): """ Class representing problems. """ + __metaclass__ = ABCMeta + MINIMIZE = -1 MAXIMIZE = 1 def __init__(self): - self.number_of_variables: int = None - self.number_of_objectives: int = None - self.number_of_constraints: int = None - self.obj_directions: list = [] + self.number_of_variables = None + self.number_of_objectives = None + self.number_of_constraints = None + self.obj_directions = [] + @abstractmethod def evaluate(self, solution: S) -> S: - raise NotImplemented + """ Evaluate a solution. - def evaluate_constraints(self, solution: S): - raise NotImplemented + :return: Evaluated solution. """ + pass + @abstractmethod def create_solution(self) -> S: - raise NotImplemented + """ Creates a random solution to the problem. + + :return: Solution. """ + pass + + def evaluate_constraints(self, solution: S): + pass def get_reference_front(self) -> list: - reference_front_path = 'problem/front/{0}.pf'.format(self.get_name()) + """ Get the reference front to the problem (if any). + This method read front files (.pf) located in `jmetal/problem/reference_front/`, which must have the same + name as the problem. + + :return: Front.""" + reference_front_path = 'problem/reference_front/{0}.pf'.format(self.get_name()) front = [] file_path = dirname(join(dirname(__file__))) @@ -49,9 +65,13 @@ def get_name(self) -> str: class BinaryProblem(Problem[BinarySolution]): """ Class representing binary problems. """ - def evaluate(self, solution: BinarySolution) -> None: + __metaclass__ = ABCMeta + + @abstractmethod + def evaluate(self, solution: BinarySolution) -> BinarySolution: pass + @abstractmethod def create_solution(self) -> BinarySolution: pass @@ -59,10 +79,16 @@ def create_solution(self) -> BinarySolution: class FloatProblem(Problem[FloatSolution]): """ Class representing float problems. """ + __metaclass__ = ABCMeta + def __init__(self): - super().__init__() - self.lower_bound: [] = None - self.upper_bound: [] = None + super(FloatProblem, self).__init__() + self.lower_bound = None + self.upper_bound = None + + @abstractmethod + def evaluate(self, solution: FloatSolution) -> FloatSolution: + pass def create_solution(self) -> FloatSolution: new_solution = FloatSolution(self.number_of_variables, self.number_of_objectives, self.number_of_constraints, @@ -76,10 +102,16 @@ def create_solution(self) -> FloatSolution: class IntegerProblem(Problem[IntegerSolution]): """ Class representing integer problems. """ + __metaclass__ = ABCMeta + def __init__(self): - super().__init__() - self.lower_bound: [] = None - self.upper_bound: [] = None + super(IntegerProblem, self).__init__() + self.lower_bound = None + self.upper_bound = None + + @abstractmethod + def evaluate(self, solution: IntegerSolution) -> IntegerSolution: + pass def create_solution(self) -> IntegerSolution: new_solution = IntegerSolution( @@ -89,6 +121,7 @@ def create_solution(self) -> IntegerSolution: self.lower_bound, self.upper_bound) new_solution.variables = \ - [int(random.uniform(self.lower_bound[i]*1.0, self.upper_bound[i]*1.0)) for i in range(self.number_of_variables)] + [int(random.uniform(self.lower_bound[i]*1.0, self.upper_bound[i]*1.0)) + for i in range(self.number_of_variables)] return new_solution diff --git a/jmetal/core/solution.py b/jmetal/core/solution.py index 9f8ff539..2ead41d7 100644 --- a/jmetal/core/solution.py +++ b/jmetal/core/solution.py @@ -8,9 +8,9 @@ class Solution(Generic[S]): """ Class representing solutions """ def __init__(self, number_of_variables: int, number_of_objectives: int, number_of_constraints: int = 0): - self.number_of_objectives: int = number_of_objectives - self.number_of_variables: int = number_of_variables - self.number_of_constraints: int = number_of_constraints + self.number_of_objectives = number_of_objectives + self.number_of_variables = number_of_variables + self.number_of_constraints = number_of_constraints self.objectives = [0.0 for _ in range(self.number_of_objectives)] self.variables = [[] for _ in range(self.number_of_variables)] self.attributes = {} diff --git a/jmetal/core/test/test_problem.py b/jmetal/core/test/test_problem.py index 2dbced3f..62954395 100644 --- a/jmetal/core/test/test_problem.py +++ b/jmetal/core/test/test_problem.py @@ -1,26 +1,22 @@ import unittest -from jmetal.core.problem import Problem, FloatProblem, IntegerProblem - - -class ProblemTestCases(unittest.TestCase): - - def test_should_default_constructor_create_a_valid_problem(self) -> None: - problem = Problem() - self.assertEqual(None, problem.number_of_variables) - self.assertEqual(None, problem.number_of_objectives) - self.assertEqual(None, problem.number_of_constraints) +from jmetal.core.problem import FloatProblem, IntegerProblem +from jmetal.core.solution import FloatSolution, IntegerSolution class FloatProblemTestCases(unittest.TestCase): + class DummyFloatProblem(FloatProblem): + + def evaluate(self, solution: FloatSolution) -> FloatSolution: + pass def test_should_default_constructor_create_a_valid_problem(self) -> None: - problem = FloatProblem() + problem = self.DummyFloatProblem() problem.number_of_variables = 1 problem.number_of_objectives = 2 problem.number_of_constraints = 0 problem.lower_bound = [-1.0] - problem.upper_bound= [1.0] + problem.upper_bound = [1.0] self.assertEqual(1, problem.number_of_variables) self.assertEqual(2, problem.number_of_objectives) self.assertEqual(0, problem.number_of_constraints) @@ -28,12 +24,12 @@ def test_should_default_constructor_create_a_valid_problem(self) -> None: self.assertEqual([1], problem.upper_bound) def test_should_create_solution_create_a_valid_solution(self) -> None: - problem = FloatProblem() + problem = self.DummyFloatProblem() problem.number_of_variables = 2 problem.number_of_objectives = 2 problem.number_of_constraints = 0 problem.lower_bound = [-1.0, -2.0] - problem.upper_bound= [1.0, 2.0] + problem.upper_bound = [1.0, 2.0] solution = problem.create_solution() self.assertNotEqual(None, solution) @@ -42,14 +38,18 @@ def test_should_create_solution_create_a_valid_solution(self) -> None: class IntegerProblemTestCases(unittest.TestCase): + class DummyIntegerProblem(IntegerProblem): + + def evaluate(self, solution: IntegerSolution) -> IntegerSolution: + pass def test_should_default_constructor_create_a_valid_problem(self) -> None: - problem = IntegerProblem() + problem = self.DummyIntegerProblem() problem.number_of_variables = 1 problem.number_of_objectives = 2 problem.number_of_constraints = 0 problem.lower_bound = [-1] - problem.upper_bound= [1] + problem.upper_bound = [1] self.assertEqual(1, problem.number_of_variables) self.assertEqual(2, problem.number_of_objectives) @@ -58,12 +58,12 @@ def test_should_default_constructor_create_a_valid_problem(self) -> None: self.assertEqual([1], problem.upper_bound) def test_should_create_solution_create_a_valid_solution(self) -> None: - problem = FloatProblem() + problem = self.DummyIntegerProblem() problem.number_of_variables = 2 problem.number_of_objectives = 2 problem.number_of_constraints = 0 problem.lower_bound = [-1, -2] - problem.upper_bound= [1, 2] + problem.upper_bound = [1, 2] solution = problem.create_solution() self.assertNotEqual(None, solution) @@ -72,4 +72,4 @@ def test_should_create_solution_create_a_valid_solution(self) -> None: if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/jmetal/operator/__init__.py b/jmetal/operator/__init__.py index 26e57f2f..f2bb825c 100644 --- a/jmetal/operator/__init__.py +++ b/jmetal/operator/__init__.py @@ -3,7 +3,9 @@ from .selection import BestSolutionSelection, BinaryTournamentSelection, BinaryTournament2Selection, \ RandomSolutionSelection, NaryRandomSolutionSelection, RankingAndCrowdingDistanceSelection -__all__ = ['NullCrossover', 'SBX', 'SP', - 'NullMutation', 'BitFlip', 'Polynomial', 'IntegerPolynomial', 'Uniform', 'SimpleRandom', - 'BestSolutionSelection', 'BinaryTournamentSelection', 'BinaryTournament2Selection', 'RandomSolutionSelection', - 'NaryRandomSolutionSelection', 'RankingAndCrowdingDistanceSelection'] \ No newline at end of file +__all__ = [ + 'NullCrossover', 'SBX', 'SP', + 'NullMutation', 'BitFlip', 'Polynomial', 'IntegerPolynomial', 'Uniform', 'SimpleRandom', + 'BestSolutionSelection', 'BinaryTournamentSelection', 'BinaryTournament2Selection', 'RandomSolutionSelection', + 'NaryRandomSolutionSelection', 'RankingAndCrowdingDistanceSelection' +] diff --git a/jmetal/operator/mutation.py b/jmetal/operator/mutation.py index 513e8520..c0459204 100644 --- a/jmetal/operator/mutation.py +++ b/jmetal/operator/mutation.py @@ -21,7 +21,7 @@ def execute(self, solution: Solution) -> Solution: return solution def get_name(self): - return "Null mutation" + return 'Null mutation' class BitFlip(Mutation[BinarySolution]): @@ -69,7 +69,7 @@ def execute(self, solution: FloatSolution) -> FloatSolution: deltaq = pow(val, mut_pow) - 1.0 else: xy = 1.0 - delta2 - val = 2.0 * (1.0 - rnd) + 2.0 * (rnd - 0.5) * (pow(xy, self.distribution_index + 1.0)); + val = 2.0 * (1.0 - rnd) + 2.0 * (rnd - 0.5) * (pow(xy, self.distribution_index + 1.0)) deltaq = 1.0 - pow(val, mut_pow) y += deltaq * (yu - yl) diff --git a/jmetal/operator/selection.py b/jmetal/operator/selection.py index 3c87a74a..d3785520 100644 --- a/jmetal/operator/selection.py +++ b/jmetal/operator/selection.py @@ -70,10 +70,13 @@ def execute(self, front: List[S]) -> S: return result + def get_name(self) -> str: + return 'Best solution selection' + class NaryRandomSolutionSelection(Selection[List[S], S]): - def __init__(self, number_of_solutions_to_be_returned:int = 1): + def __init__(self, number_of_solutions_to_be_returned: int = 1): super(NaryRandomSolutionSelection, self).__init__() if number_of_solutions_to_be_returned < 0: raise Exception('The number of solutions to be returned must be positive integer') @@ -91,6 +94,9 @@ def execute(self, front: List[S]) -> S: # random sampling without replacement return random.sample(front, self.number_of_solutions_to_be_returned) + def get_name(self) -> str: + return 'Nary random solution selection' + class RandomSolutionSelection(Selection[List[S], S]): @@ -105,6 +111,9 @@ def execute(self, front: List[S]) -> S: return random.choice(front) + def get_name(self) -> str: + return 'Random solution selection' + class RankingAndCrowdingDistanceSelection(Selection[List[S], List[S]]): @@ -133,6 +142,9 @@ def execute(self, front: List[S]) -> List[S]: return new_solution_list + def get_name(self) -> str: + return 'Ranking and crowding distance selection' + class BinaryTournament2Selection(Selection[List[S], S]): @@ -182,5 +194,5 @@ def __winner(self, front: List[S], comparator: Comparator): return result - def get_name(self): + def get_name(self) -> str: return 'Binary tournament selection (experimental)' diff --git a/jmetal/operator/test/test_mutation.py b/jmetal/operator/test/test_mutation.py index 0dfd7c40..d6bca2e3 100644 --- a/jmetal/operator/test/test_mutation.py +++ b/jmetal/operator/test/test_mutation.py @@ -208,7 +208,7 @@ def test_should_the_solution_change__if_the_probability_is_one(self): mutated_solution = operator.execute(solution) self.assertNotEqual([1, 2, 3], mutated_solution.variables) - self.assertEqual([True, True, True], [isinstance(x, int) for x in mutated_solution.variables]) + self.assertEqual([True, True, True], [isinstance(x, int) for x in mutated_solution.variables]) if __name__ == '__main__': diff --git a/jmetal/operator/test/test_selection.py b/jmetal/operator/test/test_selection.py index 5ff43b3b..08d31a0a 100644 --- a/jmetal/operator/test/test_selection.py +++ b/jmetal/operator/test/test_selection.py @@ -5,7 +5,7 @@ from jmetal.core.solution import Solution from jmetal.operator.selection import BinaryTournamentSelection, BestSolutionSelection, RandomSolutionSelection, \ NaryRandomSolutionSelection, RankingAndCrowdingDistanceSelection, BinaryTournament2Selection -from jmetal.component.comparator import Comparator, SolutionAttributeComparator +from jmetal.component.comparator import SolutionAttributeComparator, EqualSolutionsComparator class BinaryTournamentTestCases(unittest.TestCase): @@ -311,7 +311,7 @@ def test_should_operator_raise_an_exception_if_the_list_of_comparators_is_empty( def test_should_execute_return_the_solution_in_a_list_with_one_solution(self): solution = Solution(3, 2) solution_list = [solution] - selection = BinaryTournament2Selection[Solution]([Comparator()]) + selection = BinaryTournament2Selection[Solution]([EqualSolutionsComparator()]) self.assertEqual(solution, selection.execute(solution_list)) diff --git a/jmetal/problem/__init__.py b/jmetal/problem/__init__.py index f303cfbf..49d74770 100644 --- a/jmetal/problem/__init__.py +++ b/jmetal/problem/__init__.py @@ -4,8 +4,10 @@ from .multiobjective.zdt import ZDT1, ZDT2, ZDT3, ZDT4, ZDT6 from .singleobjective.unconstrained import OneMax, Sphere -__all__ = ['Srinivas', 'Tanaka', - 'Kursawe', 'Fonseca', 'Schaffer', 'Viennet2', - 'DTLZ1', 'DTLZ2', - 'ZDT1', 'ZDT2', 'ZDT3', 'ZDT4', 'ZDT6', - 'OneMax', 'Sphere'] \ No newline at end of file +__all__ = [ + 'Srinivas', 'Tanaka', + 'Kursawe', 'Fonseca', 'Schaffer', 'Viennet2', + 'DTLZ1', 'DTLZ2', + 'ZDT1', 'ZDT2', 'ZDT3', 'ZDT4', 'ZDT6', + 'OneMax', 'Sphere' +] diff --git a/jmetal/problem/multiobjective/constrained.py b/jmetal/problem/multiobjective/constrained.py index ad4aa413..c0cf034e 100644 --- a/jmetal/problem/multiobjective/constrained.py +++ b/jmetal/problem/multiobjective/constrained.py @@ -16,7 +16,7 @@ class Srinivas(FloatProblem): """ Class representing problem Srinivas. """ def __init__(self): - super().__init__() + super(Srinivas, self).__init__() self.number_of_objectives = 2 self.number_of_variables = 2 self.number_of_constraints = 2 @@ -27,13 +27,15 @@ def __init__(self): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def evaluate(self, solution: FloatSolution): + def evaluate(self, solution: FloatSolution) -> FloatSolution: x1 = solution.variables[0] x2 = solution.variables[1] solution.objectives[0] = 2.0 + (x1 - 2.0) * (x1 - 2.0) + (x2 - 1.0) * (x2 - 1.0) solution.objectives[1] = 9.0 * x1 - (x2 - 1.0) * (x2 - 1.0) + return solution + def evaluate_constraints(self, solution: FloatSolution) -> None: constraints = [0.0 for _ in range(self.number_of_constraints)] @@ -51,18 +53,18 @@ def evaluate_constraints(self, solution: FloatSolution) -> None: overall_constraint_violation += constrain number_of_violated_constraints += 1 - solution.attributes["overall_constraint_violation"] = overall_constraint_violation - solution.attributes["number_of_violated_constraints"] = number_of_violated_constraints + solution.attributes['overall_constraint_violation'] = overall_constraint_violation + solution.attributes['number_of_violated_constraints'] = number_of_violated_constraints def get_name(self): - return "Srinivas" + return 'Srinivas' class Tanaka(FloatProblem): """ Class representing problem Tanaka """ def __init__(self): - super().__init__() + super(Tanaka, self).__init__() self.number_of_objectives = 2 self.number_of_variables = 2 self.number_of_constraints = 2 @@ -73,10 +75,12 @@ def __init__(self): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def evaluate(self, solution: FloatSolution): + def evaluate(self, solution: FloatSolution) -> FloatSolution: solution.objectives[0] = solution.variables[0] solution.objectives[1] = solution.variables[1] + return solution + def evaluate_constraints(self, solution: FloatSolution) -> None: constraints = [0.0 for _ in range(self.number_of_constraints)] @@ -94,8 +98,8 @@ def evaluate_constraints(self, solution: FloatSolution) -> None: overall_constraint_violation += constrain number_of_violated_constraints += 1 - solution.attributes["overall_constraint_violation"] = overall_constraint_violation - solution.attributes["number_of_violated_constraints"] = number_of_violated_constraints + solution.attributes['overall_constraint_violation'] = overall_constraint_violation + solution.attributes['number_of_violated_constraints'] = number_of_violated_constraints def get_name(self): - return "Tanaka" + return 'Tanaka' diff --git a/jmetal/problem/multiobjective/dtlz.py b/jmetal/problem/multiobjective/dtlz.py index 89b4dd44..2a908641 100644 --- a/jmetal/problem/multiobjective/dtlz.py +++ b/jmetal/problem/multiobjective/dtlz.py @@ -21,7 +21,7 @@ class DTLZ1(FloatProblem): def __init__(self, number_of_variables: int = 7, number_of_objectives=3): """ :param number_of_variables: number of decision variables of the problem. """ - super().__init__() + super(DTLZ1, self).__init__() self.number_of_variables = number_of_variables self.number_of_objectives = number_of_objectives self.number_of_constraints = 0 @@ -34,7 +34,7 @@ def __init__(self, number_of_variables: int = 7, number_of_objectives=3): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def evaluate(self, solution: FloatSolution): + def evaluate(self, solution: FloatSolution) -> FloatSolution: k = self.number_of_variables - self.number_of_objectives + 1 g = sum([(x - 0.5) * (x - 0.5) - cos(20.0 * pi * (x - 0.5)) @@ -51,6 +51,8 @@ def evaluate(self, solution: FloatSolution): if i != 0: solution.objectives[i] *= 1 - solution.variables[self.number_of_objectives - (i + 1)] + return solution + def get_name(self): return 'DTLZ1' @@ -64,7 +66,7 @@ class DTLZ2(FloatProblem): def __init__(self, number_of_variables: int = 12, number_of_objectives=3): """:param number_of_variables: number of decision variables of the problem """ - super().__init__() + super(DTLZ2, self).__init__() self.number_of_variables = number_of_variables self.number_of_objectives = number_of_objectives self.number_of_constraints = 0 @@ -77,7 +79,7 @@ def __init__(self, number_of_variables: int = 12, number_of_objectives=3): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def evaluate(self, solution: FloatSolution): + def evaluate(self, solution: FloatSolution) -> FloatSolution: k = self.number_of_variables - self.number_of_objectives + 1 g = sum([(x - 0.5) * (x - 0.5) for x in solution.variables[self.number_of_variables - k:]]) @@ -91,5 +93,7 @@ def evaluate(self, solution: FloatSolution): if i != 0: solution.objectives[i] *= sin(0.5 * pi * solution.variables[self.number_of_objectives - (i + 1)]) + return solution + def get_name(self): return 'DTLZ2' diff --git a/jmetal/problem/multiobjective/test/test_unconstrained.py b/jmetal/problem/multiobjective/test/test_unconstrained.py index c3aab297..f2a41612 100644 --- a/jmetal/problem/multiobjective/test/test_unconstrained.py +++ b/jmetal/problem/multiobjective/test/test_unconstrained.py @@ -56,8 +56,8 @@ def test_should_constructor_create_a_valid_problem_with_default_settings(self): self.assertEqual(2, problem.number_of_objectives) self.assertEqual(0, problem.number_of_constraints) - self.assertEqual( 3 * [-4], problem.lower_bound) - self.assertEqual( 3 * [ 4], problem.upper_bound) + self.assertEqual(3 * [-4], problem.lower_bound) + self.assertEqual(3 * [4], problem.upper_bound) def test_should_create_solution_create_a_valid_float_solution(self): problem = Fonseca() @@ -70,7 +70,7 @@ def test_should_create_solution_create_a_valid_float_solution(self): self.assertEqual(0, problem.number_of_constraints) self.assertEqual(3 * [-4], problem.lower_bound) - self.assertEqual(3 * [ 4], problem.upper_bound) + self.assertEqual(3 * [4], problem.upper_bound) self.assertTrue(solution.variables[0] >= -4) self.assertTrue(solution.variables[0] <= 4) @@ -185,7 +185,7 @@ def test_should_create_solution_return_right_evaluation_values(self): problem.evaluate(solution2) - self.assertAlmostEqual(solution2.objectives[0], 14.0607692307) + self.assertAlmostEqual(solution2.objectives[0], 14.0607692307) self.assertAlmostEqual(solution2.objectives[1], -11.8818055555) self.assertAlmostEqual(solution2.objectives[2], -11.1532369747) diff --git a/jmetal/problem/multiobjective/unconstrained.py b/jmetal/problem/multiobjective/unconstrained.py index 68581e7f..cd2ade73 100644 --- a/jmetal/problem/multiobjective/unconstrained.py +++ b/jmetal/problem/multiobjective/unconstrained.py @@ -16,7 +16,7 @@ class Kursawe(FloatProblem): """ Class representing problem Kursawe. """ def __init__(self, number_of_variables: int = 3): - super().__init__() + super(Kursawe, self).__init__() self.number_of_objectives = 2 self.number_of_variables = number_of_variables self.number_of_constraints = 0 @@ -29,7 +29,7 @@ def __init__(self, number_of_variables: int = 3): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def evaluate(self, solution: FloatSolution): + def evaluate(self, solution: FloatSolution) -> FloatSolution: fx = [0.0 for _ in range(self.number_of_objectives)] for i in range(self.number_of_variables - 1): xi = solution.variables[i] * solution.variables[i] @@ -41,6 +41,8 @@ def evaluate(self, solution: FloatSolution): solution.objectives[0] = fx[0] solution.objectives[1] = fx[1] + return solution + def get_name(self): return 'Kursawe' @@ -48,7 +50,7 @@ def get_name(self): class Fonseca(FloatProblem): def __init__(self): - super().__init__() + super(Fonseca, self).__init__() self.number_of_variables = 3 self.number_of_objectives = 2 self.number_of_constraints = 0 @@ -56,16 +58,18 @@ def __init__(self): self.obj_directions = [self.MINIMIZE, self.MINIMIZE] self.lower_bound = self.number_of_variables * [-4] - self.upper_bound = self.number_of_variables * [ 4] + self.upper_bound = self.number_of_variables * [4] FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def evaluate(self, solution: FloatSolution): + def evaluate(self, solution: FloatSolution) -> FloatSolution: n = self.number_of_variables solution.objectives[0] = 1 - exp(-sum([(x - 1.0 / n ** 0.5) ** 2 for x in solution.variables])) solution.objectives[1] = 1 - exp(-sum([(x + 1.0 / n ** 0.5) ** 2 for x in solution.variables])) + return solution + def get_name(self): return 'Fonseca' @@ -73,7 +77,7 @@ def get_name(self): class Schaffer(FloatProblem): def __init__(self): - super().__init__() + super(Schaffer, self).__init__() self.number_of_variables = 1 self.number_of_objectives = 2 self.number_of_constraints = 0 @@ -86,12 +90,14 @@ def __init__(self): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def evaluate(self, solution: FloatSolution): + def evaluate(self, solution: FloatSolution) -> FloatSolution: value = solution.variables[0] solution.objectives[0] = value ** 2 solution.objectives[1] = (value - 2) ** 2 + return solution + def get_name(self): return 'Schaffer' @@ -99,7 +105,7 @@ def get_name(self): class Viennet2(FloatProblem): def __init__(self): - super().__init__() + super(Viennet2, self).__init__() self.number_of_variables = 2 self.number_of_objectives = 3 self.number_of_constraints = 0 @@ -112,7 +118,7 @@ def __init__(self): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def evaluate(self, solution: FloatSolution): + def evaluate(self, solution: FloatSolution) -> FloatSolution: x0 = solution.variables[0] x1 = solution.variables[1] @@ -124,5 +130,7 @@ def evaluate(self, solution: FloatSolution): solution.objectives[1] = f2 solution.objectives[2] = f3 + return solution + def get_name(self): return 'Viennet2' diff --git a/jmetal/problem/multiobjective/zdt.py b/jmetal/problem/multiobjective/zdt.py index 2dbf7622..8e05124a 100644 --- a/jmetal/problem/multiobjective/zdt.py +++ b/jmetal/problem/multiobjective/zdt.py @@ -23,7 +23,7 @@ def __init__(self, number_of_variables: int = 30): """ :param number_of_variables: Number of decision variables of the problem. """ - super().__init__() + super(ZDT1, self).__init__() self.number_of_variables = number_of_variables self.number_of_objectives = 2 self.number_of_constraints = 0 @@ -36,19 +36,22 @@ def __init__(self, number_of_variables: int = 30): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def evaluate(self, solution: FloatSolution): + def evaluate(self, solution: FloatSolution) -> FloatSolution: g = self.__eval_g(solution) h = self.__eval_h(solution.variables[0], g) solution.objectives[0] = solution.variables[0] solution.objectives[1] = h * g + return solution + def __eval_g(self, solution: FloatSolution): g = sum(solution.variables) - solution.variables[0] constant = 9.0 / (solution.number_of_variables - 1) g = constant * g g = g + 1.0 + return g def __eval_h(self, f: float, g: float) -> float: @@ -66,7 +69,7 @@ class ZDT2(FloatProblem): """ def __init__(self, number_of_variables: int = 30): - super().__init__() + super(ZDT2, self).__init__() self.number_of_variables = number_of_variables self.number_of_objectives = 2 self.number_of_constraints = 0 @@ -79,19 +82,22 @@ def __init__(self, number_of_variables: int = 30): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def evaluate(self, solution: FloatSolution): + def evaluate(self, solution: FloatSolution) -> FloatSolution: g = self.__eval_g(solution) h = self.__eval_h(solution.variables[0], g) solution.objectives[0] = solution.variables[0] solution.objectives[1] = h * g + return solution + def __eval_g(self, solution: FloatSolution): g = sum(solution.variables) - solution.variables[0] constant = 9.0 / (solution.number_of_variables - 1) g = constant * g g = g + 1.0 + return g def __eval_h(self, f: float, g: float) -> float: @@ -109,7 +115,7 @@ class ZDT3(FloatProblem): """ def __init__(self, number_of_variables: int = 30): - super().__init__() + super(ZDT3, self).__init__() self.number_of_variables = number_of_variables self.number_of_objectives = 2 self.number_of_constraints = 0 @@ -122,13 +128,15 @@ def __init__(self, number_of_variables: int = 30): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def evaluate(self, solution: FloatSolution): + def evaluate(self, solution: FloatSolution) -> FloatSolution: g = self.__eval_g(solution) h = self.__eval_h(solution.variables[0], g) solution.objectives[0] = solution.variables[0] solution.objectives[1] = h * g + return solution + def __eval_g(self, solution: FloatSolution): g = sum(solution.variables) - solution.variables[0] @@ -152,7 +160,7 @@ class ZDT4(FloatProblem): """ def __init__(self, number_of_variables: int = 10): - super().__init__() + super(ZDT4, self).__init__() self.number_of_variables = number_of_variables self.number_of_objectives = 2 self.number_of_constraints = 0 @@ -167,13 +175,15 @@ def __init__(self, number_of_variables: int = 10): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def evaluate(self, solution: FloatSolution): + def evaluate(self, solution: FloatSolution) -> FloatSolution: g = self.__eval_g(solution) h = self.__eval_h(solution.variables[0], g) solution.objectives[0] = solution.variables[0] solution.objectives[1] = h * g + return solution + def __eval_g(self, solution: FloatSolution): g = 0.0 @@ -199,7 +209,7 @@ class ZDT6(FloatProblem): """ def __init__(self, number_of_variables: int = 10): - super().__init__() + super(ZDT6, self).__init__() self.number_of_variables = number_of_variables self.number_of_objectives = 2 self.number_of_constraints = 0 @@ -212,13 +222,15 @@ def __init__(self, number_of_variables: int = 10): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def evaluate(self, solution: FloatSolution): + def evaluate(self, solution: FloatSolution) -> FloatSolution: g = self.__eval_g(solution) h = self.__eval_h(solution.variables[0], g) solution.objectives[0] = solution.variables[0] solution.objectives[1] = h * g + return solution + def __eval_g(self, solution: FloatSolution): g = sum(solution.variables) - solution.variables[0] g = g / (solution.number_of_variables - 1) diff --git a/jmetal/problem/front/DTLZ1.pf b/jmetal/problem/reference_front/DTLZ1.pf similarity index 100% rename from jmetal/problem/front/DTLZ1.pf rename to jmetal/problem/reference_front/DTLZ1.pf diff --git a/jmetal/problem/front/ZDT1.pf b/jmetal/problem/reference_front/ZDT1.pf similarity index 100% rename from jmetal/problem/front/ZDT1.pf rename to jmetal/problem/reference_front/ZDT1.pf diff --git a/jmetal/problem/front/ZDT2.pf b/jmetal/problem/reference_front/ZDT2.pf similarity index 100% rename from jmetal/problem/front/ZDT2.pf rename to jmetal/problem/reference_front/ZDT2.pf diff --git a/jmetal/problem/front/ZDT3.pf b/jmetal/problem/reference_front/ZDT3.pf similarity index 100% rename from jmetal/problem/front/ZDT3.pf rename to jmetal/problem/reference_front/ZDT3.pf diff --git a/jmetal/problem/front/ZDT4.pf b/jmetal/problem/reference_front/ZDT4.pf similarity index 100% rename from jmetal/problem/front/ZDT4.pf rename to jmetal/problem/reference_front/ZDT4.pf diff --git a/jmetal/problem/front/ZDT6.pf b/jmetal/problem/reference_front/ZDT6.pf similarity index 100% rename from jmetal/problem/front/ZDT6.pf rename to jmetal/problem/reference_front/ZDT6.pf diff --git a/jmetal/problem/singleobjective/test/test_unconstrained.py b/jmetal/problem/singleobjective/test/test_unconstrained.py index 2447b668..5f2ae81c 100644 --- a/jmetal/problem/singleobjective/test/test_unconstrained.py +++ b/jmetal/problem/singleobjective/test/test_unconstrained.py @@ -31,7 +31,7 @@ def test_should_create_solution_a_valid_binary_solution(self) -> None: def test_should_evaluate_work_properly_if_the_bitset_only_contains_zeroes(self) -> None: problem = OneMax(512) solution = problem.create_solution() - solution.variables[0] = [False for i in range(problem.number_of_bits)] + solution.variables[0] = [False for _ in range(problem.number_of_bits)] problem.evaluate(solution) self.assertEqual(0.0, solution.objectives[0]) diff --git a/jmetal/problem/singleobjective/unconstrained.py b/jmetal/problem/singleobjective/unconstrained.py index 56a66c11..f27bcaf4 100644 --- a/jmetal/problem/singleobjective/unconstrained.py +++ b/jmetal/problem/singleobjective/unconstrained.py @@ -13,16 +13,15 @@ class OneMax(BinaryProblem): - """ Class representing problem Kursawe. """ def __init__(self, number_of_bits: int = 256): - super().__init__() + super(OneMax, self).__init__() self.number_of_bits = number_of_bits self.number_of_objectives = 1 self.number_of_variables = 1 self.number_of_constraints = 0 - def evaluate(self, solution: BinarySolution) -> None: + def evaluate(self, solution: BinarySolution) -> BinarySolution: counter_of_ones = 0 for bits in solution.variables[0]: if bits: @@ -30,6 +29,8 @@ def evaluate(self, solution: BinarySolution) -> None: solution.objectives[0] = -1.0 * counter_of_ones + return solution + def create_solution(self) -> BinarySolution: new_solution = BinarySolution(number_of_variables=1, number_of_objectives=1) new_solution.variables[0] = \ @@ -41,8 +42,9 @@ def get_name(self) -> str: class Sphere(FloatProblem): + def __init__(self, number_of_variables: int = 10): - super().__init__() + super(Sphere, self).__init__() self.number_of_objectives = 1 self.number_of_variables = number_of_variables self.number_of_constraints = 0 @@ -53,12 +55,14 @@ def __init__(self, number_of_variables: int = 10): FloatSolution.lower_bound = self.lower_bound FloatSolution.upper_bound = self.upper_bound - def evaluate(self, solution: FloatSolution): + def evaluate(self, solution: FloatSolution) -> FloatSolution: total = 0.0 for x in solution.variables: total += x * x solution.objectives[0] = total + return solution + def get_name(self) -> str: return 'Sphere' diff --git a/jmetal/util/front_file.py b/jmetal/util/front_file.py index 21e62d94..b8c432c3 100644 --- a/jmetal/util/front_file.py +++ b/jmetal/util/front_file.py @@ -22,13 +22,13 @@ def read_front_from_file(file_name: str): return front -def read_front_from_file_as_solutions(file_name: str): +def read_front_from_file_as_solutions(file_path: str): """ Reads a front from a file and returns a list of solution objects. :return: List of solution objects. """ front = [] - with open(file_name) as file: + with open(file_path) as file: for line in file: vector = [float(x) for x in line.split()] solution = FloatSolution(2, 2, 0, [], []) diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index 91ab0642..403180df 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -1,5 +1,6 @@ import logging import warnings +from abc import ABCMeta from typing import TypeVar, List, Tuple from bokeh.embed import file_html @@ -30,6 +31,8 @@ class Plot: + __metaclass__ = ABCMeta + def __init__(self, plot_title: str, number_of_objectives: int, xaxis_label: str='', yaxis_label: str='', zaxis_label: str=''): self.plot_title = plot_title @@ -63,7 +66,7 @@ def __init__(self, plot_title: str, number_of_objectives: int): :param plot_title: Title of the scatter diagram. :param number_of_objectives: Number of objectives to be used (2D/3D). """ - super().__init__(plot_title, number_of_objectives) + super(ScatterMatplotlib, self).__init__(plot_title, number_of_objectives) # Initialize a plot self.fig = plt.figure() @@ -152,7 +155,11 @@ def update(self, front: List[S], reference: List[S], new_title: str= '', persist self.axis.autoscale_view(True, True, True) # Draw - self.fig.canvas.draw() + try: + self.fig.canvas.draw() + except KeyboardInterrupt: + pass + plt.pause(0.01) # Disconnect the pick event for the next update @@ -193,7 +200,7 @@ def __pick_handler(self, event, front: List[S]): class ScatterBokeh(Plot): def __init__(self, plot_title: str, number_of_objectives: int, ws_url: str='localhost:5006'): - super().__init__(plot_title, number_of_objectives) + super(ScatterBokeh, self).__init__(plot_title, number_of_objectives) if self.number_of_objectives == 2: self.source = ColumnDataSource(data=dict(x=[], y=[], str=[])) @@ -228,7 +235,10 @@ def plot(self, front: List[S], reference: List[S]=None, output: str= '', show: b reset_output() # Set up figure - self.figure_xy = Figure(output_backend='webgl', sizing_mode='scale_width', title=self.plot_title, tools=self.plot_tools) + self.figure_xy = Figure(output_backend='webgl', + sizing_mode='scale_width', + title=self.plot_title, + tools=self.plot_tools) self.figure_xy.scatter(x='x', y='y', legend='solution', fill_alpha=0.7, source=self.source) self.figure_xy.xaxis.axis_label = self.xaxis_label self.figure_xy.yaxis.axis_label = self.yaxis_label From eff1bcb5d9736dc66e3d4ce82c5efee8cda02e7e Mon Sep 17 00:00:00 2001 From: ajnebro Date: Thu, 12 Jul 2018 13:20:09 +0200 Subject: [PATCH 82/90] Minor changes --- requirements.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 517d7f6a..14dac7a2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,5 +4,4 @@ pytest==3.1.2 PyHamcrest==1.9.0 mockito==1.0.11 matplotlib==2.0.2 -numpy==1.13.1 -dask[complete]==0.18.0 \ No newline at end of file +numpy==1.13.1 \ No newline at end of file From bd4f21f6d52272feaadc1b409d5586b04f25d1aa Mon Sep 17 00:00:00 2001 From: ajnebro Date: Thu, 12 Jul 2018 13:31:07 +0200 Subject: [PATCH 83/90] Minor changes --- examples/multiobjective/nsgaii_full_settings.py | 11 ++++++----- examples/multiobjective/smpso_full_settings.py | 7 ++++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/examples/multiobjective/nsgaii_full_settings.py b/examples/multiobjective/nsgaii_full_settings.py index 97e6cc99..23483ca7 100644 --- a/examples/multiobjective/nsgaii_full_settings.py +++ b/examples/multiobjective/nsgaii_full_settings.py @@ -1,14 +1,14 @@ from jmetal.algorithm import NSGAII from jmetal.component.observer import VisualizerObserver, ProgressBarObserver from jmetal.component.comparator import RankingAndCrowdingDistanceComparator -from jmetal.problem import DTLZ1 +from jmetal.problem import DTLZ1, ZDT1 from jmetal.operator import SBX, Polynomial, BinaryTournamentSelection from jmetal.util.graphic import ScatterMatplotlib from jmetal.util.solution_list_output import SolutionList if __name__ == '__main__': - problem = DTLZ1() + problem = ZDT1() algorithm = NSGAII( problem=problem, @@ -28,11 +28,12 @@ front = algorithm.get_result() # Plot frontier to file - pareto_front = ScatterMatplotlib(plot_title='NSGAII for DTLZ1', number_of_objectives=problem.number_of_objectives) - pareto_front.plot(front, reference=problem.get_reference_front(), output='NSGAII-DTLZ1', show=False) + pareto_front = ScatterMatplotlib(plot_title='NSGAII for ' + problem.get_name(), number_of_objectives=problem.number_of_objectives) + pareto_front.plot(front, reference=problem.get_reference_front(), output='NSGAII-' + problem.get_name(), show=False) # Save variables to file - SolutionList.print_function_values_to_file(front, 'NSGAII.' + problem.get_name()) + SolutionList.print_function_values_to_file(front, 'FUN.NSGAII.' + problem.get_name()) + SolutionList.print_variables_to_file(front, 'VAR.NSGAII.' + problem.get_name()) print('Algorithm (continuous problem): ' + algorithm.get_name()) print('Problem: ' + problem.get_name()) diff --git a/examples/multiobjective/smpso_full_settings.py b/examples/multiobjective/smpso_full_settings.py index 6626d0e8..0b9014ea 100644 --- a/examples/multiobjective/smpso_full_settings.py +++ b/examples/multiobjective/smpso_full_settings.py @@ -27,11 +27,12 @@ front = algorithm.get_result() # Plot frontier to file - pareto_front = ScatterMatplotlib(plot_title='SMPSO for ZDT1', number_of_objectives=problem.number_of_objectives) - pareto_front.plot(front, reference=problem.get_reference_front(), output='SMPSO-ZDT1', show=False) + pareto_front = ScatterMatplotlib(plot_title='SMPSO for ' + problem.get_name(), number_of_objectives=problem.number_of_objectives) + pareto_front.plot(front, reference=problem.get_reference_front(), output='SMPSO-' + problem.get_name(), show=False) # Save variables to file - SolutionList.print_function_values_to_file(front, 'SMPSO.ZDT1') + SolutionList.print_function_values_to_file(front, 'FUN.SMPSO.' + problem.get_name()) + SolutionList.print_variables_to_file(front, 'VAR.SMPSO.' + problem.get_name()) print('Algorithm (continuous problem): ' + algorithm.get_name()) print('Problem: ' + problem.get_name()) From fd5d1c22103ee9f415f19fc2d1caaa006cb80080 Mon Sep 17 00:00:00 2001 From: benhid Date: Thu, 12 Jul 2018 13:55:23 +0200 Subject: [PATCH 84/90] Added docs --- README.md | 2 +- docs/source/NSGAII-ZDT1.png | Bin 0 -> 52697 bytes docs/source/api/jmetal.component.rst | 28 ++- docs/source/api/jmetal.util.rst | 10 +- docs/source/conf.py | 2 +- docs/source/contributing.rst | 201 ++++++++++++++++++ .../contributing}/WorkflowGitBranches.png | Bin .../source/contributing}/abstract.png | Bin .../source/contributing}/bad_access.png | Bin .../source/contributing}/class_header.png | Bin .../source/contributing}/generic_class1.png | Bin .../source/contributing}/generic_class2.png | Bin .../source/contributing}/generic_types.png | Bin .../contributing}/generic_types_fixed.png | Bin .../source/contributing}/good_access.png | Bin .../inheritance_generic_to_generic.png | Bin .../inheritance_non_generic_to_generic.png | Bin .../instance_with_generic_class_wearning.png | Bin .../instance_with_generic_types1_wearning.png | Bin .../instance_with_generic_types2_wearning.png | Bin .../source/contributing}/jMetal5UML.png | Bin .../source/contributing}/jmetalpy.png | Bin .../contributing}/method_way_sphinx.png | Bin .../contributing}/property_annotation.png | Bin .../contributing}/property_functional.png | Bin .../python_functional_programming.png | Bin .../python_imperative_programming.png | Bin .../contributing}/python_poo_programming.png | Bin .../source/contributing}/types_in_methods.png | Bin .../contributing}/with_getter_setter.png | Bin .../contributing}/without_getter_setter.png | Bin docs/source/examples.rst | 2 - docs/source/index.rst | 19 +- docs/source/runner/logger.rst | 15 -- docs/source/runner/nsgaii.rst | 55 ++--- docs/source/runner/observer.rst | 4 +- docs/source/runner/smpso.rst | 20 +- .../multiobjective/nsgaii_full_settings.py | 18 +- jmetal/__init__.py | 2 +- jmetal/algorithm/__init__.py | 2 +- jmetal/algorithm/multiobjective/smpso.py | 1 + .../singleobjective/evolutionaryalgorithm.py | 10 +- jmetal/component/__init__.py | 21 ++ jmetal/component/quality_indicator.py | 14 +- jmetal/component/ranking.py | 6 +- jmetal/util/__init__.py | 11 + jmetal/util/front_file.py | 10 - jmetal/util/graphic.py | 6 +- jmetal/util/laboratory.py | 4 +- resources/pages/auto_doc.md | 123 ----------- resources/pages/code_style.md | 17 -- resources/pages/features_python3.md | 58 ----- resources/pages/poo.md | 28 --- resources/pages/profiling.md | 55 ----- resources/pages/project_structure.md | 5 - resources/pages/workflow_git.md | 36 ---- 56 files changed, 333 insertions(+), 452 deletions(-) create mode 100644 docs/source/NSGAII-ZDT1.png rename {resources => docs/source/contributing}/WorkflowGitBranches.png (100%) rename {resources => docs/source/contributing}/abstract.png (100%) rename {resources => docs/source/contributing}/bad_access.png (100%) rename {resources => docs/source/contributing}/class_header.png (100%) rename {resources => docs/source/contributing}/generic_class1.png (100%) rename {resources => docs/source/contributing}/generic_class2.png (100%) rename {resources => docs/source/contributing}/generic_types.png (100%) rename {resources => docs/source/contributing}/generic_types_fixed.png (100%) rename {resources => docs/source/contributing}/good_access.png (100%) rename {resources => docs/source/contributing}/inheritance_generic_to_generic.png (100%) rename {resources => docs/source/contributing}/inheritance_non_generic_to_generic.png (100%) rename {resources => docs/source/contributing}/instance_with_generic_class_wearning.png (100%) rename {resources => docs/source/contributing}/instance_with_generic_types1_wearning.png (100%) rename {resources => docs/source/contributing}/instance_with_generic_types2_wearning.png (100%) rename {resources => docs/source/contributing}/jMetal5UML.png (100%) rename {resources => docs/source/contributing}/jmetalpy.png (100%) rename {resources => docs/source/contributing}/method_way_sphinx.png (100%) rename {resources => docs/source/contributing}/property_annotation.png (100%) rename {resources => docs/source/contributing}/property_functional.png (100%) rename {resources => docs/source/contributing}/python_functional_programming.png (100%) rename {resources => docs/source/contributing}/python_imperative_programming.png (100%) rename {resources => docs/source/contributing}/python_poo_programming.png (100%) rename {resources => docs/source/contributing}/types_in_methods.png (100%) rename {resources => docs/source/contributing}/with_getter_setter.png (100%) rename {resources => docs/source/contributing}/without_getter_setter.png (100%) delete mode 100644 docs/source/runner/logger.rst delete mode 100644 resources/pages/auto_doc.md delete mode 100644 resources/pages/code_style.md delete mode 100644 resources/pages/features_python3.md delete mode 100644 resources/pages/poo.md delete mode 100644 resources/pages/profiling.md delete mode 100644 resources/pages/project_structure.md delete mode 100644 resources/pages/workflow_git.md diff --git a/README.md b/README.md index 36d73a18..09bc238b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@


- jMetalPy + jMetalPy

diff --git a/docs/source/NSGAII-ZDT1.png b/docs/source/NSGAII-ZDT1.png new file mode 100644 index 0000000000000000000000000000000000000000..ac19d046bf6d460586084aa1530fa140690367c0 GIT binary patch literal 52697 zcmeFZWn5KV_b$9aKm-&EB?T2kQbJHcLQy0nBn3$UDFJE8y)9G(2?;?;=}ijK5{lB@ z(%s#?-?8@ge&T=L^L{!X&WCsXe)pq~d(F9KjJU=%#++}J74ICTpr=5gP={q@ZmFP9 zr0~}RW#nY=hedCj3;aQ1e^XYC93FRa<2UgC4?U65vPYrL{6zjEvTkw|N1<3yvbS!i zJ&l;{b8%1`+pAn^jI3j&>+p}0(^4S6ajN{nMT_4U$uxFv1`GLPdCdFMUx{yiO~QOp zIqiKaRGWtF)@ScG>7#% z8;cvA2gA;LHmvkkW^&gahY=yq1G`&=gukIspQTXbgui#u60s2eW?)2uA^Z*FdkjTP z_^Yt=|BWvSua#3vm@SW1i!6L!2?`2g4XtG>=QF1Da$TJ~Hnj{xKYD=#gF>}QsV3ZA zI(UuUll|^Tx7EDC7=5*?%C`O8K@blkOOjPw{xT2Awk=B-> zFX2nee^crD(o6BZRn_2-kdE<@shx$=&e=cNLUyAvYqNh;=el!LM=E@2n3*$Ll_Yd^ z3muw;I(1@SpK+D3>`YHnXEt%Ueuj;em1H-p?jwJ!#)imP+91bKhO6oNkGKcjoCJQJPk^^v?R+hsKGNR`D-CYA==Q%ojbumeTC$y6?>8 zsq39MaUxdQmp<8~He|ZLxF|h;n4-^lz(c#xA^G|lCFSV&bcxEh1JvT1F*^EZ{O&}1 zZYM{%jMMem)$&ZYr-VK@ z>WJIhn3-&j9qX5HT}^s_Mhx3mUlk+hBWtoD4f}A6hL@3EUMA9(| zPp_X*h`O$IsbuqEWPj((nnhQp;XdEU%dW2b@rj9C*RE-Wm?S49$vnujR+p81TUx)r zw{zfT688E^oglrK>$mTEHf1xsq4K5?wqAjOful}E>S}6nFb=cED6xIv0gsKy3rbO` zQ>}@Xd)sSr3JPh>rm2&Svnd%REinD|JevXfJ}!E0t*l!EXk0OC_0W^a;*EaQM~@!8 zOrh}YNPA#e<$pG(WWVXN)b{3x-vK?#o?NS(PRGfn8|LQbL>Wxt?)P^#7CNKE+*U{Y zB*?ytTXt}pn3`IyPBy!44!s_;E2!xc{Mh)_u$&A;Gex?S^}+?R2%Emb;6-W_hRh3f z6oq046LZU*FP!0ZoN9@0n7?M;5{FsLFsghXF5-ygEt(Z5=$psn>SbuobY^sZx&3Z+ zdnUuOHiYNKnk~rQOqglZQZ$3t=alq9xx9YYlm-c$yO4Eney`Ag=T2Hb8s~uws2!^w z8292J_4MG67ed?aq@<+#Gm(mk0)m2T^F<4CB4?;NDp8rUS(B8!`DM97(GKpyJux?4 zSU9GcXcg`**B;PgxMCeac7*Z%Tu%9G>dqhzRZb5y=*0G7IrUm2dSBJDBQ=0^%UxV- ze{*CThL~g4eC}H0Gu%o2+{aoud+!;qsbrfrrZ)=(zkTs%k29oN<`T=?tO7 z#f@aIZLiOz9AtJ^{v>SG;!VSajr864bwY{cCEBVdw;f)^uh!z=4;n9Y%aZ9_pZiLE zO>J#!Vzj6B*vdLq05(i3gl%f`F}8Gf?9%?mc>O2Mp}+|5U;eK(;BB4O?%qzq=)bWup(;6BTs{p?mK(la_bc zaas-MA}8k!)1E*}Kh&icFn$AapQyh#t-0SBh2D1og>ZB1*W^q8zAWds&>#5~^!LC` zM1K$Wg83r4@j$_uB)twcjkuvv0=FwtuyBa_`XUCMO2@%lS z7bTBC%=agfK|XGV>N=;y1ks9?=d#0*A6L|{7SOL6=DYX?y%PZkPi z(p7bIBH~6GwL}d;-?|GOE$`2G2Q`ZC+y$G|hB%^Y_Ty$C4I)nlF>-Qp-|Qz8i*frq z^q^WI4wErqf~Fmt`|>HM%acdc9v9U<; z4<9}pXwXc(Z!5RKW!e1YHqo=;qFwQ#AHFYxkobgWMH@|0E_(hIO5q&2H>?by_b8glI=!;^|_{{_cdt zOoQk`>OEiZ%&mYCxLYsNFfgQm(c}~qRE-pMPPfx|sLQXQiry?|CKgT%<1>5?TX|}^ zL@9qRw}-gF-rl~v;|dC8mXGL6X26{@F2B&$8M|!6F-jItdw|u z#wZ%SUl8?l_z^OJuq$;0vdQmGNO@5;!~7Xr z#Fd3&-m4im1n)ncGXK;RRXQOk$b3+uj1@?7x>8XWB=~*eSBXy;1X zJ^a9GNZ51tDb9Wm)J+e)=jh8UQKG{V8Wxt^o}zj1B_{TcU&pfp2eES_;Op$JGP)wh z0a}0~XC2&IpX;d|vupp6nA`=BfiClIiPY;O;jnRx?-%#&ud=bR4Qjmr*GOrJ1N35e z4n=}0d$hlvSGpzTyHJYLQxe}YPFp}W9TZ?Q+LxUPePpmEn9H$}$vNqc-x-VUZ^;c} z8#;Y16OrK(XisHBfAjF}Jez3TcZE;FIq6@8H8S+(1_pl(Ju%x{92)DsY}s*FQ^)od z?t95&G8I*1&nz>F$0bU)#yV-O!zzxugyFV?n?@-J|!JGz9>WVaC|YtRExE?pFXXKEI8(#|n`m z?GlzYxc$Av-H2@P3|xT6Rwf!XH8euNEpS;q(9ucN)N{Fw%)nvY(AL(r%;gWAm-?R) zkD`!E`g&tFj*V)f4wK4dK6zPZ2dc@aXk&7%dgKD##iO&bvtMAd#Q_@n;_?BVOt&Sg zDtGF7ZjJ4a;6TTT&OW>iVwiA7%(X4ON?SldwG_9vaKOnn>Zoqe=gF7ZJPBH*q6^)BsAg%^$oj|9tGc^k(Bs zxpkS4x-jDmtVL6&iLvpf-@AA3a_lD>IC~P~;$E604rEd2m#How5v`{_IP{Y(~vam&j0Ol#9A8D1W(e%`Zv zMV)9JCn*>iM)~b-DXgfZ48Ti^pDz#XuYjIS0?eh*LIdt>1s|Srm_e9?`#cW^NAi;c zzCl4JaZ8>0Xr>U80Dbgc4iZt}wx9uabaa#x-6*!viwU!I>Y<8@i~EIUWME)`!CdMQ zchTCY{z>=UV{fgK=#%GVt8O)$;x&z?#&D|m=g*&G=r90_kEKEse)%MRi@RX6_84?N zCL|Xvl!%UcBf@e(ZwGK=ZO+UdNrJQe<12u*2UjPza6%Tr-C(Qs(02e_09csrEwF#dB{~oGn&N6H zIHYr`5KWsY<6Q=SUQZf_YQkn?D7V%Z@LaFH4?rxDBKzS2-mnH+3L2DQFe?zMczsI% z;WlrGxR&T14L;!D<8vwlkxt#_`y+rTNj>_it!n$(RqnR7G4C%Pq&azVQ@;p7NWW<` zZ)IX7VdZqnT#x{Q6ZG=%AtDxl63!#OSIFu-w`=wHk1vZKE+;2PMJk#W2y1C+ZG%gm zlR)opO^hu)y{XZP;CqN9wj05dX%DTCaP91sGw% z|N2Gp*lTerF?!nfNgO*hBB#_j$wjc)&D-fGdS@8~q!^_hlCW3#c=%jE}v6PYsm z`B?!qE4&P18xh&?G3-&2cI1z7S5s-vQVp1;vOYm?BxR(b8#s_s@Wlzt;#~ zD&5VJ@V`tIt3hP&`0?Yi?9uVMu=CN4nj<^67|QuBgWJWq+_>=!PE+C zhzM4qsp$l6K{QM05*fS&`&VPN9q{2ptYG7H!G}V!m8QD@cV<9FI@v;XzTkFBaVw>v z!NKtWEu}L>0BJM@p;@R=sLXf>^dvz5UBLibIz%>3s5&|2f{ky_wR*4ykQsJB9qe<^ z$B#)ZEh=+=vhN^3r~m1QuiYmp;0DeQYN6RhfjtQd4NZjUZD)7@WcUU_U!>c7K}}tq z8b~nG8tm&NSb=UpmcrJ(Nw8Uy61Xj;vOUB-KC#vc(Q}<*!)*calj1bj-9Fhk_!3-s z2RZ|ZL%kpus(J9pI)Q*oeg= zzrGC5HLm(_A+DS1%o`IDxN8Qjevj(Ir(n4{5L#%)?UAwZB;dcaECoeH#j=%M)+uC& zVDvp9YR8l8|~fswnn~8qPe{n*ts;*sqR;}_c?ZwI+l7*Ni1x|P|@$Z+uR9Ja^~_3maAb>cqB1`+vDqeFaP z#bi3ubsftOUm@x91bPqPe{h8_Ln4Ilq(YX-jx!zfqE4y8R^2DnHl1(2JH>6Y`$D&Fnb%IXnMhTc#Ne;SnE`qx~A@!ggy{v zAO-3(JGVao3sfH|s+m!|9$x4)r)^#YE}+k2qpzm1Q8Q67^5=a+2YZo7i{>w{04Zk7 z_Z3+JeFO>^u915GGlG`ivPZq~2A&0V`L36GU%5L9h4OS7tvZH4K+cO7o4}$uZY~;L zi&PW>M^?JOmH~LrG#Q|+WA2KDq2XtUqt?LESqzkT0Gz4+bVc*w!!IJv^QpYLg;i6= zH>55;?#We%c3*zGKHrxT7tGkP38w?;+80)N0`V8l&?kkjxy_Ce4D z@?`Q8OCo=wP-PW}slh)C=Rub6&;S1-u_R$7{{Q9qKQ9#a(uJTH;?YVHyNfSa5$4)X zgbpAA@_a6%lDzecT4EPL|5(61`z(J&*3r*gQ}S?7&{Gqw5UO%zod~X$F;wEqC8{FB zyXA_sjhPG;muFut`E0+T!{EC@{a>HAfMNch9OFIXh5lmg?@zxXfrUJ8!7Z@Y0#s4} zQb(%-&Q93_4?%zZX(mwh$(x%`b8H6m5Iz+mr<*OzgcbW)OE*Ql_zpak*kcdKSLk}I zwYyG4Iuq;R0OqaMaAlZ5C*haP1A*OU%nc{BQr`GTL>rILSwCJJd_B8=rO)Am#BOa} zUE9xBlsRBPi#LbgO*egh0nioLh1Cr79+$BYp)JcQw7rcCSlnYfNhw-fWN)=~Z7y$s zlZ`FDVMnXLE*^p#cG;Smnie1clJWdM1g8#vOhS{L7y7qhTnO`~YhNz}2Kjbm=RIbv ztkGai-hy+wNR|$eCjjx-s=bW?<`B;_=v`acK(P6MT1KdGiZY6dNRa(yCZkjjf%TM^ zzQ-($RKAYSHB&dH;TWjX{2Z$+Ue2C4re9KTze8(KZX+K z`~Ca({zz9>7iUk!@84T~VrP`9EV8)eLrh-H?&r|N(*C~B&nYCAVq?iHRm3jVPSNq*!ghL0ffxTUxClANk4D#H>^MSVikrht;vOG@1~tk>px zGy{!krPX*Ng^VYuxNi6OOgnFhmCFT`4+exM=~GE%aZ7o9PTD;}EcE-MS0rDQ;T0eA zu0tbqYsZKT4zxnD3}@?D>*~jNZCE1Rx?r&y>sDf*Wow(B6zSdDI{kSr{*}5l$*{ka zn6B7K(_0g!DC|STj=kw#U{O{jbmdfz@A=*UpGopF4u(4QynA>4Xt@iyBt%ED(#h61 z7}s#7J=M-rx8P_ENM=3HQ5Q_`+$672na?C?}?nq~SuY4g{Ynj}<;p>nyV-bI?<($r0{65-o2mI*Gs5OT7~ne~vbW0eJ; z0FbaqPG0^%KW?d#SqL;+R^{f+=hg*dA^sgY%qO*O*YMQ0bG^Uj+8!3G$!H(+AUx$< z%Egv=!Wh)vvX$K%g+N>dA{g8*BuQ48PoF$FITosa#7x3&v`Tvo;%$_!bDtvuTu?iOq|aGle#s4mBGdv5cx*@GwxYE+3=iJcXudS0PkJ{DKHC1%?1y3*e$iMs zzmnuXvn%S;&N6i+ij$?Y+S1GM6^M?YkA=PF)vRIO7G zpgK<#Oyn3F_lv7G3lbW`!}RNl1DOZ^hjx7=B3Jvlv7)4#N3aXz?8K5W#~Y&2(}g_v zflFQmk~x@QuZAnID?qAyqJwMG?wUogo zk2vZBP7P5I=FC}{PAYjc(1+Ee!Wg@HKy~A8_(lDpSydW-wIH)~UE1P1#rXw{BIL>qk-S{*KP+VDzSdxVt{Igww4o%5~T|rPp z1mpN$4D=jw)FjEkvOZSnS~Th$ zz8Ea+L^Di1Xv}jR*eG!oapSC(@pgDi80y$j6!8sC zKFV(`UsXa3tEaB-x7!v*b|+YM>lNz4dgDz58~$BMmM9`}lFwC~EpGiA#&jBp2U?5T z5Tnt${m+)fSirZBF4w!$@k<9=`Or#jJ@Wj>Nhlm4KSIQ!e7H7C&FmCedu|hVkcs+r zd4l6(IZlpxX0bW?p>dJ4vtzM3aj=`v=H&sT%|xSwW8W#lGB6@<(t3SXJ1>-!n=Fl` zik&tk{rmC>B9@~ssqT0&w!7;x+FdLUIF|6A%Xzk1MkV3As)qS*2KSHRstf%a=~>ZL zNB;4i>VR^e2Z60*xbppT{kto*GfQ%T-_K+SU+PaKJ%8G)$J+|R>91m46@ci-@wMMt@p^cfupDn zbpQQqNFSkq+_&t0O5l4ust$9bmywfG0Z!)C0z`%o(Y-GCs|;AsA0a4b2&K@sf&AV_ zE`mrVoq-iXv^RNiEu&;x4w6M3K6HXVb&lctlpI6)1UqLvNa;1|<1AOPr0PUW5Wwb_ zx|nD57kPQtnc1E0s#UDf$0` zsW;7@J%a1?N~r8N-aPrK(1euM1rc-8I>mSnp69`Y-C(RdZV=<;!y2ozsTpE&AIun_ zsaFL8_+ep|kzs9DEUCv24IE0iJN9YI5KAaOLO_t@;rm&u`Xi+`a(KQ`m}qId;Ue^z zL=TfaAigy!=>8*5{fQM}32wduZ6ivIu+#oA7df)K1zA*hSOSqx@EIo+w~Hs`{$_Y* zLM#1W{YdH7Sqr3MUx>AuS`0~1maF~eipi;cY2cY+Z#C7}ESVAvc0;GHTlFOl4-fNc z61qS7=3o#}PE)mG0zH%M%qt~5x{!RSrs7EN`oDkqM zj=T`PXm6Lm*r1=~5ZV*JD&K0deHVbEoPFHwOoGj6YT`d|H0jmw@IyAIyWFSugU6nT ze9Ll(_fGxt&yW`>!6u)ARE&^QN0(fA=?U&~m69;#1T5iWH6Z^MKLX=*zZN~Wcwk0T zla+c@^Dj&Usvzc+y9BPy@d5s2Od%A3wLMo=yp}e&-ejw-c zys-E*EfZ`=dp7;=&OU^l~Xb}OE?K+BqD;^1U z3ytj&?Bg&0kr{n3Rf#cZOWzTVU-2U7{Gl3 zKgi1lvv*Mu#K49YDAlV&7HauS-3P%24*lvSCUm5&Vzs}qETqR%D}3lq{CS9%CCL}y zjUv84`VRQpyMb+~R)Quv(Vv5eIP3~^mtDVim)I5chwZ$tc=MMChf2`}N;lGYtAyoJ4sA5)VgsBvP|oRejL(aNe`><01A(kw>B z*BX{Nig}8ffdMDS2|i0ws^S8RBvaQPchmnxMFy`DOAej{SA8>uFDaK);~94?h3##^ zE|vlrs2H#?5pD2MAg8mNVfe2F^aKr#I0u&W$9DIw$jf%Z+a%!c6ax%t<@i;eTbJtg zXps?I>rbc+N;;tH!+Rqytvb*U|1w4u@_cR2T76r`$d_k~UDD`z=m>`7Dh+Hb6Zm#> zX>DbzJnn&W<$O2)8lW;;P2` zbeZHbVcWr`u0k%~s{lx2c$$=9)f_L@2PC9KXqvAK*TYr>vVxfcGi~{!inKfT;U`uO zc6Rna6TG3okiCo~$B1+!Q7Le|A(Em0C;kPzNW7H%a6#d@Mdc$F{J*iZfo(bZq^J+LHvO$D zRMm6~L7x5WFY6@ZMmeNSt&1Kp<6Ao_IBn(vH;=r zdgS$Cry`-*TtkcX%11;)`dVJ)O%vNX4JwJQ6{}SCukb^OIXg&)ktClJv$BbYS1i+V zIJ3Ne!g3;ynHe&TYtz@TAmBIha9OLhM>X&UA4Sgz;N+Ih5^q6odQ8u0tTF^$ndk7W znvUYX9i+;yakptsUY#@A{cI{h!!O^0&3=P;=Q|cnbCD7_d;?S)8+7)vP_*!1pKv?g zA|OdRc<}F&1Eiatn$eoe-UIPiv+sDF%!&WC$sZK{Y{!+7j6#>fY5}ezL<-T#y*u`6 zHFcUlb?ET#m_at{8Q zf)FMQK<&bQ=W)>soFm&*@l-PZc$MHDgpUC1W{`vbM%fW$?v^caZ*lqmHa^w)1miQ~ zxG*EaKF+x2Ge!6Iuhb}HlF*W8pZN5QmEa>xu2QAtbXa&yZS!doc5wD3>gXFxV@$EaKvN=BE=$`@{$8s11b(gK2=lkS|uV-_cprF9n|9 z-vVQx2~t6Fbxh6Y;dASSoxlD$CIM-H1O#%23yWLrYN`|Z@IA$xLVlP!(<(NZoBUpl z&gQgPvLLh5FFK)Wlh=q~*uroZ(SR1@s#bsiBDOjQg_>R#ELQ;L46XHC9%?0;}H1SOdkg1}y~k`r>fp^e zf~odb*WM#zmiGCqBdB>>;~p(1;md0@0KrWlB&!j~b}*=XX3-Na5NtF4`ZGbJmGzOy zCaJq~35lhdD_c>f-PF=p6C}e=MzZ`CiZ*_KX8<=1Y2OxLu#zFs!v%HN9^0$UMt))m zNSTlJh|$O6jmA~%jvu(9bu>1H|K$A2-K` z>R}-t)QOd?%cDO%MA|ged11TqD3kcSNe; zej;o2n3Fj$yp(dMlghZ?7+2%9j-}=(N;&}6RVJ_vQmbo_ENpRtV!I9I487vQiaiG? zQwYS@>-8{Rf7&D=x_Ha&mb9g_<=)zE>2!Qu=<0aAP0bTp0Y>RpRtg9qgpZ`;@SPt` zLzrz?J2qJmV>^+^;9OBCbgk7@J(1Vv^obQJ*pq&mR0Kk;ZJXWPv1`E625=|O1nZ7H z(OA)u46C`aQm#hurEi>q6Yr9zKnQ{JDVmOY4dvdHP|JP)&U?mYpb{;5I~A_<#Ubz%OAL*#1lMH6$&6a4 zCWyye>CHIU-oYOIo^hp$?TpO3n%j2Q4}32BH-#(f!PNNpeoN*tl=NF<_O=jz=gdKU z6|3wSzeJ5atKR&3Fy-z{L#bB_8E_f{Nq-}mSST~?#QGTk65r0ETU!#~(F!@X9?npC zMZ;V+`Qh+Gtd*q;&u?0On)x$S5l5?+s9q8S$^G-G*I!X=yF-GxcTQZqAI(^oUIc}V zP<4JdEg4c@%1|7E)afG0Wu(CT1=(R0NdH2mQ7jY;PL=G;w|;k7`DW41nRfr{O{Ajk z9&+9|J1Iure)OZ3% z=*UU`2ayNTbPFupUgZz&88M`+Z7_r~R9!^{pB_1Qgi#r4|JSP7qmhck{f(Y)=CKk` zbv_MMJ`LhKkC7bvmEI>W;8X{$Eh&0B%ILm^PDF~H!tGpcc`w6TapO@MN;HgI{>N0; z(8ekU6Q;N78>hCj(~-z0VOp8_e{K!Jt{+x?`Q;XH4}pR24+^zg#VjGGK@OCKU$;~W z1kj#<)OZFuKrtuO-J3W<{vJ|Vp{$67*oJaN%Qotp=c{E}Bqt=p#ItLh(w~Ov=<2xc zb@c8lLL1AH9vEnK!DnN9@iJM@nS~6dg3@L}F+f#|bA}m0X zee$z<ozuwl=*S90(OJlX6GfL>~56Hoku<<3|3rLx7^^if*Ee0gCU3C5K zYPbF2AHw0*`7^VpOkCGzlhL@H0jQ77KXT@J(%Td4A(kJaqSD#qLy}-DInyJMr)Y-~ z^Hs=lOfL?VBV`$WOCZ-FErUH{e^g?X8>by1_o@i-lvG71cg%wcDX%F%g z5fcshz6AIh=YNRbBs7$K+G`;c|jB$2+yOCZLLfTJq^J|bTX<)7vE2vq2sb6&q2 zP;W3$!j2@#1LJ_QNP>dpW9b*6Ci-9C1iSy7?;^tQ>Tt-9mDVIQs?F~ebg$0~Lr7dW zKRt8#QQb#!wYO#`eMji7()@Q8iuo%EZPEn5IlIt&A&)JG_#=0N@f4RjtibmC$U@ux z?t0;q;aB^e_VV_Bz3o&B0nX6^))sE+?$b7EJd;u@cqtU2UfwD(kvTS%9VDw6+BJEb zSv%Kq%JLnB9A(f{m0Ec0x_mXE?OvH6is+MBYl5#f>o@<5u0(*(CW;MI$ z^#JvgxA5#KR(dSx%7?V zx40z!*DeMk7K8I%hLgcA8C7FPtl2pS8VPJ{SqT)ye6pqE4P$$xY{gUC@;aV*nVZlG zsg22`E9YzDC{b;)%Cks06~wFjOzY?{A_)JEGomc)j{7**}VaD}zUY`|hf6P(nYnNxx}hW%t>TcaNgu@v~$2<6^{f?Om0QNfs&qfM(}HN_H|JGt|% zP#Bj$C-~@P!A-(vIIquAnz8)9N(V0688>vV-MJs9A6-p#79%0>R&P5^?RenPx%vB+ z@wdwTltWaEii3H3E){rkd;r;4Uo-xfu@m37hXlX_vF zK{%;Zy8bEk;Z54O!LB5A4gIl_1y0RV| z23r_U($34pTB0?VyPsU;mMw%***hsZ_|fy-gea4L^gJnZb2aX2ay`0KYu~+e_9IV$ zhd#rR*N0H}t*Ih>u>h=q@=y|Xjr%a@0Xl)m5ACLW9xzTl=I5UO^Vj_syoSiB!Od;GP&xc@6F%%ehu>P6OsGetDpsqS2%Iu z?$w#S+ES!7VX>HVAw+1w*;I|h8_zTsbGS1Z+eQ;lAPPE6w@j)Q# zOb}bAt%=W+z0cppQB9wzvE#`-h>vmo&vp@04Kn^Nd8kz%B8+y<-re$4AJ9+p?)E0C zylU5W(xyc=GKlAa=hmMycp5;G%z%^yBW~4|c_W@JKFcUqZam~Ey}jBUKv2Kd4e;X@ zASHrV=!~HLLRk075-G(=5-*Qv!92nzF{==^H(fIF5x1>p4>Tn@5_Qlj+l-MA--A~%5T=o6aZy_RdQxA9d8O_=y9@Hl))5B0x}la5Df zl21zP5&CL*hdPR3A9ESgzHA+EWViC!Xc$H#FJ6Li|3%_b=;U!aBNZ)zm6<$HYm0iS zG0PQF+|x0B@Jem;LMT%<4L2nsj5QO?n;VA~CYc-yBVjkpu>_YTlL}wGwYIi~jnLrO z3F0YG>D=cn?%AG?8PO?lAf%-XPJ;2IJ#OT)zow5{^SKf?T=P)LXo`femfK+LX|n*M zAto!36;tAmfs zi%(8%tL`Yu26A^k{A-}if2uH|$~E-$GZ188BLA*NTvgbB-JsIRVYK*s_sId)2f4e; zDQ!WVqm<2bw8+|HPCkUaH59D4$arL?<-0tM7EOSWsE6LfFQ#f4)kg}lQAB378bv+n z6;ESDBHlZM;8V0^AK`@0;CI%WWn~M*7CPNYxlC5of<$T7xtRf4C={UKK!o3Z`swfwK)p{J+RIxHr2hyl}2K%gDP0?aukOGAv|W} z(+p*IYRbwivda@YG#AOA(pyIF+v$e#{=mQG!%~PkKnoTKIT_=&J{!Q44O$a*v+VlV zl-7h6lLK`N8)0pZ{i2XWolh?*(W9ZE3FKnx^=NASm_OXTFrO$-*pl<$N6X%bu3Rq* z;o-4+Y+5#RuzOxU)ByjX25J~ikW9qE%^Q^my;Hqc8Hfwta~aiPHop9AUJg6TV&cOe ze$77N$Ymzwkrp7X%s#YR$p)rc%Ug+dpImtBR(M+XIbP;z&xB)8GRa$MoqX(H~-!tZ1bO-6+$9kO7R0B}Yn#lmxMggr+ss~V=m~N{S>9G1-+q*gSP~W6KpR{1 zsE@7EiR^pBSEd|mt6OI!c(o$fTGUOnQHe<`L zf)hC$C9K1Y|%dgaoy`{HQ@gwrrf*~6RfvMD})A|f&v@dbGUgQ*gByY;S_(=qf z#d}iR2=Su_x!rwEj=x0JMpEvDWjsE~c@SyOBKVb*RV)89+;*iHGZhKN|NI&!X zQ^if^3;*m-I453DSysThRml*XI~#IF|1 zThvj>Q+yR>kJj$uRdsDnDK7<-H^lNQ4PK%7#*wZm4j(=&vOdgzEmv^R@%`LI+)sC3 z-1bxO#w`h(7j6$bkl}a9N0$VH%6iT(&7f(c))Q;B=Y>)14e+^a(h)T3@+|jpPSM;y z(o0~;j1lS8DyNNgbk1l^p)SGxV-)|x5OyGjFqH%^%syhs2jm{I4HikbY5unb99^N_ zJzpOXdn%Dlfl!X%PlxOxlabHQp-j$1^%`*#`9QoMW^jzXOyHk=IFJri1V~a-gCqu` zudmqf{Ug;C6v)`PjuD3h2eCCCVDxFXGKVv+sl;=O`K5=@lqoA$`orBuNtYdd z^qn>vN%r;rWlo^CsyvXlqWGoJLOU6wT@5jv7wBJo#N7Lrb5IM#Z(vyx7;FC%1o58W zAi4elP{`|G3<@4hFT@Zmra=?IGffgqDn0LW!9D8{-?;N$J0e6a6fbaPNdV9MRW;C- zIsJQoiV&ahY5cKDueTe0XGg2F(NUx$Nk#Dg{;J0#pUr5rCoc})1S#pSAob~x_%8mt z9WM|5o+KEQ-FtrNoSdBQwS}USel8D)%p4z3;8;^3>W|MS&>RS0kZf4qa>p|2PvI5X zF8;~Yh+!=98I;T=VoB7sIr;%10f7U0BVF$Sk6*xjhvP76p?Hy(>;{umWqvzB#@@qz z=P(gd&pl)HTe>?%feQ%2g=Uxtd(<#Qv#0c^ ze7lD2NJ}$)g+2rjJb)Fs{A7yvG|~)n3|7qG?nQyy*y@z#*+bcm<*5wDky)(HgZwWs z_&0RQP8pz#yx|N|`#K461?=5v@i4n`KY0r(?045Zv>=3dS!aAJn=K`N)({a&8aD;^>~n7NdAvqkbZ4@Esk^K z@j!{Ldc=1}bUAwE^-gt8f@s9b7HLVxgwKhdNv$QQ0`7#f%&! zLawg~bbv!dNL}rDSDf10->!|007fMS9+=)AJ<{ozV_bc_xOv?R{JahOBP9)#9Y;o zId7C~h!rpXq_nWM?uc~m=a99qvC*`$N`uUR@a#myRok1MPDok^dZQWlt|p((q1ypas0MZ8U**`w&g->^{Y>Jce;OQhbI!CgzgY>%9*pMEW|`)4=Yd(xK?KqG9v6 zatW5xv__Epzx#(@)a63V>2w`HSRASN5C)Td4E4w#&c+ICx&FyA@z5Jt*;1$Wb@zloI*+mon1JvjeD3bErCPU+*L(Uw;zz8BXw zdhG+_fY+RcTR>(u3jbuAvg^ZTC@WH~UNeQ;Ta9R5S>(P1Z*SMUv)#FAkW-w3L$lt$ zA4>5s(SA5?N_@s`=_6y$k~pt{TIpv!e7O5l64?$(Ib^hO%275Dj$e@VIz7UPw9b@ME8FOI41iFdzOAy1f+oGgoIEL7Qw$C=6$D~OXV51A7G zsUskY>48*@=A0K-HWvL>QoiJ#+cN!cyv7|oMvP3jf|j_9$`%eFkIumP?8B}e=TO%@ zcQ^f`KHT49m&Gko<6`b}Cy-K}N=i>x{H!bk_eZo}@?4_ym=GOkMh;~o&Ig;Cs%B+1 z2aP5dXKr&p;yA_ND)^z~z&1Vc9rHy>1YLIo4U>h|ugyR3?{^M-$vJ&@$1GcYoV zootC#&`CHL%Pw0u8YsUSirxy{{vfe+qCQIO!TXWPo`L;bI0kwl?Bt$0I>ePa_Doy#L1C0Ksxd035 z!z>}bRhXD)+B9>*SA>Fs!fTIF7RfCL?24*7I_8|>)k%tmbgwJiowN#Zz5aHq#GYzn zBi&=mWw>!D4eFZZr~Aaiuup8`=*}0U2k_T~hX?4X3aP(p`0ZN%Jz+gcc+9sEVmpp* z#`ZQB)iGv?O}{>=aRv2HVFGeIXf>Rk@`Ge0X12c*r z&nTphu4L)vmrm%w#W_goeW!R`Fna55meC^IWpX_Z^(51tsxc^L0#y4 zF>j|yp-!lIdZ~1~J(fn4?t{cYhWQnxmCOCYxe=H&VpacToYW6@>2yQI^P&H?q{a+| zDAPA^h$tl~X`?RV2fZ0stAo|3Cl^iUJT|v~+$sq&qUYc>s~%}fN)eU2O@SOvzIM|OI0(%-6QPj91w!G={|-?3f2+|`Tq_s9}a zhSNq4g*zqK*1TMVgoLC#8{i}un=I&y zI^3vJ+9@O~d_kZ6r!1-*yk?qYmKM{;la-RhAUJ=(#)B9e z_vDT@MrT0%#Y|`Ee$KgoHzjaVcV>TQA(R!adozRj-g4Ipq)-E{+}a6@>*&xxc#%(6 zY&y6yzJHNn{ZhI=Q>y6o8WPr@AzggsT=d~GW=-Ofoowfvf=AhBaCIY5qI=zc<1<+0&df>^<{5=7_o zMC=;m^YiS0*8YEH4#|7YLmn z6lGMa1&tnxJUl#zr&hmr@AIJ(7bao3JJ=<*WRVL9p|%_g9-v|88hR%WouZH1?nLhU zOSl{M1*{Na?+f7;IV2&Slb1K+#b8bQOo?Q${CNG1aCG}@f#{RJ5D$uNr>CZ5ZC?>S zZK!i3=;y_&aDn2o&JW1j&UkaB(~fz6fBT!eAf3y|XL;qI{#VkcOOfc^_vyRLnl%#( zIA?+Pb4j-5v4!i-vVm|+X|>nB(Hx5Q$~}2k=nA~9`Re@qw?_H`Uyh1>yq2dy-Nn@P zmFc#|?ZBaE&>C9+73Pqyp5i=#48=bl;I%=}S|?N2bZ%R2tb(sRgJaB;WVBJ<<3BfJ z&mixVVaxzN)3G!&J%uyr+PJMX5!c})$Qig?jXTSDgzJo7DU(@|h5$$0(6tQ2vHK{1mUt!BsG}{?Cq|9fXUU zRzcgJ(x2d_o}OFITYE7gp&Y})Qo7426i=~r6S!55biAGLPevw6$BBpSQ(xZk(l2)Z ze+CM4$c+4-!K_(cur-iAwzdvw?A-91HE>ZD;<6lF+1T^=ho0b+$44N>7l|cNRm2sv z>YADxTg6So%B4g4&k-tGo>LBwMvSi_ZyX1PU_zLTpTHdbi(lj;1NuNRrD2OCqaw0NvR7q`><}s|JA3oJ-se`&^Lc(he>~40-RHi~d7trd z5WqkTUrn@$o_9LDXKx^Vm(LBDWb>r%YLu%J$wsb2|C@3X8L344UikYc;DSBCB?va0 z>0Isp42yE3()sNA@yA><{Gub00+mtB26D%0@vo1g<-~}XeE9kK-`rA-Iv#oZW&fo= z$=BQL^&fK_ggVl|TcohPB=8hXRarUY7$@hA%CY{i?`0a@VIRcEIotMyz+&p0E^oy{ zo+dA}-MshG-}%pCu7(Y+b{`U#j zu8WZmgu3gWw34H*mZm2b$7o0Zxy!!!?MTtg*jXGON0{zx0ku23UQek9J&-Lw-^InM zpbJX3p{1l@2H5243FCWV--<8LZ#`>RX)e?Bw(6upUzc+yzwzoJL|?F>&+FgKB;Jix z?1rp;Scha<4zERjTP(i5Kt%2Mt!78ML`@4$o@8;YD+p)Re zyijUFq)!2Er8%B)baLJPb&vA|WWBFGD^`cTH}7}_tm)DJEPDM`W5}avZumArzQnK7 zJSV&2G1s+4V`O~)xBP6?;Qd^b$KIWZlQIZ6_I*bcPf2_@M}CEN>~%dW=SMis*cN-iKl{36NS>RUW`8) z#Yli9u=f}VrV_25cCqh($p@`{z;2H3GPlz*?P`p#c@X?QHM(mIJC*EcL;q*zY5k78@hS(<`o^Cs5@mZSgKRvJQJ%Mv?og;n#B=#JuG)}`Q|Q@N%kD#-yG3jxX2=U$r| zKsb3xKJk3S1jS`0Fwt*YYI7B$UQD+uq7P9sX=*nY5NTZ)md{;IA(K zQv$~=TD;;(g5&g^cxl(?%7bDb>{CqWdiH)9U9F#TZ3`2ouYo{8XmIj+E=DgsmfauF znI<3q`5oN5<_@m2p0S>_UcG@(fos`t4aRGajtDQ;!$Br_h0}@VmpTN0#1K;UqFuv* z^OXw$u0iO77_m53x^x0@V99UaPNyua5m4vJeO4XY@tijiK{;nE!RA8JRHlC=7@edg zPu*PWRye^)7toi`WTACpK9a|po0#Yz@B;Bgx1|>x$NSA5&3#f*IgCE!D^CjVY>(Zb zX{q6r=TU>NUD@C_bQv3fTfdMATM-E$?RdjW*X z3^{?^KD4>9)=>{Lb7H_rk26mZw21W|H}E|!W|g-~!~wXw%e1r0Ku=h|28XzjFuj4m z+>=Di|MI+vJov7)-UenF<7oZz<;Ad5^VaU|WBAT69a&Ahy4ZIw=}l@NIgL#4|Cqy5 z=wbRPh{Ykn{<#0mlw7MV>C+>WqcoSwfihfKA28eqd%+(jqdyaRq(apacrfo?Tn zEiQw4|7?Nnf8Hi;91YPARgp)+ag}}!8~9eqw7sBzERV-Pt#i?w9Y0YS>bN> zkqZKqr==>wRYGwch@dwWtn|B?C0A$H=Ds8?)r3u_jWdFl2esx7j<7zwT!y}%cN>H| zm?ZFAfE7c7q38U@^@r%ithCi~1~`xh6j>Wh2;JBiF#Ax+Ruv|nppUNlwH2*fYz<8; zM9H;01=?F37-#thi`*tnfI&9>R#{Q4HtBT7b~}Csi_w{ugicY-5c}JWl^d+tZ@+xo zTnd=3SY@25a|GoAR<#Y-6YV0!@^q?&gTzAbV;!`5UlabFf{2I-V=|yIc=s#+BBHl@ zoaX6)ql)X{+vv1^muRIK`-tDDcb=t(mW(Z{z3e)1!&w3W?TNU$ayL4Xx_sote+w zT9<1eehd;qOnsWC+RZv z<=o$Y9LKPzBKsu*mm%l}=RGhR&iiw42kPqV2F?vjGX&~7-^apy&ETWhrM(1W+|PoX z-do)x+g1TqeT}r{1cdtVi&l$ab)Jn&`?T1SzK;-hydB<;OczrE0Ek#19~~VXe075U zwJZO#OOM^Q6Mt_mL)fE%D1^lX`|7yM{y^3}ne;jb@_h-%1kt@1(-3SxfWxRt)V|@| zWsikhyA9z)RH>1|0!PCBc{O@Kg{2=tbb=PZq%rrR^H7I_A;?pl8&=JbhrZ!=ERAd4 zmPcp{3cah0_#q4Lf450fMitnP{E%X3bD1n;&kOcg{UWp_=G|q}pSce?(r_t;Bm+8p zf(+(@zs$gB~x9_kp zKxBYap@cv&UFcGcWM3cL5++`PUZMf8c|csYr0EpATb~)VoBgB+`1$ge`W}6!-;uv3 z<@^tg`%kL92EQEzYfIwH)t_CzOEF z93U3Qu*M zMeg!Zg#%?NvJsYWqH*x%TQ6y02CzC*$vBkbdyE)9PZoHF`u5W5Krr9$Y)H86%ti$# zWAf-gQKgy2+HSX!i>G|P!hl%7vYk3QPc_=Su3(mvrIl8{bMnw1B5(PShvM+X<>v|O zlHh0%`@R_;p%<7`i(*;c`)K2Q2i9EfUi=mA%a7-^RtA=Jz&1k!4ebB;>D7NR?H^qJ zgWT#cqB|+2L2dm@ckh38q_w~GroW|sn1@T={8&${=mAnTFit~vJ&djUkN&)%a&x;T zSa#TdtY;va^t{Gf@y1=gXhf}*gN9<>Mdzl~o8I3%Wr#k$5l2u?$dGzs7=_lWbJCDc zjf^aBBlg3&iy~dIrTpt6nfp~x+M=HVv>WzaIEt23O-+rhcj1o_Dk)8ma1ubchboT2 zRU9Q2$1uqUKpEdY153Kel7UuYGe7~9gwzYZ5tF1KV!|-yUn#Ag&ByF+FPu~8d-b`| zkZ;ew7)bpKXukv!KWzOsRR-%OGFr6BM(PxtBJ33!612UgLFIEQt>?|p_DBEbT$fkZ z;go*eiwxiQLi|h5SI}_h-wHy}hC{R)JA|jL7Ks*8&*^ZR??p5T%|w6$K;;>C#Njeb zVvunhtUk?-%}mUGqBGHl(Me;nXhwIsPAuJ@Q7jEMB$SBQK;v<3)9naa2(&@@gm?sv zfvwH>XJ^wDxyse`SJtv!%=SBfSbvXUKOxwBj_0?jhyj{;EpjG!j+qQ9=dgQbJg5cn( zFyFT`-Ft=Y)>XQv({p}#3NmTE{~vmmSqJ68o?OUY0X$?*o|Zh*!^EP&pz^tfZfVtR zBXpul@zcXM&EtovafPDc9%69}J6ZKCnW%`=3%sQJ#}ZPU?I#quiyuG%ArpyH=K=G$ z;5^po3F<$32EraY`BgmX4jzve(hFPEw#kgL;BqL>6IEiJu=Ji@tmjK99k#zWc%O2s zR(adasJHJFS#IwzvBJZyvXGjN0#XVEvFVEQ}kJ$dWyMuKhK<7@8wDu6|YKU_Ksazx_Zm)nkgoDmp zFMJSBq&~dB*>m%Eg2z^#ER=rnz{R%WgUndn6=+4>1l?y;H8m4~7(7NpF#=OD+9fDO z;^582_djD-h*klGukQ&!Eoz={a5(M4n6m3Bhy#io&A%Kk!wr6Ne~pd4hUuk_b;yn| zLvmooQ0NHEn*d-?sj2etB`r{$^rCll@N_;fc6Pw-B*n%We2OW6%0hbKU*nAKm}i|a z4)Ck4UbQOu7e>J{{AI?cKY!xI!up$~Uk}<)+QDQ8Y)2jH1kL06V}}q7nn7*hCfz1o zoPXS-Zu#~tr!jqE_={Tjq&FDp15k;eT17X zM|xjR1k;MjWS-l@<7JzG?({OJWnoiuO>u8tiLB;l_)$#qfX{+qI5dux>hA8IURg5* z1QOE3X%}eKt?J~I2g4cM0o6ugDCqF|-ARm(Api{(P!VQmhd%OiUkw8M&~yMAH$d{b z-3P|44@v2**F2qb9vyA+p&aZ}sy6>ZY}(dm8kh{i8$BtG6)P33!;{PY?H@LO}uJ`pB7lYK+MxvV-FcE$Ob8 zJ0R0JmRD3Mtpe%zA8#jq{|Hvcghm~)KpXw)$;l1Jikcd+TV0oYY5hS_V+tW6kjyG> zZfhBnBv_R$<1S*#ap4xr%I~C=_AU9@b14hZsSdIy@G{Xg*63_gkjRUl{FJDiFbkZG zY%t75dPJ1Y4NNuMn%&P&&|U^-6vkb$ z%8%O^Npc{S&SZ^FKxrdck?0<5m&5DwoZ>m|qLqmP#G-?yLNLXJ!Vr4gMyLCgbCq8o z>aAm;H$Qv4J#_Ijmo?E0?b_0M)W(|v_4Ux>Df!~BV~(o=74TR7gv=65ESi_iUj8&5 zb7g7Ox?En{y&WKMj^*%`6I)cD1m{2dN9X~R^3bZQ<>#Kj=WyoG3IR{b|Ff#0;VFxq zg9GJ~CK}rWg-QJjD|65V{C11FVQw1aq*B>r>CUyb1Nm%brew<>T`R=bm&$zRfPx?W zac?8efIR>*-r!1;li&wiQ&NH&CY80VWQugWDZ_VN>?TRFH%e^brk{%V*S+APlRqqS zXYJvUObxkUkRbEM4Sl+P0;C0cA*1;?-M9VTeYH1I-WKxEjyp%dZP`|)sHq{{kGK@gNzUaF%P-eK;PTijCT%V&3 zVUQ!8?dPf;J#;>l5 zt8rgMEPi-O674U_8Cu=doDKWOkfqx|L(Hdb>3ZpDY3n(d&jFw1of~_#`$l$dh(e6& zYnup6_5MLV>zy`qd3Tq5&4EEZ4D)r;U%fhFXK%l&Q@jrf@ubN-B?O_=u`NZDSq62i zdvDp>GbHfPB?dG%&><|8MaOygHRwAg0;9KJRrJQE$TcCsM$NKCkK-c8e7%;3rv8?@ zN(4}}-Q)>IK^t}TgbK;l#>T^4?*|qZ*2Ef~ZTx~k3CZ_oeLv0r1Pa#-=Knyed^k5| z&7J~4yZ-eP4$_u(S(aHCm>GSR8^6^#K0Jo^3Ho^YHv@f~ zD)9etJ)sWiFvF*$9h!NwFD(P9CFcYjP9#Sr-EWXneSz+L(XPEH5H7N_%gN`qW1Lij z>k_go@l(tQTyP!~#)qWC0HmQa{&*A5rgCb%l!%CzQ87<`<(~cGfrbRhG=-|`K69M} z#+SCohZyVU+Du0Y$fNaZAd8&o4qEtMO4}b$30D3!5dDfdAvrpso4_99 zrom~rDi(o1hr9MO@?g-Ua$yS z@3%T~jQ<`%34Fga_fU$r;_d$m;$pRfPG@RNYN}Mw3=C~0W5f)32l<-H>~v6(GSWw@ zt8Z{_{0&lPqp9N03pfp(D!cx_S`KC?8^AoDEZq(X)aU)$a1W<77kq^j>Ad0jFbRZh zV@eZsOc?-vM^3KHtZm=#xUw_f!u)f}vqTLAU%YU_b1TAN|7iK^-|OR~h44MkHV)aC z`~_ua{`oh=#o}*eZ@*4cdbzB54F!C@*AQ!hnausLDDx5*$2adTQH@}aNIj}-s_G2h zMpnmy$zCdfMwPH#@OeX4VsS{PkL^A89Tmw#%AySr42X?A4S+zMdRAOwtSvIsm3-VT z{uL^NV=_YlrKjQm0TXoVo45Qmkj(?gY5rx)oFXp(F7h|D6QZM|Ri2>mZ1ej^0Bd7h zi3u2f`}BD8^Npo=09b+nn?lTyqr$i5B2giiw@J6&G=V=f*^hR?12!i3HE+o8fcdjc zc1iwMS{VJO@WO?3J8}N(h^*b*P`YS>qBNnhYbpV*$4>4*conXrAMAWS*D{}=BA9xz zgZ1lY=bYte7BH#qSZx0?FJH$wC&1=4HnX7Wo^mV z2iiRn3$2_!=38DjyPeP_7>vu#XuTkj#SBA_D91$<(se)cNC;aBGpXs}FkL&B+~YDX z(%^S~`6sHvJ4xuT_l$4>tATIDQpGSVNoz|>9F<2-lTB>kdZGQaK)LhvV3u|}eEB^i z#rMJ22hKrYobf#?zkVt1eOJk$48}pAv`$IZb%C!Dtv`_p7F**Khs0R~Y=x!^Z*#5Sk!<`B_pT0@T?G1_tNK$IGlY|M&NEnN2hf!l?AJ5)u&VOv~N#k znzR@BwH6h0b-9nWG2~2`ID7bA%PHvk+SbydoIO|RHgc;ew*2PZ3mPvTo|>SykUz}L zTKefwlSK(##*u2QU7&q#&Aa|CDH$2f2VP;uXpyZ(X-nEMW(^4}PE$@EJs7VtzT17X zO0T}~duq`VHPoF*xmvkZWg~R?goJp*oFNzAhyXv>KCDy@kqOwzup63J3!GD1E`Lj() zV}4~jt3a4od;0VBA^By?m=#OHPx#`7!^m$-8*z8ePf^u&mC+Tk#p0gzk6pp+)zbE# z;2N<(nntfTx149$G(~0o>&^E!F<7X7*$z#gBYv_Y#~3VyW+a5G0`|F0^=89_NYXc@ zL~$l2r>4gHu`+Hw)0&$eQmw^z)puEtawelu9ou0n|U&kH8{Qf zp-^L7g*p9ALP<#z84(kF=<@099f3vXJRFxO-!i|CE6XC%(lc+};jwbZwWFFo#(Y)s zbV~6#5)u++!5eU6OdJT1#%PXE`JEqokm^v-13&o;)H(=8haqT*F~aaEUSfMNKv?9B zw|?h8%>5|)az)9~G97eAD!RH1y?cH+MVmLo%b{~OM0yss8n*XA6lJc_XFAyKzp95~ zR2uy*k{4jI-o{%_O`0>zJHyrIbMDP%Z_EhT8QIkYF~_)qqd1m%>51iZ!Zh-MypJ;h z^uzQi`b_pW<-S(zw&?!Yqg7~{*(R2)E0yIB*T`7+|9aqXLACK1RH-O0ql7KI=qobc zfpHqKf%_)NMG7ac4d{jPc%8<-F4%rSQHCnW|^2J1X z!o|{p#Nx1mR*wX>=h^k8nu>KEPw0IZvvfK*SnHA`_rWkSiBh&4nX(l9N5+t8dv^Hm z)rbF)^H%&CW)w?ZIn|v|x>|aa`qE>y%vzl1C3w=AeP=QPp zRPMEOyBU#Z@KmyUq=_X?x#o#-L)+QMpybjC=zeW5Nb?yTTwaqg46Y52)7Y({rIlP$ zb7>24f&;10n*Z2?sFpMKpV|QLY93)sQS%vo0R>Rt;P5F_Oc(2S5wE$I^vg&c^kZM=RQTlv7zc5YZ@VBbq`Lju~A#|t5?hiOI$fLUr+>Z_#Cin8C z-+B9@LfNef3@xwQb&mae^+$%sf=W*286Ebwn#~?bHyQSmr4mq#xC__mtB|70hdd#m z2}^HIC{jqykH6ZxQMNEQ&)5@o{rN(j{=Ps%Au^Zf1lHuIN0Z*fHOrsxj2+*8^&IrJ zRbFI)tHVu>q7fQreExOPPR1GhJ`-_|#z4|FitR9bh=!bq35*9nP3H+mXrLbaL?tUQ zGuPU#O7O`e4tR1V2?VNQa?A$4(J*uj3M4M+DD{O^+&!%S_Os~K<*O>iue9L^B}N{D zZ!8%% zWa9}N;572dATX^viSG?*zA1Vy2q%l>7dUvuc+=Pp|5(0VSn&I&>fop8ti%Jx%XRF z=8e#Rv@-a376}m(2EZ?0#TyVeHi#`19$0lg_hI)JJ8gkmCMphEIV_3&VZnEQ=&kZu z&n5p#KXVZ6FK@&fVWkw;{#xGXdXbUp$skLAg}>)<3N$8H-&rdv^}TnpFn#>q>J<7Z zfEdumzji=l$GfSwejo#A&2Dx6RX~|oki6n+<|dA zcRSPQFf`8j0wa-5F8(}|PZsbgG&$*JX!HZom+Y?;-ki9U1<&O93}M-@LkNcgv1btR z$)Am=7^4%WYoM4|eH==relfXa;(dZ?J_b8c3Sa4y(&nf2K?*a`?Hv?+VYEjNkfwoD3Td~N%1jQU2_@m`NS_tl4t$*J)cN(RNoJs?ilJAmFI9}y7~ ztPYpHuj0iw=T{ESk1p7iC}?WluKR-S0E?q07Kac<}CwYKu$5 z;qcGl!i0Z@GS{82557C>;$6Se?PR@7R_mm^XPbR4Jzk(E%}449AI@qaHuE~A`(Du@ z+95&oHzVVfHT4m8dSXd=mG-Ua?WLvSkBoqe@vJ7i=K-$Trp{KgxjN zN~)--#lzOWBMu+q$DJ@HlOXFY*0nfrsu>OQhIL5M@b7z`cqMCzcp%!GE z*>?xZ()yCDWMlKY@*5o8rjp99ZnQX4`8*nEn3D}Y)b}qZwT`4HS@gJ%E~G zx#tnAVl6B4;WtkOU-W#ZORMo*b&!M;+LuRhlfe6WTE6&>=DE}iwW@jZ)`|4i8A`GA ziHRQ|-y*z<@oeWly~-Nzu0K95@fk#8;$(#T7`l5xvP13tvGY_P^T{d~tz99WWp|}i zPowLWv~$u4i8>CSt$-?1bP`U#)2wQGE!&rV7R3%CiJ3ZiLj8v##`Y6I_)JCwTMCPZ zT5%Xw`VP|lZ1awjpU-+k`=2@#HJi)r#(hjrG0n@%YkwUSf9V?``V=dD_h_8#8_Wa+ z&4q3E>S(_Z`PHrL)iI;$G2IC;5%8AAHfdy|c)PyfmB1#bX1KOJk-Ibg{>_hfJ#;Lj z%mvr{`(>bC9Dw=XkZxzeY8;!ZjQ~T7>3{nKso{mEsqMIkI;gitThSM`0h$K3>7gV3{CR1q*o`i(P zcJqw2bsvQ3vAyoxKWM%F9`?R;{FLb*-Fe?r{+9BkAyC5v9w)q9=1&p#gxCEl?WW2e z&()VX^j|n6<88d2UHmmEsVlifvFk*?MANI#$H8=Be^g&_qVp6gfq7se{^1jnKQ~W+`muO0fVb;WYKAc}f2!Y>lA0>Qyv@9`@kxe>^jqP+;in`ea^?K6 zpX%{A8Z&&7~yo~XDz!DIE^M3-$0@eE0y>E69*l(G^@_x_lbA4%s0jd*F| zY~Usj#)g-Ou-+5c)F^(Xc! zrJcm>M^uZ3#M!M2^Yai_$qfvQZG%lXbbyEneu?)^*7JK@TJPlmm42==r2mi!!lg); zCm1{j6j5*Sf?~Yrp+vCw3Zffvk8W|%W$&r#i1KbYu!EQbc@kwmJfsm1zJBdHUw~+A z8{_*LJIP!0!b(HmFI+#TZ(_nxKn#cc32xc2ifWqJttG23j*B{G_6RQeM^=3o^dLXG zm7U`N+5G%Gv^{ltE20%W>{GD$#n1(6O#)jfDWd5N%WaEza6=Bvo*lBq`y+2 z;xK&`%p&FQ?7M{2F8}PUze9~r&~+B8k>qXiGCR2cIz`WcIN^`U9>!sjEWywaC4K`;4}I$__TfV zZiQ&~!8N%6DModJcR_=PA=yzP^@QIoDgu5 zp>do;PE!+QAmbH*E2a01VRFjQw740yWPL6B)D%XyZ6_tphvk`rZppu(mNbNJ1^&Cq zKqdn9eieEOKkc1VcXuxaAO;Qe9i{YGlz0>k?-|>7!|;j4jZp+k;Glt5v!#EmNma*c zp8H&f+xG4QO=2yp-qE+CzwB!)+lWQb!Lv%o=pp$9mfP_t*>BUbR8>%DcrZy#O`V*d zfA!+Ui+v0QP*R9S`#QV0NEO|Jf!cVrA5^5>`nDil0d{rwnVgh#No@58 zAy@X z8`fr=s$N{pxUlM#HN{8w3?B2@13s*|PQ7@V3dDh+0)Xm2u$5fvJs?Ct)&AWuatnrKza&2P=)nwC(YZtg6X>__NHP|R#tT~7+A1`` z?O-NsZGw)V{p_5ZK29&}bmgh8N8+lDS;ZOcwolh>tO%DzxrrpZ8wvBhss;?y5H4y{0SLD)k9ncAKbrcFB4L+GcdSQ{% z%_g(l$GGvPqN0N1nJh1juSa)d;|bOUcv$ff5aYhTo*Lab`vkZ1DK5&8R`ApGZ-!I0 z<{O!DU{&#iq@}AX8CpX?xVq>PJybnUwy_76py?oMsYySOjzKJFVC?JHugTLnd3XXm z)}RNjcCuRPr6ujxb+egTw>JhM9Nk#Tc#L;To95BH!6r)dUyzDj5St{_SkaXwUoHIf?1<*sklr-P=?K`hW; zt9nQ_@-s|^wf$D3Pu(j*lO=N$sYlN1=pPSM5T%2zpa@uM{sfzwdP9hZ z$FgqJfJooc((=+!V{dOd5(~jb4vw>QpLxEIj=k+WbDm4*$Yc(?ZH&!lt5?&)4@+u~ z?8}G_GSO(RVo}bEX7pH z>I~|naTap!-~GBQi(V`?NXBTyIsRJp7}QX+EiW(s)MIbf;bv!-3I=Vol28DT$5O2` zsGM14P_a9zwRz$%wzpx%sP0Fjck^t&lTk$-t@Iyj^=xF$wa+ivE>hN zZL<1wCHvXyoZ5_P03Gms5Ti9|threIxtpTC{e-`eT)_ujpER4N$zM3-mTdF~zyHg2 zh4UF-ULAee-MaUoz;M;)&+;9I)(7;~FN!TU2C&FL^N?%?7%)v9AfRS44b{pnZes?F zA^aL)CzWd?e1n7=s%Sok3z9tivr0pzB0Ri1W}h1ZrBT){Qw|ZSJ39%je9^_cjJkw+I*7bmnxA6&gN#>A@=o8Ifww#f# zd&VcVwB+qUM3?MU0jjZmlvt%ro9>ab_G4e37SFQEG~IZr6Q7?i#I2E`-_!?5gTB#2 z0gA-rWMx7~`u$+vuS1d2W2@o_7QH>O2a69v_A@wcejaLQLVo9?K^;@+>`gBn-avWx zIn>M-%pMwj4qL-&ya%?t_~64WUQiV?#gu^q;qo0K+IglAPQ9rez0?8Vm%bsXr%69p zV0aNdE06V7kNmI$0n}p;H}EHy7u}&(;_{fW7-yvwYAlTIR=3dcLmwP!rYwq`#FK#f zxi3tX$ijF$S_Lh$_q)!LbRnGT^N(e~-5yLWDhpUZQ~4{XZ49dnvbb|q%mEYy6?Qsq ziys-)WMv=2Ao251wXZe3Qt2@Wqq?`EBJL=7VIZjU8W|l`y?Rw>*jTy^+;HDOZB$eg zpHcfYkCM-tlvOk-#)fol{3m6E(uaT*86W-@>p(Jzkfzbxsp+1F8O-maDMUG(l+MX` zO*oGo$Bo#J!cvOhdNVp2o;E(CBlfVW0k9ME!KbpyK%@U$U67_+Yj=fy8j5gt1Z`Z# z?@42^70trr2^b42`qOO}y-?hhqe#k#BATSMG|_|~j9^-g(tu5~C^V0q5T3kjC-U|6 z2#=bAsrm~DJt50|tj^u`H-hZDeTE0b!!0j%+>Ti4Stw3`_O@z4(igyDH-YMD|6i{! zg3s@OzVO{JhqaHPBsNw8S|!A;FII|O3SJ+MS(iZzwTn?S@;4u~j&0EK{9msgilAur zq!J9BI^|{&BHYlNRpP3~o_6NM%P3D^R|+ZXm2cbd{ut89GqpV^unE5H6UV}hMB%iK zK-K+2Xr-VA)rwG4D*rK!!09j#Ff>59`=<5gAOis`q#AU(4ajggR- zmtP)HFG+%@1Ra`FKJ@uPI>ceE-sLb5672*BBfo%BaL?SAuge%011OKK>O0mo>Ek)6 zCgP<=7)k`^4$e`|%DzJEXy3VgyXAI37XCNV0W;vr;(TGwe(gcQ3RwKUFiH9@4>^yb z$@CD0nY@jq$TSU)d)w6y)I1%HRji^2;xMBN)MyBQMo6uASs!IRqT(e&o2+L`(OYXS z2Ys-}MoS|sgSNufV(KwOLG!*Dvd<~x3n2;mz-njm{ zEHk*fb1mC>{l`#icejY67dyShnWUdrros(?XstNOTs(yE2`@=V5qv$N7d3L*f(E{C zQ_WTH9#bJuW}ALgx!FJdM8l3*ZJuk3)Fl;;omaC|aSlfa02c-#Cb-no2CCd(zoN1j z5cyKy(20XIfgH(_sq9|K_!Zq=Iv>i-sSJYLn%Y`&5+ZCj;W`tj1%ht(sSSDyPOTd{ zMOXFAL+LYFcSi60x_muZcd?7QzxMLP>=6K!izCa-TwGirS|tbKHH!fUny_%SOnNWq zil~TUVt0e|tDRS8>$@hUqbpjELL6ni9JRPWh%`c21_lNaK_vx~4wUDPg7w(U)ung9 zPV#x5oECpMRO=Y%8-Mzp58jhTNqPT1^RMx7Kz3+fmq8W^4XNQ##XBF~^UAz`*s^$W zFx>Av!Ly&J^xxtYxo;a5&W)oKSX?S_&0_`)re*2WzJSvbFm8yarH4qJquIN%2As&> z?YZjLb!!E3~cS$M6`7LS0CPT3F-HN=R$%p{g2p89Rc@+aYzH>!ahbC6gZgFn8j zW09p`yH(ZJ6K#Hz0v!A;RG;FkT@9^zjtiCp6X#*v|XL5=7h05 zW!fXP#BK|P0Ru>s50iSrqhUsVLG|PmCA-5QwRW!udT-KPv@hE*f9vUdKN$zgc>;uA zn8`zi=^xrW@uQJ$m%slpoY%vLHj(u4IzG~nVTQ4q*26=Aw|@5q{*E}FE-Qa4jNg`p-QJVj1?o;V4d!%5 zWKhF`Zpl2MB9aqo=fC}tT3o8OA;ye&h{e%!1imAvN1lx4C#9vfN%Xo&ck6sSyHz%1 zl%deFR}>wh+EKa#>pQ794@X-LW&tq5%Yjo8pcMmhFFUzCY5sNd5NZAM)04ht*Soz# ztn3%Q10fX}7G^pcol5?(gho9r;#>Tb7-ZZ8#u)k=TpuF61&!jMw+6>J0~a%Qq5C!K zn1v6B81EWRmckVBA`dDM3%>CEWrRI{;;)J$n#G^)X+{qX zi_GY*y5LAw%b#VASd{>m$-r8QFEcT-9p(Je-pRaQw?@?vMb7#OaxNOapDu93^8H4p z^Oa6IVB!SI0QxY~b&4#amUR$)1^@2!@7$%@t@|3Fl|Ey%jVJAkpTm)}8W;(*Ir`dW zD`v>nXZ46HzU;r)f|F$R@MKP3$-~dpGHGT91Jg7bs`yh(4EMI#7)=Q)AY7}!Asw83 z3W(x@c=)}$y`qSu9QeNlsXWy`dwuj-cEg*r_sE7$t(4dAIK+8DSRJJtDaLgdHaCIt z(f7=}`?r^WEQOPsSg?{}Lo8A~Yy&$}_Sk9&;s@RAV*q*Cud(+_XpT@+NSEz%bQJYg+T4Ij|EJ^u*?`4t?zy zBJFXV`3y69>c2mawte^Grc&SC(U05rZ~6J7SNbLmF-Cv~JxvTX!%kUr#-XYMK*a$s zGDTqg+1tK2vylR#mA&^prpyLR%|5H`q@ehuHv^~lv||`81f@9C4KTv@vFY#X8*8dM z%j!@4X(sYEfw9RpoSN|XF@5itmRkIsfImPWR}a@+=$g!gm$-l%p?i3Gr=m3bw|$+> zc~X;PJ&3FRlNK4-<=6!jT&oHekX0#8)TWPTUKfHPz^L#AVN{;{*@QEy!cW(lQ@p~h zDyElOEUmY?HpNe2wR|Yl@)+YxO6igjjJG9X+Vn73TpqwE7R#M%Mbp#6HpHxc$=9l? za}?O@)V?1c`eK-{1KVVvL8tzy#@mdbp@JUn9INNgB;G$fR5V!_H__PC{;DbYk}AlT zEa}dF+>M2I5R928Et~sgeMCjfj`75_KIFX2VovjRBWA&@+>JAst_xyjp2`FQe*lt) zy;NyjPk7p;&^Np!_)L8=zKWX?!}lFO1`^`BdUKklo>a3EdkZDwEx4_YEl)ncnJefh z`9>OD_>6EN6UisK`?)yj)7sWDa(m_)gq6~C!kigrRD=i5Knz8E(d*ieUW7beIEXd^ zA1NVv5GTvTl@6`*;QwE~Jlw+{XCkExzXoC}wQ6owgHsgX#VkcPKJ(RYhsFf##Nx32 zSk)DY=l8!AP2HkjoiD>Ra|pbdn7_q+HScKR)DFv|DwEZ^u(kG(5{uKt;?xv&Qk!d= zc9xMJ68NMRt3_=D%?#9vjHZ;nzlCC0A94#j zw6Glgeyh4%+qk&7TOkf7ukj|*r^7X4;KedEoNgc8A3Wp)UCYZTX?zyizLPq}OB&Fw--|S7ku*Bx^ws~v( zezDjS`!;X*HW^fUKDqUUeBtiA?S$gw9bHYqwv79S_ho|12CZ7_waY#}{)gzN{NHSb z%BoM2q=>N1`L=zv+Fv!}w=_crl~jxE<(_4JhlVNL~VV?E(#CM2aP1c?P!8u#f#X=i8W-2!5q#Ekwe z!WHv6RX_{U+$3bu@fZffo?VPb*@6(hk)QYyP{A|T zx6zns{B-Jxo7jRqySrB(-J5s~tpO76L*!4b`!#jEi&3fBpN*QOV+N| z%ZDJxPXxLv7+N+a#I&qk;MU~c?s84g`X&=GCPCmuFkWbLf3;{?xw9zo;zwf$6>%*< z!BxHDf#Yivy&mlCR_y#?^qB**XFuwCY`k3<6z4G7G)Kl{@&YeL7Y)S~8-)z|RY&4Az+Rv@#8rSI{ z>Ka!_$O4nZCk*n(YKw@LNFseUf=R~Yb{P0tzqOvF^q8SszPqtc=?=wTjn{%Ei8P); z>XwMknT4jG$#UTZ*Hw3b!0lo2-T&e01@}nN&(Qo9F>9ZY6Va2+x^?`A*Pr>g7ERo#>MWG3Zdfz z*zU#Ay!(fBblZouuCP%sk!-%ez&0qHxpy8~V)~(=9ZJMd@vMl52>8~xR|g+UT9EEF zV+uC^7zlfDu2sQZb#oiMlA|fDGZJ?9^D?=;x@d)Z4hOe%bR@#O0h4G&>*bZL9y7+i zikB~28~b6yk2Yxqgr3QjN6ZWJFp$j`rc1SdbNT$>hi;0Ow3Lp|#LYtHMC)tDr9n3| znf;BcU&%R!^%?UcFa}^SuyT=K)Bd5&mzNkl(rUe**8UL?RUUk>ILOk=`{`-aVoXiu z$sbEb#h^G5Zg@Poo4+FN*DzF)5t0QiV#11Uk`M_ko!G;|DRBs|)w+j^(|+@c$~O!cUTVqDRLlpd-M##Y)M}iEXPDy4mlt ze?{f=1_^V38iq2=?RLxFYdB`)^mP>AIJMh0zkM5o{wLLLd?LKhvja7Cfj`eIitasU z-U%=M{_zolh%;POkFEYl8r&*Iy;!~O#sra_-P*phg`=USxx9l~`3MCQ>g9;8rYV=c z_I;m&$jjREPj_!#f?;*k9qkG5#=|V=$cA+0E<$?^$OfRX`?fFFWTS6lLpnVxh zsMy-MPbubErd(L0B=HFU9Z6KDi|cH`h24=n%bAgoAQjw?6W&dS^^b%#G__IZj8Idq zpSQC^yzXF%I3{xmsg z1m_#|fhACYt_Gd?cFEAvJdtW4^@`OS$EH5m%?e~ODld+{;Iu3V&LU1IGuLhiU)nrQ z;*b71u!sn{wUl9FYfIZobJCLsz}S|XJ<4`%w$>DV3~@WlJ$ldZ1Moo50FUd5^zLYa);hsJ4;uagja|;0#>6i4J&n zcoY0CRv+XVlCH0Ig)@Z;Mi>e;H08L@aMLf26S-xKc^gcOJzpu#lj%<)3r>dV=&IL5ZxLT62)Q7~ zv9f=7o8ZJ6y-rg~qlE6wBZ+bY|9v1TiUx&Xb+|EEKGOQc9b7#f2V#df`c3;DXmp+R zL)ZlXBc`4 zs{t{t$V#no>)emy&$#%;gy3uwYAU8b6WsFZ*JoY?FzVj`BZu1oY>0r30z7sBLU96u z(>Zp^NmSwTCq*eYpG{zQ^H3-q)*q`YeR==B7a_dX9bw#7Do8-FKnc#*r0E5He2Uif z(qoEm5*w4TDe3Cg`-|(7p}vsl&*;rd<1K2?vKPovV9ZsRb_cQujNiPpURQeJlRarz z7@H_3F7f4VILInbdb^%BU_yEflPuj9w36J5uet>l%LLHl@!suE-S>j~k(%tylF@pc zJ+X5%b+6{ly5AF(nB-;vRmv5Fj(}bl^jBJI?_>P{?Nro2%W=1YGw(GEfZu(85INq7 zDT8i*V+oTJyrF+K{f+wLd!nz<+>E=(NzH0!BCGd!0tengCRx5syiablc#_;KFL#ui zj15hPfIm;ou`%8ZkcdEyb8B@7yVP1FitcY&%kvUK=c&sdoSb5}dO@rONZuQj&;uk{ z<-b;JanoO#0xcq8mI65Y%^>Y=`(}Ad?xu1$V2c-+5IFsy8ZV`7Kbh&G%e5uhTpQMkdJ4Y5byD5Glmrg^*#p38|lOE72US(bH3)Jd&i6D z(^CJs!U#?bbiI{@>Rj7qKTi#(FRa-q&DgBZ#^_at9wEu1 z!bQm7Pr?cD%G^kD`pDpO%eKUNWpIN>+huO6#r%l2p5{BoCgBXq~y$ zaJO}B-YE#FvVIavElD7eDA~jZH#!JZSZuPLyp5};g%s*yYzdt)Jf)=&-!KHI6^CQ zWqbR1Lq?*iZKR&~W%@OK`^j#>{F(0VhtC~x1vHyOeKY}DzZ??_Fbx5{@Hmgk@8IuD z!u4yY3fNnwAyj0411Ve}y5I)}s4K@(T|(j`?KOQwRuvEx-~~A{y_Pp=zIJtS%1jgB zcS)H&UbHoiDP!-lK&{m6Jeo>Qd4ZciJwAH$h|QG}dei4X18~&XeV^{kJs#I{XkI)Q z=bYfwf1*|;_khGNy<&?#UMD041*@YZh~hZg_)hLL!(~jM)~dKr{(tRVXH-+`nhqYj z0xF`?L4zU)f`W8{4GdN3Qbm*&@d(mO;0QLPXrxI;kP;w>5b21Wq8 zKIAZJ3Ka&E8@d$)oQ{AY#_&L2TGMwliaY_gY5n$2r4`zgduwK`==R!et~2wMr-tZpumbMVIGl7u{aW! zd!zr_sDEuu9Re@oy)^i+jwzQ4Ntpj)4%!g^)CgLH+Pn>U7@v=sKPEP9mVzW+JCTX? zTQAn#BD|$^BEQU4tM11kb);2B%sET)sg4MX&Jlp;3ikH{BAyV>(3@9Fr{4CUvHmb> zN>`U0$;UG>1E6Ot35CD|u(t+-Eggx)&D;4e*b&m;=ZWVpZzu)_JA2wwgh}Ub<*$Ek zd$pmG!mD|9l9y^fn63s=sFHjx4c9)7#k|)WB-(Sns=nld)M@-TRbIa4i*f)}1VI05 zxGuTW-cgTrf1gEuUPG^S=aquEpdd{_AyuKx96K+(BVy1g*XJ`*%x_BG6Q>;5a`r-g zh@c*?>mE+gYg`io`-y^_8N!8Z!%-$0wDTmakaUf;cqd%|!h}4h)X=nI!eVTH|LFFz4t?F5I_bwcjRx+>- z#T9YOt6W!)+HOiu9)l!$$TZ{o|urO=gGRyx;KnZj7WfiSYSr>si@cRfb`;Mes4uW6zH^q~ST11c>RJdy+eF~-8=CP%(6#C*-{JJw%H`Z(*d*B9Ec{Aks;bgc>E%pQ7gN1*0Kklsc-2F-k<(p zIhlw59mls{FN7=m-twKYgB>{Mp-ciE7tFoZK6hVgeAEVHlP8A+!5GH$WJ}#^m<{Bc@ zzv{95qG~v1C&#MHdMst*6}gEz)Es+`T)$za>o+$o{%G~Y>)~N5v_}hRGcB*qN4F2I zu_2Fs?;6qbp}?p`axd!4o@dXVb+|i86p4$7JT)k*zrUKRf2Af#L8jO0^_$t**FBEM z-$kJnx!r7J`l z&n=s7L-t=l&*S>xQvA9~^lk6pI}1q#l(mCX6%PW^8$@JI7)p_1yklf8E9PiBsg`=o zNMIFwmtHIJ>qZWNez@iYWypDik&pAKdAYeUbA=s=LQ+%Hu&B4qhAsjQ29FP_6_)Wa;G99_9r>I zPIg_%&(BwIqqeg$=WL;T2P(#!eC8OR=Yk?(j(^ZcO3rF zvF1Imkq3Zs&7A`34^KYGBaonMTZ8cO<;#fJSgJm2bp5NsLTPNL@zU^*AD(>C&!5}m zqO>$Mhtw)IUgeU@IOA2d#GEo$5j#w0nsJ_`_gKn9H1^5ClSW|XXxl*hM8+y}QIlYa zU%q+&ey?X>3s7}cdlRQKucVfDypVH#dG6dfG#1#UFJHOR!kTxGlhXm*9>FE{vF1rkmj5vah)WBk|zz@+507gfJhO%pH8vzv*>g^DJ z0IOCwzcO-h=pm_d%gf6kH@dZL;AWA}o~3;Jc&TclAy!5c7Nf0Bz(1$FTnS-8kqrf8 zpAaCA8TZ%#6GoxhF-E8}s^=fEry`=F(!07$WE|Ts!Ln*-YUqH`v2X9yK-lC2+F}Oz%l2?+vsu} z{SgrnaQ0!tf|y_=vfa`APr@kvhx_y>;1!5UM~H|Vn#&9Gc3xZY!j-{>g)eWsdI z-`aohpmBejs`9|E*bYpLdF>(n{^zQ*P!!jZsO*Er0ybQwc$8ogXbjU_r2hj%B~1P1 zrSN|ix;5C_i};a!0|Otb6sQ+3TnHjOe?H;EjfZRb>eB}g{e3;|aC>v>oWl&cSO4JQmaeW1m0<3rtwK*(%-{;yZ| z>?o9ABS){)eToQbkO-+x4ILf8g|5h`uC5NCEU(a-WL(ECfB5hLwx_wXvop7XYo-b` zHv~{n)Hg}HcI_eqlp_L!1>Z9Qoef{x&%u$}SK)&L+&%>$xeEx}T>OP}*A;}xeFhke zBGL82uyWXk@& zE)1{YJ{gm)lR$)36%`fLu(q~#{QBkS6&74!u2Lrc%c?_n1w}47{EzQl+(h?Q6^Zn;Ayk)6t7D7%$ z_WSncrY0@if8_{rYXb}aP+s{{$>g28b~UDktC-$YF6wczZHU?19INVP!tyBj8Ilcz zBJ$5oO~wVbjncS|6HqUref8>9Zbf&1jD${|)`9ndZgi?))kHZ|&m!Uqodx__2rm<0 z#F1dFk^d6XEpWQw|j|KQq{6DGcVmPGD9#gjY#HMP!2f( z6pL+7h0dd~0H&sAY8s35)&%eg-0S4?_?803Xy?~8c!%7E1}&_fqa%^hhUl>jodf`g zA%T1!t6|6F6v(4wGiNsMdtHB?UHJz31?Z^)n5#I;B(N9hxQ4jjE60sP!R3gB-yHdb z78ZU1yO_uFq=<+l7K`mrqFxu?b?>~zA`LLt8X?or2=*V5x4>msW5}f>1l^XUe+)G7 z^j*H>dwio~Gc-@7bi1ZRHG&s_5NiASDv6=??s2Eno}8?-&piy_d)UY!sN>Xza?XCY zJ>MqBMxjH-j2VORuk4fp6ue-W5nv4anaw5%0EV!(+;>MBxNJhCkQaT<830S%fq%H0 z>$(zu6Kh@)#=q~Ia~+==;c;;ADVU|5CQiwsn*+A*gx;j89FAF7wDPdyVq&Ku3Q(X^ z4H%iU5}gm*oUun06?-OPCMR#<8bAv8kyyGYO=KYB)HS*LwdAf{LVEy>VyxQ~C);%C z6cqht96x?s2z5afu7apYN4O+Veo=FEcxFG7@L^$LX9!yGiL@b^mt1cg2Kq2s$<_gF zi!A|xTUp=Sqk+Ej*ypP?~h+ znt>qQA%uYhgjG;2l)JZeEnp|iKQQS)h|1Hm*wSZ8X8q`{_ID(FrTbJYI?JXm%rMNM z<>h@-vZGs#XR=VKH=PJgSqAeBFxDR^J#WPc+&jo3c&{2T^w3xc zqZtB0UN-OIYz@0v4@4vBS+&3{2lic7+=9ME0#u<>yYg*RC@iqj-J-{j=f6FF?i@93 zYkZ!HxA)4@9K>b-g%Xpi&hPajYGI3ktvZGW@G0$*umr~Zcxp@x(1X+swLk#H4X)<- z(iBiNsemzFk;BiAwTRaJ7#*De?mXF$ZQL)x!!r?bbL-#5Bjb2Od^a0MDhkDV8o>qN z{+e&|5UdlY7rzGoPoA88r1 zTjYxuSz}}N0RPxDvx@42=|@1b!3ITRfi0l};)3&_GQ<=VOn2gTbOIH-%G zs35D!>2Y9W#R2gpAq^N$vw@TvKecVPmV_s*47VOiMWSW`e)G@h^X}t}om24Z@xg}z zN5>vmO)6o)p6o6SSwcu&Vd=ghKX)7q|VkJN>RUo}O)WTvpbYAPqcxtX!wi8{;m>kcA>Z z=*TchNl7s+zLR1u5#0nsw=u>X+`r$XM_5>x+L@OG{14ebe%!eK@FB7S2uyRK`;=)( zZzpD2H$fqCTlo89?*1cP5YLK|upmOT($h~_QPB*d*a&u`H}+_dl#AtF9L2M9j4-Rj@2;!bzPVjm|0 z%`nUr(iV~EGd<_@QdPXY&W;TWwT@w(+oY721_HUy+=@XvK<)>r-_%8<@=8NKcyaXU zUNfXV9 z{5GWLrc!%f<}1chLrbX}jt)eRpYwm)y8HE8kIAk@G(WC7N5Gw>|&H1ToD4w~BJ*s4IpPgYADQGa=BUS-EwM5|X^1=9flXis7h!wCVx2l;H)cM=Yu zvNCY`VD(@Ek;9T_Bf4O5`Ev67yen2O?u=7=hOR)8qmbuUN>gMV(|0%@Lr-f^*FW_>;^5=_N1=W7pdQ^wG6XXN{i}) z{-A=qV=m4Vy`3qWsdTJcnEcvS%K8ay zN}>&%S;Md%M4BcL2;cQXA!;vr=FCF+s%HVx?4}31EAr{n0e!xAVR+IBF)>Z(O^&V` zx}v2Og1`goBq%IbUT3Z_Ga5oggz|@dk z$MvwC7?X_jbcR6Vjd)DyxNA!rV6Zbul9d)ownvda)c&@@mIee(=3Byu`oe#XhQaIUm3U3&EF z27y4(vbG+C$i;yJv1w^&9KV$x-B6H?_3Xzm{FnOr(=fkk1P4$!&}*R?5WZ>YBPOPeKQDiIwdg;+qr&_@{>h~*JhKBCnxoIFGOqpCtp0m092ksew#R$N> z+CYyE1LWdzaG&X$a^rvT;zjM0I}bJ;YzuHDCXLuxCBd|#FVkuOahEvdWfSu0^XE6U zO3+wVJ2dxgmI2455$s)S^oz_)k-LB#XQs3-*)}Imtr;X2djtUq{~Si5D-cZ52P+r? z77>YwBzDZoWkN(uOeP3Yrr{AOsVn;FS}ic_$hf#{h(&29C>VlFXob`Q!pH?_1S|mv zTdV!}2Z~CkM-dd>cL6M=F2liS2MB&Rf_(&i^Jc?7Ah=RNrYw1=ZufSNPh}~CW8u_Y zh}@dqs(I1@%poczI~wuS5G@N48Pojh_Ya&f5yU!zlhg+p4aA1mv{<}rU=V>=V+biO zNKp!s`2cF!OsgtDk%aeLM*fg7=Gn4z1b;{Ef}u}GK&;O5PS+r>iM>bi{$*{+EnRIlbbY$&va|K+RT zvRb*JlG;5s?dWo#Qz_}-eRkwY^{;DcX-NZ1!cRtDH%S7qpHtPtNpBvYPun&e!ju0L z&#nhUqTbeNoygd-A0)|_7K-&2!A+k?c>HLBM@}|-`6?Nxjc)aplG(!cyiX%BOUlc? zX~oO66q}PAF}R@n_g^4_jV*k?jw~qFB$a+|{W#8mS^(^uXi*o)b?Lud6xY=BniCTz zn7Nzl)CB;bK>Q|TMS=D}1RP+*JE4|C&1t_LYf(?`hbITcjvP4;J>S8hp@ykyq5FAw zvLPIJ)7BOi@8XK%V>7TVe{+8c(Iv2ld44ZXiI3-1W=<9$mKqqwriJz?;9FCnd9W37 zAg=&!S`eikbj_%9b<(8-fyl>!$U&6&JOVupvEQ9LcH}dbku)-R{74#l>+HvXQt%XQ zZr->trt8mm4r(F;HVe4lYSiYGKs@A+?160{R?0@rPnYBDpEtE+!dZX&E8cO(%x1^0 zFv$NDGx=W!SN?rrz+aR5uVYXDo}Pa(JqzoTS@ZNr=E=Lr)L}2`Tp*phcJDs`y{2xr literal 0 HcmV?d00001 diff --git a/docs/source/api/jmetal.component.rst b/docs/source/api/jmetal.component.rst index b7a8ef1d..b6ac613f 100644 --- a/docs/source/api/jmetal.component.rst +++ b/docs/source/api/jmetal.component.rst @@ -9,6 +9,14 @@ Archive :undoc-members: :show-inheritance: +Comparator +----------------------------- + +.. automodule:: jmetal.component.comparator + :members: + :undoc-members: + :show-inheritance: + Density Estimator ------------------------------------------ @@ -25,26 +33,26 @@ Evaluator :undoc-members: :show-inheritance: -Comparator ------------------------------ +Observer +-------------------------------- -.. automodule:: jmetal.component.comparator +.. automodule:: jmetal.component.observer :members: :undoc-members: :show-inheritance: -Ranking --------------------------- +Quality indicator +----------------------------- -.. automodule:: jmetal.component.ranking +.. automodule:: jmetal.component.quality_indicator :members: :undoc-members: :show-inheritance: -Observer --------------------------------- +Ranking +-------------------------- -.. automodule:: jmetal.component.observer +.. automodule:: jmetal.component.ranking :members: :undoc-members: - :show-inheritance: \ No newline at end of file + :show-inheritance: diff --git a/docs/source/api/jmetal.util.rst b/docs/source/api/jmetal.util.rst index e82c68aa..0e330e90 100644 --- a/docs/source/api/jmetal.util.rst +++ b/docs/source/api/jmetal.util.rst @@ -9,18 +9,18 @@ Front file :undoc-members: :show-inheritance: -Quality indicator ------------------------------ +Graphic +-------------------------- -.. automodule:: jmetal.util.quality_indicator +.. automodule:: jmetal.util.graphic :members: :undoc-members: :show-inheritance: -Graphic +Lab of experiments -------------------------- -.. automodule:: jmetal.util.graphic +.. automodule:: jmetal.util.laboratory :members: :undoc-members: :show-inheritance: diff --git a/docs/source/conf.py b/docs/source/conf.py index a5e2a9c3..f2abbff3 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -20,7 +20,7 @@ import mock MOCK_MODULES = ['numpy', 'dask', 'dask.distributed', 'tqdm', 'bokeh', 'bokeh.embed', 'bokeh.front', 'bokeh.client', - 'bokeh.io', 'bokeh.layouts','bokeh.models','bokeh.plotting', + 'bokeh.io', 'bokeh.layouts','bokeh.models','bokeh.plotting', 'bokeh.resources', 'mpl_toolkits', 'mpl_toolkits.mplot3d', 'matplotlib', 'matplotlib.pyplot', 'matplotlib.axes'] for mod_name in MOCK_MODULES: sys.modules[mod_name] = mock.Mock() diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst index b4d056c9..5ddc89f8 100644 --- a/docs/source/contributing.rst +++ b/docs/source/contributing.rst @@ -1,2 +1,203 @@ Contributing ================================================ + +Contributions to the jMetalPy project are welcome. +Please, take into account the following guidelines (all developers should follow these guidelines): + +Git WorkFlow +------------------------------- + +We have a set of branches on the remote Git server. +Some branches are temporary, and others are constant throughout the life of the repository. + +* Branches always present in the repository: + * *master*: You have the latest released to production, receive merges from the develop branch, or merge from a *hotfix* branch (emergency). + * Do I have to put a TAG when doing a merge from develop to master? yes + * Do I have to put a TAG when doing a merge from a hotfix branch to master? yes + * After merge from a hotfix to master, do I have to merge from master to develop? yes + * *develop*: It is considered the "Next Release", receives merges from branches of each developer, either corrections (*fix*) or new features (*feature*). + +* Temporary branches: + * *feature/\\-\*: When we are doing a development, we create a local branch with the prefix "feature/", then only if there is a task id, we indicate it and we add a hyphen. The following we indicate a description according to the functionality that we are developing. The words are separated by hyphens. + * Where does this branch emerge? This branch always emerge from the develop branch + * When I finish the development in my feature branch, which branch to merge into?: You always merge feature branch into develop branch + + * *fix/\\-\*: When we are making a correction, we create a local branch with the prefix "fix/", then only if there is a task id, we indicate it and we add a hyphen. The following we indicate a description according to the functionality that we are correcting. The words are separated by hyphens. + * Where does this branch emerge? This branch always emerge from the develop branch + * When I finish the correction in my fix branch, which branch to merge into?: You always merge feature branch into develop branch + + * *hotfix/\\-\*: When we are correcting an emergency incidence in production, we create a local branch with the prefix "hotfix/", then only if there is a task id, we indicate it and we add a hyphen. The following we indicate a description according to the functionality that we are correcting. The words are separated by hyphens. + * Where does this branch emerge?: This branch always emerge from the master branch + * When I finish the correction in my hotfix branch, which branch to merge into?: This branch always emerge from the master and develop branch + +* Steps to follow when you are creating or going to work on a branch of any kind (feature / fix / hotfix): + 1. After you create your branch (feature / fix / hotfix) locally, upload it to the remote Git server. The integration system will verify your code from the outset. + 2. Each time you commit, as much as possible, you send a push to the server. Each push will trigger the automated launch of the tests, etc. + 3. Once the development is finished, having done a push to the remote Git server, and that the test phase has passed without problem, you create an `pull request `_. + +.. note:: Do not forget to remove your branch (feature / fix / hotfix) once the merge has been made. + +Some useful Git commands: + +* git fetch --prune: Cleaning branches removed and bringing new branches + +PEP8! +------------------------------- + +It is really important to follow some standards when a team develops an application. If all team members format the code in the same format, then it is much easier to read the code. PEP8 is Python's style guide. It's a set of rules for how to format your Python code. + +Some style rules: + +* Package and module names: Modules should have short, **all-lowercase** names. Underscores can be used in the module name if it improves readability. Python packages should also have short, **all-lowercase** names, although the use of underscores is discouraged. In Python, a module is a file with the suffix '.py'. +* Class names: Class names should normally use the **CapWords** convention. +* Method names and instance variables: **Lowercase with words separated by underscores** as necessary to improve readability. + +There are many more style standards in PEP8 so, please, refer to `PEP8 documentation `_ +. The most appropriate is to use an IDE that has support for PEP8. For example, `PyCharm `_. + +Object-oriented programming +------------------------------- + +**Object-oriented programming should be the single programming paradigm used**. Avoiding as far as possible, imperative and functional programming. + +.. image:: contributing/python_poo_programming.png + +.. image:: contributing/python_functional_programming.png + +.. image:: contributing/python_imperative_programming.png + +In classes, we directly access the attributes, which are usually defined as public. + +.. image:: contributing/without_getter_setter.png + +Only when we want to **implement additional logic in the accesses to the attributes** we define getter/setter methods, but **always by using the *property*** annotation or the ***property*** function: + +.. image:: contributing/property_annotation.png + +.. image:: contributing/property_functional.png + +By using ***property***, we continue to access the attributes directly: + +.. image:: contributing/good_access.png + +Do not use getter/setter methods without the *property* annotation or the *property* function: + +.. image:: contributing/with_getter_setter.png + +Since this way of accessing the attribute is not commonly used in Python: + +.. image:: contributing/bad_access.png + +Structure +------------------------------- + +Python is not Java. In Java you cannot, by design, have more than one class in a file. In Python, you can do it. + +In Python, **it is appropriate to group several classes into a single .py file. For that reason, the .py files are called modules.** + +Python 3.6 +------------------------------- + +We **always** define types in the parameters of the arguments and the return value: + +.. image:: contributing/types_in_methods.png + +We can define abstract classes (ABCs) in Python: + +.. image:: contributing/abstract.png + +In the case that we want to define an **interface** class, it is done in the same way. We just have to define all the methods of the class as abstract. + +Example of use of generic types: + +.. image:: contributing/generic_types.png + +In the code below, the IDE displays a **warning**, since although the 2nd parameter is a float type, which is a type allowed in the definition of the generic type X, it is not of the same type as the first, since the first 2 parameters must be of the same generic type (S): + +.. image:: contributing/instance_with_generic_types1_wearning.png + +In the code below, the IDE displays a **warning**, since the 2nd parameter is a type not allowed in the definition of the generic type ( *TypeVar('S', int, float)* ): + +.. image:: contributing/instance_with_generic_types2_wearning.png + +When the class inherits from *Generic[...]*, the **class is defined as generic**. In this way we can indicate the types that will have the values of the generic types, when using the class as type. Look at the *add_car()* method of the *Parking* class. + +.. note:: The generic classes inherit from abc.ABCMeta, so they are abstract classes and **abstract methods can be used**. + +.. image:: contributing/generic_class1.png + +.. image:: contributing/generic_class2.png + +In the code below, the IDE displays a **warning** in the call to the *add_car()* method when adding the car, since the 3rd parameter of the init must be a *str* type, as defined in the *add_car()* method of the *Parking* class. + +.. image:: contributing/instance_with_generic_class_wearning.png + +When inheriting from generic classes, some type variables could be fixed: + +.. image:: contributing/generic_types_fixed.png + +Example of inheritance from non-generic class to generic class: + +.. image:: contributing/inheritance_non_generic_to_generic.png + +Example of inheritance from generic class to another generic class: + +.. image:: contributing/inheritance_generic_to_generic.png + +Create automatic documentation files with Sphinx +-------------------------------------------------- + +First, you need to know how to correctly document your code. It is **important** to follow these simple rules in order to automatically create good documentation for the project. + +When you create a new module file (testDoc.py in this example), you should mention it using this format: + +.. code-block:: python + + """ + .. module:: testDoc + :platform: Unix, Windows + :synopsis: A useful module indeed. + + .. moduleauthor:: Andrew Carter + """ + + class testDoc(object): + """We use this as a public class example class. + + This class is ruled by the very trendy important method :func:`public_fn_with_sphinxy_docstring`. + + .. note:: + An example of intersphinx is this: you **cannot** use :mod:`pickle` on this class. + """ + + def __init__(self): + pass + +This code snippet generates the following documentation: + +.. image:: contributing/class_header.png + +Now, you can document your methods using the following sintax: + +.. code-block:: python + + def public_fn_with_sphinxy_docstring(self, name: str, state: bool = False) -> int: + """This function does something. + + :param name: The name to use. + :type name: str. + :param state: Current state to be in. + :type state: bool. + :returns: int -- the return code. + :raises: AttributeError, KeyError + """ + return 0 + + def public_fn_without_docstring(self): + return True + +And the produced output doc will be: + +.. image:: contributing/method_way_sphinx.png + +As you may notice, if you don't use any docstring, the method documentation will be empty. \ No newline at end of file diff --git a/resources/WorkflowGitBranches.png b/docs/source/contributing/WorkflowGitBranches.png similarity index 100% rename from resources/WorkflowGitBranches.png rename to docs/source/contributing/WorkflowGitBranches.png diff --git a/resources/abstract.png b/docs/source/contributing/abstract.png similarity index 100% rename from resources/abstract.png rename to docs/source/contributing/abstract.png diff --git a/resources/bad_access.png b/docs/source/contributing/bad_access.png similarity index 100% rename from resources/bad_access.png rename to docs/source/contributing/bad_access.png diff --git a/resources/class_header.png b/docs/source/contributing/class_header.png similarity index 100% rename from resources/class_header.png rename to docs/source/contributing/class_header.png diff --git a/resources/generic_class1.png b/docs/source/contributing/generic_class1.png similarity index 100% rename from resources/generic_class1.png rename to docs/source/contributing/generic_class1.png diff --git a/resources/generic_class2.png b/docs/source/contributing/generic_class2.png similarity index 100% rename from resources/generic_class2.png rename to docs/source/contributing/generic_class2.png diff --git a/resources/generic_types.png b/docs/source/contributing/generic_types.png similarity index 100% rename from resources/generic_types.png rename to docs/source/contributing/generic_types.png diff --git a/resources/generic_types_fixed.png b/docs/source/contributing/generic_types_fixed.png similarity index 100% rename from resources/generic_types_fixed.png rename to docs/source/contributing/generic_types_fixed.png diff --git a/resources/good_access.png b/docs/source/contributing/good_access.png similarity index 100% rename from resources/good_access.png rename to docs/source/contributing/good_access.png diff --git a/resources/inheritance_generic_to_generic.png b/docs/source/contributing/inheritance_generic_to_generic.png similarity index 100% rename from resources/inheritance_generic_to_generic.png rename to docs/source/contributing/inheritance_generic_to_generic.png diff --git a/resources/inheritance_non_generic_to_generic.png b/docs/source/contributing/inheritance_non_generic_to_generic.png similarity index 100% rename from resources/inheritance_non_generic_to_generic.png rename to docs/source/contributing/inheritance_non_generic_to_generic.png diff --git a/resources/instance_with_generic_class_wearning.png b/docs/source/contributing/instance_with_generic_class_wearning.png similarity index 100% rename from resources/instance_with_generic_class_wearning.png rename to docs/source/contributing/instance_with_generic_class_wearning.png diff --git a/resources/instance_with_generic_types1_wearning.png b/docs/source/contributing/instance_with_generic_types1_wearning.png similarity index 100% rename from resources/instance_with_generic_types1_wearning.png rename to docs/source/contributing/instance_with_generic_types1_wearning.png diff --git a/resources/instance_with_generic_types2_wearning.png b/docs/source/contributing/instance_with_generic_types2_wearning.png similarity index 100% rename from resources/instance_with_generic_types2_wearning.png rename to docs/source/contributing/instance_with_generic_types2_wearning.png diff --git a/resources/jMetal5UML.png b/docs/source/contributing/jMetal5UML.png similarity index 100% rename from resources/jMetal5UML.png rename to docs/source/contributing/jMetal5UML.png diff --git a/resources/jmetalpy.png b/docs/source/contributing/jmetalpy.png similarity index 100% rename from resources/jmetalpy.png rename to docs/source/contributing/jmetalpy.png diff --git a/resources/method_way_sphinx.png b/docs/source/contributing/method_way_sphinx.png similarity index 100% rename from resources/method_way_sphinx.png rename to docs/source/contributing/method_way_sphinx.png diff --git a/resources/property_annotation.png b/docs/source/contributing/property_annotation.png similarity index 100% rename from resources/property_annotation.png rename to docs/source/contributing/property_annotation.png diff --git a/resources/property_functional.png b/docs/source/contributing/property_functional.png similarity index 100% rename from resources/property_functional.png rename to docs/source/contributing/property_functional.png diff --git a/resources/python_functional_programming.png b/docs/source/contributing/python_functional_programming.png similarity index 100% rename from resources/python_functional_programming.png rename to docs/source/contributing/python_functional_programming.png diff --git a/resources/python_imperative_programming.png b/docs/source/contributing/python_imperative_programming.png similarity index 100% rename from resources/python_imperative_programming.png rename to docs/source/contributing/python_imperative_programming.png diff --git a/resources/python_poo_programming.png b/docs/source/contributing/python_poo_programming.png similarity index 100% rename from resources/python_poo_programming.png rename to docs/source/contributing/python_poo_programming.png diff --git a/resources/types_in_methods.png b/docs/source/contributing/types_in_methods.png similarity index 100% rename from resources/types_in_methods.png rename to docs/source/contributing/types_in_methods.png diff --git a/resources/with_getter_setter.png b/docs/source/contributing/with_getter_setter.png similarity index 100% rename from resources/with_getter_setter.png rename to docs/source/contributing/with_getter_setter.png diff --git a/resources/without_getter_setter.png b/docs/source/contributing/without_getter_setter.png similarity index 100% rename from resources/without_getter_setter.png rename to docs/source/contributing/without_getter_setter.png diff --git a/docs/source/examples.rst b/docs/source/examples.rst index 4c2503c4..e56a766a 100644 --- a/docs/source/examples.rst +++ b/docs/source/examples.rst @@ -1,7 +1,6 @@ Examples ============== - .. toctree:: :maxdepth: 2 :caption: Algorithms: @@ -14,4 +13,3 @@ Examples :caption: Further configuration: runner/observer - runner/logger diff --git a/docs/source/index.rst b/docs/source/index.rst index 7e37adad..586a542d 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -13,11 +13,12 @@ jMetalPy: Python version of the jMetal framework :caption: Contents: examples + contributing about api/jmetal -Installation ------------- +Installation steps +------------------------ Via pip: @@ -33,20 +34,26 @@ Via Github: $ pip install -r requirements.txt $ python setup.py install -Basic Usage +Basic usage ----------- .. code-block:: python problem = ZDT1() - algorithm = NSGAII[FloatSolution, List[FloatSolution]]( + + algorithm = NSGAII( problem=problem, population_size=100, max_evaluations=25000, mutation=Polynomial(probability=1.0/problem.number_of_variables, distribution_index=20), crossover=SBX(probability=1.0, distribution_index=20), - selection=BinaryTournamentSelection(comparator=RankingAndCrowdingDistanceComparator())) + selection=BinaryTournamentSelection(comparator=RankingAndCrowdingDistanceComparator()) + ) algorithm.run() - result = algorithm.get_result() + front = algorithm.get_result() + + pareto_front = ScatterMatplotlib(plot_title='NSGAII for ZDT1', number_of_objectives=problem.number_of_objectives) + pareto_front.plot(front, reference=problem.get_reference_front(), output='NSGAII-ZDT1', show=False) +.. image:: NSGAII-ZDT1.png diff --git a/docs/source/runner/logger.rst b/docs/source/runner/logger.rst deleted file mode 100644 index 856b31b9..00000000 --- a/docs/source/runner/logger.rst +++ /dev/null @@ -1,15 +0,0 @@ -Set up logger -======================== - -jMetalPy support the default Python's logging mechanism. This code will record logging events in a file and print them on console: - -.. code-block:: python - - logging.basicConfig( - level=logging.INFO, - format="%(asctime)s [%(threadName)-12.12s] [%(levelname)-5.5s] %(message)s", - handlers=[ - logging.FileHandler('jmetalpy.log'), - logging.StreamHandler() - ] - ) \ No newline at end of file diff --git a/docs/source/runner/nsgaii.rst b/docs/source/runner/nsgaii.rst index 594bd5a4..c391eff8 100644 --- a/docs/source/runner/nsgaii.rst +++ b/docs/source/runner/nsgaii.rst @@ -5,21 +5,19 @@ Common imports for these examples: .. code-block:: python - from jmetal.algorithm.multiobjective.nsgaii import NSGAII - from jmetal.core.solution import FloatSolution + from jmetal.algorithm import NSGAII + from jmetal.operator Polynomial, SBX, BinaryTournamentSelection + from jmetal.component import RankingAndCrowdingDistanceComparator - from jmetal.operator.mutation import Polynomial - from jmetal.operator.crossover import SBX - from jmetal.operator.selection import BinaryTournamentSelection - from jmetal.util.comparator import RankingAndCrowdingDistanceComparator + from jmetal.problem import ZDT1 NSGA-II with standard settings ------------------------------------ .. code-block:: python - algorithm = NSGAII[FloatSolution, List[FloatSolution]]( - problem=problem, + algorithm = NSGAII( + problem=ZDT1(), population_size=100, max_evaluations=25000, mutation=Polynomial(probability=1.0/problem.number_of_variables, distribution_index=20), @@ -28,37 +26,26 @@ NSGA-II with standard settings ) algorithm.run() - result = algorithm.get_result() + front = algorithm.get_result() NSGA-II stopping by time ------------------------------------ .. code-block:: python - from typing import List, TypeVar + class NSGA2b(NSGAII): + def is_stopping_condition_reached(self): + # Re-define the stopping condition + return [False, True][self.get_current_computing_time() > 4] - S = TypeVar('S') - R = TypeVar(List[S]) - - def main(): - class NSGA2b(NSGAII[S, R]): - def is_stopping_condition_reached(self): - # Re-define the stopping condition - reached = [False, True][self.get_current_computing_time() > 4] - - if reached: - logger.info("Stopping condition reached!") - - return reached - - algorithm = NSGA2b[FloatSolution, List[FloatSolution]]( - problem, - population_size=100, - max_evaluations=25000, - mutation=Polynomial(1.0/problem.number_of_variables, distribution_index=20), - crossover=SBX(1.0, distribution_index=20), - selection=BinaryTournamentSelection(RankingAndCrowdingDistanceComparator()) - ) + algorithm = NSGA2b( + problem=ZDT1(), + population_size=100, + max_evaluations=25000, + mutation=Polynomial(probability=1.0/problem.number_of_variables, distribution_index=20), + crossover=SBX(probability=1.0, distribution_index=20), + selection=BinaryTournamentSelection(comparator=RankingAndCrowdingDistanceComparator()) + ) - algorithm.run() - result = algorithm.get_result() + algorithm.run() + front = algorithm.get_result() diff --git a/docs/source/runner/observer.rst b/docs/source/runner/observer.rst index fec74f19..59082f04 100644 --- a/docs/source/runner/observer.rst +++ b/docs/source/runner/observer.rst @@ -4,11 +4,9 @@ Observers It is possible to attach any number of observers to a jMetalPy's algorithm to retrieve information from each iteration. For example, a basic algorithm observer will print the number of evaluations, the objectives from the best individual in the population and the computing time: - .. code-block:: python basic = BasicAlgorithmObserver(frequency=1.0) algorithm.observable.register(observer=basic) - -A full list of all available observer can be found at :py:mod:`observer`. \ No newline at end of file +A full list of all available observer can be found at :py:mod:`jmetal.component.observer` module. \ No newline at end of file diff --git a/docs/source/runner/smpso.rst b/docs/source/runner/smpso.rst index 60c0048c..140f5535 100644 --- a/docs/source/runner/smpso.rst +++ b/docs/source/runner/smpso.rst @@ -5,20 +5,20 @@ Common imports: .. code-block:: python - from jmetal.core.solution import FloatSolution + from jmetal.operator import Polynomial - from jmetal.operator.mutation import Polynomial - from jmetal.component.archive import CrowdingDistanceArchive + from jmetal.problem import ZDT1 SMPSO with standard settings ------------------------------------ .. code-block:: python - from jmetal.algorithm.multiobjective.smpso import SMPSO + from jmetal.algorithm import SMPSO + from jmetal.component import CrowdingDistanceArchive algorithm = SMPSO( - problem=problem, + problem=ZDT1(), swarm_size=100, max_evaluations=25000, mutation=Polynomial(probability=1.0/problem.number_of_variables, distribution_index=20), @@ -26,15 +26,15 @@ SMPSO with standard settings ) algorithm.run() - result = algorithm.get_result() + front = algorithm.get_result() SMPSO/RP with standard settings ------------------------------------ .. code-block:: python - from jmetal.algorithm.multiobjective.smpso import SMPSORP - from jmetal.component.archive import CrowdingDistanceArchiveWithReferencePoint + from jmetal.algorithm import SMPSORP + from jmetal.component import CrowdingDistanceArchiveWithReferencePoint swarm_size = 100 @@ -47,7 +47,7 @@ SMPSO/RP with standard settings ) algorithm = SMPSORP( - problem=problem, + problem=ZDT1(), swarm_size=swarm_size, max_evaluations=25000, mutation=Polynomial(probability=1.0/problem.number_of_variables, distribution_index=20), @@ -56,4 +56,4 @@ SMPSO/RP with standard settings ) algorithm.run() - result = algorithm.get_result() \ No newline at end of file + front = algorithm.get_result() \ No newline at end of file diff --git a/examples/multiobjective/nsgaii_full_settings.py b/examples/multiobjective/nsgaii_full_settings.py index 97e6cc99..bb83f213 100644 --- a/examples/multiobjective/nsgaii_full_settings.py +++ b/examples/multiobjective/nsgaii_full_settings.py @@ -1,14 +1,12 @@ from jmetal.algorithm import NSGAII -from jmetal.component.observer import VisualizerObserver, ProgressBarObserver -from jmetal.component.comparator import RankingAndCrowdingDistanceComparator -from jmetal.problem import DTLZ1 +from jmetal.component import VisualizerObserver, ProgressBarObserver, RankingAndCrowdingDistanceComparator +from jmetal.problem import ZDT1 from jmetal.operator import SBX, Polynomial, BinaryTournamentSelection -from jmetal.util.graphic import ScatterMatplotlib -from jmetal.util.solution_list_output import SolutionList +from jmetal.util import ScatterMatplotlib, SolutionList if __name__ == '__main__': - problem = DTLZ1() + problem = ZDT1() algorithm = NSGAII( problem=problem, @@ -19,20 +17,14 @@ selection=BinaryTournamentSelection(comparator=RankingAndCrowdingDistanceComparator()) ) - visualizer = VisualizerObserver(problem) - progress_bar = ProgressBarObserver(step=100, maximum=25000) - algorithm.observable.register(observer=visualizer) - algorithm.observable.register(observer=progress_bar) - algorithm.run() front = algorithm.get_result() # Plot frontier to file - pareto_front = ScatterMatplotlib(plot_title='NSGAII for DTLZ1', number_of_objectives=problem.number_of_objectives) + pareto_front = ScatterMatplotlib(plot_title='NSGAII for ZDT1', number_of_objectives=problem.number_of_objectives) pareto_front.plot(front, reference=problem.get_reference_front(), output='NSGAII-DTLZ1', show=False) # Save variables to file - SolutionList.print_function_values_to_file(front, 'NSGAII.' + problem.get_name()) print('Algorithm (continuous problem): ' + algorithm.get_name()) print('Problem: ' + problem.get_name()) diff --git a/jmetal/__init__.py b/jmetal/__init__.py index 12d3f66d..213468e7 100644 --- a/jmetal/__init__.py +++ b/jmetal/__init__.py @@ -11,7 +11,7 @@ logger.setLevel(logging.DEBUG) # create a file handler -file_handler = logging.FileHandler('jmetalpy.log') +file_handler = logging.FileHandler('jmetalpy.log', delay=True) file_handler.setLevel(logging.INFO) stream_handler = logging.StreamHandler() diff --git a/jmetal/algorithm/__init__.py b/jmetal/algorithm/__init__.py index 33004dae..839f7f76 100644 --- a/jmetal/algorithm/__init__.py +++ b/jmetal/algorithm/__init__.py @@ -6,4 +6,4 @@ 'NSGAII', 'SMPSO', 'SMPSORP', 'ElitistEvolutionStrategy', 'NonElitistEvolutionStrategy' -] \ No newline at end of file +] diff --git a/jmetal/algorithm/multiobjective/smpso.py b/jmetal/algorithm/multiobjective/smpso.py index 1401eef2..26830c9d 100644 --- a/jmetal/algorithm/multiobjective/smpso.py +++ b/jmetal/algorithm/multiobjective/smpso.py @@ -202,6 +202,7 @@ def __velocity_constriction(self, value: float, delta_max: [], delta_min: [], va return result def __inertia_weight(self, evaluations: int, max_evaluations: int, wmax: float, wmin: float): + # todo ? return wmax def __constriction_coefficient(self, c1: float, c2: float) -> float: diff --git a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py index 09e70b6d..12c60201 100644 --- a/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py +++ b/jmetal/algorithm/singleobjective/evolutionaryalgorithm.py @@ -163,7 +163,7 @@ def selection(self, population: List[S]): def reproduction(self, population: List[S]) -> List[S]: number_of_parents_to_combine = self.crossover_operator.get_number_of_parents() - self.__check_number_of_parents(population, number_of_parents_to_combine) + self.__check_number_of_parents(number_of_parents_to_combine) offspring_population = [] for i in range(0, self.population_size, number_of_parents_to_combine): @@ -197,9 +197,9 @@ def get_result(self) -> R: """ return self.population[0] - def get_name(self) -> str: - return 'Generational Genetic Algorithm' - - def __check_number_of_parents(self, population: List[S], number_of_parents_for_crossover: int): + def __check_number_of_parents(self, number_of_parents_for_crossover: int): if self.population_size % number_of_parents_for_crossover != 0: raise Exception('Wrong number of parents') + + def get_name(self) -> str: + return 'Generational Genetic Algorithm' diff --git a/jmetal/component/__init__.py b/jmetal/component/__init__.py index e69de29b..c1c61439 100644 --- a/jmetal/component/__init__.py +++ b/jmetal/component/__init__.py @@ -0,0 +1,21 @@ +from .archive import BoundedArchive, NonDominatedSolutionListArchive, CrowdingDistanceArchive, \ + CrowdingDistanceArchiveWithReferencePoint +from .comparator import EqualSolutionsComparator, SolutionAttributeComparator, RankingAndCrowdingDistanceComparator, \ + DominanceComparator +from .density_estimator import CrowdingDistance +from .evaluator import SequentialEvaluator, MapEvaluator, MultithreadedEvaluator +from .observer import ProgressBarObserver, BasicAlgorithmObserver, WriteFrontToFileObserver, VisualizerObserver +from .quality_indicator import HyperVolume +from .ranking import FastNonDominatedRanking + +__all__ = [ + 'BoundedArchive', 'NonDominatedSolutionListArchive', 'CrowdingDistanceArchive', + 'CrowdingDistanceArchiveWithReferencePoint', + 'EqualSolutionsComparator', 'SolutionAttributeComparator', 'RankingAndCrowdingDistanceComparator', + 'DominanceComparator', + 'CrowdingDistance', + 'SequentialEvaluator', 'MapEvaluator', 'MultithreadedEvaluator', + 'ProgressBarObserver', 'BasicAlgorithmObserver', 'WriteFrontToFileObserver', 'VisualizerObserver', + 'HyperVolume', + 'FastNonDominatedRanking' +] diff --git a/jmetal/component/quality_indicator.py b/jmetal/component/quality_indicator.py index 7a9bfb8d..4ce33951 100644 --- a/jmetal/component/quality_indicator.py +++ b/jmetal/component/quality_indicator.py @@ -97,10 +97,10 @@ def _hv_recursive(self, dim_index: int, length: int, bounds: list): h = q.cargo[0] p = q.next[1] while p is not sentinel: - pCargo = p.cargo - hvol += h * (q.cargo[1] - pCargo[1]) - if pCargo[0] < h: - h = pCargo[0] + p_cargo = p.cargo + hvol += h * (q.cargo[1] - p_cargo[1]) + if p_cargo[0] < h: + h = p_cargo[0] q = p p = q.next[1] hvol += h * q.cargo[1] @@ -139,9 +139,9 @@ def _hv_recursive(self, dim_index: int, length: int, bounds: list): if q_area[dim_index] <= q_prev_dim_index.area[dim_index]: q.ignore = dim_index while p is not sentinel: - pCargoDimIndex = p.cargo[dim_index] - hvol += q.area[dim_index] * (pCargoDimIndex - q.cargo[dim_index]) - bounds[dim_index] = pCargoDimIndex + p_cargo_dim_index = p.cargo[dim_index] + hvol += q.area[dim_index] * (p_cargo_dim_index - q.cargo[dim_index]) + bounds[dim_index] = p_cargo_dim_index reinsert(p, dim_index, bounds) length += 1 q = p diff --git a/jmetal/component/ranking.py b/jmetal/component/ranking.py index 24b2007f..bf3d23aa 100644 --- a/jmetal/component/ranking.py +++ b/jmetal/component/ranking.py @@ -74,10 +74,10 @@ def compute_ranking(self, solution_list: List[S]): self.ranked_sublists = [[]] * i for j in range(i): - Q = [0] * len(front[j]) + q = [0] * len(front[j]) for k in range(len(front[j])): - Q[k] = solution_list[front[j][k]] - self.ranked_sublists[j] = Q + q[k] = solution_list[front[j][k]] + self.ranked_sublists[j] = q return self.ranked_sublists diff --git a/jmetal/util/__init__.py b/jmetal/util/__init__.py index e69de29b..8869c71d 100644 --- a/jmetal/util/__init__.py +++ b/jmetal/util/__init__.py @@ -0,0 +1,11 @@ +from .front_file import read_front_from_file, read_front_from_file_as_solutions +from .graphic import ScatterBokeh, ScatterMatplotlib +from .laboratory import experiment, display +from .solution_list_output import SolutionList + +__all__ = [ + 'read_front_from_file', 'read_front_from_file_as_solutions', + 'ScatterBokeh', 'ScatterMatplotlib', + 'experiment', 'display', + 'SolutionList' +] diff --git a/jmetal/util/front_file.py b/jmetal/util/front_file.py index b8c432c3..362007cb 100644 --- a/jmetal/util/front_file.py +++ b/jmetal/util/front_file.py @@ -1,5 +1,3 @@ -from os.path import dirname - from jmetal.core.solution import FloatSolution """ @@ -37,11 +35,3 @@ def read_front_from_file_as_solutions(file_path: str): front.append(solution) return front - - -def walk_up_folder(path, depth: int =1): - _cur_depth = 1 - while _cur_depth < depth: - path = dirname(path) - _cur_depth += 1 - return path diff --git a/jmetal/util/graphic.py b/jmetal/util/graphic.py index 403180df..0619ce03 100644 --- a/jmetal/util/graphic.py +++ b/jmetal/util/graphic.py @@ -256,12 +256,14 @@ def plot(self, front: List[S], reference: List[S]=None, output: str= '', show: b self.doc.add_root(column(self.figure_xy)) else: # Add new figures for each axis - self.figure_xz = Figure(title='xz', output_backend='webgl', sizing_mode='scale_width', tools=self.plot_tools) + self.figure_xz = Figure(title='xz', output_backend='webgl', + sizing_mode='scale_width', tools=self.plot_tools) self.figure_xz.scatter(x='x', y='z', legend='solution', fill_alpha=0.7, source=self.source) self.figure_xz.xaxis.axis_label = self.xaxis_label self.figure_xz.yaxis.axis_label = self.zaxis_label - self.figure_yz = Figure(title='yz', output_backend='webgl', sizing_mode='scale_width', tools=self.plot_tools) + self.figure_yz = Figure(title='yz', output_backend='webgl', + sizing_mode='scale_width', tools=self.plot_tools) self.figure_yz.scatter(x='y', y='z', legend='solution', fill_alpha=0.7, source=self.source) self.figure_yz.xaxis.axis_label = self.yaxis_label self.figure_yz.yaxis.axis_label = self.zaxis_label diff --git a/jmetal/util/laboratory.py b/jmetal/util/laboratory.py index 29dc3abf..db00fb6f 100644 --- a/jmetal/util/laboratory.py +++ b/jmetal/util/laboratory.py @@ -6,7 +6,7 @@ """ .. module:: laboratory :platform: Unix, Windows - :synopsis: Run experiments. + :synopsis: Run experiments. WIP! .. moduleauthor:: Antonio Benítez-Hidalgo """ @@ -30,6 +30,8 @@ def experiment(algorithm_list: list, metric_list: list, problem_list: list, g_pa problem = problem(**problem_params) for a_index, (algorithm, algorithm_params) in enumerate(algorithm_list): + if g_params: + algorithm_params.update(g_params) if isinstance(algorithm, type): jMetalPyLogger.debug('Algorithm {} is not instantiated by default'.format(algorithm)) algorithm_list[a_index] = (algorithm(problem=problem, **algorithm_params), {}) diff --git a/resources/pages/auto_doc.md b/resources/pages/auto_doc.md deleted file mode 100644 index 46e1a659..00000000 --- a/resources/pages/auto_doc.md +++ /dev/null @@ -1,123 +0,0 @@ -# Create automatic documentation files with Sphinx - -First, you need to know how to correctly document your code. - -## How to write docs directly from source code - -It is **important** to follow these simple rules in order to automatically create good documentation for the project. - -When you create a new module file (testDoc.py in this example), you should mention it using this format: - -```python -""" -.. module:: testDoc - :platform: Unix, Windows - :synopsis: A useful module indeed. - -.. moduleauthor:: Andrew Carter - - -""" - - -class testDoc(object): - """We use this as a public class example class. - - This class is ruled by the very trendy important method :func:`public_fn_with_sphinxy_docstring`. - - .. note:: - - An example of intersphinx is this: you **cannot** use :mod:`pickle` on this class. - - """ - - def __init__(self, foo: str, bar: str): - """A really simple class. - - Args: - foo (str): We all know what foo does. - bar (str): Really, same as foo. - - """ - self.__foo = foo - self.__bar = bar -``` - -This code snippet generates the following documentation: -
-
-![jMetal architecture](../../resources/class_header.png) - -Now, you can document your methods using the following sintax: - - ```python - def public_fn_with_sphinxy_docstring(self, name: str, state: bool = False) -> int: - """This function does something. - - :param name: The name to use. - :type name: str. - :param state: Current state to be in. - :type state: bool. - :returns: int -- the return code. - :raises: AttributeError, KeyError - - """ - return 0 - - def public_fn_without_docstring(self): - return True -``` - -And the produced output doc will be: - -![jMetal architecture](../../resources/method_way_sphinx.png) - -As you may notice, if you don't use any docstring, the method documentation will be empty. - -In addition, if you only use "::members", even though you have a docstring, it won't be imported in the documentation. - -For example, this chunk of code does not produce any output doc: - - ```python - def __private_fn_with_docstring(self, foo: str, bar: str = 'baz', foobarbas: int = None) -> int: - """I have a docstring, but won't be imported if you just use ``:members:``. - """ - return 20 -``` -## How to compile and produce the docs - -After you have properly commented your code, you are now able to generate the documentation. - -> Note: You need to have previously installed the Sphinx dependency. - -In order to do that, from the root directory of **jMetalPy** you have to change your directory to the **auto-docs** one. - -```sh -$ cd auto-docs/ -``` -Now, you can generate all the .rst files (which is the documentation project "skeleton"). - -```sh -$ sphinx-apidoc -f -o source/ ../jmetal/ -``` - -After that, if you want to produce your docs in *html* format you onle have to run this shell command. - -```sh -$ make html -``` -Your documentation is now served in this path - -``` -jMetalPy/auto-docs/build/html -``` - -Inside that folder it exists a file called *index.html*. If you open it using a web browser, you will be able to visualize the generated docs. - -You should clean this folder if you want to perform another compilation. You can perform that operation with this command: - -```sh -$ make clean -``` - -> Note: Whenever you create another module or file (.py), if you want to add it to the docs, you have to re-run *sphinx-apidoc -f -o source/ ../jmetal/* inside the *auto-docs* folder. \ No newline at end of file diff --git a/resources/pages/code_style.md b/resources/pages/code_style.md deleted file mode 100644 index 23ea4ed5..00000000 --- a/resources/pages/code_style.md +++ /dev/null @@ -1,17 +0,0 @@ -## PEP8! - -It is really important to follow some standards when a team develops an application. If all team members format the code in the same format, then it is much easier to read the code. PEP8 is Python's style guide. It's a set of rules for how to format your Python code. - -Some style rules: - - - Package and module names:
-Modules should have short, **all-lowercase** names. Underscores can be used in the module name if it improves readability. Python packages should also have short, **all-lowercase** names, although the use of underscores is discouraged. In Python, a module is a file with the suffix '.py'. - - - Class names:
-Class names should normally use the **CapWords** convention. - - - Method names and instance variables:
-**Lowercase with words separated by underscores** as necessary to improve readability. - -There are many more style standards in PEP8!   → [PEP8 documentation](https://www.python.org/dev/peps/pep-0008).
-The most appropriate is to use an IDE that has support for PEP8. For example, [PyCharm](https://www.jetbrains.com/pycharm/). \ No newline at end of file diff --git a/resources/pages/features_python3.md b/resources/pages/features_python3.md deleted file mode 100644 index 9fe4ab91..00000000 --- a/resources/pages/features_python3.md +++ /dev/null @@ -1,58 +0,0 @@ -## Python 3.5! - -We use the new features of python 3. Concretely, up to version **3.5**. - -### Typing - -We **always** define types in the parameters of the arguments and the return value: - -![jMetal architecture](../../resources/types_in_methods.png) - -### Abstract class - -We can define abstract classes (ABCs) in Python: - -![jMetal architecture](../../resources/abstract.png) - -In the case that we want to define an **interface** class, it is done in the same way. We just have to define all the methods of the class as abstract. - -### Generic types - -Example of use of generic types: - -![jMetal architecture](../../resources/generic_types.png) - -In the code below, the IDE displays a **warning**, since although the 2nd parameter is a float type, which is a type allowed in the definition of the generic type X, it is not of the same type as the first, since the first 2 parameters must be of the same generic type (S): - -![jMetal architecture](../../resources/instance_with_generic_types1_wearning.png) - -In the code below, the IDE displays a **warning**, since the 2nd parameter is a type not allowed in the definition of the generic type ( *TypeVar('S', int, float)* ): - -![jMetal architecture](../../resources/instance_with_generic_types2_wearning.png) - -### Generic class - -When the class inherits from *Generic[...]*, the **class is defined as generic**. In this way we can indicate the types that will have the values of the generic types, when using the class as type. Look at the *add_car()* method of the *Parking* class. - -NOTE: The generic classes inherit from abc.ABCMeta, so they are abstract classes and **abstract methods can be used** . - -![jMetal architecture](../../resources/generic_class1.png) -![jMetal architecture](../../resources/generic_class2.png) - -In the code below, the IDE displays a **warning** in the call to the *add_car()* method when adding the car, since the 3rd parameter of the init must be a *str* type, as defined in the *add_car()* method of the *Parking* class. - -![jMetal architecture](../../resources/instance_with_generic_class_wearning.png) - -When inheriting from generic classes, some type variables could be fixed: - -![jMetal architecture](../../resources/generic_types_fixed.png) - -Example of inheritance from non-generic class to generic class: - -![jMetal architecture](../../resources/inheritance_non_generic_to_generic.png) - -Example of inheritance from generic class to another generic class: - -![jMetal architecture](../../resources/inheritance_generic_to_generic.png) - -There are more features in Python3.5!   → [Python3.5 documentation](https://docs.python.org/3.5/contents.html).
\ No newline at end of file diff --git a/resources/pages/poo.md b/resources/pages/poo.md deleted file mode 100644 index 4c9878c9..00000000 --- a/resources/pages/poo.md +++ /dev/null @@ -1,28 +0,0 @@ -## Object-oriented programming! - -**Object-oriented programming should be the single programming paradigm used**. Avoiding as far as possible, imperative and functional programming. - -![jMetal architecture](../../resources/python_poo_programming.png) -![jMetal architecture](../../resources/python_functional_programming.png) -![jMetal architecture](../../resources/python_imperative_programming.png) - -In classes, we directly access the attributes, which are usually defined as public. - -![jMetal architecture](../../resources/without_getter_setter.png) - -Only when we want to **implement additional logic in the accesses to the attributes** we define getter/setter methods, but **always by using the ***property*** annotation or the ***property*** function**: - -![jMetal architecture](../../resources/property_annotation.png) -![jMetal architecture](../../resources/property_functional.png) - -By using ***property***, we continue to access the attributes directly: - -![jMetal architecture](../../resources/good_access.png) - -Do not use getter/setter methods without the *property* annotation or the *property* function: - -![jMetal architecture](../../resources/with_getter_setter.png) - -Since this way of accessing the attribute is not commonly used in Python: - -![jMetal architecture](../../resources/bad_access.png) \ No newline at end of file diff --git a/resources/pages/profiling.md b/resources/pages/profiling.md deleted file mode 100644 index 6ff92e8b..00000000 --- a/resources/pages/profiling.md +++ /dev/null @@ -1,55 +0,0 @@ -# Profiling with Python using `cProfile` - -Python allow us to collect and analize statistics about it's performance using the profiler module. -This can be done by running - -`CProfile` is one of the three built-in modules of Python. [It is recommended for most users](https://docs.python.org/2/library/profile.html#introduction-to-the-profilers). - -This way we can know which functions are faster than others. The module can be invoked as a script: - -```bash -python -m cProfile -o [OUTPUT.FILE] [SCRIPT.PY] -``` - -When `-o` is not supplied, we can use `-s` to specify one of the `sort_stats()` sort values to sort the output by. - -## Reading profile results - -The `pstats.Stats` class allow us to examine the profile data: - -```python -import pstats - -p = pstats.Stats('restats') -p.strip_dirs().sort_stats(-1).print_stats() -``` - -# Memory usage - -`memory_profiler` is a python module for monitoring memory consumption of a process as well as line-by-line analysis of memory consumption for python programs - -To use it, simply install with - -```bash - pip install -U memory_profiler - pip install psutil -``` - -From its website: -> (Installing the psutil package here is recommended because it greatly improves the performance of the memory_profiler). - -Then decorate a function with `@profile` to view line-by-line memory usage: - -```python -from memory_profiler import profile - -@profile -def function(): - ... -``` - -And execute: - -```bash -python -m memory_profiler example.py -``` \ No newline at end of file diff --git a/resources/pages/project_structure.md b/resources/pages/project_structure.md deleted file mode 100644 index 3e3b4cdf..00000000 --- a/resources/pages/project_structure.md +++ /dev/null @@ -1,5 +0,0 @@ -## Structure! - -Python is not Java. In Java you cannot, by design, have more than one class in a file. In Python, you can do it. - -In Python, **it is appropriate to group several classes into a single .py file. For that reason, the .py files are called modules.** diff --git a/resources/pages/workflow_git.md b/resources/pages/workflow_git.md deleted file mode 100644 index f3ab6596..00000000 --- a/resources/pages/workflow_git.md +++ /dev/null @@ -1,36 +0,0 @@ -## Git WorkFlow - -We have a set of branches on the remote Git server. -Some branches are temporary, and others are constant throughout the life of the repository. - -* Branches always present in the repository: - * *master*: You have the latest released to production, receive merges from the develop branch, or merge from a *hotfix* branch (emergency). - * Do I have to put a TAG when doing a merge from develop to master? yes - * Do I have to put a TAG when doing a merge from a hotfix branch to master? yes - * After merge from a hotfix to master, do I have to merge from master to develop? yes - * *develop*: It is considered the "Next Release", receives merges from branches of each developer, either corrections (*fix*) or new features (*feature*). - -* Temporary branches: - * *feature/\\-\*: When we are doing a development, we create a local branch with the prefix "feature/", then only if there is a task id, we indicate it and we add a hyphen. The following we indicate a description according to the functionality that we are developing. The words are separated by hyphens. - * Where does this branch emerge? This branch always emerge from the develop branch - * When I finish the development in my feature branch, which branch to merge into?: You always merge feature branch into develop branch - - * *fix/\\-\*: When we are making a correction, we create a local branch with the prefix "fix/", then only if there is a task id, we indicate it and we add a hyphen. The following we indicate a description according to the functionality that we are correcting. The words are separated by hyphens. - * Where does this branch emerge? This branch always emerge from the develop branch - * When I finish the correction in my fix branch, which branch to merge into?: You always merge feature branch into develop branch - - * *hotfix/\\-\*: When we are correcting an emergency incidence in production, we create a local branch with the prefix "hotfix/", then only if there is a task id, we indicate it and we add a hyphen. The following we indicate a description according to the functionality that we are correcting. The words are separated by hyphens. - * Where does this branch emerge?: This branch always emerge from the master branch - * When I finish the correction in my hotfix branch, which branch to merge into?: This branch always emerge from the master and develop branch - -![jMetal architecture](../../resources/WorkflowGitBranches.png) - -* Steps to follow when you are creating or going to work on a branch of any kind (feature / fix / hotfix): - 1. After you create your branch (feature / fix / hotfix) locally, upload it to the remote Git server. The integration system will verify your code from the outset. - 2. Each time you commit, as much as possible, you send a push to the server. Each push will trigger the automated launch of the tests, etc. - 3. Once the development is finished, having done a push to the remote Git server, and that the test phase has passed without problem, you create an pull request: -https://help.github.com/articles/creating-a-pull-request/ -
NOTE: Do not forget to remove your branch (feature / fix / hotfix) once the merge has been made. - -* Some useful Git commands: - * git fetch --prune: Cleaning branches removed and bringing new branches From 744e5bd011dcb9080a0ccf4871d73e77dd595db2 Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 13 Jul 2018 10:10:55 +0200 Subject: [PATCH 85/90] Delete nsgaii_full_settings.ipynb --- .../multiobjective/nsgaii_full_settings.ipynb | 42 ------------------- 1 file changed, 42 deletions(-) delete mode 100644 examples/multiobjective/nsgaii_full_settings.ipynb diff --git a/examples/multiobjective/nsgaii_full_settings.ipynb b/examples/multiobjective/nsgaii_full_settings.ipynb deleted file mode 100644 index b360d7c2..00000000 --- a/examples/multiobjective/nsgaii_full_settings.ipynb +++ /dev/null @@ -1,42 +0,0 @@ -{ - "cells": [ - { - "cell_type": "heading", - "metadata": { - "collapsed": true - }, - "level": 1, - "source": [ - "NSGAII with full settings" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 2", - "language": "python", - "name": "python2" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 2 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython2", - "version": "2.7.6" - } - }, - "nbformat": 4, - "nbformat_minor": 0 -} From 9e23047456adb33ab9091b108ecdec1f713a8ed6 Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 13 Jul 2018 10:12:30 +0200 Subject: [PATCH 86/90] Fix import --- docs/source/runner/nsgaii.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/runner/nsgaii.rst b/docs/source/runner/nsgaii.rst index c391eff8..3a693b43 100644 --- a/docs/source/runner/nsgaii.rst +++ b/docs/source/runner/nsgaii.rst @@ -6,7 +6,7 @@ Common imports for these examples: .. code-block:: python from jmetal.algorithm import NSGAII - from jmetal.operator Polynomial, SBX, BinaryTournamentSelection + from jmetal.operator import Polynomial, SBX, BinaryTournamentSelection from jmetal.component import RankingAndCrowdingDistanceComparator from jmetal.problem import ZDT1 From bd11644ca6d62e418cb3916dc216c151766d2016 Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 13 Jul 2018 11:00:54 +0200 Subject: [PATCH 87/90] Update requirements --- setup.py | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/setup.py b/setup.py index 578494e3..ee867b5a 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,9 @@ -from setuptools import setup, find_packages +from setuptools import find_packages + +try: + from setuptools import setup +except ImportError: + from distutils.core import setup setup( name='jmetalpy', @@ -10,16 +15,24 @@ maintainer_email='antonio@lcc.uma.es', license='MIT', url='https://github.com/jMetal/jMetalPy', - classifiers=[ - 'Development Status :: 3 - Alpha', - - 'Intended Audience :: Science/Research', - - 'License :: OSI Approved :: MIT License', - - 'Topic :: Scientific/Engineering :: Artificial Intelligence', - - 'Programming Language :: Python :: 3.6'], - + long_description=open('README.md').read(), packages=find_packages(exclude=['test_']), + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Intended Audience :: Science/Research', + 'License :: OSI Approved :: MIT License', + 'Topic :: Scientific/Engineering :: Artificial Intelligence', + 'Programming Language :: Python :: 3.6' + ], + install_requires=[ + 'numpy', + 'matplotlib==2.0.2', + 'bokeh==0.12.16', + 'tqdm' + ], + tests_require=[ + 'mockito' + 'PyHamcrest', + 'pytest' + ] ) From 3bba8f1f67cb07db57e1cebcd76a30c172c1bd68 Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 13 Jul 2018 11:58:27 +0200 Subject: [PATCH 88/90] README updated --- README.md | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 09bc238b..75d242c9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@


- jMetalPy + jMetalPy

@@ -10,18 +10,16 @@ [![PyPI License](https://img.shields.io/pypi/l/jMetalPy.svg?style=flat-square)]() [![PyPI Python version](https://img.shields.io/pypi/pyversions/jMetalPy.svg?style=flat-square)]() -> jMetalPy is currently under heavy development! -> Any ideas about how the structure the project, coding style, useful tools or links to related projects are welcome (see [CONTRIBUTING](https://github.com/jMetal/jMetalPy/blob/master/CONTRIBUTING.md)). The starting point is the jMetal architecture: -> ![jMetal architecture](resources/jMetal5UML.png) +> jMetalPy is currently under heavy development!. The current version is 0.5.0 -# Table of Contents +## Table of Contents - [Installation](#installation) - - [Dependencies](#dependencies) - [Usage](#usage) +- [Features](#features) - [Contributing](#contributing) - [License](#license) -# Installation +## Installation To download jMetalPy just clone the Git repository hosted in GitHub: ```bash $ git clone https://github.com/jMetal/jMetalPy.git @@ -33,17 +31,22 @@ Alternatively, you can install with `pip`: $ pip install jmetalpy ``` -## Dependencies -With Python 3.6 installed, run: -```bash -$ pip install -r requirements.txt -``` - -# Usage +## Usage Examples of configuring and running all the included algorithms are located [in the docs](http://jmetalpy.readthedocs.io/en/develop/examples.html). -# Contributing +## Features +The current release of jMetalPy contains the following components: + +* Algorithms: Random search, NSGA-II, SMPSO, SMPSO/RP +* Problems: ZDT1-6, DTLZ1-2 +* Encodings: real, binary +* Operators: binary tournament, single-point crossover, SBX crossover, bit-blip mutation, polynomial mutation, uniform mutation +* Quality indicators: hypervolume +* Density estimator: crowding distance +* Graphics: 2D/3D plotting in real-time + +## Contributing Please read [CONTRIBUTING](CONTRIBUTING.md) for details on how to contribute to the project. -# License -This project is licensed under the terms of the MIT - see the [LICENSE](LICENSE) file for details. \ No newline at end of file +## License +This project is licensed under the terms of the MIT - see the [LICENSE](LICENSE) file for details. From 382623be4f632e5f3ec6610c9b262b34597629f2 Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 13 Jul 2018 12:07:09 +0200 Subject: [PATCH 89/90] README updated --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 75d242c9..4d093fa0 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,6 @@ [![PyPI License](https://img.shields.io/pypi/l/jMetalPy.svg?style=flat-square)]() [![PyPI Python version](https://img.shields.io/pypi/pyversions/jMetalPy.svg?style=flat-square)]() -> jMetalPy is currently under heavy development!. The current version is 0.5.0 - ## Table of Contents - [Installation](#installation) - [Usage](#usage) @@ -26,21 +24,21 @@ $ git clone https://github.com/jMetal/jMetalPy.git $ python setup.py install ``` -Alternatively, you can install with `pip`: +Alternatively, you can install it with `pip`: ```bash $ pip install jmetalpy ``` ## Usage -Examples of configuring and running all the included algorithms are located [in the docs](http://jmetalpy.readthedocs.io/en/develop/examples.html). +Examples of configuring and running all the included algorithms are located [in the docs](https://jmetalpy.readthedocs.io/en/latest/examples.html). ## Features -The current release of jMetalPy contains the following components: +The current release of jMetalPy (v0.5.0) contains the following components: -* Algorithms: Random search, NSGA-II, SMPSO, SMPSO/RP -* Problems: ZDT1-6, DTLZ1-2 +* Algorithms: random search, NSGA-II, SMPSO, SMPSO/RP +* Problems: ZDT1-6, DTLZ1-2, unconstrained (Kursawe, Fonseca, Schaffer, Viennet2), constrained (Srinivas, Tanaka). * Encodings: real, binary -* Operators: binary tournament, single-point crossover, SBX crossover, bit-blip mutation, polynomial mutation, uniform mutation +* Operators: selection (binary tournament, ranking and crowding distance, random, nary random, best solution), crosover (single-point, SBX), mutation (bit-blip, polynomial, uniform, random) * Quality indicators: hypervolume * Density estimator: crowding distance * Graphics: 2D/3D plotting in real-time From d8ddb3e350f4a05a7a25af625b97c4375e9e4463 Mon Sep 17 00:00:00 2001 From: benhid Date: Fri, 13 Jul 2018 12:08:48 +0200 Subject: [PATCH 90/90] README updated --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4d093fa0..29a5bb6b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@


- jMetalPy + jMetalPy

@@ -38,7 +38,7 @@ The current release of jMetalPy (v0.5.0) contains the following components: * Algorithms: random search, NSGA-II, SMPSO, SMPSO/RP * Problems: ZDT1-6, DTLZ1-2, unconstrained (Kursawe, Fonseca, Schaffer, Viennet2), constrained (Srinivas, Tanaka). * Encodings: real, binary -* Operators: selection (binary tournament, ranking and crowding distance, random, nary random, best solution), crosover (single-point, SBX), mutation (bit-blip, polynomial, uniform, random) +* Operators: selection (binary tournament, ranking and crowding distance, random, nary random, best solution), crossover (single-point, SBX), mutation (bit-blip, polynomial, uniform, random) * Quality indicators: hypervolume * Density estimator: crowding distance * Graphics: 2D/3D plotting in real-time