Skip to content

Commit 381c7e6

Browse files
committed
Add EFTT benchmark results
1 parent edcd832 commit 381c7e6

File tree

4 files changed

+508
-0
lines changed

4 files changed

+508
-0
lines changed
Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
from typing import Callable
2+
import math
3+
4+
import torch
5+
from torch import Tensor
6+
7+
8+
PISTON_LBS = torch.tensor([30, 0.005, 0.002, 1000, 90_000, 290, 340])
9+
PISTON_UBS = torch.tensor([60, 0.020, 0.010, 5000, 110_000, 296, 360])
10+
11+
BOREHOLE_LBS = torch.tensor([0.05, 100, 63_070, 990, 63.1, 700, 1120, 9855])
12+
BOREHOLE_UBS = torch.tensor([0.15, 50_000, 115_600, 1110, 116.0, 820, 1680, 12_045])
13+
14+
OTL_CIRCUIT_LBS = torch.tensor([ 50, 25, 0.5, 1.2, 0.25, 50])
15+
OTL_CIRCUIT_UBS = torch.tensor([150, 70, 3.0, 2.5, 1.20, 300])
16+
17+
WING_WEIGHT_LBS = torch.tensor([150, 220, 6, -10, 16, 0.5, 0.08, 2.5, 1700, 0.025])
18+
WING_WEIGHT_UBS = torch.tensor([200, 300, 10, 10, 45, 1.0, 0.18, 6.0, 2500, 0.080])
19+
20+
21+
def rescale(ls: Tensor, lbs: float | Tensor, ubs: int | Tensor) -> Tensor:
22+
ls = 0.5 * (ls + 1.0)
23+
ls = lbs + ls * (ubs-lbs)
24+
return ls
25+
26+
27+
def ackley(ls: Tensor) -> Tensor:
28+
ls = rescale(ls, -32.768, 32.768)
29+
fxs = (
30+
- 20.0 * torch.exp(-0.2 * ls.square().mean(dim=1).sqrt())
31+
- torch.exp(torch.cos(2*torch.pi*ls).mean(dim=1)) + 20 + math.exp(1.0)
32+
)
33+
return fxs
34+
35+
36+
def alpine(ls: Tensor) -> Tensor:
37+
# Mistake in Strossner et al.: should have ls[:, :1].
38+
ls = rescale(ls, -10.0, 10.0)
39+
fxs = torch.sum(torch.abs(ls * torch.sin(ls) + 0.1 * ls), dim=1)
40+
return fxs
41+
42+
43+
def dixon(ls: Tensor) -> Tensor:
44+
ls = rescale(ls, -10.0, 10.0)
45+
fls = (ls[:, 0] - 1.0) ** 2
46+
for i in range(1, 7):
47+
fls += (i + 1) * (2.0 * ls[:, i] ** 2 - ls[:, i-1]) ** 2
48+
return fls
49+
50+
51+
def exponential(ls: Tensor) -> Tensor:
52+
fls = -torch.exp(-0.5 * torch.sum(ls**2, dim=1))
53+
return fls
54+
55+
56+
def griewank(ls: Tensor) -> Tensor:
57+
# Mistake in Strosser et al.: missing sqrt().
58+
ls = rescale(ls, -600.0, 600.0)
59+
is_ = torch.arange(1, 8)
60+
fls = (
61+
torch.sum((ls ** 2) / 4000.0, dim=1)
62+
- torch.prod(torch.cos(ls / is_), dim=1)
63+
+ 1
64+
)
65+
return fls
66+
67+
68+
def michaelwicz(ls: Tensor) -> Tensor:
69+
ls = rescale(ls, 0.0, torch.pi)
70+
is_ = torch.arange(1, 8)
71+
fls = -torch.sum(
72+
torch.sin(ls) * torch.sin(is_ * ls**2 / torch.pi) ** 20,
73+
dim=1
74+
)
75+
return fls
76+
77+
78+
def piston(ls: Tensor) -> Tensor:
79+
# Mistake in Strossner et al.: A not inside sqrt() when computing V.
80+
ls = rescale(ls, PISTON_LBS, PISTON_UBS)
81+
M, S, V0, k, P0, Ta, T0 = ls.T
82+
A = P0*S + 19.62*M - (k*V0)/S
83+
V = (S/(2*k)) * (torch.sqrt(A**2 + 4*k*(P0*V0/T0)*Ta) - A)
84+
fls = 2 * torch.pi * torch.sqrt(M / (k + S**2 * (P0*V0/T0) * (Ta / V**2)))
85+
return fls
86+
87+
88+
def qing(ls: Tensor) -> Tensor:
89+
ls = rescale(ls, 0.0, 500.0)
90+
is_ = torch.arange(1, 8)
91+
fls = torch.sum((ls**2 - is_)**2, dim=1)
92+
return fls
93+
94+
95+
def rastrigin(ls: Tensor) -> Tensor:
96+
ls = rescale(ls, -5.12, 5.12)
97+
fls = 70 + torch.sum(ls**2 - 10.0 * torch.cos(2.0*torch.pi*ls), dim=1)
98+
return fls
99+
100+
101+
def rosenbrock(ls: Tensor) -> Tensor:
102+
ls = rescale(ls, -2.048, 2.048)
103+
fls = torch.zeros((ls.shape[0],))
104+
for i in range(6):
105+
fls += (
106+
100.0 * torch.square(ls[:, i+1] - ls[:, i]**2)
107+
+ torch.square(1.0 - ls[:, i])
108+
)
109+
return fls
110+
111+
112+
def schaffer(ls: Tensor) -> Tensor:
113+
ls = rescale(ls, -100.0, 100.0)
114+
fls = torch.zeros((ls.shape[0],))
115+
for i in range(6):
116+
ls_sq = ls[:, i]**2 + ls[:, i+1]**2
117+
fls += (
118+
0.5
119+
+ (torch.sin(torch.sqrt(ls_sq)).square() - 0.5)
120+
/ (1.0 + 0.001 * ls_sq).square()
121+
)
122+
return fls
123+
124+
125+
def schwefel(ls: Tensor) -> Tensor:
126+
ls = rescale(ls, -500.0, 500.0)
127+
return 2932.8803 - torch.sum(ls*torch.sin(torch.abs(ls)**0.5), dim=1)
128+
129+
130+
def borehole(ls: Tensor) -> Tensor:
131+
ls = rescale(ls, BOREHOLE_LBS, BOREHOLE_UBS)
132+
rw, r, Tu, Hu, Tl, Hl, L, Kw = ls.T
133+
d1 = torch.log(r / rw)
134+
d2 = (2.0 * L * Tu) / (torch.log(r / rw) * rw**2 * Kw)
135+
d3 = Tu / Tl
136+
fls = 2*torch.pi*Tu*(Hu-Hl) / (d1 * (1.0 + d2 + d3))
137+
return fls
138+
139+
140+
def otl_circuit(ls: Tensor) -> Tensor:
141+
ls = rescale(ls, OTL_CIRCUIT_LBS, OTL_CIRCUIT_UBS)
142+
b1, b2, f, c1, c2, beta = ls.T
143+
x = beta*(c2+9.0)
144+
t1 = (12*b2/(b1+b2) + 0.74) * x / (x+f)
145+
t2 = (11.35*f) / (x+f)
146+
t3 = (0.74*f*x) / ((x+f)*c1)
147+
Vm = t1 + t2 + t3
148+
return Vm
149+
150+
151+
def robot_arm(ls: Tensor) -> Tensor:
152+
# Mistake in Strosser et al.: Indexing issues in sum.
153+
ts = rescale(ls[:, :4], 0.0, 2.0*torch.pi)
154+
Ls = rescale(ls[:, 4:], 0.0, 1.0)
155+
u = torch.zeros((ls.shape[0],))
156+
v = torch.zeros((ls.shape[0],))
157+
for i in range(4):
158+
theta_i = torch.sum(ts[:, :i+1], dim=1)
159+
u += Ls[:, i] * torch.cos(theta_i)
160+
v += Ls[:, i] * torch.sin(theta_i)
161+
return torch.sqrt(u**2 + v**2)
162+
163+
164+
def wing_weight(ls: Tensor) -> Tensor:
165+
ls = rescale(ls, WING_WEIGHT_LBS, WING_WEIGHT_UBS)
166+
Sw, Wf, A, delta, q, lamb, tc, Nz, Wd, Wp = ls.T
167+
delta *= (torch.pi / 180) # degrees to radians
168+
fls = (
169+
0.036
170+
* Sw**0.758
171+
* Wf**0.0035
172+
* (A / torch.cos(delta)**2)**0.6
173+
* q**0.006
174+
* lamb**0.04
175+
* (100*tc/torch.cos(delta))**-0.3
176+
* (Nz*Wd)**0.49
177+
+ Sw*Wp
178+
)
179+
return fls
180+
181+
182+
def friedman(ls: Tensor) -> Tensor:
183+
ls = rescale(ls, 0.0, 1.0)
184+
fls = (
185+
10.0 * torch.sin(torch.pi*ls[:, 0]*ls[:, 1])
186+
+ 20.0 * (ls[:, 2]-0.5)**2
187+
+ 10.0 * ls[:, 3]
188+
+ 5.0 * ls[:, 4]
189+
)
190+
return fls
191+
192+
193+
def gnl(ls: Tensor) -> Tensor:
194+
ls = rescale(ls, 0.0, 1.0)
195+
fls = (
196+
torch.exp(torch.sin((0.9*(ls[:, 0]+0.48))**10.0))
197+
+ ls[:, 1]*ls[:, 2]
198+
+ ls[:, 3]
199+
)
200+
return fls
201+
202+
203+
def dnp_8d(ls: Tensor) -> Tensor:
204+
ls = rescale(ls, 0.0, 1.0)
205+
t1 = 4.0 * (ls[:, 0] - 2.0 + 8.0*ls[:, 1] - 8.0*ls[:, 1]**2)**2
206+
t2 = (3.0 - 4.0*ls[:, 1])**2
207+
t3 = 16.0*torch.sqrt(ls[:, 2]+1.0) * (2.0*ls[:, 2] - 1.0)**2
208+
t4 = torch.zeros((ls.shape[0],))
209+
for i in range(3, 8):
210+
t4 += (i+1) * torch.log(1.0+torch.sum(ls[:, 2:i+1], dim=1))
211+
return t1 + t2 + t3 + t4
212+
213+
214+
def dnp_exp(ls: Tensor) -> Tensor:
215+
ls = rescale(ls, 0.0, 1.0)
216+
fls = 100 * (
217+
torch.exp(-2.0/(ls[:, 0]**1.75))
218+
+ torch.exp(-2.0/(ls[:, 1]**1.5))
219+
+ torch.exp(-2.0/(ls[:, 2]**1.25))
220+
)
221+
return fls
222+
223+
224+
def normalise_cs(cs: Tensor, dim: int, b: int, h: int) -> Tensor:
225+
c_norm = (dim**h / b) * cs.abs().sum()
226+
return cs / c_norm
227+
228+
229+
def build_genz_1(dim: int) -> Callable:
230+
# Oscillatory Genz
231+
232+
w = torch.rand(1)
233+
cs = torch.rand(dim)
234+
cs = normalise_cs(cs, dim, b=284.6, h=1.5)
235+
236+
def genz_1(ls: Tensor) -> Tensor:
237+
fls = torch.cos(2*torch.pi*w + torch.sum(cs*0.5*(ls+1), dim=1))
238+
return fls
239+
240+
return genz_1
241+
242+
243+
def build_genz_2(dim: int) -> Callable:
244+
# Corner peak Genz
245+
246+
cs = torch.rand(dim)
247+
cs = normalise_cs(cs, dim, b=185.0, h=2.0)
248+
249+
def genz_2(ls: Tensor) -> Tensor:
250+
fls = (1.0 + torch.sum(cs*0.5*(ls+1), dim=1)) ** -(dim-1)
251+
return fls
252+
253+
return genz_2
254+
255+
def build_genz_3(dim: int) -> Callable:
256+
# Continuous Genz
257+
258+
ws = torch.rand(dim)
259+
cs = torch.rand(dim)
260+
cs = normalise_cs(cs, dim, b=2040.0, h=2.0)
261+
262+
def genz_3(ls: Tensor) -> Tensor:
263+
fls = torch.exp(-torch.sum(cs**2 * torch.abs(0.5*(ls+1) - ws), dim=1))
264+
return fls
265+
266+
return genz_3
267+
268+
269+
FUNCTIONS = {
270+
r"Ackley": (ackley, 7),
271+
r"Alpine": (alpine, 7),
272+
r"Dixon": (dixon, 7),
273+
r"Exponential": (exponential, 7),
274+
r"Griewank": (griewank, 7),
275+
r"Michaelwicz": (michaelwicz, 7),
276+
r"Piston": (piston, 7),
277+
r"Qing": (qing, 7),
278+
r"Rastrigin": (rastrigin, 7),
279+
r"Rosenbrock": (rosenbrock, 7),
280+
r"Schaffer": (schaffer, 7),
281+
r"Schwefel": (schwefel, 7),
282+
r"Borehole": (borehole, 8),
283+
r"OTL Circuit": (otl_circuit, 6),
284+
r"Robot Arm": (robot_arm, 8),
285+
r"Wing Weight": (wing_weight, 10),
286+
r"Friedman": (friedman, 5),
287+
r"G\&L": (gnl, 6),
288+
r"D\&P 8D": (dnp_8d, 8),
289+
r"D\&P Exp": (dnp_exp, 3)
290+
}

0 commit comments

Comments
 (0)