From 64fe01b10c63e0a20af300ad408f831be61acc0c Mon Sep 17 00:00:00 2001 From: kei-mo Date: Sun, 27 Feb 2022 17:42:59 +0900 Subject: [PATCH 01/26] changed relative path to run_mo_kurobako.py --- benchmarks/run_mo_kurobako.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/run_mo_kurobako.py b/benchmarks/run_mo_kurobako.py index 24eaa5a33c..3aa1ea0c8b 100644 --- a/benchmarks/run_mo_kurobako.py +++ b/benchmarks/run_mo_kurobako.py @@ -42,7 +42,7 @@ def run(args: argparse.Namespace) -> None: for sampler, sampler_kwargs in zip(sampler_list, sampler_kwargs_list): name = f"{args.name_prefix}_{sampler}" - python_command = f"mo_runner.py {sampler} {sampler_kwargs}" + python_command = f"benchmarks/mo_runner.py {sampler} {sampler_kwargs}" cmd = ( f"{kurobako_cmd} solver --name {name} command python {python_command}" f"| tee -a {solvers_filename}" From 7fb6608ce84c9c473ae714e72bff46849f877b59 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Sun, 27 Feb 2022 17:44:30 +0900 Subject: [PATCH 02/26] add binh and korn problem --- benchmarks/binh_and_korn_problem.py | 47 +++++++++++++++++++++++++++++ benchmarks/run_mo_kurobako.py | 4 +++ 2 files changed, 51 insertions(+) create mode 100644 benchmarks/binh_and_korn_problem.py diff --git a/benchmarks/binh_and_korn_problem.py b/benchmarks/binh_and_korn_problem.py new file mode 100644 index 0000000000..8a03172274 --- /dev/null +++ b/benchmarks/binh_and_korn_problem.py @@ -0,0 +1,47 @@ +from kurobako import problem + + +class BinhAndKornProblemFactory(problem.ProblemFactory): + def specification(self): + params = [ + problem.Var("x", problem.ContinuousRange(0, 5)), + problem.Var("y", problem.ContinuousRange(0, 3)), + ] + return problem.ProblemSpec( + name="Binh and Korn", + params=params, + values=[ + problem.Var("4 * x ** 2 + 4 * y ** 2"), + problem.Var("(x - 5) ** 2 + (y - 5) ** 2"), + ], + reference_point=[140, 50], # Used at `kurobako plot curve --metric hypervolume`. + ) + + def create_problem(self, seed): + return BinhAndKornProblem() + + +class BinhAndKornProblem(problem.Problem): + def create_evaluator(self, params): + return BinhAndKornEvaluator(params) + + +class BinhAndKornEvaluator(problem.Evaluator): + def __init__(self, params): + self._x, self._y = params + self._current_step = 0 + + def current_step(self): + return self._current_step + + def evaluate(self, next_step): + self._current_step = 1 + x, y = self._x, self._y + v0 = 4 * x ** 2 + 4 * y ** 2 + v1 = (x - 5) ** 2 + (y - 5) ** 2 + return [v0, v1] + + +if __name__ == "__main__": + runner = problem.ProblemRunner(BinhAndKornProblemFactory()) + runner.run() \ No newline at end of file diff --git a/benchmarks/run_mo_kurobako.py b/benchmarks/run_mo_kurobako.py index 3aa1ea0c8b..5e40682862 100644 --- a/benchmarks/run_mo_kurobako.py +++ b/benchmarks/run_mo_kurobako.py @@ -30,6 +30,10 @@ def run(args: argparse.Namespace) -> None: ) subprocess.run(cmd, shell=True) + # Create Binh and Korn problem + cmd = (f"{kurobako_cmd} problem command python3 benchmarks/binh_and_korn_problem.py | tee -a {problems_filename}") + subprocess.run(cmd, shell=True) + # Create solvers. sampler_list = args.sampler_list.split() sampler_kwargs_list = args.sampler_kwargs_list.split() From a08d26f5cca4f6f9a8f5d9d91ae470b7b46acbc0 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Sun, 27 Feb 2022 17:45:29 +0900 Subject: [PATCH 03/26] wip add wfg problem --- benchmarks/run_mo_kurobako.py | 4 ++++ benchmarks/wfg_problem.py | 37 +++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 benchmarks/wfg_problem.py diff --git a/benchmarks/run_mo_kurobako.py b/benchmarks/run_mo_kurobako.py index 5e40682862..68cc45f841 100644 --- a/benchmarks/run_mo_kurobako.py +++ b/benchmarks/run_mo_kurobako.py @@ -30,6 +30,10 @@ def run(args: argparse.Namespace) -> None: ) subprocess.run(cmd, shell=True) + # Create WFG problem + # cmd = (f"{kurobako_cmd} problem command python3 benchmarks/wfg_problem.py | tee -a {problems_filename}") + # subprocess.run(cmd, shell=True) + # Create Binh and Korn problem cmd = (f"{kurobako_cmd} problem command python3 benchmarks/binh_and_korn_problem.py | tee -a {problems_filename}") subprocess.run(cmd, shell=True) diff --git a/benchmarks/wfg_problem.py b/benchmarks/wfg_problem.py new file mode 100644 index 0000000000..1b76a9ca66 --- /dev/null +++ b/benchmarks/wfg_problem.py @@ -0,0 +1,37 @@ +from kurobako import problem + + +class WSGProblemFactory(problem.ProblemFactory): + def specification(self): + # wip + params = [] + + return problem.ProblemSpec(name="WFG", + params=params, + vales=[]) + + def create_problem(self, seed): + return WSGProblem() + +class WSGProblem(problem.Problem): + def create_evaluator(self, params): + return WSGProblem(params) + + +class WSGEvaluator(problem.Evaluator): + def __init__(self, params): + self._x, self._y = params + self._current_step = 0 + + def current_step(self): + return self._current_step + + def evaluate(self, next_step): + self._current_step = 1 + + #TODO: + return None + +if __name__ == '__main__': + runner = problem.ProblemRunner(WSGProblemFactory()) + runner.run() \ No newline at end of file From 95d4a9fe90ab23a61907513b139e628d6b59e88e Mon Sep 17 00:00:00 2001 From: kei-mo Date: Tue, 1 Mar 2022 22:45:22 +0900 Subject: [PATCH 04/26] reorganized problem directory --- benchmarks/problem/binh_and_korn_problem.py | 47 +++++++++++++++++++++ benchmarks/problem/wfg_problem.py | 37 ++++++++++++++++ benchmarks/run_mo_kurobako.py | 4 +- 3 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 benchmarks/problem/binh_and_korn_problem.py create mode 100644 benchmarks/problem/wfg_problem.py diff --git a/benchmarks/problem/binh_and_korn_problem.py b/benchmarks/problem/binh_and_korn_problem.py new file mode 100644 index 0000000000..8a03172274 --- /dev/null +++ b/benchmarks/problem/binh_and_korn_problem.py @@ -0,0 +1,47 @@ +from kurobako import problem + + +class BinhAndKornProblemFactory(problem.ProblemFactory): + def specification(self): + params = [ + problem.Var("x", problem.ContinuousRange(0, 5)), + problem.Var("y", problem.ContinuousRange(0, 3)), + ] + return problem.ProblemSpec( + name="Binh and Korn", + params=params, + values=[ + problem.Var("4 * x ** 2 + 4 * y ** 2"), + problem.Var("(x - 5) ** 2 + (y - 5) ** 2"), + ], + reference_point=[140, 50], # Used at `kurobako plot curve --metric hypervolume`. + ) + + def create_problem(self, seed): + return BinhAndKornProblem() + + +class BinhAndKornProblem(problem.Problem): + def create_evaluator(self, params): + return BinhAndKornEvaluator(params) + + +class BinhAndKornEvaluator(problem.Evaluator): + def __init__(self, params): + self._x, self._y = params + self._current_step = 0 + + def current_step(self): + return self._current_step + + def evaluate(self, next_step): + self._current_step = 1 + x, y = self._x, self._y + v0 = 4 * x ** 2 + 4 * y ** 2 + v1 = (x - 5) ** 2 + (y - 5) ** 2 + return [v0, v1] + + +if __name__ == "__main__": + runner = problem.ProblemRunner(BinhAndKornProblemFactory()) + runner.run() \ No newline at end of file diff --git a/benchmarks/problem/wfg_problem.py b/benchmarks/problem/wfg_problem.py new file mode 100644 index 0000000000..1b76a9ca66 --- /dev/null +++ b/benchmarks/problem/wfg_problem.py @@ -0,0 +1,37 @@ +from kurobako import problem + + +class WSGProblemFactory(problem.ProblemFactory): + def specification(self): + # wip + params = [] + + return problem.ProblemSpec(name="WFG", + params=params, + vales=[]) + + def create_problem(self, seed): + return WSGProblem() + +class WSGProblem(problem.Problem): + def create_evaluator(self, params): + return WSGProblem(params) + + +class WSGEvaluator(problem.Evaluator): + def __init__(self, params): + self._x, self._y = params + self._current_step = 0 + + def current_step(self): + return self._current_step + + def evaluate(self, next_step): + self._current_step = 1 + + #TODO: + return None + +if __name__ == '__main__': + runner = problem.ProblemRunner(WSGProblemFactory()) + runner.run() \ No newline at end of file diff --git a/benchmarks/run_mo_kurobako.py b/benchmarks/run_mo_kurobako.py index 68cc45f841..bfc1063314 100644 --- a/benchmarks/run_mo_kurobako.py +++ b/benchmarks/run_mo_kurobako.py @@ -31,11 +31,11 @@ def run(args: argparse.Namespace) -> None: subprocess.run(cmd, shell=True) # Create WFG problem - # cmd = (f"{kurobako_cmd} problem command python3 benchmarks/wfg_problem.py | tee -a {problems_filename}") + # cmd = (f"{kurobako_cmd} problem command python3 benchmarks/problem/wfg_problem.py | tee -a {problems_filename}") # subprocess.run(cmd, shell=True) # Create Binh and Korn problem - cmd = (f"{kurobako_cmd} problem command python3 benchmarks/binh_and_korn_problem.py | tee -a {problems_filename}") + cmd = (f"{kurobako_cmd} problem command python3 benchmarks/problem/binh_and_korn_problem.py | tee -a {problems_filename}") subprocess.run(cmd, shell=True) # Create solvers. From 1844441a33706038cb520a303a9673acff3711d9 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Tue, 1 Mar 2022 23:00:27 +0900 Subject: [PATCH 05/26] formate --- benchmarks/problem/binh_and_korn_problem.py | 4 ++-- benchmarks/problem/wfg_problem.py | 12 ++++++------ benchmarks/run_mo_kurobako.py | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/benchmarks/problem/binh_and_korn_problem.py b/benchmarks/problem/binh_and_korn_problem.py index 8a03172274..2f67a39ca9 100644 --- a/benchmarks/problem/binh_and_korn_problem.py +++ b/benchmarks/problem/binh_and_korn_problem.py @@ -37,11 +37,11 @@ def current_step(self): def evaluate(self, next_step): self._current_step = 1 x, y = self._x, self._y - v0 = 4 * x ** 2 + 4 * y ** 2 + v0 = 4 * x**2 + 4 * y**2 v1 = (x - 5) ** 2 + (y - 5) ** 2 return [v0, v1] if __name__ == "__main__": runner = problem.ProblemRunner(BinhAndKornProblemFactory()) - runner.run() \ No newline at end of file + runner.run() diff --git a/benchmarks/problem/wfg_problem.py b/benchmarks/problem/wfg_problem.py index 1b76a9ca66..3ef21d36b0 100644 --- a/benchmarks/problem/wfg_problem.py +++ b/benchmarks/problem/wfg_problem.py @@ -6,13 +6,12 @@ def specification(self): # wip params = [] - return problem.ProblemSpec(name="WFG", - params=params, - vales=[]) + return problem.ProblemSpec(name="WFG", params=params, vales=[]) def create_problem(self, seed): return WSGProblem() + class WSGProblem(problem.Problem): def create_evaluator(self, params): return WSGProblem(params) @@ -29,9 +28,10 @@ def current_step(self): def evaluate(self, next_step): self._current_step = 1 - #TODO: + # TODO: return None -if __name__ == '__main__': + +if __name__ == "__main__": runner = problem.ProblemRunner(WSGProblemFactory()) - runner.run() \ No newline at end of file + runner.run() diff --git a/benchmarks/run_mo_kurobako.py b/benchmarks/run_mo_kurobako.py index bfc1063314..a11598ded0 100644 --- a/benchmarks/run_mo_kurobako.py +++ b/benchmarks/run_mo_kurobako.py @@ -35,7 +35,7 @@ def run(args: argparse.Namespace) -> None: # subprocess.run(cmd, shell=True) # Create Binh and Korn problem - cmd = (f"{kurobako_cmd} problem command python3 benchmarks/problem/binh_and_korn_problem.py | tee -a {problems_filename}") + cmd = f"{kurobako_cmd} problem command python3 benchmarks/problem/binh_and_korn_problem.py | tee -a {problems_filename}" subprocess.run(cmd, shell=True) # Create solvers. From ba1a5b9e4970cd804fa80b327fd36143ad453214 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Tue, 1 Mar 2022 23:14:16 +0900 Subject: [PATCH 06/26] migrated wfg code from HideakiImamura's repo --- benchmarks/problem/wfg/shape_functions.py | 104 +++ .../problem/wfg/transformation_functions.py | 198 +++++ benchmarks/problem/wfg/wfg.py | 708 ++++++++++++++++++ 3 files changed, 1010 insertions(+) create mode 100644 benchmarks/problem/wfg/shape_functions.py create mode 100644 benchmarks/problem/wfg/transformation_functions.py create mode 100644 benchmarks/problem/wfg/wfg.py diff --git a/benchmarks/problem/wfg/shape_functions.py b/benchmarks/problem/wfg/shape_functions.py new file mode 100644 index 0000000000..9ad3112f90 --- /dev/null +++ b/benchmarks/problem/wfg/shape_functions.py @@ -0,0 +1,104 @@ +import abc + +import numpy as np + + +class BaseShapeFunction(object, metaclass=abc.ABCMeta): + def __init__(self, n_objectives: int) -> None: + + self._n_objectives = n_objectives + + def __call__(self, m: int, x: np.ndarray) -> float: + assert 1 <= m <= self.n_objectives + assert x.shape == (self.n_objectives - 1,) + return self._call(m, x) + + @abc.abstractmethod + def _call(self, m: int, x: np.ndarray) -> float: + raise NotImplementedError + + @property + def n_objectives(self) -> int: + + return self._n_objectives + + +class LinearShapeFunction(BaseShapeFunction): + def _call(self, m: int, x: np.ndarray) -> float: + + if m == 1: + return x[:-1].prod() + + if m == self.n_objectives: + return 1 - x[0] + + return x[: self.n_objectives - m].prod() * (1.0 - x[self.n_objectives - m]) + + +class ConvexShapeFunction(BaseShapeFunction): + def _call(self, m: int, x: np.ndarray) -> float: + + if m == 1: + return ( + 1 + - np.cos( + x * np.pi / 2, + ) + )[:-1].prod() + + if m == self.n_objectives: + return 1 - np.sin(x[0] * np.pi / 2.0) + + return (1.0 - np.cos(x * np.pi / 2.0))[: self.n_objectives - m].prod() * ( + 1.0 - np.sin(x[self.n_objectives - m] * np.pi / 2.0) + ) + + +class ConcaveShapeFunction(BaseShapeFunction): + def _call(self, m: int, x: np.ndarray) -> float: + + if m == 1: + return np.sin(x * np.pi / 2.0)[:-1].prod() + + if m == self.n_objectives: + return np.cos(x[0] * np.pi / 2.0) + + return np.sin(x * np.pi / 2.0)[: self.n_objectives - m].prod() * np.cos( + x[self.n_objectives - m] * np.pi / 2.0 + ) + + +class MixedConvexOrConcaveShapeFunction(BaseShapeFunction): + def __init__(self, n_objectives, alpha: float, n_segments: int) -> None: + super().__init__(n_objectives) + self._alpha = alpha + self._n_segments = n_segments + + def _call(self, m: int, x: np.ndarray) -> float: + if m == self.n_objectives: + two_A_pi = 2 * self._n_segments * np.pi + return np.power( + 1 - x[0] - np.cos(two_A_pi * x[0] + np.pi / 2.0) / two_A_pi, self._alpha + ) + + raise ValueError("m should be the number of objectives") + + +class DisconnectedShapeFunction(BaseShapeFunction): + def __init__( + self, n_objectives, alpha: float, beta: float, n_disconnected_regions: int + ) -> None: + super().__init__(n_objectives) + self._alpha = alpha + self._beta = beta + self._n_disconnected_regions = n_disconnected_regions + + def _call(self, m: int, x: np.ndarray) -> float: + if m == self.n_objectives: + return ( + 1 + - np.power(x[0], self._alpha) + * np.cos(self._n_disconnected_regions * np.power(x[0], self._beta) * np.pi) ** 2 + ) + + raise ValueError("m should be the number of objectives") diff --git a/benchmarks/problem/wfg/transformation_functions.py b/benchmarks/problem/wfg/transformation_functions.py new file mode 100644 index 0000000000..112c5fcd39 --- /dev/null +++ b/benchmarks/problem/wfg/transformation_functions.py @@ -0,0 +1,198 @@ +from typing import Callable + +import abc + +import numpy as np + + +class BaseTransformations(object, metaclass=abc.ABCMeta): + @abc.abstractmethod + def __call__(self, *args, **kwargs): + + raise NotImplementedError + + +class BaseBiasTransformation(BaseTransformations, metaclass=abc.ABCMeta): + @abc.abstractmethod + def __call__(self, y: np.ndarray) -> float: + + raise NotImplementedError + + +class BaseShiftTransformation(BaseTransformations, metaclass=abc.ABCMeta): + @abc.abstractmethod + def __call__(self, y: float) -> float: + + raise NotImplementedError + + +class BaseReductionTransformation(BaseTransformations, metaclass=abc.ABCMeta): + @abc.abstractmethod + def __call__(self, y: np.ndarray) -> float: + + raise NotImplementedError + + +class PolynomialBiasTransformation(BaseBiasTransformation): + def __init__(self, alpha: float) -> None: + + assert alpha > 0 and alpha != 1.0 + self._alpha = alpha + + def __call__(self, y: float) -> float: + + return np.power(y, self._alpha) + + +class FlatRegionBiasTransformation(BaseBiasTransformation): + def __init__(self, a: float, b: float, c: float) -> None: + + assert 0 <= a <= 1 + assert 0 <= b <= 1 + assert 0 <= c <= 1 + assert b < c + assert not (b == 0) or (a == 0 and c != 1) + assert not (c == 1) or (a == 1 and b != 0) + + self._a = a + self._b = b + self._c = c + + def __call__(self, y: float) -> float: + + a = self._a + b = self._b + c = self._c + return ( + a + + min(0, np.floor(y - b)) * a * (b - y) / b + - min(0, np.floor(c - y)) * (1.0 - a) * (y - c) / (1.0 - c) + ) + + +class ParameterDependentBiasTransformation(BaseReductionTransformation): + def __init__( + self, + w: np.ndarray, + input_converter: Callable[[np.ndarray], np.ndarray], + a: float, + b: float, + c: float, + i: int, + ) -> None: + + assert 0 < a < 1 + assert 0 < b < c + + self._w = w + self._input_converter = input_converter + self._a = a + self._b = b + self._c = c + self._i = i + + def __call__(self, y: np.ndarray) -> float: + + w = self._w + a = self._a + b = self._b + c = self._c + i = self._i + + u = (self._input_converter(y) * w).sum() / w.sum() + v = a - (1.0 - 2 * u) * np.fabs(np.floor(0.5 - u) + a) + return np.power(y[i], b + (c - b) * v) + + +class LinearShiftTransformation(BaseShiftTransformation): + def __init__(self, a: float) -> None: + + assert 0 < a < 1 + + self._a = a + + def __call__(self, y: float) -> float: + + return np.fabs(y - self._a) / np.fabs(np.floor(self._a - y) + self._a) + + +class DeceptiveShiftTransformation(BaseShiftTransformation): + def __init__(self, a: float, b: float, c: float) -> None: + + assert 0 < a < 1 + assert 0 < b < 1 + assert 0 < c < 1 + assert a - b > 0 + assert a + b < 1 + + self._a = a + self._b = b + self._c = c + + def __call__(self, y: float) -> float: + + a = self._a + b = self._b + c = self._c + + q1 = np.floor(y - a + b) * (1.0 - c + (a - b) / b) + q2 = np.floor(a + b - y) * (1.0 - c + (1.0 - a - b) / b) + return 1.0 + (np.fabs(y - a) - b) * (q1 / (a - b) + q2 / (1.0 - a - b) + 1.0 / b) + + +class MultiModalShiftTransformation(BaseShiftTransformation): + def __init__(self, a: int, b: float, c: float) -> None: + + assert a > 0 + assert b >= 0 + assert (4 * a + 2) * np.pi >= 4 * b + assert 0 < c < 1 + + self._a = a + self._b = b + self._c = c + + def __call__(self, y: float) -> float: + + a = self._a + b = self._b + c = self._c + + q1 = np.fabs(y - c) / (2 * (np.floor(c - y) + c)) + q2 = (4 * a + 2) * np.pi * (0.5 - q1) + return (1.0 + np.cos(q2) + 4 * b * (q1**2)) / (b + 2) + + +class WeightedSumReductionTransformation(BaseReductionTransformation): + def __init__(self, w: np.ndarray, input_converter: Callable[[np.ndarray], np.ndarray]) -> None: + + assert all(w > 0) + + self._w = w + self._input_converter = input_converter + + def __call__(self, y: np.ndarray) -> float: + + y = self._input_converter(y) + return (y * self._w).sum() / self._w.sum() + + +class NonSeparableReductionTransformation(BaseReductionTransformation): + def __init__(self, a: int, input_converter: Callable[[np.ndarray], np.ndarray]) -> None: + + assert a > 0 + + self._a = a + self._input_converter = input_converter + + def __call__(self, y: np.ndarray) -> float: + + a = float(self._a) + y = self._input_converter(y) + n = y.shape[0] + indices = [(j + k + 1) % n for k in np.arange(n) for j in np.arange(n)] + + q = y.sum() + np.fabs(y[indices].reshape((n, n)) - y)[:, 0 : int(a) - 1].sum() + r = n * np.ceil(a / 2) * (1.0 + 2 * a - 2 * np.ceil(a / 2)) / a + + return q / r diff --git a/benchmarks/problem/wfg/wfg.py b/benchmarks/problem/wfg/wfg.py new file mode 100644 index 0000000000..88c122d0ed --- /dev/null +++ b/benchmarks/problem/wfg/wfg.py @@ -0,0 +1,708 @@ +import copy +from typing import List + +import numpy as np + + +from . import shape_functions +from . import transformation_functions + + +class BaseWFG(object): + def __init__( + self, + S: np.ndarray, + A: np.ndarray, + upper_bounds: np.ndarray, + shapes: List[shape_functions.BaseShapeFunction], + transformations: List[List[transformation_functions.BaseTransformations]], + ) -> None: + + assert all(S > 0) + assert all((A == 0) + (A == 1)) + assert all(upper_bounds > 0) + + self._S = S + self._A = A + self._upper_bounds = upper_bounds + self._shapes = shapes + self._transformations = transformations + + def __call__(self, z: np.ndarray) -> np.ndarray: + + S = self._S + A = self._A + unit_z = z / self._upper_bounds + shapes = self._shapes + transformations = self._transformations + + y = unit_z + for t_p in transformations: + _y = np.empty((len(t_p),)) + for i in range(len(t_p)): + if isinstance(t_p[i], transformation_functions.BaseReductionTransformation): + _y[i] = t_p[i](y) + else: + _y[i] = t_p[i](y[i]) + y = _y + + x = np.empty(y.shape) + x[:-1] = np.maximum(y[-1], A) * (y[:-1] - 0.5) + 0.5 + x[-1] = y[-1] + + f = x[-1] + S * np.asarray([h(m + 1, x[:-1]) for m, h in enumerate(shapes)]) + return f + + +class WFG1(object): + """WFG1 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.ones(M - 1) + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.ConvexShapeFunction(M) for _ in range(M - 1)] + shapes.append(shape_functions.MixedConvexOrConcaveShapeFunction(M, 1, 5)) + + t_1 = [lambda y: y for _ in range(k)] + for _ in range(n - k): + t_1.append(transformation_functions.LinearShiftTransformation(0.35)) + + t_2 = [lambda y: y for _ in range(k)] + for _ in range(n - k): + t_2.append(transformation_functions.FlatRegionBiasTransformation(0.8, 0.75, 0.85)) + + t_3 = [transformation_functions.PolynomialBiasTransformation(0.02) for _ in range(n)] + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_4 = [ + transformation_functions.WeightedSumReductionTransformation( + 2 * np.arange(i * k // (M - 1) + 1, (i + 1) * k // (M - 1) + 1), + lambda y: _input_converter(i, y), + ) + for i in range(M - 1) + ] + t_4.append( + transformation_functions.WeightedSumReductionTransformation( + 2 * np.arange(k, n) + 1, + lambda y: y[k:n], + ) + ) + transformations = [t_1, t_2, t_3, t_4] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) + + +class WFG2(object): + """WFG2 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments // 2 + assert (n_arguments - k) % 2 == 0 + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.ones(M - 1) + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.ConvexShapeFunction(M) for _ in range(M - 1)] + shapes.append(shape_functions.DisconnectedShapeFunction(M, 1, 1, 5)) + + t_1 = [lambda y: y for _ in range(k)] + for _ in range(n - k): + t_1.append(transformation_functions.LinearShiftTransformation(0.35)) + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = [k + 2 * (i + 1 - k) - 2, k + 2 * (i - k + 1) - 1] + return y[indices] + + t_2 = [lambda y: y for _ in range(k)] + for i in range(k, n // 2): + t_2.append( + transformation_functions.NonSeparableReductionTransformation( + 2, lambda y: _input_converter(i, y) + ) + ) + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_3 = [ + transformation_functions.WeightedSumReductionTransformation( + np.ones(k // (M - 1)), + lambda y: _input_converter(i, y), + ) + for i in range(M - 1) + ] + t_3.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(n // 2 - k), + lambda y: y[k : n // 2], + ) + ) + + transformations = [t_1, t_2, t_3] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) + + +class WFG3(object): + """WFG3 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments // 2 + assert (n_arguments - k) % 2 == 0 + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.zeros(M - 1) + A[0] = 1 + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.LinearShapeFunction(M) for _ in range(M)] + + t_1 = [lambda y: y for _ in range(k)] + for _ in range(n - k): + t_1.append(transformation_functions.LinearShiftTransformation(0.35)) + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = [k + 2 * (i + 1 - k) - 2, k + 2 * (i - k + 1) - 1] + return y[indices] + + t_2 = [lambda y: y for _ in range(k)] + for i in range(k, n // 2): + t_2.append( + transformation_functions.NonSeparableReductionTransformation( + 2, lambda y: _input_converter(i, y) + ) + ) + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_3 = [ + transformation_functions.WeightedSumReductionTransformation( + np.ones(k // (M - 1)), + lambda y: _input_converter(i, y), + ) + for i in range(M - 1) + ] + t_3.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(n // 2 - k), + lambda y: y[k : n // 2], + ) + ) + + transformations = [t_1, t_2, t_3] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) + + +class WFG4(object): + """WFG4 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.ones(M - 1) + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] + + t_1 = [ + transformation_functions.MultiModalShiftTransformation(30, 10, 0.35) for _ in range(n) + ] + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_2 = [] + for i in range(M - 1): + t_2.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(k // (M - 1)), lambda y: _input_converter(i, y) + ) + ) + t_2.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(n - k), + lambda y: y[k:n], + ) + ) + + transformations = [t_1, t_2] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) + + +class WFG5(object): + """WFG5 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.ones(M - 1) + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] + + t_1 = [ + transformation_functions.DeceptiveShiftTransformation(0.35, 0.001, 0.05) + for _ in range(n) + ] + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_2 = [] + for i in range(M - 1): + t_2.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(k // (M - 1)), lambda y: _input_converter(i, y) + ) + ) + t_2.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(n - k), + lambda y: y[k:n], + ) + ) + + transformations = [t_1, t_2] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) + + +class WFG6(object): + """WFG6 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.ones(M - 1) + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] + + t_1 = [lambda y: y for _ in range(k)] + for _ in range(n - k): + t_1.append(transformation_functions.LinearShiftTransformation(0.35)) + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_2 = [] + for i in range(M - 1): + t_2.append( + transformation_functions.NonSeparableReductionTransformation( + k // (M - 1), lambda y: _input_converter(i, y) + ) + ) + t_2.append( + transformation_functions.NonSeparableReductionTransformation( + n - k, + lambda y: y[k:n], + ) + ) + + transformations = [t_1, t_2] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) + + +class WFG7(object): + """WFG7 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.ones(M - 1) + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + return y[i:n] + + t_1 = [ + transformation_functions.ParameterDependentBiasTransformation( + np.ones(n - i), + lambda y: _input_converter(i, y), + 0.98 / 49.98, + 0.02, + 50, + i, + ) + for i in range(k) + ] + for _ in range(n - k): + t_1.append(lambda y: y) + + t_2 = [lambda y: y for _ in range(k)] + for _ in range(n - k): + t_2.append(transformation_functions.LinearShiftTransformation(0.35)) + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_3 = [] + for i in range(M - 1): + t_3.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(k // (M - 1)), lambda y: _input_converter(i, y) + ) + ) + t_3.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(n - k), + lambda y: y[k:n], + ) + ) + + transformations = [t_1, t_2, t_3] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) + + +class WFG8(object): + """WFG8 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.ones(M - 1) + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + return y[: i - 1] + + t_1 = [lambda y: y for _ in range(k)] + for i in range(k, n): + t_1.append( + transformation_functions.ParameterDependentBiasTransformation( + np.ones(i - 1), + lambda y: _input_converter(i, y), + 0.98 / 49.98, + 0.02, + 50, + i, + ) + ) + + t_2 = [lambda y: y for _ in range(k)] + for _ in range(n - k): + t_2.append(transformation_functions.LinearShiftTransformation(0.35)) + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_3 = [] + for i in range(M - 1): + t_3.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(k // (M - 1)), lambda y: _input_converter(i, y) + ) + ) + t_3.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(n - k), + lambda y: y[k:n], + ) + ) + + transformations = [t_1, t_2, t_3] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) + + +class WFG9(object): + """WFG9 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.ones(M - 1) + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + return y[i:n] + + t_1 = [ + transformation_functions.ParameterDependentBiasTransformation( + np.ones(n - i), + lambda y: _input_converter(i, y), + 0.98 / 49.98, + 0.02, + 50, + i, + ) + for i in range(n - 1) + ] + t_1.append(lambda y: y) + + t_2 = [ + transformation_functions.DeceptiveShiftTransformation(0.35, 0.001, 0.05) + for _ in range(k) + ] + for _ in range(n - k): + t_2.append(transformation_functions.MultiModalShiftTransformation(30, 95, 0.35)) + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_3 = [] + for i in range(M - 1): + t_3.append( + transformation_functions.NonSeparableReductionTransformation( + k // (M - 1), lambda y: _input_converter(i, y) + ) + ) + t_3.append( + transformation_functions.NonSeparableReductionTransformation( + n - k, + lambda y: y[k:n], + ) + ) + + transformations = [t_1, t_2, t_3] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) From a53872f6549f8ae21000a9471d12e0644c332b64 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Wed, 2 Mar 2022 22:44:52 +0900 Subject: [PATCH 07/26] wip reorganized --- benchmarks/binh_and_korn_problem.py | 47 ----------------------------- benchmarks/wfg_problem.py | 37 ----------------------- 2 files changed, 84 deletions(-) delete mode 100644 benchmarks/binh_and_korn_problem.py delete mode 100644 benchmarks/wfg_problem.py diff --git a/benchmarks/binh_and_korn_problem.py b/benchmarks/binh_and_korn_problem.py deleted file mode 100644 index 8a03172274..0000000000 --- a/benchmarks/binh_and_korn_problem.py +++ /dev/null @@ -1,47 +0,0 @@ -from kurobako import problem - - -class BinhAndKornProblemFactory(problem.ProblemFactory): - def specification(self): - params = [ - problem.Var("x", problem.ContinuousRange(0, 5)), - problem.Var("y", problem.ContinuousRange(0, 3)), - ] - return problem.ProblemSpec( - name="Binh and Korn", - params=params, - values=[ - problem.Var("4 * x ** 2 + 4 * y ** 2"), - problem.Var("(x - 5) ** 2 + (y - 5) ** 2"), - ], - reference_point=[140, 50], # Used at `kurobako plot curve --metric hypervolume`. - ) - - def create_problem(self, seed): - return BinhAndKornProblem() - - -class BinhAndKornProblem(problem.Problem): - def create_evaluator(self, params): - return BinhAndKornEvaluator(params) - - -class BinhAndKornEvaluator(problem.Evaluator): - def __init__(self, params): - self._x, self._y = params - self._current_step = 0 - - def current_step(self): - return self._current_step - - def evaluate(self, next_step): - self._current_step = 1 - x, y = self._x, self._y - v0 = 4 * x ** 2 + 4 * y ** 2 - v1 = (x - 5) ** 2 + (y - 5) ** 2 - return [v0, v1] - - -if __name__ == "__main__": - runner = problem.ProblemRunner(BinhAndKornProblemFactory()) - runner.run() \ No newline at end of file diff --git a/benchmarks/wfg_problem.py b/benchmarks/wfg_problem.py deleted file mode 100644 index 1b76a9ca66..0000000000 --- a/benchmarks/wfg_problem.py +++ /dev/null @@ -1,37 +0,0 @@ -from kurobako import problem - - -class WSGProblemFactory(problem.ProblemFactory): - def specification(self): - # wip - params = [] - - return problem.ProblemSpec(name="WFG", - params=params, - vales=[]) - - def create_problem(self, seed): - return WSGProblem() - -class WSGProblem(problem.Problem): - def create_evaluator(self, params): - return WSGProblem(params) - - -class WSGEvaluator(problem.Evaluator): - def __init__(self, params): - self._x, self._y = params - self._current_step = 0 - - def current_step(self): - return self._current_step - - def evaluate(self, next_step): - self._current_step = 1 - - #TODO: - return None - -if __name__ == '__main__': - runner = problem.ProblemRunner(WSGProblemFactory()) - runner.run() \ No newline at end of file From 9b6686c2da71bb39bdf107c83a8d9df9c0d0bd5f Mon Sep 17 00:00:00 2001 From: kei-mo Date: Sun, 6 Mar 2022 17:38:02 +0900 Subject: [PATCH 08/26] add wfg1 --- .../{wfg => WFGtestSuite}/shape_functions.py | 0 .../transformation_functions.py | 0 .../problem/{wfg => WFGtestSuite}/wfg.py | 0 benchmarks/problem/binh_and_korn_problem.py | 3 +- benchmarks/problem/wfg_problem.py | 42 ++++++++++++------ benchmarks/run_mo_kurobako.py | 44 ++++++++++++------- 6 files changed, 57 insertions(+), 32 deletions(-) rename benchmarks/problem/{wfg => WFGtestSuite}/shape_functions.py (100%) rename benchmarks/problem/{wfg => WFGtestSuite}/transformation_functions.py (100%) rename benchmarks/problem/{wfg => WFGtestSuite}/wfg.py (100%) diff --git a/benchmarks/problem/wfg/shape_functions.py b/benchmarks/problem/WFGtestSuite/shape_functions.py similarity index 100% rename from benchmarks/problem/wfg/shape_functions.py rename to benchmarks/problem/WFGtestSuite/shape_functions.py diff --git a/benchmarks/problem/wfg/transformation_functions.py b/benchmarks/problem/WFGtestSuite/transformation_functions.py similarity index 100% rename from benchmarks/problem/wfg/transformation_functions.py rename to benchmarks/problem/WFGtestSuite/transformation_functions.py diff --git a/benchmarks/problem/wfg/wfg.py b/benchmarks/problem/WFGtestSuite/wfg.py similarity index 100% rename from benchmarks/problem/wfg/wfg.py rename to benchmarks/problem/WFGtestSuite/wfg.py diff --git a/benchmarks/problem/binh_and_korn_problem.py b/benchmarks/problem/binh_and_korn_problem.py index 2f67a39ca9..2ce9829b68 100644 --- a/benchmarks/problem/binh_and_korn_problem.py +++ b/benchmarks/problem/binh_and_korn_problem.py @@ -8,13 +8,12 @@ def specification(self): problem.Var("y", problem.ContinuousRange(0, 3)), ] return problem.ProblemSpec( - name="Binh and Korn", + name="BinhKorn", params=params, values=[ problem.Var("4 * x ** 2 + 4 * y ** 2"), problem.Var("(x - 5) ** 2 + (y - 5) ** 2"), ], - reference_point=[140, 50], # Used at `kurobako plot curve --metric hypervolume`. ) def create_problem(self, seed): diff --git a/benchmarks/problem/wfg_problem.py b/benchmarks/problem/wfg_problem.py index 3ef21d36b0..4a814395f8 100644 --- a/benchmarks/problem/wfg_problem.py +++ b/benchmarks/problem/wfg_problem.py @@ -1,37 +1,53 @@ +import math +import numpy as np from kurobako import problem +from WFGtestSuite import wfg - -class WSGProblemFactory(problem.ProblemFactory): +class WFG1ProblemFactory(problem.ProblemFactory): def specification(self): - # wip - params = [] - - return problem.ProblemSpec(name="WFG", params=params, vales=[]) + params = [ + problem.Var("x", problem.ContinuousRange(0, 2)), + problem.Var("y", problem.ContinuousRange(0, 4)), + ] + return problem.ProblemSpec( + name="WFG1", + params=params, + values=[ + problem.Var("f1"), + problem.Var("f2") + ],) def create_problem(self, seed): - return WSGProblem() + return WFG1Problem() -class WSGProblem(problem.Problem): +class WFG1Problem(problem.Problem): def create_evaluator(self, params): - return WSGProblem(params) + return WFG1Evaluator(params) -class WSGEvaluator(problem.Evaluator): +class WFG1Evaluator(problem.Evaluator): def __init__(self, params): self._x, self._y = params self._current_step = 0 + self.wfg = wfg.WFG1(n_arguments=2, n_objectives=2, k=1) # TODO check def current_step(self): return self._current_step def evaluate(self, next_step): self._current_step = 1 + x, y = self._x, self._y + v = self.wfg([x,y]) + v = v.tolist() - # TODO: - return None + if math.isnan(v[0]) or math.isinf(v[0]): + raise ValueError + if math.isnan(v[1]) or math.isinf(v[1]): + raise ValueError + return v if __name__ == "__main__": - runner = problem.ProblemRunner(WSGProblemFactory()) + runner = problem.ProblemRunner(WFG1ProblemFactory()) runner.run() diff --git a/benchmarks/run_mo_kurobako.py b/benchmarks/run_mo_kurobako.py index a11598ded0..3420fc0f84 100644 --- a/benchmarks/run_mo_kurobako.py +++ b/benchmarks/run_mo_kurobako.py @@ -22,21 +22,23 @@ def run(args: argparse.Namespace) -> None: cmd = f"{kurobako_cmd} problem-suite zdt | tee -a {problems_filename}" subprocess.run(cmd, shell=True) - # Create NAS bench problem(A) (for Multi-Objective Settings). - dataset = os.path.join(args.data_dir, "nasbench_full.bin") - cmd = ( - f'{kurobako_cmd} problem nasbench "{dataset}" ' - f"--metrics params accuracy | tee -a {problems_filename}" - ) + + # Create Binh and Korn problem + cmd = f"{kurobako_cmd} problem command python3 benchmarks/problem/binh_and_korn_problem.py | tee -a {problems_filename}" subprocess.run(cmd, shell=True) # Create WFG problem - # cmd = (f"{kurobako_cmd} problem command python3 benchmarks/problem/wfg_problem.py | tee -a {problems_filename}") + cmd = (f"{kurobako_cmd} problem command python3 benchmarks/problem/wfg_problem.py | tee -a {problems_filename}") + subprocess.run(cmd, shell=True) + + # Create NAS bench problem(A) (for Multi-Objective Settings). + # dataset = os.path.join(args.data_dir, "nasbench_full.bin") + # cmd = ( + # f'{kurobako_cmd} problem nasbench "{dataset}" ' + # f"--metrics params accuracy | tee -a {problems_filename}" + # ) # subprocess.run(cmd, shell=True) - # Create Binh and Korn problem - cmd = f"{kurobako_cmd} problem command python3 benchmarks/problem/binh_and_korn_problem.py | tee -a {problems_filename}" - subprocess.run(cmd, shell=True) # Create solvers. sampler_list = args.sampler_list.split() @@ -79,12 +81,21 @@ def run(args: argparse.Namespace) -> None: subprocess.run(cmd, shell=True) # Plot pareto-front. - problem_names = ["NASBench", "ZDT1", "ZDT2", "ZDT3", "ZDT4", "ZDT5", "ZDT6"] - xmins = [0, 0, 0, 0, 0, 8, 0.2] - xmaxs = [25000000, 1, 1, 1, 1, 24, 1] - ymins = [0, 1, 2, 0, 20, 1, 5] - ymaxs = [0.2, 7, 7, 7, 250, 6, 10] - for problem_name, xmin, xmax, ymin, ymax in zip(problem_names, xmins, xmaxs, ymins, ymaxs): + plot_args = { + "NASBench":{"xmin":0,"xmax":25000000,"ymin":0,"ymax":0.2}, + "ZDT1":{"xmin":0,"xmax":1,"ymin":1,"ymax":7}, + "ZDT2":{"xmin":0,"xmax":1,"ymin":2,"ymax":7}, + "ZDT3":{"xmin":0,"xmax":1,"ymin":0,"ymax":7}, + "ZDT4":{"xmin":0,"xmax":1,"ymin":20,"ymax":250}, + "ZDT5":{"xmin":8,"xmax":24,"ymin":1,"ymax":6}, + "ZDT6":{"xmin":0.2,"xmax":1,"ymin":5,"ymax":10}, + "BinhKorn":{"xmin":0,"xmax":150,"ymin":0,"ymax":50}, + "WFG1":{"xmin":2.5,"xmax":3.5,"ymin":0.8,"ymax":1.5}, + } + + for problem_name, plot_arg in plot_args.items(): + xmin, xmax = plot_arg["xmin"],plot_arg["xmax"], + ymin, ymax = plot_arg["ymin"],plot_arg["ymax"] cmd = ( f"cat {result_filename} | grep {problem_name} | " f"{kurobako_cmd} plot pareto-front -o {args.out_dir} " @@ -92,7 +103,6 @@ def run(args: argparse.Namespace) -> None: ) subprocess.run(cmd, shell=True) - if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--path-to-kurobako", type=str, default="") From c8744d0215e31c37fe90065b4de05a7fd4f56772 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Sun, 6 Mar 2022 17:48:09 +0900 Subject: [PATCH 09/26] formatted --- benchmarks/problem/WFGtestSuite/wfg.py | 1 - benchmarks/problem/wfg_problem.py | 16 ++++---- benchmarks/run_mo_kurobako.py | 54 +++++++++++++++----------- 3 files changed, 39 insertions(+), 32 deletions(-) diff --git a/benchmarks/problem/WFGtestSuite/wfg.py b/benchmarks/problem/WFGtestSuite/wfg.py index 88c122d0ed..f6939838c3 100644 --- a/benchmarks/problem/WFGtestSuite/wfg.py +++ b/benchmarks/problem/WFGtestSuite/wfg.py @@ -1,4 +1,3 @@ -import copy from typing import List import numpy as np diff --git a/benchmarks/problem/wfg_problem.py b/benchmarks/problem/wfg_problem.py index 4a814395f8..752f278a4a 100644 --- a/benchmarks/problem/wfg_problem.py +++ b/benchmarks/problem/wfg_problem.py @@ -1,8 +1,8 @@ import math -import numpy as np from kurobako import problem from WFGtestSuite import wfg + class WFG1ProblemFactory(problem.ProblemFactory): def specification(self): params = [ @@ -10,12 +10,10 @@ def specification(self): problem.Var("y", problem.ContinuousRange(0, 4)), ] return problem.ProblemSpec( - name="WFG1", - params=params, - values=[ - problem.Var("f1"), - problem.Var("f2") - ],) + name="WFG1", + params=params, + values=[problem.Var("f1"), problem.Var("f2")], + ) def create_problem(self, seed): return WFG1Problem() @@ -30,7 +28,7 @@ class WFG1Evaluator(problem.Evaluator): def __init__(self, params): self._x, self._y = params self._current_step = 0 - self.wfg = wfg.WFG1(n_arguments=2, n_objectives=2, k=1) # TODO check + self.wfg = wfg.WFG1(n_arguments=2, n_objectives=2, k=1) def current_step(self): return self._current_step @@ -38,7 +36,7 @@ def current_step(self): def evaluate(self, next_step): self._current_step = 1 x, y = self._x, self._y - v = self.wfg([x,y]) + v = self.wfg([x, y]) v = v.tolist() if math.isnan(v[0]) or math.isinf(v[0]): diff --git a/benchmarks/run_mo_kurobako.py b/benchmarks/run_mo_kurobako.py index 3420fc0f84..e820cdb406 100644 --- a/benchmarks/run_mo_kurobako.py +++ b/benchmarks/run_mo_kurobako.py @@ -22,23 +22,29 @@ def run(args: argparse.Namespace) -> None: cmd = f"{kurobako_cmd} problem-suite zdt | tee -a {problems_filename}" subprocess.run(cmd, shell=True) - # Create Binh and Korn problem - cmd = f"{kurobako_cmd} problem command python3 benchmarks/problem/binh_and_korn_problem.py | tee -a {problems_filename}" + cmd = ( + f"{kurobako_cmd} problem command " + f"python3 benchmarks/problem/binh_and_korn_problem.py" + f"| tee -a {problems_filename}" + ) subprocess.run(cmd, shell=True) # Create WFG problem - cmd = (f"{kurobako_cmd} problem command python3 benchmarks/problem/wfg_problem.py | tee -a {problems_filename}") + cmd = ( + f"{kurobako_cmd} problem command " + f"python3 benchmarks/problem/wfg_problem.py " + f"| tee -a {problems_filename}" + ) subprocess.run(cmd, shell=True) - - # Create NAS bench problem(A) (for Multi-Objective Settings). - # dataset = os.path.join(args.data_dir, "nasbench_full.bin") - # cmd = ( - # f'{kurobako_cmd} problem nasbench "{dataset}" ' - # f"--metrics params accuracy | tee -a {problems_filename}" - # ) - # subprocess.run(cmd, shell=True) + # Create NAS bench problem(A) (for Multi-Objective Settings). + dataset = os.path.join(args.data_dir, "nasbench_full.bin") + cmd = ( + f'{kurobako_cmd} problem nasbench "{dataset}" ' + f"--metrics params accuracy | tee -a {problems_filename}" + ) + subprocess.run(cmd, shell=True) # Create solvers. sampler_list = args.sampler_list.split() @@ -82,20 +88,23 @@ def run(args: argparse.Namespace) -> None: # Plot pareto-front. plot_args = { - "NASBench":{"xmin":0,"xmax":25000000,"ymin":0,"ymax":0.2}, - "ZDT1":{"xmin":0,"xmax":1,"ymin":1,"ymax":7}, - "ZDT2":{"xmin":0,"xmax":1,"ymin":2,"ymax":7}, - "ZDT3":{"xmin":0,"xmax":1,"ymin":0,"ymax":7}, - "ZDT4":{"xmin":0,"xmax":1,"ymin":20,"ymax":250}, - "ZDT5":{"xmin":8,"xmax":24,"ymin":1,"ymax":6}, - "ZDT6":{"xmin":0.2,"xmax":1,"ymin":5,"ymax":10}, - "BinhKorn":{"xmin":0,"xmax":150,"ymin":0,"ymax":50}, - "WFG1":{"xmin":2.5,"xmax":3.5,"ymin":0.8,"ymax":1.5}, + "NASBench": {"xmin": 0, "xmax": 25000000, "ymin": 0, "ymax": 0.2}, + "ZDT1": {"xmin": 0, "xmax": 1, "ymin": 1, "ymax": 7}, + "ZDT2": {"xmin": 0, "xmax": 1, "ymin": 2, "ymax": 7}, + "ZDT3": {"xmin": 0, "xmax": 1, "ymin": 0, "ymax": 7}, + "ZDT4": {"xmin": 0, "xmax": 1, "ymin": 20, "ymax": 250}, + "ZDT5": {"xmin": 8, "xmax": 24, "ymin": 1, "ymax": 6}, + "ZDT6": {"xmin": 0.2, "xmax": 1, "ymin": 5, "ymax": 10}, + "BinhKorn": {"xmin": 0, "xmax": 150, "ymin": 0, "ymax": 50}, + "WFG1": {"xmin": 2.5, "xmax": 3.5, "ymin": 0.8, "ymax": 1.5}, } for problem_name, plot_arg in plot_args.items(): - xmin, xmax = plot_arg["xmin"],plot_arg["xmax"], - ymin, ymax = plot_arg["ymin"],plot_arg["ymax"] + xmin, xmax = ( + plot_arg["xmin"], + plot_arg["xmax"], + ) + ymin, ymax = plot_arg["ymin"], plot_arg["ymax"] cmd = ( f"cat {result_filename} | grep {problem_name} | " f"{kurobako_cmd} plot pareto-front -o {args.out_dir} " @@ -103,6 +112,7 @@ def run(args: argparse.Namespace) -> None: ) subprocess.run(cmd, shell=True) + if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument("--path-to-kurobako", type=str, default="") From 5dc4be53704bfc44441e91c79389bc0e9cc59e1f Mon Sep 17 00:00:00 2001 From: kei-mo Date: Sun, 6 Mar 2022 18:27:17 +0900 Subject: [PATCH 10/26] wip add wfg2~9 --- benchmarks/mo_runner.py | 2 +- benchmarks/problem/WFGtestSuite/wfg.py | 32 +++++------ .../{wfg_problem.py => wfg1_problem.py} | 12 ++--- benchmarks/problem/wfg2_problem.py | 51 ++++++++++++++++++ benchmarks/problem/wfg3_problem.py | 51 ++++++++++++++++++ benchmarks/problem/wfg4_problem.py | 51 ++++++++++++++++++ benchmarks/problem/wfg5_problem.py | 51 ++++++++++++++++++ benchmarks/problem/wfg6_problem.py | 51 ++++++++++++++++++ benchmarks/problem/wfg7_problem.py | 51 ++++++++++++++++++ benchmarks/problem/wfg8_problem.py | 51 ++++++++++++++++++ benchmarks/problem/wfg9_problem.py | 51 ++++++++++++++++++ benchmarks/run_mo_kurobako.py | 53 ++++++++++--------- 12 files changed, 458 insertions(+), 49 deletions(-) rename benchmarks/problem/{wfg_problem.py => wfg1_problem.py} (81%) create mode 100644 benchmarks/problem/wfg2_problem.py create mode 100644 benchmarks/problem/wfg3_problem.py create mode 100644 benchmarks/problem/wfg4_problem.py create mode 100644 benchmarks/problem/wfg5_problem.py create mode 100644 benchmarks/problem/wfg6_problem.py create mode 100644 benchmarks/problem/wfg7_problem.py create mode 100644 benchmarks/problem/wfg8_problem.py create mode 100644 benchmarks/problem/wfg9_problem.py diff --git a/benchmarks/mo_runner.py b/benchmarks/mo_runner.py index e5a1b23c9e..5f727a2fcd 100644 --- a/benchmarks/mo_runner.py +++ b/benchmarks/mo_runner.py @@ -30,7 +30,7 @@ def create_study(seed: int) -> optuna.Study: # try: # sampler_kwargs["seed"] = seed # sampler = sampler_cls(**sampler_kwargs) - # except: + # except ValueError: # del sampler_kwargs["seed"] # sampler = sampler_cls(**sampler_kwargs) sampler = sampler_cls() diff --git a/benchmarks/problem/WFGtestSuite/wfg.py b/benchmarks/problem/WFGtestSuite/wfg.py index f6939838c3..c8cd790ca2 100644 --- a/benchmarks/problem/WFGtestSuite/wfg.py +++ b/benchmarks/problem/WFGtestSuite/wfg.py @@ -161,7 +161,7 @@ def __init__(self, n_arguments: int, n_objectives: int, k: int): for _ in range(n - k): t_1.append(transformation_functions.LinearShiftTransformation(0.35)) - def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: indices = [k + 2 * (i + 1 - k) - 2, k + 2 * (i - k + 1) - 1] return y[indices] @@ -169,18 +169,18 @@ def _input_converter(i: int, y: np.ndarray) -> np.ndarray: for i in range(k, n // 2): t_2.append( transformation_functions.NonSeparableReductionTransformation( - 2, lambda y: _input_converter(i, y) + 2, lambda y: _input_converter0(i, y) ) ) - def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + def _input_converter1(i: int, y: np.ndarray) -> np.ndarray: indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) return y[indices] t_3 = [ transformation_functions.WeightedSumReductionTransformation( np.ones(k // (M - 1)), - lambda y: _input_converter(i, y), + lambda y: _input_converter1(i, y), ) for i in range(M - 1) ] @@ -238,7 +238,7 @@ def __init__(self, n_arguments: int, n_objectives: int, k: int): for _ in range(n - k): t_1.append(transformation_functions.LinearShiftTransformation(0.35)) - def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: indices = [k + 2 * (i + 1 - k) - 2, k + 2 * (i - k + 1) - 1] return y[indices] @@ -246,18 +246,18 @@ def _input_converter(i: int, y: np.ndarray) -> np.ndarray: for i in range(k, n // 2): t_2.append( transformation_functions.NonSeparableReductionTransformation( - 2, lambda y: _input_converter(i, y) + 2, lambda y: _input_converter0(i, y) ) ) - def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + def _input_converter1(i: int, y: np.ndarray) -> np.ndarray: indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) return y[indices] t_3 = [ transformation_functions.WeightedSumReductionTransformation( np.ones(k // (M - 1)), - lambda y: _input_converter(i, y), + lambda y: _input_converter1(i, y), ) for i in range(M - 1) ] @@ -499,13 +499,13 @@ def __init__(self, n_arguments: int, n_objectives: int, k: int): shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] - def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: return y[i:n] t_1 = [ transformation_functions.ParameterDependentBiasTransformation( np.ones(n - i), - lambda y: _input_converter(i, y), + lambda y: _input_converter0(i, y), 0.98 / 49.98, 0.02, 50, @@ -520,7 +520,7 @@ def _input_converter(i: int, y: np.ndarray) -> np.ndarray: for _ in range(n - k): t_2.append(transformation_functions.LinearShiftTransformation(0.35)) - def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + def _input_converter1(i: int, y: np.ndarray) -> np.ndarray: indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) return y[indices] @@ -528,7 +528,7 @@ def _input_converter(i: int, y: np.ndarray) -> np.ndarray: for i in range(M - 1): t_3.append( transformation_functions.WeightedSumReductionTransformation( - np.ones(k // (M - 1)), lambda y: _input_converter(i, y) + np.ones(k // (M - 1)), lambda y: _input_converter1(i, y) ) ) t_3.append( @@ -579,7 +579,7 @@ def __init__(self, n_arguments: int, n_objectives: int, k: int): shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] - def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: return y[: i - 1] t_1 = [lambda y: y for _ in range(k)] @@ -587,7 +587,7 @@ def _input_converter(i: int, y: np.ndarray) -> np.ndarray: t_1.append( transformation_functions.ParameterDependentBiasTransformation( np.ones(i - 1), - lambda y: _input_converter(i, y), + lambda y: _input_converter0(i, y), 0.98 / 49.98, 0.02, 50, @@ -658,13 +658,13 @@ def __init__(self, n_arguments: int, n_objectives: int, k: int): shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] - def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: return y[i:n] t_1 = [ transformation_functions.ParameterDependentBiasTransformation( np.ones(n - i), - lambda y: _input_converter(i, y), + lambda y: _input_converter0(i, y), 0.98 / 49.98, 0.02, 50, diff --git a/benchmarks/problem/wfg_problem.py b/benchmarks/problem/wfg1_problem.py similarity index 81% rename from benchmarks/problem/wfg_problem.py rename to benchmarks/problem/wfg1_problem.py index 752f278a4a..fdb44d0d76 100644 --- a/benchmarks/problem/wfg_problem.py +++ b/benchmarks/problem/wfg1_problem.py @@ -3,7 +3,7 @@ from WFGtestSuite import wfg -class WFG1ProblemFactory(problem.ProblemFactory): +class WFGProblemFactory(problem.ProblemFactory): def specification(self): params = [ problem.Var("x", problem.ContinuousRange(0, 2)), @@ -16,15 +16,15 @@ def specification(self): ) def create_problem(self, seed): - return WFG1Problem() + return WFGProblem() -class WFG1Problem(problem.Problem): +class WFGProblem(problem.Problem): def create_evaluator(self, params): - return WFG1Evaluator(params) + return WFGEvaluator(params) -class WFG1Evaluator(problem.Evaluator): +class WFGEvaluator(problem.Evaluator): def __init__(self, params): self._x, self._y = params self._current_step = 0 @@ -47,5 +47,5 @@ def evaluate(self, next_step): if __name__ == "__main__": - runner = problem.ProblemRunner(WFG1ProblemFactory()) + runner = problem.ProblemRunner(WFGProblemFactory()) runner.run() diff --git a/benchmarks/problem/wfg2_problem.py b/benchmarks/problem/wfg2_problem.py new file mode 100644 index 0000000000..488d0bec2b --- /dev/null +++ b/benchmarks/problem/wfg2_problem.py @@ -0,0 +1,51 @@ +import math +from kurobako import problem +from WFGtestSuite import wfg + + +class WFGProblemFactory(problem.ProblemFactory): + def specification(self): + params = [ + problem.Var("x", problem.ContinuousRange(0, 2)), + problem.Var("y", problem.ContinuousRange(0, 4)), + ] + return problem.ProblemSpec( + name="WFG2", + params=params, + values=[problem.Var("f1"), problem.Var("f2")], + ) + + def create_problem(self, seed): + return WFGProblem() + + +class WFGProblem(problem.Problem): + def create_evaluator(self, params): + return WFGEvaluator(params) + + +class WFGEvaluator(problem.Evaluator): + def __init__(self, params): + self._x, self._y = params + self._current_step = 0 + self.wfg = wfg.WFG2(n_arguments=2, n_objectives=2, k=1) + + def current_step(self): + return self._current_step + + def evaluate(self, next_step): + self._current_step = 1 + x, y = self._x, self._y + v = self.wfg([x, y]) + v = v.tolist() + + if math.isnan(v[0]) or math.isinf(v[0]): + raise ValueError + if math.isnan(v[1]) or math.isinf(v[1]): + raise ValueError + return v + + +if __name__ == "__main__": + runner = problem.ProblemRunner(WFGProblemFactory()) + runner.run() diff --git a/benchmarks/problem/wfg3_problem.py b/benchmarks/problem/wfg3_problem.py new file mode 100644 index 0000000000..a8bc5e6372 --- /dev/null +++ b/benchmarks/problem/wfg3_problem.py @@ -0,0 +1,51 @@ +import math +from kurobako import problem +from WFGtestSuite import wfg + + +class WFGProblemFactory(problem.ProblemFactory): + def specification(self): + params = [ + problem.Var("x", problem.ContinuousRange(0, 2)), + problem.Var("y", problem.ContinuousRange(0, 4)), + ] + return problem.ProblemSpec( + name="WFG3", + params=params, + values=[problem.Var("f1"), problem.Var("f2")], + ) + + def create_problem(self, seed): + return WFGProblem() + + +class WFGProblem(problem.Problem): + def create_evaluator(self, params): + return WFGEvaluator(params) + + +class WFGEvaluator(problem.Evaluator): + def __init__(self, params): + self._x, self._y = params + self._current_step = 0 + self.wfg = wfg.WFG3(n_arguments=2, n_objectives=2, k=1) + + def current_step(self): + return self._current_step + + def evaluate(self, next_step): + self._current_step = 1 + x, y = self._x, self._y + v = self.wfg([x, y]) + v = v.tolist() + + if math.isnan(v[0]) or math.isinf(v[0]): + raise ValueError + if math.isnan(v[1]) or math.isinf(v[1]): + raise ValueError + return v + + +if __name__ == "__main__": + runner = problem.ProblemRunner(WFGProblemFactory()) + runner.run() diff --git a/benchmarks/problem/wfg4_problem.py b/benchmarks/problem/wfg4_problem.py new file mode 100644 index 0000000000..5f3660741c --- /dev/null +++ b/benchmarks/problem/wfg4_problem.py @@ -0,0 +1,51 @@ +import math +from kurobako import problem +from WFGtestSuite import wfg + + +class WFGProblemFactory(problem.ProblemFactory): + def specification(self): + params = [ + problem.Var("x", problem.ContinuousRange(0, 2)), + problem.Var("y", problem.ContinuousRange(0, 4)), + ] + return problem.ProblemSpec( + name="WFG4", + params=params, + values=[problem.Var("f1"), problem.Var("f2")], + ) + + def create_problem(self, seed): + return WFGProblem() + + +class WFGProblem(problem.Problem): + def create_evaluator(self, params): + return WFGEvaluator(params) + + +class WFGEvaluator(problem.Evaluator): + def __init__(self, params): + self._x, self._y = params + self._current_step = 0 + self.wfg = wfg.WFG4(n_arguments=2, n_objectives=2, k=1) + + def current_step(self): + return self._current_step + + def evaluate(self, next_step): + self._current_step = 1 + x, y = self._x, self._y + v = self.wfg([x, y]) + v = v.tolist() + + if math.isnan(v[0]) or math.isinf(v[0]): + raise ValueError + if math.isnan(v[1]) or math.isinf(v[1]): + raise ValueError + return v + + +if __name__ == "__main__": + runner = problem.ProblemRunner(WFGProblemFactory()) + runner.run() diff --git a/benchmarks/problem/wfg5_problem.py b/benchmarks/problem/wfg5_problem.py new file mode 100644 index 0000000000..76c7b20ff5 --- /dev/null +++ b/benchmarks/problem/wfg5_problem.py @@ -0,0 +1,51 @@ +import math +from kurobako import problem +from WFGtestSuite import wfg + + +class WFGProblemFactory(problem.ProblemFactory): + def specification(self): + params = [ + problem.Var("x", problem.ContinuousRange(0, 2)), + problem.Var("y", problem.ContinuousRange(0, 4)), + ] + return problem.ProblemSpec( + name="WFG5", + params=params, + values=[problem.Var("f1"), problem.Var("f2")], + ) + + def create_problem(self, seed): + return WFGProblem() + + +class WFGProblem(problem.Problem): + def create_evaluator(self, params): + return WFGEvaluator(params) + + +class WFGEvaluator(problem.Evaluator): + def __init__(self, params): + self._x, self._y = params + self._current_step = 0 + self.wfg = wfg.WFG5(n_arguments=2, n_objectives=2, k=1) + + def current_step(self): + return self._current_step + + def evaluate(self, next_step): + self._current_step = 1 + x, y = self._x, self._y + v = self.wfg([x, y]) + v = v.tolist() + + if math.isnan(v[0]) or math.isinf(v[0]): + raise ValueError + if math.isnan(v[1]) or math.isinf(v[1]): + raise ValueError + return v + + +if __name__ == "__main__": + runner = problem.ProblemRunner(WFGProblemFactory()) + runner.run() diff --git a/benchmarks/problem/wfg6_problem.py b/benchmarks/problem/wfg6_problem.py new file mode 100644 index 0000000000..4718ef8734 --- /dev/null +++ b/benchmarks/problem/wfg6_problem.py @@ -0,0 +1,51 @@ +import math +from kurobako import problem +from WFGtestSuite import wfg + + +class WFGProblemFactory(problem.ProblemFactory): + def specification(self): + params = [ + problem.Var("x", problem.ContinuousRange(0, 2)), + problem.Var("y", problem.ContinuousRange(0, 4)), + ] + return problem.ProblemSpec( + name="WFG6", + params=params, + values=[problem.Var("f1"), problem.Var("f2")], + ) + + def create_problem(self, seed): + return WFGProblem() + + +class WFGProblem(problem.Problem): + def create_evaluator(self, params): + return WFGEvaluator(params) + + +class WFGEvaluator(problem.Evaluator): + def __init__(self, params): + self._x, self._y = params + self._current_step = 0 + self.wfg = wfg.WFG6(n_arguments=2, n_objectives=2, k=1) + + def current_step(self): + return self._current_step + + def evaluate(self, next_step): + self._current_step = 1 + x, y = self._x, self._y + v = self.wfg([x, y]) + v = v.tolist() + + if math.isnan(v[0]) or math.isinf(v[0]): + raise ValueError + if math.isnan(v[1]) or math.isinf(v[1]): + raise ValueError + return v + + +if __name__ == "__main__": + runner = problem.ProblemRunner(WFGProblemFactory()) + runner.run() diff --git a/benchmarks/problem/wfg7_problem.py b/benchmarks/problem/wfg7_problem.py new file mode 100644 index 0000000000..1592aae199 --- /dev/null +++ b/benchmarks/problem/wfg7_problem.py @@ -0,0 +1,51 @@ +import math +from kurobako import problem +from WFGtestSuite import wfg + + +class WFGProblemFactory(problem.ProblemFactory): + def specification(self): + params = [ + problem.Var("x", problem.ContinuousRange(0, 2)), + problem.Var("y", problem.ContinuousRange(0, 4)), + ] + return problem.ProblemSpec( + name="WFG7", + params=params, + values=[problem.Var("f1"), problem.Var("f2")], + ) + + def create_problem(self, seed): + return WFGProblem() + + +class WFGProblem(problem.Problem): + def create_evaluator(self, params): + return WFGEvaluator(params) + + +class WFGEvaluator(problem.Evaluator): + def __init__(self, params): + self._x, self._y = params + self._current_step = 0 + self.wfg = wfg.WFG7(n_arguments=2, n_objectives=2, k=1) + + def current_step(self): + return self._current_step + + def evaluate(self, next_step): + self._current_step = 1 + x, y = self._x, self._y + v = self.wfg([x, y]) + v = v.tolist() + + if math.isnan(v[0]) or math.isinf(v[0]): + raise ValueError + if math.isnan(v[1]) or math.isinf(v[1]): + raise ValueError + return v + + +if __name__ == "__main__": + runner = problem.ProblemRunner(WFGProblemFactory()) + runner.run() diff --git a/benchmarks/problem/wfg8_problem.py b/benchmarks/problem/wfg8_problem.py new file mode 100644 index 0000000000..ea649e4173 --- /dev/null +++ b/benchmarks/problem/wfg8_problem.py @@ -0,0 +1,51 @@ +import math +from kurobako import problem +from WFGtestSuite import wfg + + +class WFGProblemFactory(problem.ProblemFactory): + def specification(self): + params = [ + problem.Var("x", problem.ContinuousRange(0, 2)), + problem.Var("y", problem.ContinuousRange(0, 4)), + ] + return problem.ProblemSpec( + name="WFG8", + params=params, + values=[problem.Var("f1"), problem.Var("f2")], + ) + + def create_problem(self, seed): + return WFGProblem() + + +class WFGProblem(problem.Problem): + def create_evaluator(self, params): + return WFGEvaluator(params) + + +class WFGEvaluator(problem.Evaluator): + def __init__(self, params): + self._x, self._y = params + self._current_step = 0 + self.wfg = wfg.WFG8(n_arguments=2, n_objectives=2, k=1) + + def current_step(self): + return self._current_step + + def evaluate(self, next_step): + self._current_step = 1 + x, y = self._x, self._y + v = self.wfg([x, y]) + v = v.tolist() + + if math.isnan(v[0]) or math.isinf(v[0]): + raise ValueError + if math.isnan(v[1]) or math.isinf(v[1]): + raise ValueError + return v + + +if __name__ == "__main__": + runner = problem.ProblemRunner(WFGProblemFactory()) + runner.run() diff --git a/benchmarks/problem/wfg9_problem.py b/benchmarks/problem/wfg9_problem.py new file mode 100644 index 0000000000..cdd79a0e2f --- /dev/null +++ b/benchmarks/problem/wfg9_problem.py @@ -0,0 +1,51 @@ +import math +from kurobako import problem +from WFGtestSuite import wfg + + +class WFGProblemFactory(problem.ProblemFactory): + def specification(self): + params = [ + problem.Var("x", problem.ContinuousRange(0, 2)), + problem.Var("y", problem.ContinuousRange(0, 4)), + ] + return problem.ProblemSpec( + name="WFG9", + params=params, + values=[problem.Var("f1"), problem.Var("f2")], + ) + + def create_problem(self, seed): + return WFGProblem() + + +class WFGProblem(problem.Problem): + def create_evaluator(self, params): + return WFGEvaluator(params) + + +class WFGEvaluator(problem.Evaluator): + def __init__(self, params): + self._x, self._y = params + self._current_step = 0 + self.wfg = wfg.WFG9(n_arguments=2, n_objectives=2, k=1) + + def current_step(self): + return self._current_step + + def evaluate(self, next_step): + self._current_step = 1 + x, y = self._x, self._y + v = self.wfg([x, y]) + v = v.tolist() + + if math.isnan(v[0]) or math.isinf(v[0]): + raise ValueError + if math.isnan(v[1]) or math.isinf(v[1]): + raise ValueError + return v + + +if __name__ == "__main__": + runner = problem.ProblemRunner(WFGProblemFactory()) + runner.run() diff --git a/benchmarks/run_mo_kurobako.py b/benchmarks/run_mo_kurobako.py index e820cdb406..f362dd94e1 100644 --- a/benchmarks/run_mo_kurobako.py +++ b/benchmarks/run_mo_kurobako.py @@ -18,33 +18,34 @@ def run(args: argparse.Namespace) -> None: problems_filename = os.path.join(args.out_dir, "problems.json") subprocess.check_call(f"echo >| {problems_filename}", shell=True) - # Create ZDT problems - cmd = f"{kurobako_cmd} problem-suite zdt | tee -a {problems_filename}" - subprocess.run(cmd, shell=True) - - # Create Binh and Korn problem - cmd = ( - f"{kurobako_cmd} problem command " - f"python3 benchmarks/problem/binh_and_korn_problem.py" - f"| tee -a {problems_filename}" - ) - subprocess.run(cmd, shell=True) - - # Create WFG problem - cmd = ( - f"{kurobako_cmd} problem command " - f"python3 benchmarks/problem/wfg_problem.py " - f"| tee -a {problems_filename}" - ) - subprocess.run(cmd, shell=True) + # # Create ZDT problems + # cmd = f"{kurobako_cmd} problem-suite zdt | tee -a {problems_filename}" + # subprocess.run(cmd, shell=True) + + # # Create Binh and Korn problem + # cmd = ( + # f"{kurobako_cmd} problem command " + # f"python3 benchmarks/problem/binh_and_korn_problem.py" + # f"| tee -a {problems_filename}" + # ) + # subprocess.run(cmd, shell=True) + + # Create WFG 1~9 problem + for n_wfg in range(1, 10): + cmd = ( + f"{kurobako_cmd} problem command " + f"python3 benchmarks/problem/wfg{n_wfg}_problem.py " + f"| tee -a {problems_filename}" + ) + subprocess.run(cmd, shell=True) - # Create NAS bench problem(A) (for Multi-Objective Settings). - dataset = os.path.join(args.data_dir, "nasbench_full.bin") - cmd = ( - f'{kurobako_cmd} problem nasbench "{dataset}" ' - f"--metrics params accuracy | tee -a {problems_filename}" - ) - subprocess.run(cmd, shell=True) + # # Create NAS bench problem(A) (for Multi-Objective Settings). + # dataset = os.path.join(args.data_dir, "nasbench_full.bin") + # cmd = ( + # f'{kurobako_cmd} problem nasbench "{dataset}" ' + # f"--metrics params accuracy | tee -a {problems_filename}" + # ) + # subprocess.run(cmd, shell=True) # Create solvers. sampler_list = args.sampler_list.split() From 81242dc3a1493deebf94279251e5dc2382d03dd7 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Sun, 6 Mar 2022 18:42:15 +0900 Subject: [PATCH 11/26] formatted --- benchmarks/problem/WFGtestSuite/transformation_functions.py | 3 +-- benchmarks/problem/WFGtestSuite/wfg.py | 1 - benchmarks/problem/wfg1_problem.py | 2 ++ benchmarks/problem/wfg2_problem.py | 2 ++ benchmarks/problem/wfg3_problem.py | 2 ++ benchmarks/problem/wfg4_problem.py | 2 ++ benchmarks/problem/wfg5_problem.py | 2 ++ benchmarks/problem/wfg6_problem.py | 2 ++ benchmarks/problem/wfg7_problem.py | 2 ++ benchmarks/problem/wfg8_problem.py | 2 ++ benchmarks/problem/wfg9_problem.py | 2 ++ 11 files changed, 19 insertions(+), 3 deletions(-) diff --git a/benchmarks/problem/WFGtestSuite/transformation_functions.py b/benchmarks/problem/WFGtestSuite/transformation_functions.py index 112c5fcd39..882bc83904 100644 --- a/benchmarks/problem/WFGtestSuite/transformation_functions.py +++ b/benchmarks/problem/WFGtestSuite/transformation_functions.py @@ -1,6 +1,5 @@ -from typing import Callable - import abc +from typing import Callable import numpy as np diff --git a/benchmarks/problem/WFGtestSuite/wfg.py b/benchmarks/problem/WFGtestSuite/wfg.py index c8cd790ca2..3393c37646 100644 --- a/benchmarks/problem/WFGtestSuite/wfg.py +++ b/benchmarks/problem/WFGtestSuite/wfg.py @@ -2,7 +2,6 @@ import numpy as np - from . import shape_functions from . import transformation_functions diff --git a/benchmarks/problem/wfg1_problem.py b/benchmarks/problem/wfg1_problem.py index fdb44d0d76..d1a9d44eec 100644 --- a/benchmarks/problem/wfg1_problem.py +++ b/benchmarks/problem/wfg1_problem.py @@ -1,5 +1,7 @@ import math + from kurobako import problem + from WFGtestSuite import wfg diff --git a/benchmarks/problem/wfg2_problem.py b/benchmarks/problem/wfg2_problem.py index 488d0bec2b..bc8ab47340 100644 --- a/benchmarks/problem/wfg2_problem.py +++ b/benchmarks/problem/wfg2_problem.py @@ -1,5 +1,7 @@ import math + from kurobako import problem + from WFGtestSuite import wfg diff --git a/benchmarks/problem/wfg3_problem.py b/benchmarks/problem/wfg3_problem.py index a8bc5e6372..164ea92b59 100644 --- a/benchmarks/problem/wfg3_problem.py +++ b/benchmarks/problem/wfg3_problem.py @@ -1,5 +1,7 @@ import math + from kurobako import problem + from WFGtestSuite import wfg diff --git a/benchmarks/problem/wfg4_problem.py b/benchmarks/problem/wfg4_problem.py index 5f3660741c..15433c0edc 100644 --- a/benchmarks/problem/wfg4_problem.py +++ b/benchmarks/problem/wfg4_problem.py @@ -1,5 +1,7 @@ import math + from kurobako import problem + from WFGtestSuite import wfg diff --git a/benchmarks/problem/wfg5_problem.py b/benchmarks/problem/wfg5_problem.py index 76c7b20ff5..3e970265ed 100644 --- a/benchmarks/problem/wfg5_problem.py +++ b/benchmarks/problem/wfg5_problem.py @@ -1,5 +1,7 @@ import math + from kurobako import problem + from WFGtestSuite import wfg diff --git a/benchmarks/problem/wfg6_problem.py b/benchmarks/problem/wfg6_problem.py index 4718ef8734..8581eed95d 100644 --- a/benchmarks/problem/wfg6_problem.py +++ b/benchmarks/problem/wfg6_problem.py @@ -1,5 +1,7 @@ import math + from kurobako import problem + from WFGtestSuite import wfg diff --git a/benchmarks/problem/wfg7_problem.py b/benchmarks/problem/wfg7_problem.py index 1592aae199..905623891f 100644 --- a/benchmarks/problem/wfg7_problem.py +++ b/benchmarks/problem/wfg7_problem.py @@ -1,5 +1,7 @@ import math + from kurobako import problem + from WFGtestSuite import wfg diff --git a/benchmarks/problem/wfg8_problem.py b/benchmarks/problem/wfg8_problem.py index ea649e4173..b9edce2848 100644 --- a/benchmarks/problem/wfg8_problem.py +++ b/benchmarks/problem/wfg8_problem.py @@ -1,5 +1,7 @@ import math + from kurobako import problem + from WFGtestSuite import wfg diff --git a/benchmarks/problem/wfg9_problem.py b/benchmarks/problem/wfg9_problem.py index cdd79a0e2f..9bc264430d 100644 --- a/benchmarks/problem/wfg9_problem.py +++ b/benchmarks/problem/wfg9_problem.py @@ -1,5 +1,7 @@ import math + from kurobako import problem + from WFGtestSuite import wfg From 6c4da1daf783cc3451591c9d44f0deef41c81696 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Sun, 6 Mar 2022 21:53:20 +0900 Subject: [PATCH 12/26] modified wfg1~9 --- benchmarks/problem/wfg1_problem.py | 15 +++++++++------ benchmarks/problem/wfg2_problem.py | 16 ++++++++++------ benchmarks/problem/wfg3_problem.py | 15 +++++++++------ benchmarks/problem/wfg4_problem.py | 15 +++++++++------ benchmarks/problem/wfg5_problem.py | 15 +++++++++------ benchmarks/problem/wfg6_problem.py | 15 +++++++++------ benchmarks/problem/wfg7_problem.py | 16 ++++++++++------ benchmarks/problem/wfg8_problem.py | 14 ++++++++------ benchmarks/run_mo_kurobako.py | 10 +++++++++- 9 files changed, 82 insertions(+), 49 deletions(-) diff --git a/benchmarks/problem/wfg1_problem.py b/benchmarks/problem/wfg1_problem.py index d1a9d44eec..7ae687a5ed 100644 --- a/benchmarks/problem/wfg1_problem.py +++ b/benchmarks/problem/wfg1_problem.py @@ -4,12 +4,16 @@ from WFGtestSuite import wfg +N_VAR = 2 +K = 1 + class WFGProblemFactory(problem.ProblemFactory): def specification(self): + self._low = 0 + self._high = 2 params = [ - problem.Var("x", problem.ContinuousRange(0, 2)), - problem.Var("y", problem.ContinuousRange(0, 4)), + problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(N_VAR) ] return problem.ProblemSpec( name="WFG1", @@ -28,17 +32,16 @@ def create_evaluator(self, params): class WFGEvaluator(problem.Evaluator): def __init__(self, params): - self._x, self._y = params + self._x = params self._current_step = 0 - self.wfg = wfg.WFG1(n_arguments=2, n_objectives=2, k=1) + self.wfg = wfg.WFG1(n_arguments=N_VAR, n_objectives=2, k=K) def current_step(self): return self._current_step def evaluate(self, next_step): self._current_step = 1 - x, y = self._x, self._y - v = self.wfg([x, y]) + v = self.wfg(self._x) v = v.tolist() if math.isnan(v[0]) or math.isinf(v[0]): diff --git a/benchmarks/problem/wfg2_problem.py b/benchmarks/problem/wfg2_problem.py index bc8ab47340..34dfca0c8e 100644 --- a/benchmarks/problem/wfg2_problem.py +++ b/benchmarks/problem/wfg2_problem.py @@ -5,11 +5,16 @@ from WFGtestSuite import wfg +N_VAR = 10 +K = 2 + + class WFGProblemFactory(problem.ProblemFactory): def specification(self): + self._low = 0 + self._high = 2 params = [ - problem.Var("x", problem.ContinuousRange(0, 2)), - problem.Var("y", problem.ContinuousRange(0, 4)), + problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(N_VAR) ] return problem.ProblemSpec( name="WFG2", @@ -28,17 +33,16 @@ def create_evaluator(self, params): class WFGEvaluator(problem.Evaluator): def __init__(self, params): - self._x, self._y = params + self._x = params self._current_step = 0 - self.wfg = wfg.WFG2(n_arguments=2, n_objectives=2, k=1) + self.wfg = wfg.WFG2(n_arguments=N_VAR, n_objectives=2, k=K) def current_step(self): return self._current_step def evaluate(self, next_step): self._current_step = 1 - x, y = self._x, self._y - v = self.wfg([x, y]) + v = self.wfg(self._x) v = v.tolist() if math.isnan(v[0]) or math.isinf(v[0]): diff --git a/benchmarks/problem/wfg3_problem.py b/benchmarks/problem/wfg3_problem.py index 164ea92b59..4c907d8ba7 100644 --- a/benchmarks/problem/wfg3_problem.py +++ b/benchmarks/problem/wfg3_problem.py @@ -4,12 +4,16 @@ from WFGtestSuite import wfg +N_VAR = 10 +K = 2 + class WFGProblemFactory(problem.ProblemFactory): def specification(self): + self._low = 0 + self._high = 2 params = [ - problem.Var("x", problem.ContinuousRange(0, 2)), - problem.Var("y", problem.ContinuousRange(0, 4)), + problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(N_VAR) ] return problem.ProblemSpec( name="WFG3", @@ -28,17 +32,16 @@ def create_evaluator(self, params): class WFGEvaluator(problem.Evaluator): def __init__(self, params): - self._x, self._y = params + self._x = params self._current_step = 0 - self.wfg = wfg.WFG3(n_arguments=2, n_objectives=2, k=1) + self.wfg = wfg.WFG3(n_arguments=N_VAR, n_objectives=2, k=K) def current_step(self): return self._current_step def evaluate(self, next_step): self._current_step = 1 - x, y = self._x, self._y - v = self.wfg([x, y]) + v = self.wfg(self._x) v = v.tolist() if math.isnan(v[0]) or math.isinf(v[0]): diff --git a/benchmarks/problem/wfg4_problem.py b/benchmarks/problem/wfg4_problem.py index 15433c0edc..6c19ef5a44 100644 --- a/benchmarks/problem/wfg4_problem.py +++ b/benchmarks/problem/wfg4_problem.py @@ -4,12 +4,16 @@ from WFGtestSuite import wfg +N_VAR = 3 +K = 2 + class WFGProblemFactory(problem.ProblemFactory): def specification(self): + self._low = 0 + self._high = 2 params = [ - problem.Var("x", problem.ContinuousRange(0, 2)), - problem.Var("y", problem.ContinuousRange(0, 4)), + problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(N_VAR) ] return problem.ProblemSpec( name="WFG4", @@ -28,17 +32,16 @@ def create_evaluator(self, params): class WFGEvaluator(problem.Evaluator): def __init__(self, params): - self._x, self._y = params + self._x = params self._current_step = 0 - self.wfg = wfg.WFG4(n_arguments=2, n_objectives=2, k=1) + self.wfg = wfg.WFG4(n_arguments=N_VAR, n_objectives=2, k=K) def current_step(self): return self._current_step def evaluate(self, next_step): self._current_step = 1 - x, y = self._x, self._y - v = self.wfg([x, y]) + v = self.wfg(self._x) v = v.tolist() if math.isnan(v[0]) or math.isinf(v[0]): diff --git a/benchmarks/problem/wfg5_problem.py b/benchmarks/problem/wfg5_problem.py index 3e970265ed..b002a74759 100644 --- a/benchmarks/problem/wfg5_problem.py +++ b/benchmarks/problem/wfg5_problem.py @@ -4,12 +4,16 @@ from WFGtestSuite import wfg +N_VAR = 3 +K = 2 + class WFGProblemFactory(problem.ProblemFactory): def specification(self): + self._low = 0 + self._high = 2 params = [ - problem.Var("x", problem.ContinuousRange(0, 2)), - problem.Var("y", problem.ContinuousRange(0, 4)), + problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(N_VAR) ] return problem.ProblemSpec( name="WFG5", @@ -28,17 +32,16 @@ def create_evaluator(self, params): class WFGEvaluator(problem.Evaluator): def __init__(self, params): - self._x, self._y = params + self._x = params self._current_step = 0 - self.wfg = wfg.WFG5(n_arguments=2, n_objectives=2, k=1) + self.wfg = wfg.WFG5(n_arguments=N_VAR, n_objectives=2, k=K) def current_step(self): return self._current_step def evaluate(self, next_step): self._current_step = 1 - x, y = self._x, self._y - v = self.wfg([x, y]) + v = self.wfg(self._x) v = v.tolist() if math.isnan(v[0]) or math.isinf(v[0]): diff --git a/benchmarks/problem/wfg6_problem.py b/benchmarks/problem/wfg6_problem.py index 8581eed95d..2d83a652f4 100644 --- a/benchmarks/problem/wfg6_problem.py +++ b/benchmarks/problem/wfg6_problem.py @@ -4,12 +4,16 @@ from WFGtestSuite import wfg +N_VAR = 3 +K = 2 + class WFGProblemFactory(problem.ProblemFactory): def specification(self): + self._low = 0 + self._high = 2 params = [ - problem.Var("x", problem.ContinuousRange(0, 2)), - problem.Var("y", problem.ContinuousRange(0, 4)), + problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(N_VAR) ] return problem.ProblemSpec( name="WFG6", @@ -28,17 +32,16 @@ def create_evaluator(self, params): class WFGEvaluator(problem.Evaluator): def __init__(self, params): - self._x, self._y = params + self._x = params self._current_step = 0 - self.wfg = wfg.WFG6(n_arguments=2, n_objectives=2, k=1) + self.wfg = wfg.WFG6(n_arguments=N_VAR, n_objectives=2, k=K) def current_step(self): return self._current_step def evaluate(self, next_step): self._current_step = 1 - x, y = self._x, self._y - v = self.wfg([x, y]) + v = self.wfg(self._x) v = v.tolist() if math.isnan(v[0]) or math.isinf(v[0]): diff --git a/benchmarks/problem/wfg7_problem.py b/benchmarks/problem/wfg7_problem.py index 905623891f..78057790e8 100644 --- a/benchmarks/problem/wfg7_problem.py +++ b/benchmarks/problem/wfg7_problem.py @@ -4,12 +4,16 @@ from WFGtestSuite import wfg +N_VAR = 3 +K = 1 + class WFGProblemFactory(problem.ProblemFactory): def specification(self): + self._low = 0 + self._high = 2 params = [ - problem.Var("x", problem.ContinuousRange(0, 2)), - problem.Var("y", problem.ContinuousRange(0, 4)), + problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(N_VAR) ] return problem.ProblemSpec( name="WFG7", @@ -28,17 +32,17 @@ def create_evaluator(self, params): class WFGEvaluator(problem.Evaluator): def __init__(self, params): - self._x, self._y = params + self._x = params self._current_step = 0 - self.wfg = wfg.WFG7(n_arguments=2, n_objectives=2, k=1) + self.wfg = wfg.WFG7(n_arguments=N_VAR, n_objectives=2, k=K) def current_step(self): return self._current_step def evaluate(self, next_step): self._current_step = 1 - x, y = self._x, self._y - v = self.wfg([x, y]) + + v = self.wfg(self._x) v = v.tolist() if math.isnan(v[0]) or math.isinf(v[0]): diff --git a/benchmarks/problem/wfg8_problem.py b/benchmarks/problem/wfg8_problem.py index b9edce2848..0f6dabafc3 100644 --- a/benchmarks/problem/wfg8_problem.py +++ b/benchmarks/problem/wfg8_problem.py @@ -4,12 +4,15 @@ from WFGtestSuite import wfg +N_VAR = 3 + class WFGProblemFactory(problem.ProblemFactory): def specification(self): + self._low = 0 + self._high = 2 params = [ - problem.Var("x", problem.ContinuousRange(0, 2)), - problem.Var("y", problem.ContinuousRange(0, 4)), + problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(N_VAR) ] return problem.ProblemSpec( name="WFG8", @@ -28,17 +31,16 @@ def create_evaluator(self, params): class WFGEvaluator(problem.Evaluator): def __init__(self, params): - self._x, self._y = params + self._x = params self._current_step = 0 - self.wfg = wfg.WFG8(n_arguments=2, n_objectives=2, k=1) + self.wfg = wfg.WFG8(n_arguments=N_VAR, n_objectives=2, k=2) def current_step(self): return self._current_step def evaluate(self, next_step): self._current_step = 1 - x, y = self._x, self._y - v = self.wfg([x, y]) + v = self.wfg(self._x) v = v.tolist() if math.isnan(v[0]) or math.isinf(v[0]): diff --git a/benchmarks/run_mo_kurobako.py b/benchmarks/run_mo_kurobako.py index f362dd94e1..0faaf969e5 100644 --- a/benchmarks/run_mo_kurobako.py +++ b/benchmarks/run_mo_kurobako.py @@ -97,7 +97,15 @@ def run(args: argparse.Namespace) -> None: "ZDT5": {"xmin": 8, "xmax": 24, "ymin": 1, "ymax": 6}, "ZDT6": {"xmin": 0.2, "xmax": 1, "ymin": 5, "ymax": 10}, "BinhKorn": {"xmin": 0, "xmax": 150, "ymin": 0, "ymax": 50}, - "WFG1": {"xmin": 2.5, "xmax": 3.5, "ymin": 0.8, "ymax": 1.5}, + "WFG1": {"xmin": 2.7, "xmax": 3.05, "ymin": 4.7, "ymax": 5.05}, + "WFG2": {"xmin": 2.0, "xmax": 2.8, "ymin": 3.0, "ymax": 4.8}, + "WFG3": {"xmin": 2.0, "xmax": 2.8, "ymin": 3.0, "ymax": 4.8}, + "WFG4": {"xmin": 2.0, "xmax": 3.0, "ymin": 0.0, "ymax": 3.6}, + "WFG5": {"xmin": 2.0, "xmax": 3.0, "ymin": 2.5, "ymax": 5.0}, + "WFG6": {"xmin": 2.0, "xmax": 3.0, "ymin": 3.4, "ymax": 5.0}, + "WFG7": {"xmin": 2.0, "xmax": 3.0, "ymin": 4.0, "ymax": 5.0}, + "WFG8": {"xmin": 2.0, "xmax": 3.0, "ymin": 3.4, "ymax": 5.0}, + "WFG9": {"xmin": 2.0, "xmax": 3.0, "ymin": 0.0, "ymax": 5.0}, } for problem_name, plot_arg in plot_args.items(): From 0af4a7f1a62de85859f1cecfcbad7666743dfa79 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Wed, 9 Mar 2022 22:05:52 +0900 Subject: [PATCH 13/26] reoriganized --- benchmarks/problem/wfg1_problem.py | 56 ------------ benchmarks/problem/wfg2_problem.py | 57 ------------ benchmarks/problem/wfg3_problem.py | 56 ------------ benchmarks/problem/wfg4_problem.py | 56 ------------ benchmarks/problem/wfg5_problem.py | 56 ------------ benchmarks/problem/wfg6_problem.py | 56 ------------ benchmarks/problem/wfg7_problem.py | 57 ------------ benchmarks/problem/wfg8_problem.py | 55 ------------ benchmarks/problem/wfg9_problem.py | 53 ------------ .../WFGtestSuite/shape_functions.py | 0 .../WFGtestSuite/transformation_functions.py | 0 .../{problem => problems}/WFGtestSuite/wfg.py | 0 .../binh_and_korn_problem.py | 0 benchmarks/problems/wfg_problem.py | 86 +++++++++++++++++++ benchmarks/run_mo_kurobako.py | 19 +++- 15 files changed, 102 insertions(+), 505 deletions(-) delete mode 100644 benchmarks/problem/wfg1_problem.py delete mode 100644 benchmarks/problem/wfg2_problem.py delete mode 100644 benchmarks/problem/wfg3_problem.py delete mode 100644 benchmarks/problem/wfg4_problem.py delete mode 100644 benchmarks/problem/wfg5_problem.py delete mode 100644 benchmarks/problem/wfg6_problem.py delete mode 100644 benchmarks/problem/wfg7_problem.py delete mode 100644 benchmarks/problem/wfg8_problem.py delete mode 100644 benchmarks/problem/wfg9_problem.py rename benchmarks/{problem => problems}/WFGtestSuite/shape_functions.py (100%) rename benchmarks/{problem => problems}/WFGtestSuite/transformation_functions.py (100%) rename benchmarks/{problem => problems}/WFGtestSuite/wfg.py (100%) rename benchmarks/{problem => problems}/binh_and_korn_problem.py (100%) create mode 100644 benchmarks/problems/wfg_problem.py diff --git a/benchmarks/problem/wfg1_problem.py b/benchmarks/problem/wfg1_problem.py deleted file mode 100644 index 7ae687a5ed..0000000000 --- a/benchmarks/problem/wfg1_problem.py +++ /dev/null @@ -1,56 +0,0 @@ -import math - -from kurobako import problem - -from WFGtestSuite import wfg - -N_VAR = 2 -K = 1 - - -class WFGProblemFactory(problem.ProblemFactory): - def specification(self): - self._low = 0 - self._high = 2 - params = [ - problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(N_VAR) - ] - return problem.ProblemSpec( - name="WFG1", - params=params, - values=[problem.Var("f1"), problem.Var("f2")], - ) - - def create_problem(self, seed): - return WFGProblem() - - -class WFGProblem(problem.Problem): - def create_evaluator(self, params): - return WFGEvaluator(params) - - -class WFGEvaluator(problem.Evaluator): - def __init__(self, params): - self._x = params - self._current_step = 0 - self.wfg = wfg.WFG1(n_arguments=N_VAR, n_objectives=2, k=K) - - def current_step(self): - return self._current_step - - def evaluate(self, next_step): - self._current_step = 1 - v = self.wfg(self._x) - v = v.tolist() - - if math.isnan(v[0]) or math.isinf(v[0]): - raise ValueError - if math.isnan(v[1]) or math.isinf(v[1]): - raise ValueError - return v - - -if __name__ == "__main__": - runner = problem.ProblemRunner(WFGProblemFactory()) - runner.run() diff --git a/benchmarks/problem/wfg2_problem.py b/benchmarks/problem/wfg2_problem.py deleted file mode 100644 index 34dfca0c8e..0000000000 --- a/benchmarks/problem/wfg2_problem.py +++ /dev/null @@ -1,57 +0,0 @@ -import math - -from kurobako import problem - -from WFGtestSuite import wfg - - -N_VAR = 10 -K = 2 - - -class WFGProblemFactory(problem.ProblemFactory): - def specification(self): - self._low = 0 - self._high = 2 - params = [ - problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(N_VAR) - ] - return problem.ProblemSpec( - name="WFG2", - params=params, - values=[problem.Var("f1"), problem.Var("f2")], - ) - - def create_problem(self, seed): - return WFGProblem() - - -class WFGProblem(problem.Problem): - def create_evaluator(self, params): - return WFGEvaluator(params) - - -class WFGEvaluator(problem.Evaluator): - def __init__(self, params): - self._x = params - self._current_step = 0 - self.wfg = wfg.WFG2(n_arguments=N_VAR, n_objectives=2, k=K) - - def current_step(self): - return self._current_step - - def evaluate(self, next_step): - self._current_step = 1 - v = self.wfg(self._x) - v = v.tolist() - - if math.isnan(v[0]) or math.isinf(v[0]): - raise ValueError - if math.isnan(v[1]) or math.isinf(v[1]): - raise ValueError - return v - - -if __name__ == "__main__": - runner = problem.ProblemRunner(WFGProblemFactory()) - runner.run() diff --git a/benchmarks/problem/wfg3_problem.py b/benchmarks/problem/wfg3_problem.py deleted file mode 100644 index 4c907d8ba7..0000000000 --- a/benchmarks/problem/wfg3_problem.py +++ /dev/null @@ -1,56 +0,0 @@ -import math - -from kurobako import problem - -from WFGtestSuite import wfg - -N_VAR = 10 -K = 2 - - -class WFGProblemFactory(problem.ProblemFactory): - def specification(self): - self._low = 0 - self._high = 2 - params = [ - problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(N_VAR) - ] - return problem.ProblemSpec( - name="WFG3", - params=params, - values=[problem.Var("f1"), problem.Var("f2")], - ) - - def create_problem(self, seed): - return WFGProblem() - - -class WFGProblem(problem.Problem): - def create_evaluator(self, params): - return WFGEvaluator(params) - - -class WFGEvaluator(problem.Evaluator): - def __init__(self, params): - self._x = params - self._current_step = 0 - self.wfg = wfg.WFG3(n_arguments=N_VAR, n_objectives=2, k=K) - - def current_step(self): - return self._current_step - - def evaluate(self, next_step): - self._current_step = 1 - v = self.wfg(self._x) - v = v.tolist() - - if math.isnan(v[0]) or math.isinf(v[0]): - raise ValueError - if math.isnan(v[1]) or math.isinf(v[1]): - raise ValueError - return v - - -if __name__ == "__main__": - runner = problem.ProblemRunner(WFGProblemFactory()) - runner.run() diff --git a/benchmarks/problem/wfg4_problem.py b/benchmarks/problem/wfg4_problem.py deleted file mode 100644 index 6c19ef5a44..0000000000 --- a/benchmarks/problem/wfg4_problem.py +++ /dev/null @@ -1,56 +0,0 @@ -import math - -from kurobako import problem - -from WFGtestSuite import wfg - -N_VAR = 3 -K = 2 - - -class WFGProblemFactory(problem.ProblemFactory): - def specification(self): - self._low = 0 - self._high = 2 - params = [ - problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(N_VAR) - ] - return problem.ProblemSpec( - name="WFG4", - params=params, - values=[problem.Var("f1"), problem.Var("f2")], - ) - - def create_problem(self, seed): - return WFGProblem() - - -class WFGProblem(problem.Problem): - def create_evaluator(self, params): - return WFGEvaluator(params) - - -class WFGEvaluator(problem.Evaluator): - def __init__(self, params): - self._x = params - self._current_step = 0 - self.wfg = wfg.WFG4(n_arguments=N_VAR, n_objectives=2, k=K) - - def current_step(self): - return self._current_step - - def evaluate(self, next_step): - self._current_step = 1 - v = self.wfg(self._x) - v = v.tolist() - - if math.isnan(v[0]) or math.isinf(v[0]): - raise ValueError - if math.isnan(v[1]) or math.isinf(v[1]): - raise ValueError - return v - - -if __name__ == "__main__": - runner = problem.ProblemRunner(WFGProblemFactory()) - runner.run() diff --git a/benchmarks/problem/wfg5_problem.py b/benchmarks/problem/wfg5_problem.py deleted file mode 100644 index b002a74759..0000000000 --- a/benchmarks/problem/wfg5_problem.py +++ /dev/null @@ -1,56 +0,0 @@ -import math - -from kurobako import problem - -from WFGtestSuite import wfg - -N_VAR = 3 -K = 2 - - -class WFGProblemFactory(problem.ProblemFactory): - def specification(self): - self._low = 0 - self._high = 2 - params = [ - problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(N_VAR) - ] - return problem.ProblemSpec( - name="WFG5", - params=params, - values=[problem.Var("f1"), problem.Var("f2")], - ) - - def create_problem(self, seed): - return WFGProblem() - - -class WFGProblem(problem.Problem): - def create_evaluator(self, params): - return WFGEvaluator(params) - - -class WFGEvaluator(problem.Evaluator): - def __init__(self, params): - self._x = params - self._current_step = 0 - self.wfg = wfg.WFG5(n_arguments=N_VAR, n_objectives=2, k=K) - - def current_step(self): - return self._current_step - - def evaluate(self, next_step): - self._current_step = 1 - v = self.wfg(self._x) - v = v.tolist() - - if math.isnan(v[0]) or math.isinf(v[0]): - raise ValueError - if math.isnan(v[1]) or math.isinf(v[1]): - raise ValueError - return v - - -if __name__ == "__main__": - runner = problem.ProblemRunner(WFGProblemFactory()) - runner.run() diff --git a/benchmarks/problem/wfg6_problem.py b/benchmarks/problem/wfg6_problem.py deleted file mode 100644 index 2d83a652f4..0000000000 --- a/benchmarks/problem/wfg6_problem.py +++ /dev/null @@ -1,56 +0,0 @@ -import math - -from kurobako import problem - -from WFGtestSuite import wfg - -N_VAR = 3 -K = 2 - - -class WFGProblemFactory(problem.ProblemFactory): - def specification(self): - self._low = 0 - self._high = 2 - params = [ - problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(N_VAR) - ] - return problem.ProblemSpec( - name="WFG6", - params=params, - values=[problem.Var("f1"), problem.Var("f2")], - ) - - def create_problem(self, seed): - return WFGProblem() - - -class WFGProblem(problem.Problem): - def create_evaluator(self, params): - return WFGEvaluator(params) - - -class WFGEvaluator(problem.Evaluator): - def __init__(self, params): - self._x = params - self._current_step = 0 - self.wfg = wfg.WFG6(n_arguments=N_VAR, n_objectives=2, k=K) - - def current_step(self): - return self._current_step - - def evaluate(self, next_step): - self._current_step = 1 - v = self.wfg(self._x) - v = v.tolist() - - if math.isnan(v[0]) or math.isinf(v[0]): - raise ValueError - if math.isnan(v[1]) or math.isinf(v[1]): - raise ValueError - return v - - -if __name__ == "__main__": - runner = problem.ProblemRunner(WFGProblemFactory()) - runner.run() diff --git a/benchmarks/problem/wfg7_problem.py b/benchmarks/problem/wfg7_problem.py deleted file mode 100644 index 78057790e8..0000000000 --- a/benchmarks/problem/wfg7_problem.py +++ /dev/null @@ -1,57 +0,0 @@ -import math - -from kurobako import problem - -from WFGtestSuite import wfg - -N_VAR = 3 -K = 1 - - -class WFGProblemFactory(problem.ProblemFactory): - def specification(self): - self._low = 0 - self._high = 2 - params = [ - problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(N_VAR) - ] - return problem.ProblemSpec( - name="WFG7", - params=params, - values=[problem.Var("f1"), problem.Var("f2")], - ) - - def create_problem(self, seed): - return WFGProblem() - - -class WFGProblem(problem.Problem): - def create_evaluator(self, params): - return WFGEvaluator(params) - - -class WFGEvaluator(problem.Evaluator): - def __init__(self, params): - self._x = params - self._current_step = 0 - self.wfg = wfg.WFG7(n_arguments=N_VAR, n_objectives=2, k=K) - - def current_step(self): - return self._current_step - - def evaluate(self, next_step): - self._current_step = 1 - - v = self.wfg(self._x) - v = v.tolist() - - if math.isnan(v[0]) or math.isinf(v[0]): - raise ValueError - if math.isnan(v[1]) or math.isinf(v[1]): - raise ValueError - return v - - -if __name__ == "__main__": - runner = problem.ProblemRunner(WFGProblemFactory()) - runner.run() diff --git a/benchmarks/problem/wfg8_problem.py b/benchmarks/problem/wfg8_problem.py deleted file mode 100644 index 0f6dabafc3..0000000000 --- a/benchmarks/problem/wfg8_problem.py +++ /dev/null @@ -1,55 +0,0 @@ -import math - -from kurobako import problem - -from WFGtestSuite import wfg - -N_VAR = 3 - - -class WFGProblemFactory(problem.ProblemFactory): - def specification(self): - self._low = 0 - self._high = 2 - params = [ - problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(N_VAR) - ] - return problem.ProblemSpec( - name="WFG8", - params=params, - values=[problem.Var("f1"), problem.Var("f2")], - ) - - def create_problem(self, seed): - return WFGProblem() - - -class WFGProblem(problem.Problem): - def create_evaluator(self, params): - return WFGEvaluator(params) - - -class WFGEvaluator(problem.Evaluator): - def __init__(self, params): - self._x = params - self._current_step = 0 - self.wfg = wfg.WFG8(n_arguments=N_VAR, n_objectives=2, k=2) - - def current_step(self): - return self._current_step - - def evaluate(self, next_step): - self._current_step = 1 - v = self.wfg(self._x) - v = v.tolist() - - if math.isnan(v[0]) or math.isinf(v[0]): - raise ValueError - if math.isnan(v[1]) or math.isinf(v[1]): - raise ValueError - return v - - -if __name__ == "__main__": - runner = problem.ProblemRunner(WFGProblemFactory()) - runner.run() diff --git a/benchmarks/problem/wfg9_problem.py b/benchmarks/problem/wfg9_problem.py deleted file mode 100644 index 9bc264430d..0000000000 --- a/benchmarks/problem/wfg9_problem.py +++ /dev/null @@ -1,53 +0,0 @@ -import math - -from kurobako import problem - -from WFGtestSuite import wfg - - -class WFGProblemFactory(problem.ProblemFactory): - def specification(self): - params = [ - problem.Var("x", problem.ContinuousRange(0, 2)), - problem.Var("y", problem.ContinuousRange(0, 4)), - ] - return problem.ProblemSpec( - name="WFG9", - params=params, - values=[problem.Var("f1"), problem.Var("f2")], - ) - - def create_problem(self, seed): - return WFGProblem() - - -class WFGProblem(problem.Problem): - def create_evaluator(self, params): - return WFGEvaluator(params) - - -class WFGEvaluator(problem.Evaluator): - def __init__(self, params): - self._x, self._y = params - self._current_step = 0 - self.wfg = wfg.WFG9(n_arguments=2, n_objectives=2, k=1) - - def current_step(self): - return self._current_step - - def evaluate(self, next_step): - self._current_step = 1 - x, y = self._x, self._y - v = self.wfg([x, y]) - v = v.tolist() - - if math.isnan(v[0]) or math.isinf(v[0]): - raise ValueError - if math.isnan(v[1]) or math.isinf(v[1]): - raise ValueError - return v - - -if __name__ == "__main__": - runner = problem.ProblemRunner(WFGProblemFactory()) - runner.run() diff --git a/benchmarks/problem/WFGtestSuite/shape_functions.py b/benchmarks/problems/WFGtestSuite/shape_functions.py similarity index 100% rename from benchmarks/problem/WFGtestSuite/shape_functions.py rename to benchmarks/problems/WFGtestSuite/shape_functions.py diff --git a/benchmarks/problem/WFGtestSuite/transformation_functions.py b/benchmarks/problems/WFGtestSuite/transformation_functions.py similarity index 100% rename from benchmarks/problem/WFGtestSuite/transformation_functions.py rename to benchmarks/problems/WFGtestSuite/transformation_functions.py diff --git a/benchmarks/problem/WFGtestSuite/wfg.py b/benchmarks/problems/WFGtestSuite/wfg.py similarity index 100% rename from benchmarks/problem/WFGtestSuite/wfg.py rename to benchmarks/problems/WFGtestSuite/wfg.py diff --git a/benchmarks/problem/binh_and_korn_problem.py b/benchmarks/problems/binh_and_korn_problem.py similarity index 100% rename from benchmarks/problem/binh_and_korn_problem.py rename to benchmarks/problems/binh_and_korn_problem.py diff --git a/benchmarks/problems/wfg_problem.py b/benchmarks/problems/wfg_problem.py new file mode 100644 index 0000000000..c3304fec51 --- /dev/null +++ b/benchmarks/problems/wfg_problem.py @@ -0,0 +1,86 @@ +import math +import sys +import argparse + +from kurobako import problem + +from WFGtestSuite import wfg + + +class WFGProblemFactory(problem.ProblemFactory): + def specification(self): + self._n_wfg = int(sys.argv[1]) + self._n_dim = int(sys.argv[2]) + + self._low = 0 + self._high = 2 + params = [ + problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(self._n_dim) + ] + return problem.ProblemSpec( + name=f"WFG{self._n_wfg}", + params=params, + values=[problem.Var("f1"), problem.Var("f2")], + ) + + def create_problem(self, seed): + return WFGProblem() + + +class WFGProblem(problem.Problem): + def __init__(self) -> None: + super().__init__() + + def create_evaluator(self, params): + return WFGEvaluator(params) + + +class WFGEvaluator(problem.Evaluator): + def __init__(self, params): + self._n_wfg = int(sys.argv[1]) + self._n_dim = int(sys.argv[2]) + self._n_obj = int(sys.argv[3]) + self._k = int(sys.argv[4]) + + self._x = params + self._current_step = 0 + + if self._n_wfg == 1: + self.wfg = wfg.WFG1(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + elif self._n_wfg == 2: + self.wfg = wfg.WFG2(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + elif self._n_wfg == 3: + self.wfg = wfg.WFG3(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + elif self._n_wfg == 4: + self.wfg = wfg.WFG4(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + elif self._n_wfg == 5: + self.wfg = wfg.WFG5(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + elif self._n_wfg == 6: + self.wfg = wfg.WFG6(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + elif self._n_wfg == 7: + self.wfg = wfg.WFG7(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + elif self._n_wfg == 8: + self.wfg = wfg.WFG8(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + elif self._n_wfg == 9: + self.wfg = wfg.WFG9(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + else: + assert False, "Invalid specification for WFG number." + + def current_step(self): + return self._current_step + + def evaluate(self, next_step): + self._current_step = 1 + v = self.wfg(self._x) + v = v.tolist() + + if math.isnan(v[0]) or math.isinf(v[0]): + raise ValueError + if math.isnan(v[1]) or math.isinf(v[1]): + raise ValueError + return v + + +if __name__ == "__main__": + runner = problem.ProblemRunner(WFGProblemFactory()) + runner.run() diff --git a/benchmarks/run_mo_kurobako.py b/benchmarks/run_mo_kurobako.py index 0faaf969e5..502213b9db 100644 --- a/benchmarks/run_mo_kurobako.py +++ b/benchmarks/run_mo_kurobako.py @@ -32,13 +32,26 @@ def run(args: argparse.Namespace) -> None: # Create WFG 1~9 problem for n_wfg in range(1, 10): + if n_wfg ==8: + n_dim = 3 + k = 2 + elif n_wfg in (7,8,9): + n_dim = 2 + k = 1 + else: + n_dim = 10 + k = 2 + n_objective = 2 + + python_command = f"benchmarks/problems/wfg_problem.py \ + {n_wfg} {n_dim} {n_objective} {k}" cmd = ( - f"{kurobako_cmd} problem command " - f"python3 benchmarks/problem/wfg{n_wfg}_problem.py " + f"{kurobako_cmd} problem command python {python_command}" f"| tee -a {problems_filename}" ) subprocess.run(cmd, shell=True) + # # Create NAS bench problem(A) (for Multi-Objective Settings). # dataset = os.path.join(args.data_dir, "nasbench_full.bin") # cmd = ( @@ -117,7 +130,7 @@ def run(args: argparse.Namespace) -> None: cmd = ( f"cat {result_filename} | grep {problem_name} | " f"{kurobako_cmd} plot pareto-front -o {args.out_dir} " - f"--xmin {xmin} --xmax {xmax} --ymin {ymin} --ymax {ymax}" + # f"--xmin {xmin} --xmax {xmax} --ymin {ymin} --ymax {ymax}" ) subprocess.run(cmd, shell=True) From f92ad3ba4882d4a15a1e730da28a96e89bb8bf8d Mon Sep 17 00:00:00 2001 From: kei-mo Date: Wed, 9 Mar 2022 22:09:49 +0900 Subject: [PATCH 14/26] formatted --- benchmarks/problems/wfg_problem.py | 12 ++++++------ benchmarks/run_mo_kurobako.py | 9 ++++----- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/benchmarks/problems/wfg_problem.py b/benchmarks/problems/wfg_problem.py index c3304fec51..49bd91e219 100644 --- a/benchmarks/problems/wfg_problem.py +++ b/benchmarks/problems/wfg_problem.py @@ -1,6 +1,5 @@ import math import sys -import argparse from kurobako import problem @@ -11,11 +10,12 @@ class WFGProblemFactory(problem.ProblemFactory): def specification(self): self._n_wfg = int(sys.argv[1]) self._n_dim = int(sys.argv[2]) - + self._low = 0 self._high = 2 params = [ - problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) for i in range(self._n_dim) + problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) + for i in range(self._n_dim) ] return problem.ProblemSpec( name=f"WFG{self._n_wfg}", @@ -30,7 +30,7 @@ def create_problem(self, seed): class WFGProblem(problem.Problem): def __init__(self) -> None: super().__init__() - + def create_evaluator(self, params): return WFGEvaluator(params) @@ -40,7 +40,7 @@ def __init__(self, params): self._n_wfg = int(sys.argv[1]) self._n_dim = int(sys.argv[2]) self._n_obj = int(sys.argv[3]) - self._k = int(sys.argv[4]) + self._k = int(sys.argv[4]) self._x = params self._current_step = 0 @@ -64,7 +64,7 @@ def __init__(self, params): elif self._n_wfg == 9: self.wfg = wfg.WFG9(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) else: - assert False, "Invalid specification for WFG number." + assert False, "Invalid specification for WFG number." def current_step(self): return self._current_step diff --git a/benchmarks/run_mo_kurobako.py b/benchmarks/run_mo_kurobako.py index 502213b9db..c997a2792a 100644 --- a/benchmarks/run_mo_kurobako.py +++ b/benchmarks/run_mo_kurobako.py @@ -32,14 +32,14 @@ def run(args: argparse.Namespace) -> None: # Create WFG 1~9 problem for n_wfg in range(1, 10): - if n_wfg ==8: + if n_wfg == 8: n_dim = 3 k = 2 - elif n_wfg in (7,8,9): + elif n_wfg in (7, 8, 9): n_dim = 2 k = 1 else: - n_dim = 10 + n_dim = 10 k = 2 n_objective = 2 @@ -51,7 +51,6 @@ def run(args: argparse.Namespace) -> None: ) subprocess.run(cmd, shell=True) - # # Create NAS bench problem(A) (for Multi-Objective Settings). # dataset = os.path.join(args.data_dir, "nasbench_full.bin") # cmd = ( @@ -130,7 +129,7 @@ def run(args: argparse.Namespace) -> None: cmd = ( f"cat {result_filename} | grep {problem_name} | " f"{kurobako_cmd} plot pareto-front -o {args.out_dir} " - # f"--xmin {xmin} --xmax {xmax} --ymin {ymin} --ymax {ymax}" + f"--xmin {xmin} --xmax {xmax} --ymin {ymin} --ymax {ymax}" ) subprocess.run(cmd, shell=True) From 1dc64c481026e83be70c26bc717fdca6493512c8 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Tue, 29 Mar 2022 12:16:32 +0900 Subject: [PATCH 15/26] removed binh and korn problem --- benchmarks/problems/binh_and_korn_problem.py | 46 -------------------- 1 file changed, 46 deletions(-) delete mode 100644 benchmarks/problems/binh_and_korn_problem.py diff --git a/benchmarks/problems/binh_and_korn_problem.py b/benchmarks/problems/binh_and_korn_problem.py deleted file mode 100644 index 2ce9829b68..0000000000 --- a/benchmarks/problems/binh_and_korn_problem.py +++ /dev/null @@ -1,46 +0,0 @@ -from kurobako import problem - - -class BinhAndKornProblemFactory(problem.ProblemFactory): - def specification(self): - params = [ - problem.Var("x", problem.ContinuousRange(0, 5)), - problem.Var("y", problem.ContinuousRange(0, 3)), - ] - return problem.ProblemSpec( - name="BinhKorn", - params=params, - values=[ - problem.Var("4 * x ** 2 + 4 * y ** 2"), - problem.Var("(x - 5) ** 2 + (y - 5) ** 2"), - ], - ) - - def create_problem(self, seed): - return BinhAndKornProblem() - - -class BinhAndKornProblem(problem.Problem): - def create_evaluator(self, params): - return BinhAndKornEvaluator(params) - - -class BinhAndKornEvaluator(problem.Evaluator): - def __init__(self, params): - self._x, self._y = params - self._current_step = 0 - - def current_step(self): - return self._current_step - - def evaluate(self, next_step): - self._current_step = 1 - x, y = self._x, self._y - v0 = 4 * x**2 + 4 * y**2 - v1 = (x - 5) ** 2 + (y - 5) ** 2 - return [v0, v1] - - -if __name__ == "__main__": - runner = problem.ProblemRunner(BinhAndKornProblemFactory()) - runner.run() From d78a28e428ea91411dbdcaf53ee2793834f7fd44 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Tue, 29 Mar 2022 12:18:43 +0900 Subject: [PATCH 16/26] renamed wfg dir --- benchmarks/problems/wfg/__init__.py | 0 benchmarks/problems/wfg/shape_functions.py | 104 +++ .../problems/wfg/transformation_functions.py | 197 +++++ benchmarks/problems/wfg/wfg.py | 706 ++++++++++++++++++ 4 files changed, 1007 insertions(+) create mode 100644 benchmarks/problems/wfg/__init__.py create mode 100644 benchmarks/problems/wfg/shape_functions.py create mode 100644 benchmarks/problems/wfg/transformation_functions.py create mode 100644 benchmarks/problems/wfg/wfg.py diff --git a/benchmarks/problems/wfg/__init__.py b/benchmarks/problems/wfg/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/benchmarks/problems/wfg/shape_functions.py b/benchmarks/problems/wfg/shape_functions.py new file mode 100644 index 0000000000..9ad3112f90 --- /dev/null +++ b/benchmarks/problems/wfg/shape_functions.py @@ -0,0 +1,104 @@ +import abc + +import numpy as np + + +class BaseShapeFunction(object, metaclass=abc.ABCMeta): + def __init__(self, n_objectives: int) -> None: + + self._n_objectives = n_objectives + + def __call__(self, m: int, x: np.ndarray) -> float: + assert 1 <= m <= self.n_objectives + assert x.shape == (self.n_objectives - 1,) + return self._call(m, x) + + @abc.abstractmethod + def _call(self, m: int, x: np.ndarray) -> float: + raise NotImplementedError + + @property + def n_objectives(self) -> int: + + return self._n_objectives + + +class LinearShapeFunction(BaseShapeFunction): + def _call(self, m: int, x: np.ndarray) -> float: + + if m == 1: + return x[:-1].prod() + + if m == self.n_objectives: + return 1 - x[0] + + return x[: self.n_objectives - m].prod() * (1.0 - x[self.n_objectives - m]) + + +class ConvexShapeFunction(BaseShapeFunction): + def _call(self, m: int, x: np.ndarray) -> float: + + if m == 1: + return ( + 1 + - np.cos( + x * np.pi / 2, + ) + )[:-1].prod() + + if m == self.n_objectives: + return 1 - np.sin(x[0] * np.pi / 2.0) + + return (1.0 - np.cos(x * np.pi / 2.0))[: self.n_objectives - m].prod() * ( + 1.0 - np.sin(x[self.n_objectives - m] * np.pi / 2.0) + ) + + +class ConcaveShapeFunction(BaseShapeFunction): + def _call(self, m: int, x: np.ndarray) -> float: + + if m == 1: + return np.sin(x * np.pi / 2.0)[:-1].prod() + + if m == self.n_objectives: + return np.cos(x[0] * np.pi / 2.0) + + return np.sin(x * np.pi / 2.0)[: self.n_objectives - m].prod() * np.cos( + x[self.n_objectives - m] * np.pi / 2.0 + ) + + +class MixedConvexOrConcaveShapeFunction(BaseShapeFunction): + def __init__(self, n_objectives, alpha: float, n_segments: int) -> None: + super().__init__(n_objectives) + self._alpha = alpha + self._n_segments = n_segments + + def _call(self, m: int, x: np.ndarray) -> float: + if m == self.n_objectives: + two_A_pi = 2 * self._n_segments * np.pi + return np.power( + 1 - x[0] - np.cos(two_A_pi * x[0] + np.pi / 2.0) / two_A_pi, self._alpha + ) + + raise ValueError("m should be the number of objectives") + + +class DisconnectedShapeFunction(BaseShapeFunction): + def __init__( + self, n_objectives, alpha: float, beta: float, n_disconnected_regions: int + ) -> None: + super().__init__(n_objectives) + self._alpha = alpha + self._beta = beta + self._n_disconnected_regions = n_disconnected_regions + + def _call(self, m: int, x: np.ndarray) -> float: + if m == self.n_objectives: + return ( + 1 + - np.power(x[0], self._alpha) + * np.cos(self._n_disconnected_regions * np.power(x[0], self._beta) * np.pi) ** 2 + ) + + raise ValueError("m should be the number of objectives") diff --git a/benchmarks/problems/wfg/transformation_functions.py b/benchmarks/problems/wfg/transformation_functions.py new file mode 100644 index 0000000000..882bc83904 --- /dev/null +++ b/benchmarks/problems/wfg/transformation_functions.py @@ -0,0 +1,197 @@ +import abc +from typing import Callable + +import numpy as np + + +class BaseTransformations(object, metaclass=abc.ABCMeta): + @abc.abstractmethod + def __call__(self, *args, **kwargs): + + raise NotImplementedError + + +class BaseBiasTransformation(BaseTransformations, metaclass=abc.ABCMeta): + @abc.abstractmethod + def __call__(self, y: np.ndarray) -> float: + + raise NotImplementedError + + +class BaseShiftTransformation(BaseTransformations, metaclass=abc.ABCMeta): + @abc.abstractmethod + def __call__(self, y: float) -> float: + + raise NotImplementedError + + +class BaseReductionTransformation(BaseTransformations, metaclass=abc.ABCMeta): + @abc.abstractmethod + def __call__(self, y: np.ndarray) -> float: + + raise NotImplementedError + + +class PolynomialBiasTransformation(BaseBiasTransformation): + def __init__(self, alpha: float) -> None: + + assert alpha > 0 and alpha != 1.0 + self._alpha = alpha + + def __call__(self, y: float) -> float: + + return np.power(y, self._alpha) + + +class FlatRegionBiasTransformation(BaseBiasTransformation): + def __init__(self, a: float, b: float, c: float) -> None: + + assert 0 <= a <= 1 + assert 0 <= b <= 1 + assert 0 <= c <= 1 + assert b < c + assert not (b == 0) or (a == 0 and c != 1) + assert not (c == 1) or (a == 1 and b != 0) + + self._a = a + self._b = b + self._c = c + + def __call__(self, y: float) -> float: + + a = self._a + b = self._b + c = self._c + return ( + a + + min(0, np.floor(y - b)) * a * (b - y) / b + - min(0, np.floor(c - y)) * (1.0 - a) * (y - c) / (1.0 - c) + ) + + +class ParameterDependentBiasTransformation(BaseReductionTransformation): + def __init__( + self, + w: np.ndarray, + input_converter: Callable[[np.ndarray], np.ndarray], + a: float, + b: float, + c: float, + i: int, + ) -> None: + + assert 0 < a < 1 + assert 0 < b < c + + self._w = w + self._input_converter = input_converter + self._a = a + self._b = b + self._c = c + self._i = i + + def __call__(self, y: np.ndarray) -> float: + + w = self._w + a = self._a + b = self._b + c = self._c + i = self._i + + u = (self._input_converter(y) * w).sum() / w.sum() + v = a - (1.0 - 2 * u) * np.fabs(np.floor(0.5 - u) + a) + return np.power(y[i], b + (c - b) * v) + + +class LinearShiftTransformation(BaseShiftTransformation): + def __init__(self, a: float) -> None: + + assert 0 < a < 1 + + self._a = a + + def __call__(self, y: float) -> float: + + return np.fabs(y - self._a) / np.fabs(np.floor(self._a - y) + self._a) + + +class DeceptiveShiftTransformation(BaseShiftTransformation): + def __init__(self, a: float, b: float, c: float) -> None: + + assert 0 < a < 1 + assert 0 < b < 1 + assert 0 < c < 1 + assert a - b > 0 + assert a + b < 1 + + self._a = a + self._b = b + self._c = c + + def __call__(self, y: float) -> float: + + a = self._a + b = self._b + c = self._c + + q1 = np.floor(y - a + b) * (1.0 - c + (a - b) / b) + q2 = np.floor(a + b - y) * (1.0 - c + (1.0 - a - b) / b) + return 1.0 + (np.fabs(y - a) - b) * (q1 / (a - b) + q2 / (1.0 - a - b) + 1.0 / b) + + +class MultiModalShiftTransformation(BaseShiftTransformation): + def __init__(self, a: int, b: float, c: float) -> None: + + assert a > 0 + assert b >= 0 + assert (4 * a + 2) * np.pi >= 4 * b + assert 0 < c < 1 + + self._a = a + self._b = b + self._c = c + + def __call__(self, y: float) -> float: + + a = self._a + b = self._b + c = self._c + + q1 = np.fabs(y - c) / (2 * (np.floor(c - y) + c)) + q2 = (4 * a + 2) * np.pi * (0.5 - q1) + return (1.0 + np.cos(q2) + 4 * b * (q1**2)) / (b + 2) + + +class WeightedSumReductionTransformation(BaseReductionTransformation): + def __init__(self, w: np.ndarray, input_converter: Callable[[np.ndarray], np.ndarray]) -> None: + + assert all(w > 0) + + self._w = w + self._input_converter = input_converter + + def __call__(self, y: np.ndarray) -> float: + + y = self._input_converter(y) + return (y * self._w).sum() / self._w.sum() + + +class NonSeparableReductionTransformation(BaseReductionTransformation): + def __init__(self, a: int, input_converter: Callable[[np.ndarray], np.ndarray]) -> None: + + assert a > 0 + + self._a = a + self._input_converter = input_converter + + def __call__(self, y: np.ndarray) -> float: + + a = float(self._a) + y = self._input_converter(y) + n = y.shape[0] + indices = [(j + k + 1) % n for k in np.arange(n) for j in np.arange(n)] + + q = y.sum() + np.fabs(y[indices].reshape((n, n)) - y)[:, 0 : int(a) - 1].sum() + r = n * np.ceil(a / 2) * (1.0 + 2 * a - 2 * np.ceil(a / 2)) / a + + return q / r diff --git a/benchmarks/problems/wfg/wfg.py b/benchmarks/problems/wfg/wfg.py new file mode 100644 index 0000000000..3393c37646 --- /dev/null +++ b/benchmarks/problems/wfg/wfg.py @@ -0,0 +1,706 @@ +from typing import List + +import numpy as np + +from . import shape_functions +from . import transformation_functions + + +class BaseWFG(object): + def __init__( + self, + S: np.ndarray, + A: np.ndarray, + upper_bounds: np.ndarray, + shapes: List[shape_functions.BaseShapeFunction], + transformations: List[List[transformation_functions.BaseTransformations]], + ) -> None: + + assert all(S > 0) + assert all((A == 0) + (A == 1)) + assert all(upper_bounds > 0) + + self._S = S + self._A = A + self._upper_bounds = upper_bounds + self._shapes = shapes + self._transformations = transformations + + def __call__(self, z: np.ndarray) -> np.ndarray: + + S = self._S + A = self._A + unit_z = z / self._upper_bounds + shapes = self._shapes + transformations = self._transformations + + y = unit_z + for t_p in transformations: + _y = np.empty((len(t_p),)) + for i in range(len(t_p)): + if isinstance(t_p[i], transformation_functions.BaseReductionTransformation): + _y[i] = t_p[i](y) + else: + _y[i] = t_p[i](y[i]) + y = _y + + x = np.empty(y.shape) + x[:-1] = np.maximum(y[-1], A) * (y[:-1] - 0.5) + 0.5 + x[-1] = y[-1] + + f = x[-1] + S * np.asarray([h(m + 1, x[:-1]) for m, h in enumerate(shapes)]) + return f + + +class WFG1(object): + """WFG1 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.ones(M - 1) + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.ConvexShapeFunction(M) for _ in range(M - 1)] + shapes.append(shape_functions.MixedConvexOrConcaveShapeFunction(M, 1, 5)) + + t_1 = [lambda y: y for _ in range(k)] + for _ in range(n - k): + t_1.append(transformation_functions.LinearShiftTransformation(0.35)) + + t_2 = [lambda y: y for _ in range(k)] + for _ in range(n - k): + t_2.append(transformation_functions.FlatRegionBiasTransformation(0.8, 0.75, 0.85)) + + t_3 = [transformation_functions.PolynomialBiasTransformation(0.02) for _ in range(n)] + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_4 = [ + transformation_functions.WeightedSumReductionTransformation( + 2 * np.arange(i * k // (M - 1) + 1, (i + 1) * k // (M - 1) + 1), + lambda y: _input_converter(i, y), + ) + for i in range(M - 1) + ] + t_4.append( + transformation_functions.WeightedSumReductionTransformation( + 2 * np.arange(k, n) + 1, + lambda y: y[k:n], + ) + ) + transformations = [t_1, t_2, t_3, t_4] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) + + +class WFG2(object): + """WFG2 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments // 2 + assert (n_arguments - k) % 2 == 0 + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.ones(M - 1) + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.ConvexShapeFunction(M) for _ in range(M - 1)] + shapes.append(shape_functions.DisconnectedShapeFunction(M, 1, 1, 5)) + + t_1 = [lambda y: y for _ in range(k)] + for _ in range(n - k): + t_1.append(transformation_functions.LinearShiftTransformation(0.35)) + + def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: + indices = [k + 2 * (i + 1 - k) - 2, k + 2 * (i - k + 1) - 1] + return y[indices] + + t_2 = [lambda y: y for _ in range(k)] + for i in range(k, n // 2): + t_2.append( + transformation_functions.NonSeparableReductionTransformation( + 2, lambda y: _input_converter0(i, y) + ) + ) + + def _input_converter1(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_3 = [ + transformation_functions.WeightedSumReductionTransformation( + np.ones(k // (M - 1)), + lambda y: _input_converter1(i, y), + ) + for i in range(M - 1) + ] + t_3.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(n // 2 - k), + lambda y: y[k : n // 2], + ) + ) + + transformations = [t_1, t_2, t_3] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) + + +class WFG3(object): + """WFG3 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments // 2 + assert (n_arguments - k) % 2 == 0 + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.zeros(M - 1) + A[0] = 1 + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.LinearShapeFunction(M) for _ in range(M)] + + t_1 = [lambda y: y for _ in range(k)] + for _ in range(n - k): + t_1.append(transformation_functions.LinearShiftTransformation(0.35)) + + def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: + indices = [k + 2 * (i + 1 - k) - 2, k + 2 * (i - k + 1) - 1] + return y[indices] + + t_2 = [lambda y: y for _ in range(k)] + for i in range(k, n // 2): + t_2.append( + transformation_functions.NonSeparableReductionTransformation( + 2, lambda y: _input_converter0(i, y) + ) + ) + + def _input_converter1(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_3 = [ + transformation_functions.WeightedSumReductionTransformation( + np.ones(k // (M - 1)), + lambda y: _input_converter1(i, y), + ) + for i in range(M - 1) + ] + t_3.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(n // 2 - k), + lambda y: y[k : n // 2], + ) + ) + + transformations = [t_1, t_2, t_3] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) + + +class WFG4(object): + """WFG4 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.ones(M - 1) + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] + + t_1 = [ + transformation_functions.MultiModalShiftTransformation(30, 10, 0.35) for _ in range(n) + ] + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_2 = [] + for i in range(M - 1): + t_2.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(k // (M - 1)), lambda y: _input_converter(i, y) + ) + ) + t_2.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(n - k), + lambda y: y[k:n], + ) + ) + + transformations = [t_1, t_2] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) + + +class WFG5(object): + """WFG5 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.ones(M - 1) + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] + + t_1 = [ + transformation_functions.DeceptiveShiftTransformation(0.35, 0.001, 0.05) + for _ in range(n) + ] + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_2 = [] + for i in range(M - 1): + t_2.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(k // (M - 1)), lambda y: _input_converter(i, y) + ) + ) + t_2.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(n - k), + lambda y: y[k:n], + ) + ) + + transformations = [t_1, t_2] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) + + +class WFG6(object): + """WFG6 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.ones(M - 1) + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] + + t_1 = [lambda y: y for _ in range(k)] + for _ in range(n - k): + t_1.append(transformation_functions.LinearShiftTransformation(0.35)) + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_2 = [] + for i in range(M - 1): + t_2.append( + transformation_functions.NonSeparableReductionTransformation( + k // (M - 1), lambda y: _input_converter(i, y) + ) + ) + t_2.append( + transformation_functions.NonSeparableReductionTransformation( + n - k, + lambda y: y[k:n], + ) + ) + + transformations = [t_1, t_2] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) + + +class WFG7(object): + """WFG7 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.ones(M - 1) + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] + + def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: + return y[i:n] + + t_1 = [ + transformation_functions.ParameterDependentBiasTransformation( + np.ones(n - i), + lambda y: _input_converter0(i, y), + 0.98 / 49.98, + 0.02, + 50, + i, + ) + for i in range(k) + ] + for _ in range(n - k): + t_1.append(lambda y: y) + + t_2 = [lambda y: y for _ in range(k)] + for _ in range(n - k): + t_2.append(transformation_functions.LinearShiftTransformation(0.35)) + + def _input_converter1(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_3 = [] + for i in range(M - 1): + t_3.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(k // (M - 1)), lambda y: _input_converter1(i, y) + ) + ) + t_3.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(n - k), + lambda y: y[k:n], + ) + ) + + transformations = [t_1, t_2, t_3] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) + + +class WFG8(object): + """WFG8 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.ones(M - 1) + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] + + def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: + return y[: i - 1] + + t_1 = [lambda y: y for _ in range(k)] + for i in range(k, n): + t_1.append( + transformation_functions.ParameterDependentBiasTransformation( + np.ones(i - 1), + lambda y: _input_converter0(i, y), + 0.98 / 49.98, + 0.02, + 50, + i, + ) + ) + + t_2 = [lambda y: y for _ in range(k)] + for _ in range(n - k): + t_2.append(transformation_functions.LinearShiftTransformation(0.35)) + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_3 = [] + for i in range(M - 1): + t_3.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(k // (M - 1)), lambda y: _input_converter(i, y) + ) + ) + t_3.append( + transformation_functions.WeightedSumReductionTransformation( + np.ones(n - k), + lambda y: y[k:n], + ) + ) + + transformations = [t_1, t_2, t_3] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) + + +class WFG9(object): + """WFG9 + + Args: + n_arguments: + The number of arguments. + n_objectives: + The number of objectives. + k: + The degree of the Pareto front. + """ + + def __init__(self, n_arguments: int, n_objectives: int, k: int): + + assert k % (n_objectives - 1) == 0 + assert k + 1 <= n_arguments + + self._n_arguments = n_arguments + self._n_objectives = n_objectives + self._k = k + + n = self._n_arguments + M = self._n_objectives + + S = 2 * (np.arange(M) + 1) + A = np.ones(M - 1) + upper_bounds = 2 * (np.arange(n) + 1) + + self.domain = np.zeros((n, 2)) + self.domain[:, 1] = upper_bounds + + shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] + + def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: + return y[i:n] + + t_1 = [ + transformation_functions.ParameterDependentBiasTransformation( + np.ones(n - i), + lambda y: _input_converter0(i, y), + 0.98 / 49.98, + 0.02, + 50, + i, + ) + for i in range(n - 1) + ] + t_1.append(lambda y: y) + + t_2 = [ + transformation_functions.DeceptiveShiftTransformation(0.35, 0.001, 0.05) + for _ in range(k) + ] + for _ in range(n - k): + t_2.append(transformation_functions.MultiModalShiftTransformation(30, 95, 0.35)) + + def _input_converter(i: int, y: np.ndarray) -> np.ndarray: + indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) + return y[indices] + + t_3 = [] + for i in range(M - 1): + t_3.append( + transformation_functions.NonSeparableReductionTransformation( + k // (M - 1), lambda y: _input_converter(i, y) + ) + ) + t_3.append( + transformation_functions.NonSeparableReductionTransformation( + n - k, + lambda y: y[k:n], + ) + ) + + transformations = [t_1, t_2, t_3] + + self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) + + def __call__(self, z: np.ndarray) -> np.ndarray: + return self.wfg.__call__(z) From 93af92515f121ac066c58bf87c6fccebc4087993 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Tue, 29 Mar 2022 12:45:31 +0900 Subject: [PATCH 17/26] reorganized wfg dir --- benchmarks/problems/WFGtestSuite/wfg.py | 706 ------------------ benchmarks/problems/wfg/__init__.py | 0 .../func}/shape_functions.py | 0 .../func}/transformation_functions.py | 0 benchmarks/problems/wfg/shape_functions.py | 104 --- .../problems/wfg/transformation_functions.py | 197 ----- benchmarks/problems/wfg/wfg.py | 88 ++- benchmarks/problems/wfg_problem.py | 86 --- benchmarks/run_mo_kurobako.py | 2 +- 9 files changed, 87 insertions(+), 1096 deletions(-) delete mode 100644 benchmarks/problems/WFGtestSuite/wfg.py delete mode 100644 benchmarks/problems/wfg/__init__.py rename benchmarks/problems/{WFGtestSuite => wfg/func}/shape_functions.py (100%) rename benchmarks/problems/{WFGtestSuite => wfg/func}/transformation_functions.py (100%) delete mode 100644 benchmarks/problems/wfg/shape_functions.py delete mode 100644 benchmarks/problems/wfg/transformation_functions.py delete mode 100644 benchmarks/problems/wfg_problem.py diff --git a/benchmarks/problems/WFGtestSuite/wfg.py b/benchmarks/problems/WFGtestSuite/wfg.py deleted file mode 100644 index 3393c37646..0000000000 --- a/benchmarks/problems/WFGtestSuite/wfg.py +++ /dev/null @@ -1,706 +0,0 @@ -from typing import List - -import numpy as np - -from . import shape_functions -from . import transformation_functions - - -class BaseWFG(object): - def __init__( - self, - S: np.ndarray, - A: np.ndarray, - upper_bounds: np.ndarray, - shapes: List[shape_functions.BaseShapeFunction], - transformations: List[List[transformation_functions.BaseTransformations]], - ) -> None: - - assert all(S > 0) - assert all((A == 0) + (A == 1)) - assert all(upper_bounds > 0) - - self._S = S - self._A = A - self._upper_bounds = upper_bounds - self._shapes = shapes - self._transformations = transformations - - def __call__(self, z: np.ndarray) -> np.ndarray: - - S = self._S - A = self._A - unit_z = z / self._upper_bounds - shapes = self._shapes - transformations = self._transformations - - y = unit_z - for t_p in transformations: - _y = np.empty((len(t_p),)) - for i in range(len(t_p)): - if isinstance(t_p[i], transformation_functions.BaseReductionTransformation): - _y[i] = t_p[i](y) - else: - _y[i] = t_p[i](y[i]) - y = _y - - x = np.empty(y.shape) - x[:-1] = np.maximum(y[-1], A) * (y[:-1] - 0.5) + 0.5 - x[-1] = y[-1] - - f = x[-1] + S * np.asarray([h(m + 1, x[:-1]) for m, h in enumerate(shapes)]) - return f - - -class WFG1(object): - """WFG1 - - Args: - n_arguments: - The number of arguments. - n_objectives: - The number of objectives. - k: - The degree of the Pareto front. - """ - - def __init__(self, n_arguments: int, n_objectives: int, k: int): - - assert k % (n_objectives - 1) == 0 - assert k + 1 <= n_arguments - - self._n_arguments = n_arguments - self._n_objectives = n_objectives - self._k = k - - n = self._n_arguments - M = self._n_objectives - - S = 2 * (np.arange(M) + 1) - A = np.ones(M - 1) - upper_bounds = 2 * (np.arange(n) + 1) - - self.domain = np.zeros((n, 2)) - self.domain[:, 1] = upper_bounds - - shapes = [shape_functions.ConvexShapeFunction(M) for _ in range(M - 1)] - shapes.append(shape_functions.MixedConvexOrConcaveShapeFunction(M, 1, 5)) - - t_1 = [lambda y: y for _ in range(k)] - for _ in range(n - k): - t_1.append(transformation_functions.LinearShiftTransformation(0.35)) - - t_2 = [lambda y: y for _ in range(k)] - for _ in range(n - k): - t_2.append(transformation_functions.FlatRegionBiasTransformation(0.8, 0.75, 0.85)) - - t_3 = [transformation_functions.PolynomialBiasTransformation(0.02) for _ in range(n)] - - def _input_converter(i: int, y: np.ndarray) -> np.ndarray: - indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) - return y[indices] - - t_4 = [ - transformation_functions.WeightedSumReductionTransformation( - 2 * np.arange(i * k // (M - 1) + 1, (i + 1) * k // (M - 1) + 1), - lambda y: _input_converter(i, y), - ) - for i in range(M - 1) - ] - t_4.append( - transformation_functions.WeightedSumReductionTransformation( - 2 * np.arange(k, n) + 1, - lambda y: y[k:n], - ) - ) - transformations = [t_1, t_2, t_3, t_4] - - self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) - - def __call__(self, z: np.ndarray) -> np.ndarray: - return self.wfg.__call__(z) - - -class WFG2(object): - """WFG2 - - Args: - n_arguments: - The number of arguments. - n_objectives: - The number of objectives. - k: - The degree of the Pareto front. - """ - - def __init__(self, n_arguments: int, n_objectives: int, k: int): - - assert k % (n_objectives - 1) == 0 - assert k + 1 <= n_arguments // 2 - assert (n_arguments - k) % 2 == 0 - - self._n_arguments = n_arguments - self._n_objectives = n_objectives - self._k = k - - n = self._n_arguments - M = self._n_objectives - - S = 2 * (np.arange(M) + 1) - A = np.ones(M - 1) - upper_bounds = 2 * (np.arange(n) + 1) - - self.domain = np.zeros((n, 2)) - self.domain[:, 1] = upper_bounds - - shapes = [shape_functions.ConvexShapeFunction(M) for _ in range(M - 1)] - shapes.append(shape_functions.DisconnectedShapeFunction(M, 1, 1, 5)) - - t_1 = [lambda y: y for _ in range(k)] - for _ in range(n - k): - t_1.append(transformation_functions.LinearShiftTransformation(0.35)) - - def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: - indices = [k + 2 * (i + 1 - k) - 2, k + 2 * (i - k + 1) - 1] - return y[indices] - - t_2 = [lambda y: y for _ in range(k)] - for i in range(k, n // 2): - t_2.append( - transformation_functions.NonSeparableReductionTransformation( - 2, lambda y: _input_converter0(i, y) - ) - ) - - def _input_converter1(i: int, y: np.ndarray) -> np.ndarray: - indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) - return y[indices] - - t_3 = [ - transformation_functions.WeightedSumReductionTransformation( - np.ones(k // (M - 1)), - lambda y: _input_converter1(i, y), - ) - for i in range(M - 1) - ] - t_3.append( - transformation_functions.WeightedSumReductionTransformation( - np.ones(n // 2 - k), - lambda y: y[k : n // 2], - ) - ) - - transformations = [t_1, t_2, t_3] - - self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) - - def __call__(self, z: np.ndarray) -> np.ndarray: - return self.wfg.__call__(z) - - -class WFG3(object): - """WFG3 - - Args: - n_arguments: - The number of arguments. - n_objectives: - The number of objectives. - k: - The degree of the Pareto front. - """ - - def __init__(self, n_arguments: int, n_objectives: int, k: int): - - assert k % (n_objectives - 1) == 0 - assert k + 1 <= n_arguments // 2 - assert (n_arguments - k) % 2 == 0 - - self._n_arguments = n_arguments - self._n_objectives = n_objectives - self._k = k - - n = self._n_arguments - M = self._n_objectives - - S = 2 * (np.arange(M) + 1) - A = np.zeros(M - 1) - A[0] = 1 - upper_bounds = 2 * (np.arange(n) + 1) - - self.domain = np.zeros((n, 2)) - self.domain[:, 1] = upper_bounds - - shapes = [shape_functions.LinearShapeFunction(M) for _ in range(M)] - - t_1 = [lambda y: y for _ in range(k)] - for _ in range(n - k): - t_1.append(transformation_functions.LinearShiftTransformation(0.35)) - - def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: - indices = [k + 2 * (i + 1 - k) - 2, k + 2 * (i - k + 1) - 1] - return y[indices] - - t_2 = [lambda y: y for _ in range(k)] - for i in range(k, n // 2): - t_2.append( - transformation_functions.NonSeparableReductionTransformation( - 2, lambda y: _input_converter0(i, y) - ) - ) - - def _input_converter1(i: int, y: np.ndarray) -> np.ndarray: - indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) - return y[indices] - - t_3 = [ - transformation_functions.WeightedSumReductionTransformation( - np.ones(k // (M - 1)), - lambda y: _input_converter1(i, y), - ) - for i in range(M - 1) - ] - t_3.append( - transformation_functions.WeightedSumReductionTransformation( - np.ones(n // 2 - k), - lambda y: y[k : n // 2], - ) - ) - - transformations = [t_1, t_2, t_3] - - self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) - - def __call__(self, z: np.ndarray) -> np.ndarray: - return self.wfg.__call__(z) - - -class WFG4(object): - """WFG4 - - Args: - n_arguments: - The number of arguments. - n_objectives: - The number of objectives. - k: - The degree of the Pareto front. - """ - - def __init__(self, n_arguments: int, n_objectives: int, k: int): - - assert k % (n_objectives - 1) == 0 - assert k + 1 <= n_arguments - - self._n_arguments = n_arguments - self._n_objectives = n_objectives - self._k = k - - n = self._n_arguments - M = self._n_objectives - - S = 2 * (np.arange(M) + 1) - A = np.ones(M - 1) - upper_bounds = 2 * (np.arange(n) + 1) - - self.domain = np.zeros((n, 2)) - self.domain[:, 1] = upper_bounds - - shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] - - t_1 = [ - transformation_functions.MultiModalShiftTransformation(30, 10, 0.35) for _ in range(n) - ] - - def _input_converter(i: int, y: np.ndarray) -> np.ndarray: - indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) - return y[indices] - - t_2 = [] - for i in range(M - 1): - t_2.append( - transformation_functions.WeightedSumReductionTransformation( - np.ones(k // (M - 1)), lambda y: _input_converter(i, y) - ) - ) - t_2.append( - transformation_functions.WeightedSumReductionTransformation( - np.ones(n - k), - lambda y: y[k:n], - ) - ) - - transformations = [t_1, t_2] - - self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) - - def __call__(self, z: np.ndarray) -> np.ndarray: - return self.wfg.__call__(z) - - -class WFG5(object): - """WFG5 - - Args: - n_arguments: - The number of arguments. - n_objectives: - The number of objectives. - k: - The degree of the Pareto front. - """ - - def __init__(self, n_arguments: int, n_objectives: int, k: int): - - assert k % (n_objectives - 1) == 0 - assert k + 1 <= n_arguments - - self._n_arguments = n_arguments - self._n_objectives = n_objectives - self._k = k - - n = self._n_arguments - M = self._n_objectives - - S = 2 * (np.arange(M) + 1) - A = np.ones(M - 1) - upper_bounds = 2 * (np.arange(n) + 1) - - self.domain = np.zeros((n, 2)) - self.domain[:, 1] = upper_bounds - - shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] - - t_1 = [ - transformation_functions.DeceptiveShiftTransformation(0.35, 0.001, 0.05) - for _ in range(n) - ] - - def _input_converter(i: int, y: np.ndarray) -> np.ndarray: - indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) - return y[indices] - - t_2 = [] - for i in range(M - 1): - t_2.append( - transformation_functions.WeightedSumReductionTransformation( - np.ones(k // (M - 1)), lambda y: _input_converter(i, y) - ) - ) - t_2.append( - transformation_functions.WeightedSumReductionTransformation( - np.ones(n - k), - lambda y: y[k:n], - ) - ) - - transformations = [t_1, t_2] - - self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) - - def __call__(self, z: np.ndarray) -> np.ndarray: - return self.wfg.__call__(z) - - -class WFG6(object): - """WFG6 - - Args: - n_arguments: - The number of arguments. - n_objectives: - The number of objectives. - k: - The degree of the Pareto front. - """ - - def __init__(self, n_arguments: int, n_objectives: int, k: int): - - assert k % (n_objectives - 1) == 0 - assert k + 1 <= n_arguments - - self._n_arguments = n_arguments - self._n_objectives = n_objectives - self._k = k - - n = self._n_arguments - M = self._n_objectives - - S = 2 * (np.arange(M) + 1) - A = np.ones(M - 1) - upper_bounds = 2 * (np.arange(n) + 1) - - self.domain = np.zeros((n, 2)) - self.domain[:, 1] = upper_bounds - - shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] - - t_1 = [lambda y: y for _ in range(k)] - for _ in range(n - k): - t_1.append(transformation_functions.LinearShiftTransformation(0.35)) - - def _input_converter(i: int, y: np.ndarray) -> np.ndarray: - indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) - return y[indices] - - t_2 = [] - for i in range(M - 1): - t_2.append( - transformation_functions.NonSeparableReductionTransformation( - k // (M - 1), lambda y: _input_converter(i, y) - ) - ) - t_2.append( - transformation_functions.NonSeparableReductionTransformation( - n - k, - lambda y: y[k:n], - ) - ) - - transformations = [t_1, t_2] - - self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) - - def __call__(self, z: np.ndarray) -> np.ndarray: - return self.wfg.__call__(z) - - -class WFG7(object): - """WFG7 - - Args: - n_arguments: - The number of arguments. - n_objectives: - The number of objectives. - k: - The degree of the Pareto front. - """ - - def __init__(self, n_arguments: int, n_objectives: int, k: int): - - assert k % (n_objectives - 1) == 0 - assert k + 1 <= n_arguments - - self._n_arguments = n_arguments - self._n_objectives = n_objectives - self._k = k - - n = self._n_arguments - M = self._n_objectives - - S = 2 * (np.arange(M) + 1) - A = np.ones(M - 1) - upper_bounds = 2 * (np.arange(n) + 1) - - self.domain = np.zeros((n, 2)) - self.domain[:, 1] = upper_bounds - - shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] - - def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: - return y[i:n] - - t_1 = [ - transformation_functions.ParameterDependentBiasTransformation( - np.ones(n - i), - lambda y: _input_converter0(i, y), - 0.98 / 49.98, - 0.02, - 50, - i, - ) - for i in range(k) - ] - for _ in range(n - k): - t_1.append(lambda y: y) - - t_2 = [lambda y: y for _ in range(k)] - for _ in range(n - k): - t_2.append(transformation_functions.LinearShiftTransformation(0.35)) - - def _input_converter1(i: int, y: np.ndarray) -> np.ndarray: - indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) - return y[indices] - - t_3 = [] - for i in range(M - 1): - t_3.append( - transformation_functions.WeightedSumReductionTransformation( - np.ones(k // (M - 1)), lambda y: _input_converter1(i, y) - ) - ) - t_3.append( - transformation_functions.WeightedSumReductionTransformation( - np.ones(n - k), - lambda y: y[k:n], - ) - ) - - transformations = [t_1, t_2, t_3] - - self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) - - def __call__(self, z: np.ndarray) -> np.ndarray: - return self.wfg.__call__(z) - - -class WFG8(object): - """WFG8 - - Args: - n_arguments: - The number of arguments. - n_objectives: - The number of objectives. - k: - The degree of the Pareto front. - """ - - def __init__(self, n_arguments: int, n_objectives: int, k: int): - - assert k % (n_objectives - 1) == 0 - assert k + 1 <= n_arguments - - self._n_arguments = n_arguments - self._n_objectives = n_objectives - self._k = k - - n = self._n_arguments - M = self._n_objectives - - S = 2 * (np.arange(M) + 1) - A = np.ones(M - 1) - upper_bounds = 2 * (np.arange(n) + 1) - - self.domain = np.zeros((n, 2)) - self.domain[:, 1] = upper_bounds - - shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] - - def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: - return y[: i - 1] - - t_1 = [lambda y: y for _ in range(k)] - for i in range(k, n): - t_1.append( - transformation_functions.ParameterDependentBiasTransformation( - np.ones(i - 1), - lambda y: _input_converter0(i, y), - 0.98 / 49.98, - 0.02, - 50, - i, - ) - ) - - t_2 = [lambda y: y for _ in range(k)] - for _ in range(n - k): - t_2.append(transformation_functions.LinearShiftTransformation(0.35)) - - def _input_converter(i: int, y: np.ndarray) -> np.ndarray: - indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) - return y[indices] - - t_3 = [] - for i in range(M - 1): - t_3.append( - transformation_functions.WeightedSumReductionTransformation( - np.ones(k // (M - 1)), lambda y: _input_converter(i, y) - ) - ) - t_3.append( - transformation_functions.WeightedSumReductionTransformation( - np.ones(n - k), - lambda y: y[k:n], - ) - ) - - transformations = [t_1, t_2, t_3] - - self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) - - def __call__(self, z: np.ndarray) -> np.ndarray: - return self.wfg.__call__(z) - - -class WFG9(object): - """WFG9 - - Args: - n_arguments: - The number of arguments. - n_objectives: - The number of objectives. - k: - The degree of the Pareto front. - """ - - def __init__(self, n_arguments: int, n_objectives: int, k: int): - - assert k % (n_objectives - 1) == 0 - assert k + 1 <= n_arguments - - self._n_arguments = n_arguments - self._n_objectives = n_objectives - self._k = k - - n = self._n_arguments - M = self._n_objectives - - S = 2 * (np.arange(M) + 1) - A = np.ones(M - 1) - upper_bounds = 2 * (np.arange(n) + 1) - - self.domain = np.zeros((n, 2)) - self.domain[:, 1] = upper_bounds - - shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] - - def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: - return y[i:n] - - t_1 = [ - transformation_functions.ParameterDependentBiasTransformation( - np.ones(n - i), - lambda y: _input_converter0(i, y), - 0.98 / 49.98, - 0.02, - 50, - i, - ) - for i in range(n - 1) - ] - t_1.append(lambda y: y) - - t_2 = [ - transformation_functions.DeceptiveShiftTransformation(0.35, 0.001, 0.05) - for _ in range(k) - ] - for _ in range(n - k): - t_2.append(transformation_functions.MultiModalShiftTransformation(30, 95, 0.35)) - - def _input_converter(i: int, y: np.ndarray) -> np.ndarray: - indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) - return y[indices] - - t_3 = [] - for i in range(M - 1): - t_3.append( - transformation_functions.NonSeparableReductionTransformation( - k // (M - 1), lambda y: _input_converter(i, y) - ) - ) - t_3.append( - transformation_functions.NonSeparableReductionTransformation( - n - k, - lambda y: y[k:n], - ) - ) - - transformations = [t_1, t_2, t_3] - - self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) - - def __call__(self, z: np.ndarray) -> np.ndarray: - return self.wfg.__call__(z) diff --git a/benchmarks/problems/wfg/__init__.py b/benchmarks/problems/wfg/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/benchmarks/problems/WFGtestSuite/shape_functions.py b/benchmarks/problems/wfg/func/shape_functions.py similarity index 100% rename from benchmarks/problems/WFGtestSuite/shape_functions.py rename to benchmarks/problems/wfg/func/shape_functions.py diff --git a/benchmarks/problems/WFGtestSuite/transformation_functions.py b/benchmarks/problems/wfg/func/transformation_functions.py similarity index 100% rename from benchmarks/problems/WFGtestSuite/transformation_functions.py rename to benchmarks/problems/wfg/func/transformation_functions.py diff --git a/benchmarks/problems/wfg/shape_functions.py b/benchmarks/problems/wfg/shape_functions.py deleted file mode 100644 index 9ad3112f90..0000000000 --- a/benchmarks/problems/wfg/shape_functions.py +++ /dev/null @@ -1,104 +0,0 @@ -import abc - -import numpy as np - - -class BaseShapeFunction(object, metaclass=abc.ABCMeta): - def __init__(self, n_objectives: int) -> None: - - self._n_objectives = n_objectives - - def __call__(self, m: int, x: np.ndarray) -> float: - assert 1 <= m <= self.n_objectives - assert x.shape == (self.n_objectives - 1,) - return self._call(m, x) - - @abc.abstractmethod - def _call(self, m: int, x: np.ndarray) -> float: - raise NotImplementedError - - @property - def n_objectives(self) -> int: - - return self._n_objectives - - -class LinearShapeFunction(BaseShapeFunction): - def _call(self, m: int, x: np.ndarray) -> float: - - if m == 1: - return x[:-1].prod() - - if m == self.n_objectives: - return 1 - x[0] - - return x[: self.n_objectives - m].prod() * (1.0 - x[self.n_objectives - m]) - - -class ConvexShapeFunction(BaseShapeFunction): - def _call(self, m: int, x: np.ndarray) -> float: - - if m == 1: - return ( - 1 - - np.cos( - x * np.pi / 2, - ) - )[:-1].prod() - - if m == self.n_objectives: - return 1 - np.sin(x[0] * np.pi / 2.0) - - return (1.0 - np.cos(x * np.pi / 2.0))[: self.n_objectives - m].prod() * ( - 1.0 - np.sin(x[self.n_objectives - m] * np.pi / 2.0) - ) - - -class ConcaveShapeFunction(BaseShapeFunction): - def _call(self, m: int, x: np.ndarray) -> float: - - if m == 1: - return np.sin(x * np.pi / 2.0)[:-1].prod() - - if m == self.n_objectives: - return np.cos(x[0] * np.pi / 2.0) - - return np.sin(x * np.pi / 2.0)[: self.n_objectives - m].prod() * np.cos( - x[self.n_objectives - m] * np.pi / 2.0 - ) - - -class MixedConvexOrConcaveShapeFunction(BaseShapeFunction): - def __init__(self, n_objectives, alpha: float, n_segments: int) -> None: - super().__init__(n_objectives) - self._alpha = alpha - self._n_segments = n_segments - - def _call(self, m: int, x: np.ndarray) -> float: - if m == self.n_objectives: - two_A_pi = 2 * self._n_segments * np.pi - return np.power( - 1 - x[0] - np.cos(two_A_pi * x[0] + np.pi / 2.0) / two_A_pi, self._alpha - ) - - raise ValueError("m should be the number of objectives") - - -class DisconnectedShapeFunction(BaseShapeFunction): - def __init__( - self, n_objectives, alpha: float, beta: float, n_disconnected_regions: int - ) -> None: - super().__init__(n_objectives) - self._alpha = alpha - self._beta = beta - self._n_disconnected_regions = n_disconnected_regions - - def _call(self, m: int, x: np.ndarray) -> float: - if m == self.n_objectives: - return ( - 1 - - np.power(x[0], self._alpha) - * np.cos(self._n_disconnected_regions * np.power(x[0], self._beta) * np.pi) ** 2 - ) - - raise ValueError("m should be the number of objectives") diff --git a/benchmarks/problems/wfg/transformation_functions.py b/benchmarks/problems/wfg/transformation_functions.py deleted file mode 100644 index 882bc83904..0000000000 --- a/benchmarks/problems/wfg/transformation_functions.py +++ /dev/null @@ -1,197 +0,0 @@ -import abc -from typing import Callable - -import numpy as np - - -class BaseTransformations(object, metaclass=abc.ABCMeta): - @abc.abstractmethod - def __call__(self, *args, **kwargs): - - raise NotImplementedError - - -class BaseBiasTransformation(BaseTransformations, metaclass=abc.ABCMeta): - @abc.abstractmethod - def __call__(self, y: np.ndarray) -> float: - - raise NotImplementedError - - -class BaseShiftTransformation(BaseTransformations, metaclass=abc.ABCMeta): - @abc.abstractmethod - def __call__(self, y: float) -> float: - - raise NotImplementedError - - -class BaseReductionTransformation(BaseTransformations, metaclass=abc.ABCMeta): - @abc.abstractmethod - def __call__(self, y: np.ndarray) -> float: - - raise NotImplementedError - - -class PolynomialBiasTransformation(BaseBiasTransformation): - def __init__(self, alpha: float) -> None: - - assert alpha > 0 and alpha != 1.0 - self._alpha = alpha - - def __call__(self, y: float) -> float: - - return np.power(y, self._alpha) - - -class FlatRegionBiasTransformation(BaseBiasTransformation): - def __init__(self, a: float, b: float, c: float) -> None: - - assert 0 <= a <= 1 - assert 0 <= b <= 1 - assert 0 <= c <= 1 - assert b < c - assert not (b == 0) or (a == 0 and c != 1) - assert not (c == 1) or (a == 1 and b != 0) - - self._a = a - self._b = b - self._c = c - - def __call__(self, y: float) -> float: - - a = self._a - b = self._b - c = self._c - return ( - a - + min(0, np.floor(y - b)) * a * (b - y) / b - - min(0, np.floor(c - y)) * (1.0 - a) * (y - c) / (1.0 - c) - ) - - -class ParameterDependentBiasTransformation(BaseReductionTransformation): - def __init__( - self, - w: np.ndarray, - input_converter: Callable[[np.ndarray], np.ndarray], - a: float, - b: float, - c: float, - i: int, - ) -> None: - - assert 0 < a < 1 - assert 0 < b < c - - self._w = w - self._input_converter = input_converter - self._a = a - self._b = b - self._c = c - self._i = i - - def __call__(self, y: np.ndarray) -> float: - - w = self._w - a = self._a - b = self._b - c = self._c - i = self._i - - u = (self._input_converter(y) * w).sum() / w.sum() - v = a - (1.0 - 2 * u) * np.fabs(np.floor(0.5 - u) + a) - return np.power(y[i], b + (c - b) * v) - - -class LinearShiftTransformation(BaseShiftTransformation): - def __init__(self, a: float) -> None: - - assert 0 < a < 1 - - self._a = a - - def __call__(self, y: float) -> float: - - return np.fabs(y - self._a) / np.fabs(np.floor(self._a - y) + self._a) - - -class DeceptiveShiftTransformation(BaseShiftTransformation): - def __init__(self, a: float, b: float, c: float) -> None: - - assert 0 < a < 1 - assert 0 < b < 1 - assert 0 < c < 1 - assert a - b > 0 - assert a + b < 1 - - self._a = a - self._b = b - self._c = c - - def __call__(self, y: float) -> float: - - a = self._a - b = self._b - c = self._c - - q1 = np.floor(y - a + b) * (1.0 - c + (a - b) / b) - q2 = np.floor(a + b - y) * (1.0 - c + (1.0 - a - b) / b) - return 1.0 + (np.fabs(y - a) - b) * (q1 / (a - b) + q2 / (1.0 - a - b) + 1.0 / b) - - -class MultiModalShiftTransformation(BaseShiftTransformation): - def __init__(self, a: int, b: float, c: float) -> None: - - assert a > 0 - assert b >= 0 - assert (4 * a + 2) * np.pi >= 4 * b - assert 0 < c < 1 - - self._a = a - self._b = b - self._c = c - - def __call__(self, y: float) -> float: - - a = self._a - b = self._b - c = self._c - - q1 = np.fabs(y - c) / (2 * (np.floor(c - y) + c)) - q2 = (4 * a + 2) * np.pi * (0.5 - q1) - return (1.0 + np.cos(q2) + 4 * b * (q1**2)) / (b + 2) - - -class WeightedSumReductionTransformation(BaseReductionTransformation): - def __init__(self, w: np.ndarray, input_converter: Callable[[np.ndarray], np.ndarray]) -> None: - - assert all(w > 0) - - self._w = w - self._input_converter = input_converter - - def __call__(self, y: np.ndarray) -> float: - - y = self._input_converter(y) - return (y * self._w).sum() / self._w.sum() - - -class NonSeparableReductionTransformation(BaseReductionTransformation): - def __init__(self, a: int, input_converter: Callable[[np.ndarray], np.ndarray]) -> None: - - assert a > 0 - - self._a = a - self._input_converter = input_converter - - def __call__(self, y: np.ndarray) -> float: - - a = float(self._a) - y = self._input_converter(y) - n = y.shape[0] - indices = [(j + k + 1) % n for k in np.arange(n) for j in np.arange(n)] - - q = y.sum() + np.fabs(y[indices].reshape((n, n)) - y)[:, 0 : int(a) - 1].sum() - r = n * np.ceil(a / 2) * (1.0 + 2 * a - 2 * np.ceil(a / 2)) / a - - return q / r diff --git a/benchmarks/problems/wfg/wfg.py b/benchmarks/problems/wfg/wfg.py index 3393c37646..b2dd50f14f 100644 --- a/benchmarks/problems/wfg/wfg.py +++ b/benchmarks/problems/wfg/wfg.py @@ -1,9 +1,13 @@ from typing import List import numpy as np +import math +import sys -from . import shape_functions -from . import transformation_functions +from kurobako import problem + +from func import shape_functions +from func import transformation_functions class BaseWFG(object): @@ -704,3 +708,83 @@ def _input_converter(i: int, y: np.ndarray) -> np.ndarray: def __call__(self, z: np.ndarray) -> np.ndarray: return self.wfg.__call__(z) + + +class WFGProblemFactory(problem.ProblemFactory): + def specification(self): + self._n_wfg = int(sys.argv[1]) + self._n_dim = int(sys.argv[2]) + + self._low = 0 + self._high = 2 + params = [ + problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) + for i in range(self._n_dim) + ] + return problem.ProblemSpec( + name=f"WFG{self._n_wfg}", + params=params, + values=[problem.Var("f1"), problem.Var("f2")], + ) + + def create_problem(self, seed): + return WFGProblem() + + +class WFGProblem(problem.Problem): + def __init__(self) -> None: + super().__init__() + + def create_evaluator(self, params): + return WFGEvaluator(params) + + +class WFGEvaluator(problem.Evaluator): + def __init__(self, params): + self._n_wfg = int(sys.argv[1]) + self._n_dim = int(sys.argv[2]) + self._n_obj = int(sys.argv[3]) + self._k = int(sys.argv[4]) + + self._x = params + self._current_step = 0 + + if self._n_wfg == 1: + self.wfg = WFG1(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + elif self._n_wfg == 2: + self.wfg = WFG2(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + elif self._n_wfg == 3: + self.wfg = WFG3(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + elif self._n_wfg == 4: + self.wfg = WFG4(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + elif self._n_wfg == 5: + self.wfg = WFG5(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + elif self._n_wfg == 6: + self.wfg = WFG6(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + elif self._n_wfg == 7: + self.wfg = WFG7(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + elif self._n_wfg == 8: + self.wfg = WFG8(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + elif self._n_wfg == 9: + self.wfg = WFG9(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) + else: + assert False, "Invalid specification for WFG number." + + def current_step(self): + return self._current_step + + def evaluate(self, next_step): + self._current_step = 1 + v = self.wfg(self._x) + v = v.tolist() + + if math.isnan(v[0]) or math.isinf(v[0]): + raise ValueError + if math.isnan(v[1]) or math.isinf(v[1]): + raise ValueError + return v + + +if __name__ == "__main__": + runner = problem.ProblemRunner(WFGProblemFactory()) + runner.run() diff --git a/benchmarks/problems/wfg_problem.py b/benchmarks/problems/wfg_problem.py deleted file mode 100644 index 49bd91e219..0000000000 --- a/benchmarks/problems/wfg_problem.py +++ /dev/null @@ -1,86 +0,0 @@ -import math -import sys - -from kurobako import problem - -from WFGtestSuite import wfg - - -class WFGProblemFactory(problem.ProblemFactory): - def specification(self): - self._n_wfg = int(sys.argv[1]) - self._n_dim = int(sys.argv[2]) - - self._low = 0 - self._high = 2 - params = [ - problem.Var(f"x{i}", problem.ContinuousRange(0, self._high * i)) - for i in range(self._n_dim) - ] - return problem.ProblemSpec( - name=f"WFG{self._n_wfg}", - params=params, - values=[problem.Var("f1"), problem.Var("f2")], - ) - - def create_problem(self, seed): - return WFGProblem() - - -class WFGProblem(problem.Problem): - def __init__(self) -> None: - super().__init__() - - def create_evaluator(self, params): - return WFGEvaluator(params) - - -class WFGEvaluator(problem.Evaluator): - def __init__(self, params): - self._n_wfg = int(sys.argv[1]) - self._n_dim = int(sys.argv[2]) - self._n_obj = int(sys.argv[3]) - self._k = int(sys.argv[4]) - - self._x = params - self._current_step = 0 - - if self._n_wfg == 1: - self.wfg = wfg.WFG1(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) - elif self._n_wfg == 2: - self.wfg = wfg.WFG2(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) - elif self._n_wfg == 3: - self.wfg = wfg.WFG3(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) - elif self._n_wfg == 4: - self.wfg = wfg.WFG4(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) - elif self._n_wfg == 5: - self.wfg = wfg.WFG5(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) - elif self._n_wfg == 6: - self.wfg = wfg.WFG6(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) - elif self._n_wfg == 7: - self.wfg = wfg.WFG7(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) - elif self._n_wfg == 8: - self.wfg = wfg.WFG8(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) - elif self._n_wfg == 9: - self.wfg = wfg.WFG9(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) - else: - assert False, "Invalid specification for WFG number." - - def current_step(self): - return self._current_step - - def evaluate(self, next_step): - self._current_step = 1 - v = self.wfg(self._x) - v = v.tolist() - - if math.isnan(v[0]) or math.isinf(v[0]): - raise ValueError - if math.isnan(v[1]) or math.isinf(v[1]): - raise ValueError - return v - - -if __name__ == "__main__": - runner = problem.ProblemRunner(WFGProblemFactory()) - runner.run() diff --git a/benchmarks/run_mo_kurobako.py b/benchmarks/run_mo_kurobako.py index c997a2792a..ca10029f47 100644 --- a/benchmarks/run_mo_kurobako.py +++ b/benchmarks/run_mo_kurobako.py @@ -43,7 +43,7 @@ def run(args: argparse.Namespace) -> None: k = 2 n_objective = 2 - python_command = f"benchmarks/problems/wfg_problem.py \ + python_command = f"benchmarks/problems/wfg/wfg.py \ {n_wfg} {n_dim} {n_objective} {k}" cmd = ( f"{kurobako_cmd} problem command python {python_command}" From 5e6cf7e0b00c530999732332989b325843dd6ea7 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Tue, 29 Mar 2022 18:34:01 +0900 Subject: [PATCH 18/26] reorganized wfg dir --- benchmarks/__init__.py | 0 benchmarks/problems/wfg/{wfg.py => problem.py} | 4 ++-- benchmarks/problems/wfg/{func => }/shape_functions.py | 0 .../problems/wfg/{func => }/transformation_functions.py | 0 benchmarks/run_mo_kurobako.py | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 benchmarks/__init__.py rename benchmarks/problems/wfg/{wfg.py => problem.py} (99%) rename benchmarks/problems/wfg/{func => }/shape_functions.py (100%) rename benchmarks/problems/wfg/{func => }/transformation_functions.py (100%) diff --git a/benchmarks/__init__.py b/benchmarks/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/benchmarks/problems/wfg/wfg.py b/benchmarks/problems/wfg/problem.py similarity index 99% rename from benchmarks/problems/wfg/wfg.py rename to benchmarks/problems/wfg/problem.py index b2dd50f14f..4d984e9f95 100644 --- a/benchmarks/problems/wfg/wfg.py +++ b/benchmarks/problems/wfg/problem.py @@ -6,8 +6,8 @@ from kurobako import problem -from func import shape_functions -from func import transformation_functions +import shape_functions +import transformation_functions class BaseWFG(object): diff --git a/benchmarks/problems/wfg/func/shape_functions.py b/benchmarks/problems/wfg/shape_functions.py similarity index 100% rename from benchmarks/problems/wfg/func/shape_functions.py rename to benchmarks/problems/wfg/shape_functions.py diff --git a/benchmarks/problems/wfg/func/transformation_functions.py b/benchmarks/problems/wfg/transformation_functions.py similarity index 100% rename from benchmarks/problems/wfg/func/transformation_functions.py rename to benchmarks/problems/wfg/transformation_functions.py diff --git a/benchmarks/run_mo_kurobako.py b/benchmarks/run_mo_kurobako.py index ca10029f47..08ca266bd6 100644 --- a/benchmarks/run_mo_kurobako.py +++ b/benchmarks/run_mo_kurobako.py @@ -43,7 +43,7 @@ def run(args: argparse.Namespace) -> None: k = 2 n_objective = 2 - python_command = f"benchmarks/problems/wfg/wfg.py \ + python_command = f"benchmarks/problems/wfg/problem.py \ {n_wfg} {n_dim} {n_objective} {k}" cmd = ( f"{kurobako_cmd} problem command python {python_command}" From 861002510ffc6c773a98736d601b532d3723e955 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Sun, 24 Apr 2022 15:54:48 +0900 Subject: [PATCH 19/26] add type annotations --- benchmarks/mo_runner.py | 4 +- benchmarks/problems/wfg/problem.py | 190 +++++++++++------- benchmarks/problems/wfg/shape_functions.py | 4 +- .../problems/wfg/transformation_functions.py | 35 +++- benchmarks/run_mo_kurobako.py | 3 + 5 files changed, 153 insertions(+), 83 deletions(-) diff --git a/benchmarks/mo_runner.py b/benchmarks/mo_runner.py index 5f727a2fcd..910e514bf4 100644 --- a/benchmarks/mo_runner.py +++ b/benchmarks/mo_runner.py @@ -1,9 +1,9 @@ import sys + from kurobako import solver from kurobako.solver.optuna import OptunaSolverFactory -import optuna -# import json +import optuna optuna.logging.disable_default_handler() diff --git a/benchmarks/problems/wfg/problem.py b/benchmarks/problems/wfg/problem.py index 4d984e9f95..be85e8eae2 100644 --- a/benchmarks/problems/wfg/problem.py +++ b/benchmarks/problems/wfg/problem.py @@ -1,11 +1,10 @@ -from typing import List - -import numpy as np import math import sys +from typing import List +from typing import Union from kurobako import problem - +import numpy as np import shape_functions import transformation_functions @@ -87,37 +86,47 @@ def __init__(self, n_arguments: int, n_objectives: int, k: int): self.domain = np.zeros((n, 2)) self.domain[:, 1] = upper_bounds + shapes: List[shape_functions.BaseShapeFunction] shapes = [shape_functions.ConvexShapeFunction(M) for _ in range(M - 1)] shapes.append(shape_functions.MixedConvexOrConcaveShapeFunction(M, 1, 5)) - t_1 = [lambda y: y for _ in range(k)] + transformations: List[List[transformation_functions.BaseTransformations]] + transformations = [[] for _ in range(4)] + + transformations[0] = [transformation_functions.IdenticalTransformation() for _ in range(k)] + # transformations[0] = [lambda y: y for _ in range(k)] for _ in range(n - k): - t_1.append(transformation_functions.LinearShiftTransformation(0.35)) + transformations[0].append(transformation_functions.LinearShiftTransformation(0.35)) + + # transformations[1] = [lambda y: y for _ in range(k)] - t_2 = [lambda y: y for _ in range(k)] + transformations[1] = [transformation_functions.IdenticalTransformation() for _ in range(k)] for _ in range(n - k): - t_2.append(transformation_functions.FlatRegionBiasTransformation(0.8, 0.75, 0.85)) + transformations[1].append( + transformation_functions.FlatRegionBiasTransformation(0.8, 0.75, 0.85) + ) - t_3 = [transformation_functions.PolynomialBiasTransformation(0.02) for _ in range(n)] + transformations[2] = [ + transformation_functions.PolynomialBiasTransformation(0.02) for _ in range(n) + ] def _input_converter(i: int, y: np.ndarray) -> np.ndarray: indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) return y[indices] - t_4 = [ + transformations[3] = [ transformation_functions.WeightedSumReductionTransformation( 2 * np.arange(i * k // (M - 1) + 1, (i + 1) * k // (M - 1) + 1), lambda y: _input_converter(i, y), ) for i in range(M - 1) ] - t_4.append( + transformations[3].append( transformation_functions.WeightedSumReductionTransformation( 2 * np.arange(k, n) + 1, lambda y: y[k:n], ) ) - transformations = [t_1, t_2, t_3, t_4] self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) @@ -157,20 +166,24 @@ def __init__(self, n_arguments: int, n_objectives: int, k: int): self.domain = np.zeros((n, 2)) self.domain[:, 1] = upper_bounds + shapes: List[shape_functions.BaseShapeFunction] shapes = [shape_functions.ConvexShapeFunction(M) for _ in range(M - 1)] shapes.append(shape_functions.DisconnectedShapeFunction(M, 1, 1, 5)) - t_1 = [lambda y: y for _ in range(k)] + transformations: List[List[transformation_functions.BaseTransformations]] + transformations = [[] for _ in range(3)] + + transformations[0] = [transformation_functions.IdenticalTransformation() for _ in range(k)] for _ in range(n - k): - t_1.append(transformation_functions.LinearShiftTransformation(0.35)) + transformations[0].append(transformation_functions.LinearShiftTransformation(0.35)) def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: indices = [k + 2 * (i + 1 - k) - 2, k + 2 * (i - k + 1) - 1] return y[indices] - t_2 = [lambda y: y for _ in range(k)] + transformations[1] = [transformation_functions.IdenticalTransformation() for _ in range(k)] for i in range(k, n // 2): - t_2.append( + transformations[1].append( transformation_functions.NonSeparableReductionTransformation( 2, lambda y: _input_converter0(i, y) ) @@ -180,21 +193,21 @@ def _input_converter1(i: int, y: np.ndarray) -> np.ndarray: indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) return y[indices] - t_3 = [ + transformations[2] = [ transformation_functions.WeightedSumReductionTransformation( np.ones(k // (M - 1)), lambda y: _input_converter1(i, y), ) for i in range(M - 1) ] - t_3.append( + transformations[2].append( transformation_functions.WeightedSumReductionTransformation( np.ones(n // 2 - k), lambda y: y[k : n // 2], ) ) - transformations = [t_1, t_2, t_3] + # transformations = [transformations[0], transformations[1], transformations[2]] self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) @@ -235,19 +248,23 @@ def __init__(self, n_arguments: int, n_objectives: int, k: int): self.domain = np.zeros((n, 2)) self.domain[:, 1] = upper_bounds + shapes: List[shape_functions.BaseShapeFunction] shapes = [shape_functions.LinearShapeFunction(M) for _ in range(M)] - t_1 = [lambda y: y for _ in range(k)] + transformations: List[List[transformation_functions.BaseTransformations]] + transformations = [[] for _ in range(3)] + + transformations[0] = [transformation_functions.IdenticalTransformation() for _ in range(k)] for _ in range(n - k): - t_1.append(transformation_functions.LinearShiftTransformation(0.35)) + transformations[0].append(transformation_functions.LinearShiftTransformation(0.35)) def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: indices = [k + 2 * (i + 1 - k) - 2, k + 2 * (i - k + 1) - 1] return y[indices] - t_2 = [lambda y: y for _ in range(k)] + transformations[1] = [transformation_functions.IdenticalTransformation() for _ in range(k)] for i in range(k, n // 2): - t_2.append( + transformations[1].append( transformation_functions.NonSeparableReductionTransformation( 2, lambda y: _input_converter0(i, y) ) @@ -257,21 +274,21 @@ def _input_converter1(i: int, y: np.ndarray) -> np.ndarray: indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) return y[indices] - t_3 = [ + transformations[2] = [ transformation_functions.WeightedSumReductionTransformation( np.ones(k // (M - 1)), lambda y: _input_converter1(i, y), ) for i in range(M - 1) ] - t_3.append( + transformations[2].append( transformation_functions.WeightedSumReductionTransformation( np.ones(n // 2 - k), lambda y: y[k : n // 2], ) ) - transformations = [t_1, t_2, t_3] + # transformations = [transformations[0], transformations[1], transformations[2]] self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) @@ -310,9 +327,13 @@ def __init__(self, n_arguments: int, n_objectives: int, k: int): self.domain = np.zeros((n, 2)) self.domain[:, 1] = upper_bounds + shapes: List[shape_functions.BaseShapeFunction] shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] - t_1 = [ + transformations: List[List[transformation_functions.BaseTransformations]] + transformations = [[] for _ in range(2)] + + transformations[0] = [ transformation_functions.MultiModalShiftTransformation(30, 10, 0.35) for _ in range(n) ] @@ -320,21 +341,21 @@ def _input_converter(i: int, y: np.ndarray) -> np.ndarray: indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) return y[indices] - t_2 = [] + # transformations[1] = [] for i in range(M - 1): - t_2.append( + transformations[1].append( transformation_functions.WeightedSumReductionTransformation( np.ones(k // (M - 1)), lambda y: _input_converter(i, y) ) ) - t_2.append( + transformations[1].append( transformation_functions.WeightedSumReductionTransformation( np.ones(n - k), lambda y: y[k:n], ) ) - transformations = [t_1, t_2] + # transformations = [transformations[0], transformations[1]] self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) @@ -373,9 +394,13 @@ def __init__(self, n_arguments: int, n_objectives: int, k: int): self.domain = np.zeros((n, 2)) self.domain[:, 1] = upper_bounds + shapes: List[shape_functions.BaseShapeFunction] shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] - t_1 = [ + transformations: List[List[transformation_functions.BaseTransformations]] + transformations = [[] for _ in range(2)] + + transformations[0] = [ transformation_functions.DeceptiveShiftTransformation(0.35, 0.001, 0.05) for _ in range(n) ] @@ -384,21 +409,21 @@ def _input_converter(i: int, y: np.ndarray) -> np.ndarray: indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) return y[indices] - t_2 = [] + transformations[1] = [] for i in range(M - 1): - t_2.append( + transformations[1].append( transformation_functions.WeightedSumReductionTransformation( np.ones(k // (M - 1)), lambda y: _input_converter(i, y) ) ) - t_2.append( + transformations[1].append( transformation_functions.WeightedSumReductionTransformation( np.ones(n - k), lambda y: y[k:n], ) ) - transformations = [t_1, t_2] + # transformations = [transformations[0], transformations[1]] self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) @@ -437,31 +462,35 @@ def __init__(self, n_arguments: int, n_objectives: int, k: int): self.domain = np.zeros((n, 2)) self.domain[:, 1] = upper_bounds + shapes: List[shape_functions.BaseShapeFunction] shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] - t_1 = [lambda y: y for _ in range(k)] + transformations: List[List[transformation_functions.BaseTransformations]] + transformations = [[] for _ in range(2)] + + transformations[0] = [transformation_functions.IdenticalTransformation() for _ in range(k)] for _ in range(n - k): - t_1.append(transformation_functions.LinearShiftTransformation(0.35)) + transformations[0].append(transformation_functions.LinearShiftTransformation(0.35)) def _input_converter(i: int, y: np.ndarray) -> np.ndarray: indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) return y[indices] - t_2 = [] + # transformations[1] = [] for i in range(M - 1): - t_2.append( + transformations[1].append( transformation_functions.NonSeparableReductionTransformation( k // (M - 1), lambda y: _input_converter(i, y) ) ) - t_2.append( + transformations[1].append( transformation_functions.NonSeparableReductionTransformation( n - k, lambda y: y[k:n], ) ) - transformations = [t_1, t_2] + # transformations = [transformations[0], transformations[1]] self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) @@ -500,12 +529,16 @@ def __init__(self, n_arguments: int, n_objectives: int, k: int): self.domain = np.zeros((n, 2)) self.domain[:, 1] = upper_bounds + shapes: List[shape_functions.BaseShapeFunction] shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: return y[i:n] - t_1 = [ + transformations: List[List[transformation_functions.BaseTransformations]] + transformations = [[] for _ in range(3)] + + transformations[0] = [ transformation_functions.ParameterDependentBiasTransformation( np.ones(n - i), lambda y: _input_converter0(i, y), @@ -517,31 +550,31 @@ def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: for i in range(k) ] for _ in range(n - k): - t_1.append(lambda y: y) + transformations[0].append(transformation_functions.IdenticalTransformation()) - t_2 = [lambda y: y for _ in range(k)] + transformations[1] = [transformation_functions.IdenticalTransformation() for _ in range(k)] for _ in range(n - k): - t_2.append(transformation_functions.LinearShiftTransformation(0.35)) + transformations[1].append(transformation_functions.LinearShiftTransformation(0.35)) def _input_converter1(i: int, y: np.ndarray) -> np.ndarray: indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) return y[indices] - t_3 = [] + transformations[2] = [] for i in range(M - 1): - t_3.append( + transformations[2].append( transformation_functions.WeightedSumReductionTransformation( np.ones(k // (M - 1)), lambda y: _input_converter1(i, y) ) ) - t_3.append( + transformations[2].append( transformation_functions.WeightedSumReductionTransformation( np.ones(n - k), lambda y: y[k:n], ) ) - transformations = [t_1, t_2, t_3] + # transformations = [transformations[0], transformations[1], transformations[2]] self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) @@ -580,14 +613,18 @@ def __init__(self, n_arguments: int, n_objectives: int, k: int): self.domain = np.zeros((n, 2)) self.domain[:, 1] = upper_bounds + shapes: List[shape_functions.BaseShapeFunction] shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: return y[: i - 1] - t_1 = [lambda y: y for _ in range(k)] + transformations: List[List[transformation_functions.BaseTransformations]] + transformations = [[] for _ in range(3)] + + transformations[0] = [transformation_functions.IdenticalTransformation() for _ in range(k)] for i in range(k, n): - t_1.append( + transformations[0].append( transformation_functions.ParameterDependentBiasTransformation( np.ones(i - 1), lambda y: _input_converter0(i, y), @@ -598,29 +635,29 @@ def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: ) ) - t_2 = [lambda y: y for _ in range(k)] + transformations[1] = [transformation_functions.IdenticalTransformation() for _ in range(k)] for _ in range(n - k): - t_2.append(transformation_functions.LinearShiftTransformation(0.35)) + transformations[1].append(transformation_functions.LinearShiftTransformation(0.35)) def _input_converter(i: int, y: np.ndarray) -> np.ndarray: indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) return y[indices] - t_3 = [] + transformations[2] = [] for i in range(M - 1): - t_3.append( + transformations[2].append( transformation_functions.WeightedSumReductionTransformation( np.ones(k // (M - 1)), lambda y: _input_converter(i, y) ) ) - t_3.append( + transformations[2].append( transformation_functions.WeightedSumReductionTransformation( np.ones(n - k), lambda y: y[k:n], ) ) - transformations = [t_1, t_2, t_3] + # transformations = [transformations[0], transformations[1], transformations[2]] self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) @@ -659,12 +696,16 @@ def __init__(self, n_arguments: int, n_objectives: int, k: int): self.domain = np.zeros((n, 2)) self.domain[:, 1] = upper_bounds + shapes: List[shape_functions.BaseShapeFunction] shapes = [shape_functions.ConcaveShapeFunction(M) for _ in range(M)] def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: return y[i:n] - t_1 = [ + transformations: List[List[transformation_functions.BaseTransformations]] + transformations = [[] for _ in range(3)] + + transformations[0] = [ transformation_functions.ParameterDependentBiasTransformation( np.ones(n - i), lambda y: _input_converter0(i, y), @@ -675,34 +716,36 @@ def _input_converter0(i: int, y: np.ndarray) -> np.ndarray: ) for i in range(n - 1) ] - t_1.append(lambda y: y) + transformations[0].append(transformation_functions.IdenticalTransformation()) - t_2 = [ + transformations[1] = [ transformation_functions.DeceptiveShiftTransformation(0.35, 0.001, 0.05) for _ in range(k) ] for _ in range(n - k): - t_2.append(transformation_functions.MultiModalShiftTransformation(30, 95, 0.35)) + transformations[1].append( + transformation_functions.MultiModalShiftTransformation(30, 95, 0.35) + ) def _input_converter(i: int, y: np.ndarray) -> np.ndarray: indices = np.arange(i * k // (M - 1), (i + 1) * k // (M - 1)) return y[indices] - t_3 = [] + transformations[2] = [] for i in range(M - 1): - t_3.append( + transformations[2].append( transformation_functions.NonSeparableReductionTransformation( k // (M - 1), lambda y: _input_converter(i, y) ) ) - t_3.append( + transformations[2].append( transformation_functions.NonSeparableReductionTransformation( n - k, lambda y: y[k:n], ) ) - transformations = [t_1, t_2, t_3] + # transformations = [transformations[0], transformations[1], transformations[2]] self.wfg = BaseWFG(S, A, upper_bounds, shapes, transformations) @@ -711,7 +754,7 @@ def __call__(self, z: np.ndarray) -> np.ndarray: class WFGProblemFactory(problem.ProblemFactory): - def specification(self): + def specification(self) -> problem.ProblemSpec: self._n_wfg = int(sys.argv[1]) self._n_dim = int(sys.argv[2]) @@ -727,7 +770,7 @@ def specification(self): values=[problem.Var("f1"), problem.Var("f2")], ) - def create_problem(self, seed): + def create_problem(self,seed:int) -> problem.Problem: return WFGProblem() @@ -735,20 +778,21 @@ class WFGProblem(problem.Problem): def __init__(self) -> None: super().__init__() - def create_evaluator(self, params): + def create_evaluator(self, params: List[problem.Var]) -> problem.Evaluator: return WFGEvaluator(params) class WFGEvaluator(problem.Evaluator): - def __init__(self, params): + def __init__(self, params: List[problem.Var]) -> None: self._n_wfg = int(sys.argv[1]) self._n_dim = int(sys.argv[2]) self._n_obj = int(sys.argv[3]) self._k = int(sys.argv[4]) - self._x = params + self._x = np.array(params) self._current_step = 0 + self.wfg: Union[WFG1, WFG2, WFG3, WFG4, WFG5, WFG6, WFG7, WFG8, WFG9] if self._n_wfg == 1: self.wfg = WFG1(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) elif self._n_wfg == 2: @@ -770,10 +814,10 @@ def __init__(self, params): else: assert False, "Invalid specification for WFG number." - def current_step(self): + def current_step(self) -> int: return self._current_step - def evaluate(self, next_step): + def evaluate(self, next_step: int) -> list: self._current_step = 1 v = self.wfg(self._x) v = v.tolist() diff --git a/benchmarks/problems/wfg/shape_functions.py b/benchmarks/problems/wfg/shape_functions.py index 9ad3112f90..79ef4d9790 100644 --- a/benchmarks/problems/wfg/shape_functions.py +++ b/benchmarks/problems/wfg/shape_functions.py @@ -69,7 +69,7 @@ def _call(self, m: int, x: np.ndarray) -> float: class MixedConvexOrConcaveShapeFunction(BaseShapeFunction): - def __init__(self, n_objectives, alpha: float, n_segments: int) -> None: + def __init__(self, n_objectives: int, alpha: float, n_segments: int) -> None: super().__init__(n_objectives) self._alpha = alpha self._n_segments = n_segments @@ -86,7 +86,7 @@ def _call(self, m: int, x: np.ndarray) -> float: class DisconnectedShapeFunction(BaseShapeFunction): def __init__( - self, n_objectives, alpha: float, beta: float, n_disconnected_regions: int + self, n_objectives: int, alpha: float, beta: float, n_disconnected_regions: int ) -> None: super().__init__(n_objectives) self._alpha = alpha diff --git a/benchmarks/problems/wfg/transformation_functions.py b/benchmarks/problems/wfg/transformation_functions.py index 882bc83904..7c79e2df92 100644 --- a/benchmarks/problems/wfg/transformation_functions.py +++ b/benchmarks/problems/wfg/transformation_functions.py @@ -1,37 +1,60 @@ import abc from typing import Callable +from typing import Union import numpy as np -class BaseTransformations(object, metaclass=abc.ABCMeta): - @abc.abstractmethod - def __call__(self, *args, **kwargs): +# class BaseTransformations(object, metaclass=abc.ABCMeta): +# @abc.abstractmethod +# def __call__(self, *args, **kwargs): + +# raise NotImplementedError + +class BaseIdenticalTransformations(metaclass=abc.ABCMeta): + @abc.abstractclassmethod + def __call__(self, y: np.ndarray) -> float: raise NotImplementedError -class BaseBiasTransformation(BaseTransformations, metaclass=abc.ABCMeta): +class BaseBiasTransformation(metaclass=abc.ABCMeta): @abc.abstractmethod def __call__(self, y: np.ndarray) -> float: raise NotImplementedError -class BaseShiftTransformation(BaseTransformations, metaclass=abc.ABCMeta): +class BaseShiftTransformation(metaclass=abc.ABCMeta): @abc.abstractmethod def __call__(self, y: float) -> float: raise NotImplementedError -class BaseReductionTransformation(BaseTransformations, metaclass=abc.ABCMeta): +class BaseReductionTransformation(metaclass=abc.ABCMeta): @abc.abstractmethod def __call__(self, y: np.ndarray) -> float: raise NotImplementedError +BaseTransformations = Union[ + BaseIdenticalTransformations, + BaseBiasTransformation, + BaseShiftTransformation, + BaseReductionTransformation, +] + + +class IdenticalTransformation(BaseIdenticalTransformations): + def __init__(self) -> None: + pass + + def __call__(self, y: float) -> float: + return y + + class PolynomialBiasTransformation(BaseBiasTransformation): def __init__(self, alpha: float) -> None: diff --git a/benchmarks/run_mo_kurobako.py b/benchmarks/run_mo_kurobako.py index 08ca266bd6..898efa6266 100644 --- a/benchmarks/run_mo_kurobako.py +++ b/benchmarks/run_mo_kurobako.py @@ -1,6 +1,8 @@ import argparse import os import subprocess +from typing import Dict +from typing import Union def run(args: argparse.Namespace) -> None: @@ -100,6 +102,7 @@ def run(args: argparse.Namespace) -> None: subprocess.run(cmd, shell=True) # Plot pareto-front. + plot_args: Dict[str, Dict[str, Union[int, float]]] plot_args = { "NASBench": {"xmin": 0, "xmax": 25000000, "ymin": 0, "ymax": 0.2}, "ZDT1": {"xmin": 0, "xmax": 1, "ymin": 1, "ymax": 7}, From 9e4833e5c4b0288cc2bfb26cb3f9288f6964c8ec Mon Sep 17 00:00:00 2001 From: kei-mo Date: Sun, 24 Apr 2022 15:59:25 +0900 Subject: [PATCH 20/26] fixed code to match black format --- benchmarks/problems/wfg/problem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/problems/wfg/problem.py b/benchmarks/problems/wfg/problem.py index be85e8eae2..9e596b1d92 100644 --- a/benchmarks/problems/wfg/problem.py +++ b/benchmarks/problems/wfg/problem.py @@ -770,7 +770,7 @@ def specification(self) -> problem.ProblemSpec: values=[problem.Var("f1"), problem.Var("f2")], ) - def create_problem(self,seed:int) -> problem.Problem: + def create_problem(self, seed: int) -> problem.Problem: return WFGProblem() From bffde92834de252be3205c890de7b1c94595b64b Mon Sep 17 00:00:00 2001 From: kei-mo Date: Sun, 24 Apr 2022 16:09:34 +0900 Subject: [PATCH 21/26] fixed code to match mypy format --- benchmarks/problems/wfg/problem.py | 4 ++-- benchmarks/problems/wfg/transformation_functions.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/benchmarks/problems/wfg/problem.py b/benchmarks/problems/wfg/problem.py index 9e596b1d92..51ac0f76ca 100644 --- a/benchmarks/problems/wfg/problem.py +++ b/benchmarks/problems/wfg/problem.py @@ -817,7 +817,7 @@ def __init__(self, params: List[problem.Var]) -> None: def current_step(self) -> int: return self._current_step - def evaluate(self, next_step: int) -> list: + def evaluate(self, next_step: int) -> List[float]: self._current_step = 1 v = self.wfg(self._x) v = v.tolist() @@ -826,7 +826,7 @@ def evaluate(self, next_step: int) -> list: raise ValueError if math.isnan(v[1]) or math.isinf(v[1]): raise ValueError - return v + return [v[0],v[1]] if __name__ == "__main__": diff --git a/benchmarks/problems/wfg/transformation_functions.py b/benchmarks/problems/wfg/transformation_functions.py index 7c79e2df92..cfb9eed626 100644 --- a/benchmarks/problems/wfg/transformation_functions.py +++ b/benchmarks/problems/wfg/transformation_functions.py @@ -14,13 +14,13 @@ class BaseIdenticalTransformations(metaclass=abc.ABCMeta): @abc.abstractclassmethod - def __call__(self, y: np.ndarray) -> float: + def __call__(self, y: float) -> float: raise NotImplementedError class BaseBiasTransformation(metaclass=abc.ABCMeta): @abc.abstractmethod - def __call__(self, y: np.ndarray) -> float: + def __call__(self, y: float) -> float: raise NotImplementedError From 135851a0ef83772e0e63396919c8593fa71c9f60 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Sun, 24 Apr 2022 16:15:50 +0900 Subject: [PATCH 22/26] fixed code to match black format --- benchmarks/problems/wfg/problem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/problems/wfg/problem.py b/benchmarks/problems/wfg/problem.py index 51ac0f76ca..7d525b3d1e 100644 --- a/benchmarks/problems/wfg/problem.py +++ b/benchmarks/problems/wfg/problem.py @@ -826,7 +826,7 @@ def evaluate(self, next_step: int) -> List[float]: raise ValueError if math.isnan(v[1]) or math.isinf(v[1]): raise ValueError - return [v[0],v[1]] + return [v[0], v[1]] if __name__ == "__main__": From 24f56627e172e4d53325e3543e7e340e604f6588 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Sun, 24 Apr 2022 20:42:15 +0900 Subject: [PATCH 23/26] fixed code to match black format --- benchmarks/run_mo_kurobako.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/run_mo_kurobako.py b/benchmarks/run_mo_kurobako.py index a9c267daa1..6352047d53 100644 --- a/benchmarks/run_mo_kurobako.py +++ b/benchmarks/run_mo_kurobako.py @@ -16,7 +16,7 @@ def run(args: argparse.Namespace) -> None: study_json_filename = os.path.join(args.out_dir, "studies.json") solvers_filename = os.path.join(args.out_dir, "solvers.json") problems_filename = os.path.join(args.out_dir, "problems.json") - + # Ensure all files are empty. for filename in [study_json_filename, solvers_filename, problems_filename]: with open(filename, "w"): From 2857a8337031d848884b2ee40e82382e1b5c0d2a Mon Sep 17 00:00:00 2001 From: kei-mo Date: Thu, 26 May 2022 17:37:10 +0900 Subject: [PATCH 24/26] merged master --- benchmarks/__init__.py | 0 .../{ => kurobako}/problems/wfg/problem.py | 5 ++-- .../problems/wfg/shape_functions.py | 0 .../problems/wfg/transformation_functions.py | 2 +- benchmarks/run_mo_kurobako.py | 30 ++++++++----------- 5 files changed, 17 insertions(+), 20 deletions(-) create mode 100644 benchmarks/__init__.py rename benchmarks/{ => kurobako}/problems/wfg/problem.py (99%) rename benchmarks/{ => kurobako}/problems/wfg/shape_functions.py (100%) rename benchmarks/{ => kurobako}/problems/wfg/transformation_functions.py (98%) diff --git a/benchmarks/__init__.py b/benchmarks/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/benchmarks/problems/wfg/problem.py b/benchmarks/kurobako/problems/wfg/problem.py similarity index 99% rename from benchmarks/problems/wfg/problem.py rename to benchmarks/kurobako/problems/wfg/problem.py index 7d525b3d1e..208d5db3fa 100644 --- a/benchmarks/problems/wfg/problem.py +++ b/benchmarks/kurobako/problems/wfg/problem.py @@ -3,11 +3,12 @@ from typing import List from typing import Union -from kurobako import problem import numpy as np import shape_functions import transformation_functions +from kurobako import problem + class BaseWFG(object): def __init__( @@ -812,7 +813,7 @@ def __init__(self, params: List[problem.Var]) -> None: elif self._n_wfg == 9: self.wfg = WFG9(n_arguments=self._n_dim, n_objectives=self._n_obj, k=self._k) else: - assert False, "Invalid specification for WFG number." + raise AssertionError("Invalid specification for WFG number.") def current_step(self) -> int: return self._current_step diff --git a/benchmarks/problems/wfg/shape_functions.py b/benchmarks/kurobako/problems/wfg/shape_functions.py similarity index 100% rename from benchmarks/problems/wfg/shape_functions.py rename to benchmarks/kurobako/problems/wfg/shape_functions.py diff --git a/benchmarks/problems/wfg/transformation_functions.py b/benchmarks/kurobako/problems/wfg/transformation_functions.py similarity index 98% rename from benchmarks/problems/wfg/transformation_functions.py rename to benchmarks/kurobako/problems/wfg/transformation_functions.py index cfb9eed626..08704642e4 100644 --- a/benchmarks/problems/wfg/transformation_functions.py +++ b/benchmarks/kurobako/problems/wfg/transformation_functions.py @@ -182,7 +182,7 @@ def __call__(self, y: float) -> float: q1 = np.fabs(y - c) / (2 * (np.floor(c - y) + c)) q2 = (4 * a + 2) * np.pi * (0.5 - q1) - return (1.0 + np.cos(q2) + 4 * b * (q1**2)) / (b + 2) + return (1.0 + np.cos(q2) + 4 * b * (q1 ** 2)) / (b + 2) class WeightedSumReductionTransformation(BaseReductionTransformation): diff --git a/benchmarks/run_mo_kurobako.py b/benchmarks/run_mo_kurobako.py index 8c63933f53..d7a8122206 100644 --- a/benchmarks/run_mo_kurobako.py +++ b/benchmarks/run_mo_kurobako.py @@ -22,16 +22,16 @@ def run(args: argparse.Namespace) -> None: with open(filename, "w"): pass - # # Create ZDT problems - # cmd = f"{kurobako_cmd} problem-suite zdt | tee -a {problems_filename}" - # subprocess.run(cmd, shell=True) + # Create ZDT problems + cmd = f"{kurobako_cmd} problem-suite zdt | tee -a {problems_filename}" + subprocess.run(cmd, shell=True) # Create WFG 1~9 problem for n_wfg in range(1, 10): if n_wfg == 8: n_dim = 3 k = 2 - elif n_wfg in (7, 8, 9): + elif n_wfg in (7, 9): n_dim = 2 k = 1 else: @@ -39,7 +39,7 @@ def run(args: argparse.Namespace) -> None: k = 2 n_objective = 2 - python_command = f"benchmarks/problems/wfg/problem.py \ + python_command = f"benchmarks/kurobako/problems/wfg/problem.py \ {n_wfg} {n_dim} {n_objective} {k}" cmd = ( f"{kurobako_cmd} problem command python {python_command}" @@ -47,13 +47,13 @@ def run(args: argparse.Namespace) -> None: ) subprocess.run(cmd, shell=True) - # # Create NAS bench problem(A) (for Multi-Objective Settings). - # dataset = os.path.join(args.data_dir, "nasbench_full.bin") - # cmd = ( - # f'{kurobako_cmd} problem nasbench "{dataset}" ' - # f"--metrics params accuracy | tee -a {problems_filename}" - # ) - # subprocess.run(cmd, shell=True) + # Create NAS bench problem(A) (for Multi-Objective Settings). + dataset = os.path.join(args.data_dir, "nasbench_full.bin") + cmd = ( + f'{kurobako_cmd} problem nasbench "{dataset}" ' + f"--metrics params accuracy | tee -a {problems_filename}" + ) + subprocess.run(cmd, shell=True) # Create solvers. sampler_list = args.sampler_list.split() @@ -105,7 +105,6 @@ def run(args: argparse.Namespace) -> None: "ZDT4": {"xmin": 0, "xmax": 1, "ymin": 20, "ymax": 250}, "ZDT5": {"xmin": 8, "xmax": 24, "ymin": 1, "ymax": 6}, "ZDT6": {"xmin": 0.2, "xmax": 1, "ymin": 5, "ymax": 10}, - "BinhKorn": {"xmin": 0, "xmax": 150, "ymin": 0, "ymax": 50}, "WFG1": {"xmin": 2.7, "xmax": 3.05, "ymin": 4.7, "ymax": 5.05}, "WFG2": {"xmin": 2.0, "xmax": 2.8, "ymin": 3.0, "ymax": 4.8}, "WFG3": {"xmin": 2.0, "xmax": 2.8, "ymin": 3.0, "ymax": 4.8}, @@ -118,10 +117,7 @@ def run(args: argparse.Namespace) -> None: } for problem_name, plot_arg in plot_args.items(): - xmin, xmax = ( - plot_arg["xmin"], - plot_arg["xmax"], - ) + xmin, xmax = plot_arg["xmin"], plot_arg["xmax"] ymin, ymax = plot_arg["ymin"], plot_arg["ymax"] cmd = ( f"cat {result_filename} | grep {problem_name} | " From 6b06b05541e281855d5badf7ea314a8df6d5fc22 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Thu, 26 May 2022 17:46:36 +0900 Subject: [PATCH 25/26] reformat --- benchmarks/kurobako/problems/wfg/transformation_functions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/benchmarks/kurobako/problems/wfg/transformation_functions.py b/benchmarks/kurobako/problems/wfg/transformation_functions.py index 08704642e4..cfb9eed626 100644 --- a/benchmarks/kurobako/problems/wfg/transformation_functions.py +++ b/benchmarks/kurobako/problems/wfg/transformation_functions.py @@ -182,7 +182,7 @@ def __call__(self, y: float) -> float: q1 = np.fabs(y - c) / (2 * (np.floor(c - y) + c)) q2 = (4 * a + 2) * np.pi * (0.5 - q1) - return (1.0 + np.cos(q2) + 4 * b * (q1 ** 2)) / (b + 2) + return (1.0 + np.cos(q2) + 4 * b * (q1**2)) / (b + 2) class WeightedSumReductionTransformation(BaseReductionTransformation): From b0ff609bde1deff1fef4b6146c8c50aeb6b6ba58 Mon Sep 17 00:00:00 2001 From: kei-mo Date: Thu, 26 May 2022 18:00:02 +0900 Subject: [PATCH 26/26] fixed mypy --- benchmarks/kurobako/__init__.py | 0 .../problems/wfg/transformation_functions.py | 15 ++++----------- benchmarks/naslib/__init__.py | 0 3 files changed, 4 insertions(+), 11 deletions(-) create mode 100644 benchmarks/kurobako/__init__.py create mode 100644 benchmarks/naslib/__init__.py diff --git a/benchmarks/kurobako/__init__.py b/benchmarks/kurobako/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/benchmarks/kurobako/problems/wfg/transformation_functions.py b/benchmarks/kurobako/problems/wfg/transformation_functions.py index cfb9eed626..88cd3c8e60 100644 --- a/benchmarks/kurobako/problems/wfg/transformation_functions.py +++ b/benchmarks/kurobako/problems/wfg/transformation_functions.py @@ -5,15 +5,8 @@ import numpy as np -# class BaseTransformations(object, metaclass=abc.ABCMeta): -# @abc.abstractmethod -# def __call__(self, *args, **kwargs): - -# raise NotImplementedError - - -class BaseIdenticalTransformations(metaclass=abc.ABCMeta): - @abc.abstractclassmethod +class BaseIdenticalTransformation(metaclass=abc.ABCMeta): + @abc.abstractmethod def __call__(self, y: float) -> float: raise NotImplementedError @@ -40,14 +33,14 @@ def __call__(self, y: np.ndarray) -> float: BaseTransformations = Union[ - BaseIdenticalTransformations, + BaseIdenticalTransformation, BaseBiasTransformation, BaseShiftTransformation, BaseReductionTransformation, ] -class IdenticalTransformation(BaseIdenticalTransformations): +class IdenticalTransformation(BaseIdenticalTransformation): def __init__(self) -> None: pass diff --git a/benchmarks/naslib/__init__.py b/benchmarks/naslib/__init__.py new file mode 100644 index 0000000000..e69de29bb2