Skip to content

Commit b2a00ed

Browse files
Automatic build\nPublished by build of: SciML/SciMLBenchmarks.jl@e01de71
1 parent d9bc4fa commit b2a00ed

8 files changed

Lines changed: 451 additions & 0 deletions
Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
1+
---
2+
author: "Jonathan Bieler, Chris Rackauckas"
3+
title: "Black-Box Global Optimizer Benchmarks"
4+
---
5+
6+
7+
In this benchmark we will run the [BlackboxGlobalOptimization.jl](https://github.com/jonathanBieler/BlackBoxOptimizationBenchmarking.jl)
8+
benchmarks, a set of global optimization benchmarks on the [Optimization.jl](https://github.com/SciML/Optimization.jl)
9+
interface that test a wide variety of behaviors. This tests time and iterations vs accuracy,
10+
i.e. for a given amount of time to the optimizer, what percentage of problems from the set is
11+
it able to solve. This gives a global view of which methods are the most efficient at finding
12+
difficult global optima.
13+
14+
## Setup
15+
16+
```julia
17+
using BlackBoxOptimizationBenchmarking, Plots, Optimization, Memoize, Statistics
18+
import BlackBoxOptimizationBenchmarking.Chain
19+
const BBOB = BlackBoxOptimizationBenchmarking
20+
21+
using OptimizationBBO, OptimizationOptimJL, OptimizationEvolutionary, OptimizationNLopt
22+
using OptimizationMetaheuristics, OptimizationNOMAD, OptimizationPRIMA, OptimizationOptimisers
23+
```
24+
25+
26+
```julia
27+
chain = (t; isboxed=false) -> Chain(
28+
BenchmarkSetup(t, isboxed = isboxed),
29+
BenchmarkSetup(NelderMead(), isboxed = false),
30+
0.9
31+
)
32+
33+
test_functions = BBOB.list_functions()
34+
dimension = 3
35+
run_length = round.(Int, 10 .^ LinRange(1,5,30))
36+
37+
@memoize run_bench(algo) = BBOB.benchmark(setup[algo], test_functions, run_length, Ntrials=40, dimension = dimension)
38+
```
39+
40+
```
41+
run_bench (generic function with 1 method)
42+
```
43+
44+
45+
46+
```julia
47+
setup = Dict(
48+
"NelderMead" => NelderMead(),
49+
#Optim.BFGS(),
50+
#"NLopt.GN_MLSL_LDS" => chain(NLopt.GN_MLSL_LDS(), isboxed=true), # gives me errors
51+
"NLopt.GN_CRS2_LM()" => chain(NLopt.GN_CRS2_LM(), isboxed=true),
52+
"NLopt.GN_DIRECT()" => chain(NLopt.GN_DIRECT(), isboxed=true),
53+
"NLopt.GN_ESCH()" => chain(NLopt.GN_ESCH(), isboxed=true),
54+
"OptimizationEvolutionary.GA()" => chain(OptimizationEvolutionary.GA(), isboxed=true),
55+
"OptimizationEvolutionary.DE()" => chain(OptimizationEvolutionary.DE(), isboxed=true),
56+
"OptimizationEvolutionary.ES()" => chain(OptimizationEvolutionary.ES(), isboxed=true),
57+
"Optim.SAMIN" => chain(SAMIN(verbosity=0), isboxed=true),
58+
"BBO_adaptive_de_rand_1_bin" => chain(BBO_adaptive_de_rand_1_bin(), isboxed=true),
59+
"BBO_adaptive_de_rand_1_bin_radiuslimited" => chain(BBO_adaptive_de_rand_1_bin_radiuslimited(), isboxed=true), # same as BBO_adaptive_de_rand_1_bin
60+
"BBO_separable_nes" => chain(BBO_separable_nes(), isboxed=true),
61+
"BBO_de_rand_2_bin" => chain(BBO_de_rand_2_bin(), isboxed=true),
62+
#"BBO_xnes" => chain(BBO_xnes(), isboxed=true), # good but slow
63+
#"BBO_dxnes" => chain(BBO_dxnes(), isboxed=true),
64+
"OptimizationMetaheuristics.ECA" => chain(OptimizationMetaheuristics.ECA(), isboxed=true),
65+
#"OptimizationMetaheuristics.CGSA" => () -> chain(OptimizationMetaheuristics.CGSA(), isboxed=true), #give me strange results
66+
"OptimizationMetaheuristics.DE" => chain(OptimizationMetaheuristics.DE(), isboxed=true),
67+
"Optimisers.AdamW" => chain(Optimisers.AdamW(), isboxed=false),
68+
"Optimisers.RMSProp" => chain(Optimisers.RMSProp(), isboxed=false),
69+
# "NOMADOpt" => chain(NOMADOpt()), too much printing
70+
# "OptimizationPRIMA.UOBYQA()" => chain(OptimizationPRIMA.UOBYQA()), :StackOverflowError?
71+
# "OptimizationPRIMA.NEWUOA()" => OptimizationPRIMA.UOBYQA(),
72+
#
73+
)
74+
```
75+
76+
```
77+
Dict{String, Any} with 16 entries:
78+
"OptimizationEvolutionar… => Chain(GA → NelderMead)…
79+
"BBO_separable_nes" => Chain(BBO_separable_nes → NelderMead)…
80+
"NelderMead" => NelderMead{AffineSimplexer, AdaptiveParamete
81+
rs}(…
82+
"BBO_adaptive_de_rand_1_… => Chain(BBO_adaptive_de_rand_1_bin → NelderMea
83+
d)…
84+
"BBO_adaptive_de_rand_1_… => Chain(BBO_adaptive_de_rand_1_bin_radiuslimit
85+
ed →…
86+
"BBO_de_rand_2_bin" => Chain(BBO_de_rand_2_bin → NelderMead)…
87+
"NLopt.GN_DIRECT()" => Chain(Algorithm → NelderMead)…
88+
"NLopt.GN_ESCH()" => Chain(Algorithm → NelderMead)…
89+
"OptimizationMetaheurist… => Chain(Algorithm → NelderMead)…
90+
"OptimizationEvolutionar… => Chain(ES → NelderMead)…
91+
"Optimisers.AdamW" => Chain(AdamW → NelderMead)…
92+
"OptimizationEvolutionar… => Chain(DE → NelderMead)…
93+
"Optimisers.RMSProp" => Chain(RMSProp → NelderMead)…
94+
"OptimizationMetaheurist… => Chain(Algorithm → NelderMead)…
95+
"NLopt.GN_CRS2_LM()" => Chain(Algorithm → NelderMead)…
96+
"Optim.SAMIN" => Chain(SAMIN → NelderMead)…
97+
```
98+
99+
100+
101+
102+
103+
## Test one optimizer
104+
105+
```julia
106+
@time b = BBOB.benchmark(
107+
chain(OptimizationMetaheuristics.CGSA(), isboxed=true),
108+
test_functions[1:10], 100:500:10_000, Ntrials=10, dimension = 3
109+
)
110+
111+
plot(b)
112+
```
113+
114+
```
115+
11.445198 seconds (72.19 M allocations: 6.253 GiB, 5.34% gc time, 45.68% c
116+
ompilation time: 4% of which was recompilation)
117+
```
118+
119+
120+
![](figures/blackbox_global_optimizers_4_1.png)
121+
122+
123+
124+
## Test one test function (Rastrigin)
125+
126+
```julia
127+
Δf = 1e-6
128+
f = test_functions[3]
129+
130+
single_setup = BenchmarkSetup(NLopt.GN_CRS2_LM(), isboxed=true)
131+
132+
sol = [BBOB.solve_problem(single_setup, f, 3, 5_000) for in in 1:10]
133+
@info [sol.objective < Δf + f.f_opt for sol in sol]
134+
135+
p = plot(f, size = (600,600), zoom = 1.5)
136+
for sol in sol
137+
scatter!(sol.u[1:1], sol.u[2:2], label="", c="blue", marker = :xcross, markersize=5, markerstrokewidth=0)
138+
end
139+
p
140+
```
141+
142+
![](figures/blackbox_global_optimizers_5_1.png)
143+
144+
145+
146+
## Test all
147+
148+
```julia
149+
results = Array{BBOB.BenchmarkResults}(undef, length(setup))
150+
151+
Threads.@threads for (i,algo) in collect(enumerate(keys(setup)))
152+
results[i] = run_bench(algo)
153+
end
154+
155+
results
156+
```
157+
158+
```
159+
16-element Vector{BlackBoxOptimizationBenchmarking.BenchmarkResults}:
160+
BenchmarkResults :
161+
Run length : [10, 14, 19, 26, 36, 49, 67, 92, 127, 174 … 5736, 7880, 1082
162+
6, 14874, 20434, 28072, 38566, 52983, 72790, 100000]
163+
Success rate : [0.0, 0.0, 0.0, 0.0, 0.0025, 0.00125, 0.0125, 0.015, 0.02625
164+
, 0.03 … 0.525, 0.5225, 0.53125, 0.53125, 0.52625, 0.52375, 0.5425, 0.526
165+
25, 0.52875, 0.53125]
166+
BenchmarkResults :
167+
Run length : [10, 14, 19, 26, 36, 49, 67, 92, 127, 174 … 5736, 7880, 1082
168+
6, 14874, 20434, 28072, 38566, 52983, 72790, 100000]
169+
Success rate : [0.01875, 0.03, 0.0425, 0.04625, 0.05, 0.0525, 0.07125, 0.10
170+
375, 0.17625, 0.27625 … 0.63375, 0.6275, 0.64, 0.66125, 0.665, 0.65375, 0
171+
.64, 0.6475, 0.66, 0.6475]
172+
BenchmarkResults :
173+
Run length : [10, 14, 19, 26, 36, 49, 67, 92, 127, 174 … 5736, 7880, 1082
174+
6, 14874, 20434, 28072, 38566, 52983, 72790, 100000]
175+
Success rate : [0.01625, 0.03, 0.04, 0.04625, 0.05, 0.05625, 0.08125, 0.146
176+
25, 0.25625, 0.35625 … 0.53875, 0.5375, 0.52875, 0.5425, 0.53375, 0.5275,
177+
0.53875, 0.5425, 0.53375, 0.53125]
178+
BenchmarkResults :
179+
Run length : [10, 14, 19, 26, 36, 49, 67, 92, 127, 174 … 5736, 7880, 1082
180+
6, 14874, 20434, 28072, 38566, 52983, 72790, 100000]
181+
Success rate : [0.00125, 0.005, 0.005, 0.00875, 0.01, 0.02, 0.02875, 0.0412
182+
5, 0.04625, 0.05 … 0.8375, 0.92, 0.92875, 0.93875, 0.95875, 0.97375, 0.99
183+
, 0.99875, 0.99875, 0.99625]
184+
BenchmarkResults :
185+
Run length : [10, 14, 19, 26, 36, 49, 67, 92, 127, 174 … 5736, 7880, 1082
186+
6, 14874, 20434, 28072, 38566, 52983, 72790, 100000]
187+
Success rate : [0.00125, 0.0025, 0.005, 0.01, 0.01875, 0.0175, 0.0375, 0.04
188+
, 0.0475, 0.05 … 0.855, 0.92375, 0.945, 0.95875, 0.95875, 0.96375, 0.9662
189+
5, 0.96, 0.95625, 0.965]
190+
BenchmarkResults :
191+
Run length : [10, 14, 19, 26, 36, 49, 67, 92, 127, 174 … 5736, 7880, 1082
192+
6, 14874, 20434, 28072, 38566, 52983, 72790, 100000]
193+
Success rate : [0.00125, 0.00375, 0.00625, 0.005, 0.01625, 0.0225, 0.0275,
194+
0.04125, 0.04875, 0.04875 … 0.7675, 0.84, 0.89125, 0.905, 0.91625, 0.9337
195+
5, 0.93875, 0.94875, 0.96375, 0.96375]
196+
BenchmarkResults :
197+
Run length : [10, 14, 19, 26, 36, 49, 67, 92, 127, 174 … 5736, 7880, 1082
198+
6, 14874, 20434, 28072, 38566, 52983, 72790, 100000]
199+
Success rate : [0.0, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05
200+
… 0.6, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7]
201+
BenchmarkResults :
202+
Run length : [10, 14, 19, 26, 36, 49, 67, 92, 127, 174 … 5736, 7880, 1082
203+
6, 14874, 20434, 28072, 38566, 52983, 72790, 100000]
204+
Success rate : [0.0, 0.0025, 0.00125, 0.0025, 0.00375, 0.0125, 0.0175, 0.03
205+
, 0.0475, 0.05 … 0.57875, 0.59, 0.62875, 0.63, 0.6375, 0.635, 0.63875, 0.
206+
6525, 0.6425, 0.64]
207+
BenchmarkResults :
208+
Run length : [10, 14, 19, 26, 36, 49, 67, 92, 127, 174 … 5736, 7880, 1082
209+
6, 14874, 20434, 28072, 38566, 52983, 72790, 100000]
210+
Success rate : [0.0425, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.1
211+
… 0.5, 0.5, 0.5, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55]
212+
BenchmarkResults :
213+
Run length : [10, 14, 19, 26, 36, 49, 67, 92, 127, 174 … 5736, 7880, 1082
214+
6, 14874, 20434, 28072, 38566, 52983, 72790, 100000]
215+
Success rate : [0.0, 0.0, 0.0, 0.0, 0.005, 0.0025, 0.0075, 0.01, 0.0175, 0.
216+
02875 … 0.52, 0.525, 0.5275, 0.54, 0.535, 0.53375, 0.5275, 0.54125, 0.538
217+
75, 0.53875]
218+
BenchmarkResults :
219+
Run length : [10, 14, 19, 26, 36, 49, 67, 92, 127, 174 … 5736, 7880, 1082
220+
6, 14874, 20434, 28072, 38566, 52983, 72790, 100000]
221+
Success rate : [0.0, 0.0, 0.00125, 0.0, 0.0, 0.00125, 0.00875, 0.01375, 0.0
222+
275, 0.0325 … 0.53, 0.5275, 0.53375, 0.53375, 0.53625, 0.545, 0.54125, 0.
223+
5525, 0.54375, 0.5575]
224+
BenchmarkResults :
225+
Run length : [10, 14, 19, 26, 36, 49, 67, 92, 127, 174 … 5736, 7880, 1082
226+
6, 14874, 20434, 28072, 38566, 52983, 72790, 100000]
227+
Success rate : [0.0, 0.0, 0.0, 0.0, 0.00125, 0.0, 0.0075, 0.0175, 0.03125,
228+
0.035 … 0.5225, 0.51375, 0.52625, 0.54, 0.54375, 0.53, 0.54, 0.53625, 0.5
229+
3625, 0.53625]
230+
BenchmarkResults :
231+
Run length : [10, 14, 19, 26, 36, 49, 67, 92, 127, 174 … 5736, 7880, 1082
232+
6, 14874, 20434, 28072, 38566, 52983, 72790, 100000]
233+
Success rate : [0.0, 0.0, 0.0, 0.0, 0.00625, 0.00375, 0.01125, 0.00875, 0.0
234+
225, 0.0375 … 0.52125, 0.52125, 0.52125, 0.52875, 0.53625, 0.5275, 0.5525
235+
, 0.545, 0.53875, 0.54875]
236+
BenchmarkResults :
237+
Run length : [10, 14, 19, 26, 36, 49, 67, 92, 127, 174 … 5736, 7880, 1082
238+
6, 14874, 20434, 28072, 38566, 52983, 72790, 100000]
239+
Success rate : [0.045, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.1
240+
… 0.5, 0.5, 0.5, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55, 0.55]
241+
BenchmarkResults :
242+
Run length : [10, 14, 19, 26, 36, 49, 67, 92, 127, 174 … 5736, 7880, 1082
243+
6, 14874, 20434, 28072, 38566, 52983, 72790, 100000]
244+
Success rate : [0.00125, 0.00125, 0.005, 0.00875, 0.015, 0.04125, 0.04125,
245+
0.0475, 0.05, 0.05 … 0.80125, 0.785, 0.79625, 0.77625, 0.8, 0.79625, 0.79
246+
625, 0.8, 0.79125, 0.79875]
247+
BenchmarkResults :
248+
Run length : [10, 14, 19, 26, 36, 49, 67, 92, 127, 174 … 5736, 7880, 1082
249+
6, 14874, 20434, 28072, 38566, 52983, 72790, 100000]
250+
Success rate : [0.00125, 0.01, 0.01125, 0.02, 0.0375, 0.03875, 0.0475, 0.04
251+
875, 0.05125, 0.05 … 0.64, 0.73625, 0.80125, 0.7775, 0.8175, 0.83875, 0.8
252+
175, 0.8125, 0.82125, 0.82625]
253+
```
254+
255+
256+
257+
```julia
258+
labels = collect(keys(setup))
259+
idx = sortperm([b.success_rate[end] for b in results], rev=true)
260+
261+
p = plot(xscale = :log10, legend = :outerright, size = (700,350), margin=10Plots.px, dpi=200)
262+
for i in idx
263+
plot!(results[i], label = labels[i], showribbon=false, lw=2.5, xlim = (1,1e5), x = :run_length)
264+
end
265+
p
266+
```
267+
268+
![](figures/blackbox_global_optimizers_7_1.png)
269+
270+
```julia
271+
success_rate_per_function = reduce(hcat, b.success_rate_per_function for b in results)
272+
273+
idx = sortperm(mean(success_rate_per_function, dims=1)[:], rev=false)
274+
idxfunc = sortperm(mean(success_rate_per_function, dims=2)[:], rev=true)
275+
idxfunc = 1:length(test_functions)
276+
277+
p = heatmap(
278+
string.(test_functions)[idxfunc], labels[idx], success_rate_per_function[idxfunc, idx]',
279+
cmap = :RdYlGn,
280+
xticks = :all,
281+
yticks = :all,
282+
xrotation = 45,
283+
dpi = 200,
284+
)
285+
```
286+
287+
![](figures/blackbox_global_optimizers_8_1.png)
288+
289+
```julia
290+
labels = collect(keys(setup))
291+
idx = sortperm([b.distance_to_minimizer[end] for b in results], rev=false)
292+
293+
p = plot(xscale = :log10, legend = :outerright, size = (900,500), margin=10Plots.px, ylim = (0,5))
294+
for i in idx
295+
plot!(
296+
results[i].run_length, results[i].distance_to_minimizer, label = labels[i],
297+
showribbon=false, lw=2, xlim = (1,1e5),
298+
xlabel = "Iterations", ylabel = "Mean distance to minimum"
299+
)
300+
end
301+
p
302+
```
303+
304+
![](figures/blackbox_global_optimizers_9_1.png)
305+
306+
```julia
307+
ref = findfirst("NelderMead" .== labels)
308+
runtimes = getfield.(results, :runtime)
309+
runtimes = runtimes ./ runtimes[ref]
310+
311+
bar(
312+
labels, runtimes, xrotation = :45, xticks = :all, ylabel = "Run time relative to NM",
313+
yscale = :log10, yticks = [0.1,1,10,100],
314+
legend = false, margin = 25Plots.px
315+
)
316+
```
317+
318+
![](figures/blackbox_global_optimizers_10_1.png)
47.5 KB
Loading
21.5 KB
Loading
170 KB
Loading
178 KB
Loading
188 KB
Loading
120 KB
Loading

0 commit comments

Comments
 (0)