From 9a91197034f8e238ac0ec06fb36dd938862e9037 Mon Sep 17 00:00:00 2001 From: XU-Boqing Date: Mon, 19 May 2025 17:14:18 +0800 Subject: [PATCH 1/3] reconstruct cec2022, fix and add funcs of basic.py --- src/evox/problems/numerical/basic.py | 48 +++++++++++++++- src/evox/problems/numerical/cec2022.py | 80 +++++++++----------------- unit_test/problems/test_cec2022.py | 3 +- 3 files changed, 76 insertions(+), 55 deletions(-) diff --git a/src/evox/problems/numerical/basic.py b/src/evox/problems/numerical/basic.py index 80a6320bc..5321a4817 100644 --- a/src/evox/problems/numerical/basic.py +++ b/src/evox/problems/numerical/basic.py @@ -7,6 +7,8 @@ "Schwefel", "Sphere", "Ellipsoid", + "Zakharov", + "Levy", "ackley_func", "griewank_func", "rastrigin_func", @@ -14,6 +16,8 @@ "schwefel_func", "sphere_func", "ellipsoid_func", + "zakharov_func", + "levy_func", ] @@ -86,7 +90,7 @@ def _true_evaluate(self, x: torch.Tensor) -> torch.Tensor: def griewank_func(x: torch.Tensor) -> torch.Tensor: - f = 1 / 4000 * torch.sum(x**2, dim=1) - torch.prod(torch.cos(x / torch.sqrt(torch.arange(1, x.size(1) + 1)))) + 1 + f = 1 / 4000 * torch.sum(x**2, dim=1) - torch.prod(torch.cos(x / torch.sqrt(torch.arange(1, x.size(1) + 1, device=x.device))), dim=1) + 1 return f @@ -193,3 +197,45 @@ def _true_evaluate(self, x: torch.Tensor) -> torch.Tensor: def ellipsoid_func(x: torch.Tensor): return torch.sum(torch.arange(1, x.size(1) + 1, device=x.device) * x**2, dim=1) + + +def zakharov_func(x: torch.Tensor) -> torch.Tensor: + d = x.size(-1) + i = torch.arange(1, d + 1, dtype=x.dtype, device=x.device) + sum1 = torch.sum(x ** 2, dim=-1) + sum2 = torch.sum(0.5 * i * x, dim=-1) + return sum1 + sum2 ** 2 + sum2 ** 4 + + +class Zakharov(ShiftAffineNumericalProblem): + """The Zakharov function whose minimum is x = [0, ..., 0]""" + + def __init__(self, **kwargs): + """Initialize the Zakharov function with the given parameters. + + :param **kwargs: The keyword arguments (`shift` and `affine`) to pass to the superclass `ShiftAffineNumericalProblem`. + """ + super().__init__(**kwargs) + + def _true_evaluate(self, x: torch.Tensor) -> torch.Tensor: + return zakharov_func(x) + +def levy_func(x: torch.Tensor) -> torch.Tensor: + w = 1 + (x - 1) / 4 + term1 = torch.sin(torch.pi * w[:, 0]) ** 2 + term2 = torch.sum((w[:, :-1] - 1) ** 2 * (1 + 10 * torch.sin(torch.pi * w[:, :-1] + 1) ** 2), dim=1) + term3 = (w[:, -1] - 1) ** 2 * (1 + torch.sin(2 * torch.pi * w[:, -1]) ** 2) + return term1 + term2 + term3 + +class Levy(ShiftAffineNumericalProblem): + """The Levy function whose minimum is x = [1, ..., 1]""" + + def __init__(self, **kwargs): + """Initialize the Levy function with the given parameters. + + :param **kwargs: The keyword arguments (`shift` and `affine`) to pass to the superclass `ShiftAffineNumericalProblem`. + """ + super().__init__(**kwargs) + + def _true_evaluate(self, x: torch.Tensor) -> torch.Tensor: + return levy_func(x) diff --git a/src/evox/problems/numerical/cec2022.py b/src/evox/problems/numerical/cec2022.py index 349691ec3..7df96b2da 100644 --- a/src/evox/problems/numerical/cec2022.py +++ b/src/evox/problems/numerical/cec2022.py @@ -10,6 +10,13 @@ import torch from evox.core import Problem +from evox.problems.numerical.basic import ( + ackley_func, + griewank_func, + rastrigin_func, + rosenbrock_func, + zakharov_func, +) class CEC2022(Problem): @@ -141,11 +148,11 @@ def cf_cal(self, x: torch.Tensor, fit: List[torch.Tensor], delta: List[int], bia # Problem def cec2022_f1(self, x: torch.Tensor) -> torch.Tensor: """Zakharov Function""" - return self.zakharov_func(self.sr_func_rate(x, 1.0, True, True, self.OShift, self.M)) + 300.0 + return zakharov_func(self.sr_func_rate(x, 1.0, True, True, self.OShift, self.M)) + 300.0 def cec2022_f2(self, x: torch.Tensor) -> torch.Tensor: """Rosenbrock Function""" - return self.rosenbrock_func(self.sr_func_rate(x, 2.048e-2, True, True, self.OShift, self.M)) + 400 + return rosenbrock_func(1 + self.sr_func_rate(x, 2.048e-2, True, True, self.OShift, self.M)) + 400 def cec2022_f3(self, x: torch.Tensor) -> torch.Tensor: """Schaffer F7 Function""" @@ -153,7 +160,7 @@ def cec2022_f3(self, x: torch.Tensor) -> torch.Tensor: def cec2022_f4(self, x: torch.Tensor) -> torch.Tensor: """Step Rastrigin Function (Noncontinuous Rastrigin's)""" - return self.step_rastrigin_func(self.sr_func_rate(x, 5.12e-2, True, True, self.OShift, self.M)) + 800.0 + return rastrigin_func(self.sr_func_rate(x, 5.12e-2, True, True, self.OShift, self.M)) + 800.0 def cec2022_f5(self, x: torch.Tensor) -> torch.Tensor: """Levy Function""" @@ -167,7 +174,7 @@ def cec2022_f6(self, x: torch.Tensor) -> torch.Tensor: fit0 = self.bent_cigar_func(self.sr_func_rate(y[0], 1.0, False, False, self.OShift, self.M)) fit1 = self.hgbat_func(self.sr_func_rate(y[1], 5.00e-2, False, False, self.OShift, self.M)) - fit2 = self.rastrigin_func(self.sr_func_rate(y[2], 5.12e-2, False, False, self.OShift, self.M)) + fit2 = rastrigin_func(self.sr_func_rate(y[2], 5.12e-2, False, False, self.OShift, self.M)) return fit0 + fit1 + fit2 + 1800.0 @@ -179,9 +186,9 @@ def cec2022_f7(self, x: torch.Tensor) -> torch.Tensor: fit0 = self.hgbat_func(self.sr_func_rate(y[0], 5.00e-2, False, False, self.OShift, self.M)) fit1 = self.katsuura_func(self.sr_func_rate(y[1], 5.00e-2, False, False, self.OShift, self.M)) - fit2 = self.ackley_func(self.sr_func_rate(y[2], 1.0, False, False, self.OShift, self.M)) - fit3 = self.rastrigin_func(self.sr_func_rate(y[3], 5.12e-2, False, False, self.OShift, self.M)) - fit4 = self.schwefel_func(self.sr_func_rate(y[4], 10.0, False, False, self.OShift, self.M)) + fit2 = ackley_func(20.0, 0.2, 2 * torch.pi, self.sr_func_rate(y[2], 1.0, False, False, self.OShift, self.M)) + fit3 = rastrigin_func(self.sr_func_rate(y[3], 5.12e-2, False, False, self.OShift, self.M)) + fit4 = self.modified_schwefel_func(self.sr_func_rate(y[4], 10.0, False, False, self.OShift, self.M)) fit5 = self.schaffer_F7_func(self.sr_func_rate(y[5], 1.0, False, False, self.OShift, self.M)) return fit0 + fit1 + fit2 + fit3 + fit4 + fit5 + 2000.0 @@ -195,8 +202,8 @@ def cec2022_f8(self, x: torch.Tensor) -> torch.Tensor: fit0 = self.katsuura_func(self.sr_func_rate(y[0], 5.00e-2, False, False, self.OShift, self.M)) fit1 = self.happycat_func(self.sr_func_rate(y[1], 5.00e-2, False, False, self.OShift, self.M)) fit2 = self.grie_rosen_func(self.sr_func_rate(y[2], 5.00e-2, False, False, self.OShift, self.M)) - fit3 = self.schwefel_func(self.sr_func_rate(y[3], 10.0, False, False, self.OShift, self.M)) - fit4 = self.ackley_func(self.sr_func_rate(y[4], 1.0, False, False, self.OShift, self.M)) + fit3 = self.modified_schwefel_func(self.sr_func_rate(y[3], 10.0, False, False, self.OShift, self.M)) + fit4 = ackley_func(20.0, 0.2, 2 * torch.pi, self.sr_func_rate(y[4], 1.0, False, False, self.OShift, self.M)) return fit0 + fit1 + fit2 + fit3 + fit4 + 2200.0 @@ -206,8 +213,8 @@ def cec2022_f9(self, x: torch.Tensor) -> torch.Tensor: delta = [10, 20, 30, 40, 50] bias = [0, 200, 300, 100, 400] fit = [ - self.rosenbrock_func( - self.sr_func_rate(x, 2.048e-2, True, True, self.OShift[:, 0 * nx : 1 * nx], self.M[:, 0 * nx : 1 * nx]) + rosenbrock_func( + 1 + self.sr_func_rate(x, 2.048e-2, True, True, self.OShift[:, 0 * nx : 1 * nx], self.M[:, 0 * nx : 1 * nx]) ) * 10000 / 1e4, @@ -240,11 +247,11 @@ def cec2022_f10(self, x: torch.Tensor) -> torch.Tensor: delta = [20, 10, 10] bias = [0, 200, 100] fit = [ - self.schwefel_func( + self.modified_schwefel_func( self.sr_func_rate(x, 10.0, True, False, self.OShift[:, 0 * nx : 1 * nx], self.M[:, 0 * nx : 1 * nx]) ) * 1.0, - self.rastrigin_func( + rastrigin_func( self.sr_func_rate(x, 5.12e-2, True, True, self.OShift[:, 1 * nx : 2 * nx], self.M[:, 1 * nx : 2 * nx]) ) * 1.0, @@ -267,20 +274,18 @@ def cec2022_f11(self, x: torch.Tensor) -> torch.Tensor: ) * 10000 / 2e7, - self.schwefel_func( + self.modified_schwefel_func( self.sr_func_rate(x, 10.0, True, True, self.OShift[:, 1 * nx : 2 * nx], self.M[:, 1 * nx : 2 * nx]) ) * 1.0, - self.griewank_func( - self.sr_func_rate(x, 6.0, True, True, self.OShift[:, 2 * nx : 3 * nx], self.M[:, 2 * nx : 3 * nx]) - ) + griewank_func(self.sr_func_rate(x, 6.0, True, True, self.OShift[:, 2 * nx : 3 * nx], self.M[:, 2 * nx : 3 * nx])) * 1000 / 100, - self.rosenbrock_func( - self.sr_func_rate(x, 2.048e-2, True, True, self.OShift[:, 3 * nx : 4 * nx], self.M[:, 3 * nx : 4 * nx]) + rosenbrock_func( + 1 + self.sr_func_rate(x, 2.048e-2, True, True, self.OShift[:, 3 * nx : 4 * nx], self.M[:, 3 * nx : 4 * nx]) ) * 1.0, - self.rastrigin_func( + rastrigin_func( self.sr_func_rate(x, 5.12e-2, True, True, self.OShift[:, 4 * nx : 5 * nx], self.M[:, 4 * nx : 5 * nx]) ) * 10000 @@ -300,12 +305,12 @@ def cec2022_f12(self, x: torch.Tensor) -> torch.Tensor: ) * 10000 / 1000, - self.rastrigin_func( + rastrigin_func( self.sr_func_rate(x, 5.12e-2, True, True, self.OShift[:, 1 * nx : 2 * nx], self.M[:, 1 * nx : 2 * nx]) ) * 10000 / 1e3, - self.schwefel_func( + self.modified_schwefel_func( self.sr_func_rate(x, 10.0, True, True, self.OShift[:, 2 * nx : 3 * nx], self.M[:, 2 * nx : 3 * nx]) ) * 10000 @@ -331,17 +336,6 @@ def cec2022_f12(self, x: torch.Tensor) -> torch.Tensor: return f + 2700.0 # Basic functions - def zakharov_func(self, x: torch.Tensor) -> torch.Tensor: - """Problem number = 1.""" - sum1 = x**2 - idx = torch.arange(1, x.size(1) + 1, device=x.device) - sum2 = torch.sum((0.5 * idx) * x, dim=1) - return torch.sum(sum1, dim=1) + sum2**2 + sum2**4 - - def step_rastrigin_func(self, x: torch.Tensor) -> torch.Tensor: - """Problem number = 4.""" - return torch.sum(x**2 - 10.0 * torch.cos(2.0 * torch.pi * x) + 10.0, dim=1) - def levy_func(self, x: torch.Tensor) -> torch.Tensor: """Problem number = 5.""" w = 1.0 + x / 4.0 @@ -360,9 +354,6 @@ def hgbat_func(self, x: torch.Tensor) -> torch.Tensor: sum_x = torch.sum(tmp, dim=1) return torch.abs(r2**2 - sum_x**2) ** (2 * alpha) + (0.5 * r2 + sum_x) / x.size(1) + 0.5 - def rastrigin_func(self, x: torch.Tensor) -> torch.Tensor: - return torch.sum(x**2 - 10.0 * torch.cos(2.0 * torch.pi * x) + 10.0, dim=1) - def katsuura_func(self, x: torch.Tensor) -> torch.Tensor: nx = x.size(1) tmp1 = 2.0 ** torch.arange(1, 33, device=x.device) @@ -372,12 +363,7 @@ def katsuura_func(self, x: torch.Tensor) -> torch.Tensor: f = torch.prod((1 + temp * tmp3.unsqueeze(0)) ** (10.0 / (nx**1.2)), dim=1) return (f - 1) * (10.0 / nx / nx) - def ackley_func(self, x: torch.Tensor) -> torch.Tensor: - mean1 = torch.mean(x**2, dim=1) - mean2 = torch.mean(torch.cos(2.0 * torch.pi * x), dim=1) - return torch.e - 20.0 * torch.exp(-0.2 * torch.sqrt(mean1)) - torch.exp(mean2) + 20.0 - - def schwefel_func(self, x: torch.Tensor) -> torch.Tensor: + def modified_schwefel_func(self, x: torch.Tensor) -> torch.Tensor: nx = x.size(1) tmp1 = x + 420.9687462275036 tmp2 = -tmp1 * tmp1.abs().sqrt().sin() @@ -413,16 +399,6 @@ def grie_rosen_func(self, x: torch.Tensor) -> torch.Tensor: tmp = 100.0 * (x**2 - y) ** 2 + (x - 1.0) ** 2 return torch.sum((tmp**2) / 4000.0 - torch.cos(tmp) + 1.0, dim=1) - def griewank_func(self, x: torch.Tensor) -> torch.Tensor: - sum_sq = torch.sum(x**2, dim=1) - idx = torch.arange(1, x.size(1) + 1, device=x.device) - prod_cos = torch.prod(torch.cos(x / torch.sqrt(idx)), dim=1) - return 1.0 + sum_sq / 4000.0 - prod_cos - - def rosenbrock_func(self, x: torch.Tensor) -> torch.Tensor: - tmp = x + 1 - return torch.sum(100.0 * (tmp[:, :-1] ** 2 - tmp[:, 1:]) ** 2 + (tmp[:, :-1] - 1.0) ** 2, dim=1) - def discus_func(self, x: torch.Tensor) -> torch.Tensor: return (10.0**6) * x[:, 0] ** 2 + torch.sum(x[:, 1:] ** 2, dim=1) diff --git a/unit_test/problems/test_cec2022.py b/unit_test/problems/test_cec2022.py index aca9335c8..887b173c5 100644 --- a/unit_test/problems/test_cec2022.py +++ b/unit_test/problems/test_cec2022.py @@ -1,11 +1,10 @@ import unittest import torch +from CEC2022_by_P_N_Suganthan import cec2022_func from evox.problems.numerical import CEC2022 -from .CEC2022_by_P_N_Suganthan import cec2022_func - class TestCEC2022(unittest.TestCase): def setUp(self): From cfe480059cd9e4012189860c30aab1ad126acdbf Mon Sep 17 00:00:00 2001 From: XU-Boqing Date: Mon, 19 May 2025 17:17:24 +0800 Subject: [PATCH 2/3] Use ruff to modify basic.py --- src/evox/problems/numerical/basic.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/evox/problems/numerical/basic.py b/src/evox/problems/numerical/basic.py index 5321a4817..2a85dfe31 100644 --- a/src/evox/problems/numerical/basic.py +++ b/src/evox/problems/numerical/basic.py @@ -90,7 +90,11 @@ def _true_evaluate(self, x: torch.Tensor) -> torch.Tensor: def griewank_func(x: torch.Tensor) -> torch.Tensor: - f = 1 / 4000 * torch.sum(x**2, dim=1) - torch.prod(torch.cos(x / torch.sqrt(torch.arange(1, x.size(1) + 1, device=x.device))), dim=1) + 1 + f = ( + 1 / 4000 * torch.sum(x**2, dim=1) + - torch.prod(torch.cos(x / torch.sqrt(torch.arange(1, x.size(1) + 1, device=x.device))), dim=1) + + 1 + ) return f @@ -202,9 +206,9 @@ def ellipsoid_func(x: torch.Tensor): def zakharov_func(x: torch.Tensor) -> torch.Tensor: d = x.size(-1) i = torch.arange(1, d + 1, dtype=x.dtype, device=x.device) - sum1 = torch.sum(x ** 2, dim=-1) + sum1 = torch.sum(x**2, dim=-1) sum2 = torch.sum(0.5 * i * x, dim=-1) - return sum1 + sum2 ** 2 + sum2 ** 4 + return sum1 + sum2**2 + sum2**4 class Zakharov(ShiftAffineNumericalProblem): @@ -220,6 +224,7 @@ def __init__(self, **kwargs): def _true_evaluate(self, x: torch.Tensor) -> torch.Tensor: return zakharov_func(x) + def levy_func(x: torch.Tensor) -> torch.Tensor: w = 1 + (x - 1) / 4 term1 = torch.sin(torch.pi * w[:, 0]) ** 2 @@ -227,6 +232,7 @@ def levy_func(x: torch.Tensor) -> torch.Tensor: term3 = (w[:, -1] - 1) ** 2 * (1 + torch.sin(2 * torch.pi * w[:, -1]) ** 2) return term1 + term2 + term3 + class Levy(ShiftAffineNumericalProblem): """The Levy function whose minimum is x = [1, ..., 1]""" From 59408dcba38224983c80331041acd9a1b25508c9 Mon Sep 17 00:00:00 2001 From: Bill Huang Date: Fri, 22 Aug 2025 13:30:07 +0800 Subject: [PATCH 3/3] Fix module import --- unit_test/problems/test_cec2022.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unit_test/problems/test_cec2022.py b/unit_test/problems/test_cec2022.py index 887b173c5..aca9335c8 100644 --- a/unit_test/problems/test_cec2022.py +++ b/unit_test/problems/test_cec2022.py @@ -1,10 +1,11 @@ import unittest import torch -from CEC2022_by_P_N_Suganthan import cec2022_func from evox.problems.numerical import CEC2022 +from .CEC2022_by_P_N_Suganthan import cec2022_func + class TestCEC2022(unittest.TestCase): def setUp(self):