evograd-diff 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- evograd/__init__.py +67 -0
- evograd/algorithms/__init__.py +138 -0
- evograd/algorithms/cmaes.py +1365 -0
- evograd/algorithms/de.py +895 -0
- evograd/algorithms/ga.py +532 -0
- evograd/algorithms/pso.py +648 -0
- evograd/algorithms/shade.py +1165 -0
- evograd/benchmarks/functions/__init__.py +229 -0
- evograd/benchmarks/functions/base.py +217 -0
- evograd/benchmarks/functions/cec2017/__init__.py +250 -0
- evograd/benchmarks/functions/cec2017/basic.py +413 -0
- evograd/benchmarks/functions/cec2017/composition.py +580 -0
- evograd/benchmarks/functions/cec2017/data.pkl +0 -0
- evograd/benchmarks/functions/cec2017/data.py +350 -0
- evograd/benchmarks/functions/cec2017/hybrid.py +406 -0
- evograd/benchmarks/functions/cec2017/simple.py +326 -0
- evograd/benchmarks/functions/classical.py +649 -0
- evograd/benchmarks/functions/smoothed_funnel.py +476 -0
- evograd/benchmarks/functions/transforms.py +463 -0
- evograd/benchmarks/run_benchmark_functions.py +1208 -0
- evograd/core/__init__.py +73 -0
- evograd/core/algorithm.py +778 -0
- evograd/core/maximize.py +269 -0
- evograd/core/minimize.py +740 -0
- evograd/core/problem.py +444 -0
- evograd/core/result.py +571 -0
- evograd/core/termination.py +602 -0
- evograd/operators/__init__.py +178 -0
- evograd/operators/crossover.py +1117 -0
- evograd/operators/mutation.py +1098 -0
- evograd/operators/relaxations.py +175 -0
- evograd/operators/repair.py +601 -0
- evograd/operators/sampling.py +577 -0
- evograd/operators/selection.py +981 -0
- evograd/operators/survival.py +1000 -0
- evograd/tests/__init__.py +11 -0
- evograd/tests/run_all.py +78 -0
- evograd/tests/test_core.py +528 -0
- evograd/tests/test_ga.py +572 -0
- evograd/tests/test_operators.py +662 -0
- evograd/tests/test_per_individual.py +326 -0
- evograd/tests/test_utils.py +328 -0
- evograd/utils/__init__.py +97 -0
- evograd/utils/callbacks.py +926 -0
- evograd/utils/device.py +502 -0
- evograd/utils/duplicates.py +421 -0
- evograd_diff-0.1.0.dist-info/METADATA +439 -0
- evograd_diff-0.1.0.dist-info/RECORD +50 -0
- evograd_diff-0.1.0.dist-info/WHEEL +4 -0
- evograd_diff-0.1.0.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"""
|
|
2
|
+
EvoGrad Benchmark Functions.
|
|
3
|
+
|
|
4
|
+
This package provides a comprehensive set of benchmark functions for
|
|
5
|
+
testing and comparing optimization algorithms.
|
|
6
|
+
|
|
7
|
+
Categories:
|
|
8
|
+
- Classical: Standard test functions (Sphere, Rosenbrock, Rastrigin, etc.)
|
|
9
|
+
- CEC 2017: Competition benchmark suite (F1-F30)
|
|
10
|
+
- Smoothed Funnel: Multi-basin problems designed for differentiable EAs
|
|
11
|
+
- Transforms: Wrappers for creating shifted/rotated variants
|
|
12
|
+
|
|
13
|
+
Usage:
|
|
14
|
+
>>> from evograd.benchmarks.functions import Sphere, Rastrigin
|
|
15
|
+
>>> from evograd.benchmarks.functions import CEC2017_F1, get_cec2017_function
|
|
16
|
+
>>> from evograd.benchmarks.functions import SmoothedMultiFunnel
|
|
17
|
+
>>>
|
|
18
|
+
>>> # Create function with default bounds
|
|
19
|
+
>>> sphere = Sphere(n_var=30)
|
|
20
|
+
>>>
|
|
21
|
+
>>> # Create function with custom bounds
|
|
22
|
+
>>> sphere = Sphere(n_var=30, xl=-5.0, xu=5.0)
|
|
23
|
+
>>>
|
|
24
|
+
>>> # Evaluate population
|
|
25
|
+
>>> x = torch.randn(100, 30)
|
|
26
|
+
>>> f = sphere(x) # Shape: [100]
|
|
27
|
+
>>>
|
|
28
|
+
>>> # Get bounds
|
|
29
|
+
>>> lb, ub = sphere.bounds
|
|
30
|
+
>>>
|
|
31
|
+
>>> # CEC 2017 functions
|
|
32
|
+
>>> f1 = CEC2017_F1(n_var=10)
|
|
33
|
+
>>> f15 = get_cec2017_function(15, n_var=10)
|
|
34
|
+
>>>
|
|
35
|
+
>>> # Smoothed multi-funnel (designed for differentiable EAs)
|
|
36
|
+
>>> funnel = SmoothedMultiFunnel(n_var=10, tau=1.0, delta=10.0)
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
from .base import BenchmarkFunction, CompositeFunction
|
|
40
|
+
|
|
41
|
+
from .classical import (
|
|
42
|
+
# Unimodal
|
|
43
|
+
Sphere,
|
|
44
|
+
Ellipsoid,
|
|
45
|
+
SumOfDifferentPowers,
|
|
46
|
+
Schwefel222,
|
|
47
|
+
Cigar,
|
|
48
|
+
Discus,
|
|
49
|
+
BentCigar,
|
|
50
|
+
Rosenbrock,
|
|
51
|
+
DixonPrice,
|
|
52
|
+
Powell,
|
|
53
|
+
Trid,
|
|
54
|
+
# Multimodal
|
|
55
|
+
Rastrigin,
|
|
56
|
+
Ackley,
|
|
57
|
+
Griewank,
|
|
58
|
+
Schwefel,
|
|
59
|
+
Levy,
|
|
60
|
+
Michalewicz,
|
|
61
|
+
Zakharov,
|
|
62
|
+
Weierstrass,
|
|
63
|
+
Alpine,
|
|
64
|
+
Salomon,
|
|
65
|
+
StyblinskiTang,
|
|
66
|
+
# Registry
|
|
67
|
+
CLASSICAL_FUNCTIONS,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
from .transforms import (
|
|
71
|
+
ShiftedFunction,
|
|
72
|
+
RotatedFunction,
|
|
73
|
+
ShiftedRotatedFunction,
|
|
74
|
+
ScaledFunction,
|
|
75
|
+
AsymmetricFunction,
|
|
76
|
+
OscillatedFunction,
|
|
77
|
+
BiasedFunction,
|
|
78
|
+
generate_rotation_matrix,
|
|
79
|
+
generate_shift_vector,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
# CEC 2017 Benchmark Suite
|
|
83
|
+
from .cec2017 import (
|
|
84
|
+
# Simple functions (F1-F10)
|
|
85
|
+
CEC2017_F1,
|
|
86
|
+
CEC2017_F2,
|
|
87
|
+
CEC2017_F3,
|
|
88
|
+
CEC2017_F4,
|
|
89
|
+
CEC2017_F5,
|
|
90
|
+
CEC2017_F6,
|
|
91
|
+
CEC2017_F7,
|
|
92
|
+
CEC2017_F8,
|
|
93
|
+
CEC2017_F9,
|
|
94
|
+
CEC2017_F10,
|
|
95
|
+
# Hybrid functions (F11-F20)
|
|
96
|
+
CEC2017_F11,
|
|
97
|
+
CEC2017_F12,
|
|
98
|
+
CEC2017_F13,
|
|
99
|
+
CEC2017_F14,
|
|
100
|
+
CEC2017_F15,
|
|
101
|
+
CEC2017_F16,
|
|
102
|
+
CEC2017_F17,
|
|
103
|
+
CEC2017_F18,
|
|
104
|
+
CEC2017_F19,
|
|
105
|
+
CEC2017_F20,
|
|
106
|
+
# Composition functions (F21-F30)
|
|
107
|
+
CEC2017_F21,
|
|
108
|
+
CEC2017_F22,
|
|
109
|
+
CEC2017_F23,
|
|
110
|
+
CEC2017_F24,
|
|
111
|
+
CEC2017_F25,
|
|
112
|
+
CEC2017_F26,
|
|
113
|
+
CEC2017_F27,
|
|
114
|
+
CEC2017_F28,
|
|
115
|
+
CEC2017_F29,
|
|
116
|
+
CEC2017_F30,
|
|
117
|
+
# Registries
|
|
118
|
+
CEC2017_FUNCTIONS,
|
|
119
|
+
ALL_CEC2017_CLASSES,
|
|
120
|
+
# Utilities
|
|
121
|
+
get_function as get_cec2017_function,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
# Smoothed Multi-Funnel Functions (designed for differentiable EAs)
|
|
125
|
+
from .smoothed_funnel import (
|
|
126
|
+
# Core utilities
|
|
127
|
+
log_sum_exp_min,
|
|
128
|
+
random_orthogonal_matrix,
|
|
129
|
+
# Benchmark functions
|
|
130
|
+
MultiBasinRastrigin,
|
|
131
|
+
MultiBasinRosenbrock,
|
|
132
|
+
DeceptiveLandscape,
|
|
133
|
+
# Registry
|
|
134
|
+
SMOOTHED_FUNNEL_FUNCTIONS,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
# Combined registry of all functions
|
|
138
|
+
ALL_FUNCTIONS = {
|
|
139
|
+
**CLASSICAL_FUNCTIONS,
|
|
140
|
+
**CEC2017_FUNCTIONS,
|
|
141
|
+
**SMOOTHED_FUNNEL_FUNCTIONS,
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
__all__ = [
|
|
145
|
+
# Base
|
|
146
|
+
"BenchmarkFunction",
|
|
147
|
+
"CompositeFunction",
|
|
148
|
+
# Classical - Unimodal
|
|
149
|
+
"Sphere",
|
|
150
|
+
"Ellipsoid",
|
|
151
|
+
"SumOfDifferentPowers",
|
|
152
|
+
"Schwefel222",
|
|
153
|
+
"Cigar",
|
|
154
|
+
"Discus",
|
|
155
|
+
"BentCigar",
|
|
156
|
+
"Rosenbrock",
|
|
157
|
+
"DixonPrice",
|
|
158
|
+
"Powell",
|
|
159
|
+
"Trid",
|
|
160
|
+
# Classical - Multimodal
|
|
161
|
+
"Rastrigin",
|
|
162
|
+
"Ackley",
|
|
163
|
+
"Griewank",
|
|
164
|
+
"Schwefel",
|
|
165
|
+
"Levy",
|
|
166
|
+
"Michalewicz",
|
|
167
|
+
"Zakharov",
|
|
168
|
+
"Weierstrass",
|
|
169
|
+
"Alpine",
|
|
170
|
+
"Salomon",
|
|
171
|
+
"StyblinskiTang",
|
|
172
|
+
# Transforms
|
|
173
|
+
"ShiftedFunction",
|
|
174
|
+
"RotatedFunction",
|
|
175
|
+
"ShiftedRotatedFunction",
|
|
176
|
+
"ScaledFunction",
|
|
177
|
+
"AsymmetricFunction",
|
|
178
|
+
"OscillatedFunction",
|
|
179
|
+
"BiasedFunction",
|
|
180
|
+
"generate_rotation_matrix",
|
|
181
|
+
"generate_shift_vector",
|
|
182
|
+
# CEC 2017 - Simple (F1-F10)
|
|
183
|
+
"CEC2017_F1",
|
|
184
|
+
"CEC2017_F2",
|
|
185
|
+
"CEC2017_F3",
|
|
186
|
+
"CEC2017_F4",
|
|
187
|
+
"CEC2017_F5",
|
|
188
|
+
"CEC2017_F6",
|
|
189
|
+
"CEC2017_F7",
|
|
190
|
+
"CEC2017_F8",
|
|
191
|
+
"CEC2017_F9",
|
|
192
|
+
"CEC2017_F10",
|
|
193
|
+
# CEC 2017 - Hybrid (F11-F20)
|
|
194
|
+
"CEC2017_F11",
|
|
195
|
+
"CEC2017_F12",
|
|
196
|
+
"CEC2017_F13",
|
|
197
|
+
"CEC2017_F14",
|
|
198
|
+
"CEC2017_F15",
|
|
199
|
+
"CEC2017_F16",
|
|
200
|
+
"CEC2017_F17",
|
|
201
|
+
"CEC2017_F18",
|
|
202
|
+
"CEC2017_F19",
|
|
203
|
+
"CEC2017_F20",
|
|
204
|
+
# CEC 2017 - Composition (F21-F30)
|
|
205
|
+
"CEC2017_F21",
|
|
206
|
+
"CEC2017_F22",
|
|
207
|
+
"CEC2017_F23",
|
|
208
|
+
"CEC2017_F24",
|
|
209
|
+
"CEC2017_F25",
|
|
210
|
+
"CEC2017_F26",
|
|
211
|
+
"CEC2017_F27",
|
|
212
|
+
"CEC2017_F28",
|
|
213
|
+
"CEC2017_F29",
|
|
214
|
+
"CEC2017_F30",
|
|
215
|
+
# CEC 2017 utilities
|
|
216
|
+
"CEC2017_FUNCTIONS",
|
|
217
|
+
"ALL_CEC2017_CLASSES",
|
|
218
|
+
"get_cec2017_function",
|
|
219
|
+
# Smoothed Multi-Funnel (for differentiable EAs)
|
|
220
|
+
"log_sum_exp_min",
|
|
221
|
+
"random_orthogonal_matrix",
|
|
222
|
+
"MultiBasinRastrigin",
|
|
223
|
+
"MultiBasinRosenbrock",
|
|
224
|
+
"DeceptiveLandscape",
|
|
225
|
+
"SMOOTHED_FUNNEL_FUNCTIONS",
|
|
226
|
+
# Registries
|
|
227
|
+
"CLASSICAL_FUNCTIONS",
|
|
228
|
+
"ALL_FUNCTIONS",
|
|
229
|
+
]
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base class for benchmark functions.
|
|
3
|
+
|
|
4
|
+
All benchmark functions inherit from BenchmarkFunction and implement
|
|
5
|
+
the __call__ method for evaluation. Bounds can be specified per-function
|
|
6
|
+
or overridden at instantiation.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from abc import ABC, abstractmethod
|
|
10
|
+
from typing import Optional, Tuple, Union
|
|
11
|
+
|
|
12
|
+
import torch
|
|
13
|
+
from torch import Tensor
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class BenchmarkFunction(ABC):
|
|
17
|
+
"""
|
|
18
|
+
Abstract base class for benchmark optimization functions.
|
|
19
|
+
|
|
20
|
+
All benchmark functions support:
|
|
21
|
+
- Configurable dimensionality (n_var)
|
|
22
|
+
- Configurable bounds (xl, xu) - can be scalar or per-dimension
|
|
23
|
+
- Known optimal value and location
|
|
24
|
+
- Batch evaluation for populations
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
n_var: Number of decision variables (dimensions).
|
|
28
|
+
xl: Lower bound(s). Scalar or tensor of shape [n_var].
|
|
29
|
+
xu: Upper bound(s). Scalar or tensor of shape [n_var].
|
|
30
|
+
|
|
31
|
+
Example:
|
|
32
|
+
>>> sphere = Sphere(n_var=10)
|
|
33
|
+
>>> x = torch.randn(100, 10) # Population of 100 individuals
|
|
34
|
+
>>> f = sphere(x) # Shape: [100]
|
|
35
|
+
|
|
36
|
+
>>> # Custom bounds
|
|
37
|
+
>>> sphere = Sphere(n_var=10, xl=-5.0, xu=5.0)
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
# Class attributes (can be overridden in subclasses)
|
|
41
|
+
name: str = "base_function"
|
|
42
|
+
optimal_value: float = 0.0
|
|
43
|
+
|
|
44
|
+
def __init__(
|
|
45
|
+
self,
|
|
46
|
+
n_var: int = 30,
|
|
47
|
+
xl: Optional[Union[float, Tensor]] = None,
|
|
48
|
+
xu: Optional[Union[float, Tensor]] = None,
|
|
49
|
+
):
|
|
50
|
+
"""
|
|
51
|
+
Initialize benchmark function.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
n_var: Number of decision variables.
|
|
55
|
+
xl: Lower bound(s). If None, uses default_bounds().
|
|
56
|
+
xu: Upper bound(s). If None, uses default_bounds().
|
|
57
|
+
"""
|
|
58
|
+
self.n_var = n_var
|
|
59
|
+
|
|
60
|
+
# Get default bounds
|
|
61
|
+
default_lb, default_ub = self.default_bounds()
|
|
62
|
+
|
|
63
|
+
# Set lower bounds
|
|
64
|
+
if xl is None:
|
|
65
|
+
xl = default_lb
|
|
66
|
+
if isinstance(xl, (int, float)):
|
|
67
|
+
self._xl = torch.full((n_var,), float(xl))
|
|
68
|
+
else:
|
|
69
|
+
self._xl = xl.clone() if isinstance(xl, Tensor) else torch.tensor(xl)
|
|
70
|
+
if self._xl.numel() == 1:
|
|
71
|
+
self._xl = self._xl.expand(n_var).clone()
|
|
72
|
+
|
|
73
|
+
# Set upper bounds
|
|
74
|
+
if xu is None:
|
|
75
|
+
xu = default_ub
|
|
76
|
+
if isinstance(xu, (int, float)):
|
|
77
|
+
self._xu = torch.full((n_var,), float(xu))
|
|
78
|
+
else:
|
|
79
|
+
self._xu = xu.clone() if isinstance(xu, Tensor) else torch.tensor(xu)
|
|
80
|
+
if self._xu.numel() == 1:
|
|
81
|
+
self._xu = self._xu.expand(n_var).clone()
|
|
82
|
+
|
|
83
|
+
# Compute optimal location (default: origin)
|
|
84
|
+
self._optimal_x = self._compute_optimal_x()
|
|
85
|
+
|
|
86
|
+
@property
|
|
87
|
+
def xl(self) -> Tensor:
|
|
88
|
+
"""Lower bounds as tensor of shape [n_var]."""
|
|
89
|
+
return self._xl
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def xu(self) -> Tensor:
|
|
93
|
+
"""Upper bounds as tensor of shape [n_var]."""
|
|
94
|
+
return self._xu
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def bounds(self) -> Tuple[Tensor, Tensor]:
|
|
98
|
+
"""Return (lower_bounds, upper_bounds) tuple."""
|
|
99
|
+
return (self._xl, self._xu)
|
|
100
|
+
|
|
101
|
+
@property
|
|
102
|
+
def optimal_x(self) -> Tensor:
|
|
103
|
+
"""Optimal solution location."""
|
|
104
|
+
return self._optimal_x
|
|
105
|
+
|
|
106
|
+
def _compute_optimal_x(self) -> Tensor:
|
|
107
|
+
"""
|
|
108
|
+
Compute the optimal solution location.
|
|
109
|
+
|
|
110
|
+
Override in subclasses if optimal is not at origin.
|
|
111
|
+
"""
|
|
112
|
+
return torch.zeros(self.n_var)
|
|
113
|
+
|
|
114
|
+
@abstractmethod
|
|
115
|
+
def default_bounds(self) -> Tuple[float, float]:
|
|
116
|
+
"""
|
|
117
|
+
Return default (lower, upper) bounds for this function.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
Tuple of (lower_bound, upper_bound) scalars.
|
|
121
|
+
"""
|
|
122
|
+
pass
|
|
123
|
+
|
|
124
|
+
@abstractmethod
|
|
125
|
+
def __call__(self, x: Tensor) -> Tensor:
|
|
126
|
+
"""
|
|
127
|
+
Evaluate the function at point(s) x.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
x: Decision variables of shape [..., n_var].
|
|
131
|
+
Can be single point [n_var] or batch [N, n_var].
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
Function values of shape [...] (same batch dimensions as input).
|
|
135
|
+
"""
|
|
136
|
+
pass
|
|
137
|
+
|
|
138
|
+
def to(self, device: torch.device) -> "BenchmarkFunction":
|
|
139
|
+
"""Move bounds to specified device."""
|
|
140
|
+
self._xl = self._xl.to(device)
|
|
141
|
+
self._xu = self._xu.to(device)
|
|
142
|
+
self._optimal_x = self._optimal_x.to(device)
|
|
143
|
+
return self
|
|
144
|
+
|
|
145
|
+
def __repr__(self) -> str:
|
|
146
|
+
return (
|
|
147
|
+
f"{self.__class__.__name__}("
|
|
148
|
+
f"n_var={self.n_var}, "
|
|
149
|
+
f"xl={self._xl[0].item():.2f}, "
|
|
150
|
+
f"xu={self._xu[0].item():.2f})"
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
def info(self) -> str:
|
|
154
|
+
"""Return detailed information about the function."""
|
|
155
|
+
return (
|
|
156
|
+
f"Function: {self.name}\n"
|
|
157
|
+
f" Dimensions: {self.n_var}\n"
|
|
158
|
+
f" Bounds: [{self._xl[0].item():.2f}, {self._xu[0].item():.2f}]\n"
|
|
159
|
+
f" Optimal value: {self.optimal_value}\n"
|
|
160
|
+
f" Optimal location: {self._optimal_x[:3].tolist()}..."
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class CompositeFunction(BenchmarkFunction):
|
|
165
|
+
"""
|
|
166
|
+
Composite function combining multiple base functions.
|
|
167
|
+
|
|
168
|
+
Used for creating CEC-style hybrid and composition functions.
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
def __init__(
|
|
172
|
+
self,
|
|
173
|
+
functions: list,
|
|
174
|
+
weights: Optional[Tensor] = None,
|
|
175
|
+
n_var: int = 30,
|
|
176
|
+
xl: Optional[Union[float, Tensor]] = None,
|
|
177
|
+
xu: Optional[Union[float, Tensor]] = None,
|
|
178
|
+
):
|
|
179
|
+
"""
|
|
180
|
+
Initialize composite function.
|
|
181
|
+
|
|
182
|
+
Args:
|
|
183
|
+
functions: List of BenchmarkFunction instances.
|
|
184
|
+
weights: Weights for combining functions. If None, equal weights.
|
|
185
|
+
n_var: Number of decision variables.
|
|
186
|
+
xl: Lower bounds.
|
|
187
|
+
xu: Upper bounds.
|
|
188
|
+
"""
|
|
189
|
+
self.functions = functions
|
|
190
|
+
self.n_functions = len(functions)
|
|
191
|
+
|
|
192
|
+
if weights is None:
|
|
193
|
+
self.weights = torch.ones(self.n_functions) / self.n_functions
|
|
194
|
+
else:
|
|
195
|
+
self.weights = weights / weights.sum()
|
|
196
|
+
|
|
197
|
+
# Use first function's bounds as default
|
|
198
|
+
if xl is None and functions:
|
|
199
|
+
xl = functions[0]._xl[0].item()
|
|
200
|
+
if xu is None and functions:
|
|
201
|
+
xu = functions[0]._xu[0].item()
|
|
202
|
+
|
|
203
|
+
super().__init__(n_var=n_var, xl=xl, xu=xu)
|
|
204
|
+
self.name = "composite"
|
|
205
|
+
|
|
206
|
+
def default_bounds(self) -> Tuple[float, float]:
|
|
207
|
+
return (-100.0, 100.0)
|
|
208
|
+
|
|
209
|
+
def __call__(self, x: Tensor) -> Tensor:
|
|
210
|
+
"""Weighted sum of component functions."""
|
|
211
|
+
result = torch.zeros(x.shape[:-1], device=x.device, dtype=x.dtype)
|
|
212
|
+
weights = self.weights.to(x.device, x.dtype)
|
|
213
|
+
|
|
214
|
+
for i, func in enumerate(self.functions):
|
|
215
|
+
result = result + weights[i] * func(x)
|
|
216
|
+
|
|
217
|
+
return result
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CEC 2017 Benchmark Functions for PyTorch.
|
|
3
|
+
|
|
4
|
+
This package provides a comprehensive implementation of the CEC 2017
|
|
5
|
+
benchmark suite for real-parameter single objective optimization.
|
|
6
|
+
|
|
7
|
+
The suite consists of 30 functions:
|
|
8
|
+
- F1-F10: Simple functions (shifted and rotated basic functions)
|
|
9
|
+
- F11-F20: Hybrid functions (combinations of basic functions)
|
|
10
|
+
- F21-F30: Composition functions (weighted combinations)
|
|
11
|
+
|
|
12
|
+
All functions:
|
|
13
|
+
- Accept PyTorch tensors
|
|
14
|
+
- Support batch evaluation
|
|
15
|
+
- Have bounds of [-100, 100]
|
|
16
|
+
- Have optimal values of F_i* = i * 100
|
|
17
|
+
|
|
18
|
+
Usage:
|
|
19
|
+
>>> from evograd.benchmarks.functions.cec2017 import CEC2017_F1, CEC2017_F10
|
|
20
|
+
>>>
|
|
21
|
+
>>> # Create function with default settings
|
|
22
|
+
>>> f1 = CEC2017_F1(n_var=10)
|
|
23
|
+
>>>
|
|
24
|
+
>>> # Evaluate population
|
|
25
|
+
>>> x = torch.randn(100, 10)
|
|
26
|
+
>>> fitness = f1(x) # Shape: [100]
|
|
27
|
+
>>>
|
|
28
|
+
>>> # Get optimal value
|
|
29
|
+
>>> print(f"Optimal value: {f1.optimal_value}") # 100.0
|
|
30
|
+
|
|
31
|
+
Supported dimensions: 2, 10, 20, 30, 50, 100 (for official data)
|
|
32
|
+
Other dimensions will use randomly generated transforms.
|
|
33
|
+
|
|
34
|
+
Reference:
|
|
35
|
+
N. H. Awad, M. Z. Ali, J. J. Liang, B. Y. Qu, and P. N. Suganthan,
|
|
36
|
+
"Problem Definitions and Evaluation Criteria for the CEC 2017
|
|
37
|
+
Special Session and Competition on Single Objective Real-Parameter
|
|
38
|
+
Numerical Optimization," Technical Report, 2016.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
# Basic functions (stateless, for internal use)
|
|
42
|
+
from .basic import (
|
|
43
|
+
bent_cigar,
|
|
44
|
+
sum_diff_pow,
|
|
45
|
+
zakharov,
|
|
46
|
+
rosenbrock,
|
|
47
|
+
rastrigin,
|
|
48
|
+
expanded_schaffers_f6,
|
|
49
|
+
lunacek_bi_rastrigin,
|
|
50
|
+
non_cont_rastrigin,
|
|
51
|
+
levy,
|
|
52
|
+
modified_schwefel,
|
|
53
|
+
high_conditioned_elliptic,
|
|
54
|
+
discus,
|
|
55
|
+
ackley,
|
|
56
|
+
weierstrass,
|
|
57
|
+
griewank,
|
|
58
|
+
katsuura,
|
|
59
|
+
happy_cat,
|
|
60
|
+
h_g_bat,
|
|
61
|
+
expanded_griewanks_plus_rosenbrock,
|
|
62
|
+
schaffers_f7,
|
|
63
|
+
BASIC_FUNCTIONS,
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
# Simple functions (F1-F10)
|
|
67
|
+
from .simple import (
|
|
68
|
+
CEC2017_F1,
|
|
69
|
+
CEC2017_F2,
|
|
70
|
+
CEC2017_F3,
|
|
71
|
+
CEC2017_F4,
|
|
72
|
+
CEC2017_F5,
|
|
73
|
+
CEC2017_F6,
|
|
74
|
+
CEC2017_F7,
|
|
75
|
+
CEC2017_F8,
|
|
76
|
+
CEC2017_F9,
|
|
77
|
+
CEC2017_F10,
|
|
78
|
+
SIMPLE_FUNCTIONS,
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Hybrid functions (F11-F20)
|
|
82
|
+
from .hybrid import (
|
|
83
|
+
CEC2017_F11,
|
|
84
|
+
CEC2017_F12,
|
|
85
|
+
CEC2017_F13,
|
|
86
|
+
CEC2017_F14,
|
|
87
|
+
CEC2017_F15,
|
|
88
|
+
CEC2017_F16,
|
|
89
|
+
CEC2017_F17,
|
|
90
|
+
CEC2017_F18,
|
|
91
|
+
CEC2017_F19,
|
|
92
|
+
CEC2017_F20,
|
|
93
|
+
HYBRID_FUNCTIONS,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# Composition functions (F21-F30)
|
|
97
|
+
from .composition import (
|
|
98
|
+
CEC2017_F21,
|
|
99
|
+
CEC2017_F22,
|
|
100
|
+
CEC2017_F23,
|
|
101
|
+
CEC2017_F24,
|
|
102
|
+
CEC2017_F25,
|
|
103
|
+
CEC2017_F26,
|
|
104
|
+
CEC2017_F27,
|
|
105
|
+
CEC2017_F28,
|
|
106
|
+
CEC2017_F29,
|
|
107
|
+
CEC2017_F30,
|
|
108
|
+
COMPOSITION_FUNCTIONS,
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
# Data utilities
|
|
112
|
+
from .data import (
|
|
113
|
+
data_available,
|
|
114
|
+
get_rotation,
|
|
115
|
+
get_rotation_cf,
|
|
116
|
+
get_shift,
|
|
117
|
+
get_shift_cf,
|
|
118
|
+
get_shuffle,
|
|
119
|
+
get_shuffle_cf,
|
|
120
|
+
generate_rotation_matrix,
|
|
121
|
+
generate_shift_vector,
|
|
122
|
+
generate_shuffle,
|
|
123
|
+
shift_rotate,
|
|
124
|
+
shuffle_and_partition,
|
|
125
|
+
SUPPORTED_DIMS,
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
# Combined registry of all CEC 2017 functions
|
|
130
|
+
CEC2017_FUNCTIONS = {
|
|
131
|
+
**SIMPLE_FUNCTIONS,
|
|
132
|
+
**HYBRID_FUNCTIONS,
|
|
133
|
+
**COMPOSITION_FUNCTIONS,
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
# List of all function classes for iteration
|
|
137
|
+
ALL_CEC2017_CLASSES = [
|
|
138
|
+
# Simple (F1-F10)
|
|
139
|
+
CEC2017_F1, CEC2017_F2, CEC2017_F3, CEC2017_F4, CEC2017_F5,
|
|
140
|
+
CEC2017_F6, CEC2017_F7, CEC2017_F8, CEC2017_F9, CEC2017_F10,
|
|
141
|
+
# Hybrid (F11-F20)
|
|
142
|
+
CEC2017_F11, CEC2017_F12, CEC2017_F13, CEC2017_F14, CEC2017_F15,
|
|
143
|
+
CEC2017_F16, CEC2017_F17, CEC2017_F18, CEC2017_F19, CEC2017_F20,
|
|
144
|
+
# Composition (F21-F30)
|
|
145
|
+
CEC2017_F21, CEC2017_F22, CEC2017_F23, CEC2017_F24, CEC2017_F25,
|
|
146
|
+
CEC2017_F26, CEC2017_F27, CEC2017_F28, CEC2017_F29, CEC2017_F30,
|
|
147
|
+
]
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def get_function(func_num: int, n_var: int = 10, **kwargs):
|
|
151
|
+
"""
|
|
152
|
+
Get CEC 2017 function by number.
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
func_num: Function number (1-30).
|
|
156
|
+
n_var: Number of variables.
|
|
157
|
+
**kwargs: Additional arguments passed to the function constructor.
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
BenchmarkFunction instance.
|
|
161
|
+
|
|
162
|
+
Example:
|
|
163
|
+
>>> f1 = get_function(1, n_var=10)
|
|
164
|
+
>>> f15 = get_function(15, n_var=30)
|
|
165
|
+
"""
|
|
166
|
+
if func_num < 1 or func_num > 30:
|
|
167
|
+
raise ValueError(f"Function number must be 1-30, got {func_num}")
|
|
168
|
+
|
|
169
|
+
func_class = ALL_CEC2017_CLASSES[func_num - 1]
|
|
170
|
+
return func_class(n_var=n_var, **kwargs)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
__all__ = [
|
|
174
|
+
# Basic functions
|
|
175
|
+
"bent_cigar",
|
|
176
|
+
"sum_diff_pow",
|
|
177
|
+
"zakharov",
|
|
178
|
+
"rosenbrock",
|
|
179
|
+
"rastrigin",
|
|
180
|
+
"expanded_schaffers_f6",
|
|
181
|
+
"lunacek_bi_rastrigin",
|
|
182
|
+
"non_cont_rastrigin",
|
|
183
|
+
"levy",
|
|
184
|
+
"modified_schwefel",
|
|
185
|
+
"high_conditioned_elliptic",
|
|
186
|
+
"discus",
|
|
187
|
+
"ackley",
|
|
188
|
+
"weierstrass",
|
|
189
|
+
"griewank",
|
|
190
|
+
"katsuura",
|
|
191
|
+
"happy_cat",
|
|
192
|
+
"h_g_bat",
|
|
193
|
+
"expanded_griewanks_plus_rosenbrock",
|
|
194
|
+
"schaffers_f7",
|
|
195
|
+
"BASIC_FUNCTIONS",
|
|
196
|
+
# Simple functions (F1-F10)
|
|
197
|
+
"CEC2017_F1",
|
|
198
|
+
"CEC2017_F2",
|
|
199
|
+
"CEC2017_F3",
|
|
200
|
+
"CEC2017_F4",
|
|
201
|
+
"CEC2017_F5",
|
|
202
|
+
"CEC2017_F6",
|
|
203
|
+
"CEC2017_F7",
|
|
204
|
+
"CEC2017_F8",
|
|
205
|
+
"CEC2017_F9",
|
|
206
|
+
"CEC2017_F10",
|
|
207
|
+
"SIMPLE_FUNCTIONS",
|
|
208
|
+
# Hybrid functions (F11-F20)
|
|
209
|
+
"CEC2017_F11",
|
|
210
|
+
"CEC2017_F12",
|
|
211
|
+
"CEC2017_F13",
|
|
212
|
+
"CEC2017_F14",
|
|
213
|
+
"CEC2017_F15",
|
|
214
|
+
"CEC2017_F16",
|
|
215
|
+
"CEC2017_F17",
|
|
216
|
+
"CEC2017_F18",
|
|
217
|
+
"CEC2017_F19",
|
|
218
|
+
"CEC2017_F20",
|
|
219
|
+
"HYBRID_FUNCTIONS",
|
|
220
|
+
# Composition functions (F21-F30)
|
|
221
|
+
"CEC2017_F21",
|
|
222
|
+
"CEC2017_F22",
|
|
223
|
+
"CEC2017_F23",
|
|
224
|
+
"CEC2017_F24",
|
|
225
|
+
"CEC2017_F25",
|
|
226
|
+
"CEC2017_F26",
|
|
227
|
+
"CEC2017_F27",
|
|
228
|
+
"CEC2017_F28",
|
|
229
|
+
"CEC2017_F29",
|
|
230
|
+
"CEC2017_F30",
|
|
231
|
+
"COMPOSITION_FUNCTIONS",
|
|
232
|
+
# Combined registries
|
|
233
|
+
"CEC2017_FUNCTIONS",
|
|
234
|
+
"ALL_CEC2017_CLASSES",
|
|
235
|
+
# Utilities
|
|
236
|
+
"get_function",
|
|
237
|
+
"data_available",
|
|
238
|
+
"get_rotation",
|
|
239
|
+
"get_rotation_cf",
|
|
240
|
+
"get_shift",
|
|
241
|
+
"get_shift_cf",
|
|
242
|
+
"get_shuffle",
|
|
243
|
+
"get_shuffle_cf",
|
|
244
|
+
"generate_rotation_matrix",
|
|
245
|
+
"generate_shift_vector",
|
|
246
|
+
"generate_shuffle",
|
|
247
|
+
"shift_rotate",
|
|
248
|
+
"shuffle_and_partition",
|
|
249
|
+
"SUPPORTED_DIMS",
|
|
250
|
+
]
|