fcmaes 1.1.3__py3-none-any.whl → 1.6.9__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.
- fcmaes/__init__.py +12 -2
- fcmaes/advretry.py +217 -159
- fcmaes/astro.py +143 -27
- fcmaes/bitecpp.py +107 -0
- fcmaes/cmaes.py +204 -173
- fcmaes/cmaescpp.py +253 -87
- fcmaes/crfmnes.py +339 -0
- fcmaes/crfmnescpp.py +273 -0
- fcmaes/dacpp.py +39 -51
- fcmaes/de.py +472 -0
- fcmaes/decpp.py +222 -64
- fcmaes/diversifier.py +357 -0
- fcmaes/evaluator.py +297 -14
- fcmaes/lib/libacmalib.dll +0 -0
- fcmaes/lib/libacmalib.dylib +0 -0
- fcmaes/lib/libacmalib.so +0 -0
- fcmaes/lib/libhbv.so +0 -0
- fcmaes/lib/liblrgv.so +0 -0
- fcmaes/lib/librw_top_trumps.dll +0 -0
- fcmaes/lib/librw_top_trumps.so +0 -0
- fcmaes/mapelites.py +737 -0
- fcmaes/mode.py +719 -0
- fcmaes/modecpp.py +470 -0
- fcmaes/moretry.py +270 -0
- fcmaes/multiretry.py +195 -0
- fcmaes/optimizer.py +883 -112
- fcmaes/pgpecpp.py +340 -0
- fcmaes/pygmoretry.py +10 -19
- fcmaes/retry.py +248 -121
- fcmaes/test_cma.py +207 -30
- fcmaes/testfun.py +38 -1
- {fcmaes-1.1.3.dist-info → fcmaes-1.6.9.dist-info}/METADATA +22 -12
- fcmaes-1.6.9.dist-info/RECORD +36 -0
- {fcmaes-1.1.3.dist-info → fcmaes-1.6.9.dist-info}/WHEEL +1 -1
- fcmaes/hhcpp.py +0 -114
- fcmaes/lib/libgtoplib.dll +0 -0
- fcmaes/lib/libgtoplib.so +0 -0
- fcmaes-1.1.3.dist-info/RECORD +0 -23
- {fcmaes-1.1.3.dist-info → fcmaes-1.6.9.dist-info}/LICENSE +0 -0
- {fcmaes-1.1.3.dist-info → fcmaes-1.6.9.dist-info}/top_level.txt +0 -0
fcmaes/diversifier.py
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
# Copyright (c) Dietmar Wolz.
|
|
2
|
+
#
|
|
3
|
+
# This source code is licensed under the MIT license found in the
|
|
4
|
+
# LICENSE file in the root directory.
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
""" Numpy based implementation of an diversifying wrapper / parallel retry mechanism.
|
|
8
|
+
|
|
9
|
+
Uses the archive from CVT MAP-Elites (https://arxiv.org/abs/1610.05729)
|
|
10
|
+
and generalizes ideas from CMA-ME (https://arxiv.org/pdf/1912.02400.pdf)
|
|
11
|
+
to other wrapped algorithms.
|
|
12
|
+
|
|
13
|
+
Both the parallel retry and the archive based modification of the fitness
|
|
14
|
+
function enhance the diversification of the optimization result.
|
|
15
|
+
The resulting archive may be stored and can be used to continue the
|
|
16
|
+
optimization later.
|
|
17
|
+
|
|
18
|
+
Requires a QD-fitness function returning both an fitness value and a
|
|
19
|
+
behavior vector used to determine the corresponding archive niche using
|
|
20
|
+
Voronoi tesselation.
|
|
21
|
+
|
|
22
|
+
Returns an archive of niche-elites containing also for each niche statistics
|
|
23
|
+
about the associated solutions.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
import numpy as np
|
|
27
|
+
from numpy.random import Generator, PCG64DXSM, SeedSequence
|
|
28
|
+
from multiprocessing import Process
|
|
29
|
+
from scipy.optimize import Bounds
|
|
30
|
+
from fcmaes.optimizer import dtime, de_cma, Optimizer
|
|
31
|
+
import multiprocessing as mp
|
|
32
|
+
import ctypes as ct
|
|
33
|
+
from time import perf_counter
|
|
34
|
+
from fcmaes.mapelites import Archive, update_archive, rng
|
|
35
|
+
from fcmaes import advretry
|
|
36
|
+
from fcmaes.evaluator import is_debug_active
|
|
37
|
+
from loguru import logger
|
|
38
|
+
import threadpoolctl
|
|
39
|
+
|
|
40
|
+
from typing import Optional, Callable, Tuple, Dict
|
|
41
|
+
from numpy.typing import ArrayLike
|
|
42
|
+
|
|
43
|
+
def minimize(qd_fitness: Callable[[ArrayLike], Tuple[float, np.ndarray]],
|
|
44
|
+
bounds: Bounds,
|
|
45
|
+
qd_bounds: Bounds,
|
|
46
|
+
niche_num: Optional[int] = 10000,
|
|
47
|
+
samples_per_niche: Optional[int] = 20,
|
|
48
|
+
max_evals: Optional[int] = None,
|
|
49
|
+
workers: Optional[int] = mp.cpu_count(),
|
|
50
|
+
archive: Optional[Archive] = None,
|
|
51
|
+
opt_params: Optional[Dict] = {},
|
|
52
|
+
use_stats: Optional[bool] = False,
|
|
53
|
+
) -> Archive:
|
|
54
|
+
|
|
55
|
+
"""Wraps an fcmaes optmizer/solver by hijacking its tell function.
|
|
56
|
+
Works as CVT Map-Elites in maintaining an archive of diverse elites.
|
|
57
|
+
But this archive is not used to derive solution vectors, but to reevaluate them.
|
|
58
|
+
For each fitness result it determines its niche. The "told" fitness is
|
|
59
|
+
determined relative to its local elite. If it is better the evaluated solution
|
|
60
|
+
becomes the new niche-elite.
|
|
61
|
+
This way the wrapped solver is "tricked" to follow a QD-goal: Finding empty niches
|
|
62
|
+
and improving all niches. This works not only for CMA-ES, but also for other
|
|
63
|
+
solvers: DE, CR-FM-NES and PGPE. Both their Python and C++ versions are supported.
|
|
64
|
+
|
|
65
|
+
Parameters
|
|
66
|
+
----------
|
|
67
|
+
solver : evolutionary algorithm, needs to support ask/tell
|
|
68
|
+
qd_fitness : callable
|
|
69
|
+
The objective function to be minimized. Returns a fitness value and a behavior vector.
|
|
70
|
+
``qd_fitness(x) -> float, array``
|
|
71
|
+
where ``x`` is an 1-D array with shape (n,)
|
|
72
|
+
bounds : `Bounds`
|
|
73
|
+
Bounds on variables. Instance of the `scipy.Bounds` class.
|
|
74
|
+
qd_bounds : `Bounds`
|
|
75
|
+
Bounds on behavior descriptors. Instance of the `scipy.Bounds` class.
|
|
76
|
+
niche_num : int, optional
|
|
77
|
+
Number of niches.
|
|
78
|
+
samples_per_niche : int, optional
|
|
79
|
+
Number of samples used for niche computation.
|
|
80
|
+
If samples_per_niche > 0 cvt-clustering is used, else grid-clustering is used.
|
|
81
|
+
max_evals : int, optional
|
|
82
|
+
Number of fitness evaluations.
|
|
83
|
+
workers : int, optional
|
|
84
|
+
Number of spawned parallel worker processes.
|
|
85
|
+
archive : Archive, optional
|
|
86
|
+
If defined MAP-elites is continued for this archive.
|
|
87
|
+
opt_params : dictionary, optional (or a list/tuple/array of these)
|
|
88
|
+
Parameters selecting and configuring the wrapped solver.
|
|
89
|
+
'solver' - supported are 'CMA','CMA_CPP','CRMFNES','CRMFNES_CPP','DE','DE_CPP','PGPE'
|
|
90
|
+
default is 'CMA_CPP'
|
|
91
|
+
'popsize' - population size, default = 32
|
|
92
|
+
'sigma' - initial distribution sigma, default = rg.uniform(0.03, 0.3)**2)
|
|
93
|
+
'mean' - initial distribution mean, default=rg.uniform(bounds.lb, bounds.ub))
|
|
94
|
+
'max_evals' - maximal number of evaluations per run, default = 50000
|
|
95
|
+
'stall_criterion' - how many iterations without progress allowed, default = 50 iterations
|
|
96
|
+
If a list/tuple/array of parameters are given, the corresponding solvers are called in a
|
|
97
|
+
sequence.
|
|
98
|
+
use_stats : bool, optional
|
|
99
|
+
If True, archive accumulates statistics of the solutions
|
|
100
|
+
|
|
101
|
+
Returns
|
|
102
|
+
-------
|
|
103
|
+
archive : Archive
|
|
104
|
+
Resulting archive of niches. Can be stored for later continuation of MAP-elites."""
|
|
105
|
+
|
|
106
|
+
if max_evals is None:
|
|
107
|
+
max_evals = workers*50000
|
|
108
|
+
dim = len(bounds.lb)
|
|
109
|
+
if archive is None:
|
|
110
|
+
archive = Archive(dim, qd_bounds, niche_num, use_stats)
|
|
111
|
+
archive.init_niches(samples_per_niche)
|
|
112
|
+
# initialize archive with random values
|
|
113
|
+
archive.xs_view[:] = rng.uniform(bounds.lb, bounds.ub, (niche_num, dim))
|
|
114
|
+
t0 = perf_counter()
|
|
115
|
+
qd_fitness.archive = archive # attach archive for logging
|
|
116
|
+
minimize_parallel_(archive, qd_fitness, bounds, workers, opt_params, max_evals)
|
|
117
|
+
if is_debug_active():
|
|
118
|
+
ys = np.sort(archive.get_ys())[:min(100, archive.capacity)] # best fitness values
|
|
119
|
+
logger.debug(f'best {min(ys):.3f} worst {max(ys):.3f} ' +
|
|
120
|
+
f'mean {np.mean(ys):.3f} stdev {np.std(ys):.3f} time {dtime(t0)} s')
|
|
121
|
+
return archive
|
|
122
|
+
|
|
123
|
+
def apply_advretry(fitness: Callable[[ArrayLike], float],
|
|
124
|
+
qd_fitness: Callable[[ArrayLike], Tuple[float, np.ndarray]],
|
|
125
|
+
bounds: Bounds,
|
|
126
|
+
archive: Archive,
|
|
127
|
+
optimizer: Optional[Optimizer] = None,
|
|
128
|
+
num_retries: Optional[int] = 1000,
|
|
129
|
+
workers: Optional[int] = mp.cpu_count(),
|
|
130
|
+
max_eval_fac: Optional[float] = 5.0,
|
|
131
|
+
xs: Optional[np.ndarray] = None,
|
|
132
|
+
ys: Optional[np.ndarray] = None,
|
|
133
|
+
x_conv: Callable[[ArrayLike], ArrayLike] = None):
|
|
134
|
+
|
|
135
|
+
"""Unifies the QD world with traditional optimization. It converts
|
|
136
|
+
a QD-archive into a multiprocessing store used by the fcmaes smart
|
|
137
|
+
boundary management meta algorithm (advretry). Then advretry is applied
|
|
138
|
+
to find the global optimum. Finally the updated store is feed back into
|
|
139
|
+
the QD-archive. For this we need a descriptor generating function
|
|
140
|
+
'descriptors' which may require reevaluation of the new solutions.
|
|
141
|
+
|
|
142
|
+
Parameters
|
|
143
|
+
----------
|
|
144
|
+
solver : evolutionary algorithm, needs to support ask/tell
|
|
145
|
+
fitness : callable
|
|
146
|
+
The objective function to be minimized. Returns a fitness value.
|
|
147
|
+
``fitness(x) -> float``
|
|
148
|
+
qf_fun : callable
|
|
149
|
+
Generates the descriptors for a solution. Returns a behavior vector.
|
|
150
|
+
``descriptors(x) -> array``
|
|
151
|
+
where ``x`` is an 1-D array with shape (n,)
|
|
152
|
+
bounds : `Bounds`
|
|
153
|
+
Bounds on variables. Instance of the `scipy.Bounds` class.
|
|
154
|
+
archive : Archive
|
|
155
|
+
Improves the solutions if this archive.
|
|
156
|
+
optimizer : optimizer.Optimizer, optional
|
|
157
|
+
Optimizer to use. Default is a sequence of differential evolution and CMA-ES.
|
|
158
|
+
num_retries : int, optional
|
|
159
|
+
Number of optimization runs.
|
|
160
|
+
workers : int, optional
|
|
161
|
+
Number of spawned parallel worker processes.
|
|
162
|
+
max_eval_fac : int, optional
|
|
163
|
+
Final limit of the number of function evaluations = max_eval_fac*min_evaluations
|
|
164
|
+
xs : ndarray, optional
|
|
165
|
+
Used to initialize advretry. If undefined the archive content is used.
|
|
166
|
+
If xs is defined, ys must be too
|
|
167
|
+
ys : ndarray, optional
|
|
168
|
+
Used to initialize advretry. If undefined the archive content is used.
|
|
169
|
+
x_conv : callable, optional
|
|
170
|
+
If defined converts the x in xs to solutions suitable for the given archive.
|
|
171
|
+
If undefined it is assumed that the x in xs are valid archive solutons.
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
if optimizer is None:
|
|
175
|
+
optimizer = de_cma(1500)
|
|
176
|
+
# generate advretry store
|
|
177
|
+
store = advretry.Store(fitness, bounds, num_retries=num_retries,
|
|
178
|
+
max_eval_fac=max_eval_fac)
|
|
179
|
+
|
|
180
|
+
# select only occupied entries
|
|
181
|
+
if xs is None:
|
|
182
|
+
ys = archive.get_ys()
|
|
183
|
+
valid = (ys < np.inf)
|
|
184
|
+
ys = ys[valid]
|
|
185
|
+
xs = archive.xs_view[valid]
|
|
186
|
+
t0 = perf_counter()
|
|
187
|
+
# transfer to advretry store
|
|
188
|
+
for i in range(len(ys)):
|
|
189
|
+
store.add_result(ys[i], xs[i], 1)
|
|
190
|
+
# perform parallel retry
|
|
191
|
+
advretry.retry(store, optimizer.minimize, workers=workers)
|
|
192
|
+
# transfer back to archive
|
|
193
|
+
xs = store.xs_view
|
|
194
|
+
if not x_conv is None:
|
|
195
|
+
xs = [x_conv(x) for x in xs]
|
|
196
|
+
yds = [qd_fitness(x) for x in xs]
|
|
197
|
+
descs = np.array([yd[1] for yd in yds])
|
|
198
|
+
ys = np.array([yd[0] for yd in yds])
|
|
199
|
+
niches = archive.index_of_niches(descs)
|
|
200
|
+
for i in range(len(ys)):
|
|
201
|
+
archive.set(niches[i], (ys[i], descs[i]), xs[i])
|
|
202
|
+
archive.argsort()
|
|
203
|
+
if is_debug_active():
|
|
204
|
+
ys = np.sort(archive.get_ys())[:min(100, archive.capacity)] # best fitness values
|
|
205
|
+
logger.debug(f'best {min(ys):.3f} worst {max(ys):.3f} ' +
|
|
206
|
+
f'mean {np.mean(ys):.3f} stdev {np.std(ys):.3f} time {dtime(t0)} s')
|
|
207
|
+
|
|
208
|
+
def minimize_parallel_(archive, fitness, bounds, workers, opt_params, max_evals):
|
|
209
|
+
sg = SeedSequence()
|
|
210
|
+
rgs = [Generator(PCG64DXSM(s)) for s in sg.spawn(workers)]
|
|
211
|
+
evals = mp.RawValue(ct.c_long, 0)
|
|
212
|
+
proc=[Process(target=run_minimize_,
|
|
213
|
+
args=(archive, fitness, bounds, rgs[p],
|
|
214
|
+
opt_params, p, workers, evals, max_evals)) for p in range(workers)]
|
|
215
|
+
[p.start() for p in proc]
|
|
216
|
+
[p.join() for p in proc]
|
|
217
|
+
|
|
218
|
+
def run_minimize_(archive, fitness, bounds, rg, opt_params, p, workers, evals, max_evals):
|
|
219
|
+
with threadpoolctl.threadpool_limits(limits=1, user_api="blas"):
|
|
220
|
+
if isinstance(opt_params, (list, tuple, np.ndarray)):
|
|
221
|
+
default_workers = int(workers/2) if len(opt_params) > 1 else workers
|
|
222
|
+
for params in opt_params: # call MAP-Elites
|
|
223
|
+
if 'elites' == params.get('solver'):
|
|
224
|
+
elites_workers = params.get('workers', default_workers)
|
|
225
|
+
if p < elites_workers:
|
|
226
|
+
run_map_elites_(archive, fitness, bounds, rg, evals, max_evals, params)
|
|
227
|
+
return
|
|
228
|
+
while evals.value < max_evals: # call solvers in loop
|
|
229
|
+
best_x = None
|
|
230
|
+
if isinstance(opt_params, (list, tuple, np.ndarray)):
|
|
231
|
+
for params in opt_params: # call in sequence
|
|
232
|
+
if 'elites' == params.get('solver'):
|
|
233
|
+
continue # ignore in loop
|
|
234
|
+
if best_x is None:
|
|
235
|
+
# selecting a niche elite is no improvement over random x0
|
|
236
|
+
x0 = None#, _, _ = archive.random_xs_one(select_n, rg)
|
|
237
|
+
best_x = minimize_(archive, fitness, bounds, rg, evals, max_evals, params,
|
|
238
|
+
x0 = x0)
|
|
239
|
+
else:
|
|
240
|
+
best_x = minimize_(archive, fitness, bounds, rg, evals, max_evals, params, x0 = best_x)
|
|
241
|
+
else:
|
|
242
|
+
minimize_(archive, fitness, bounds, rg, evals, max_evals, opt_params)
|
|
243
|
+
|
|
244
|
+
from fcmaes.mapelites import variation_, iso_dd_
|
|
245
|
+
|
|
246
|
+
def run_map_elites_(archive, fitness, bounds, rg, evals, max_evals, opt_params = {}):
|
|
247
|
+
popsize = opt_params.get('popsize', 32)
|
|
248
|
+
use_sbx = opt_params.get('use_sbx', True)
|
|
249
|
+
dis_c = opt_params.get('dis_c', 20)
|
|
250
|
+
dis_m = opt_params.get('dis_m', 20)
|
|
251
|
+
iso_sigma = opt_params.get('iso_sigma', 0.01)
|
|
252
|
+
line_sigma = opt_params.get('line_sigma', 0.2)
|
|
253
|
+
select_n = archive.capacity
|
|
254
|
+
while evals.value < max_evals:
|
|
255
|
+
if use_sbx:
|
|
256
|
+
pop = archive.random_xs(select_n, popsize, rg)
|
|
257
|
+
xs = variation_(pop, bounds.lb, bounds.ub, rg, dis_c, dis_m)
|
|
258
|
+
else:
|
|
259
|
+
x1 = archive.random_xs(select_n, popsize, rg)
|
|
260
|
+
x2 = archive.random_xs(select_n, popsize, rg)
|
|
261
|
+
xs = iso_dd_(x1, x2, bounds.lb, bounds.ub, rg, iso_sigma, line_sigma)
|
|
262
|
+
yds = [fitness(x) for x in xs]
|
|
263
|
+
evals.value += popsize
|
|
264
|
+
descs = np.array([yd[1] for yd in yds])
|
|
265
|
+
niches = archive.index_of_niches(descs)
|
|
266
|
+
for i in range(len(yds)):
|
|
267
|
+
archive.set(niches[i], yds[i], xs[i])
|
|
268
|
+
archive.argsort()
|
|
269
|
+
select_n = archive.get_occupied()
|
|
270
|
+
|
|
271
|
+
def minimize_(archive, fitness, bounds, rg, evals, max_evals, opt_params, x0 = None):
|
|
272
|
+
if 'BITE_CPP' == opt_params.get('solver'):
|
|
273
|
+
return run_bite_(archive, fitness, bounds, rg, evals, max_evals, opt_params, x0 = None)
|
|
274
|
+
else:
|
|
275
|
+
es = get_solver_(bounds, opt_params, rg, x0)
|
|
276
|
+
stall_criterion = opt_params.get('stall_criterion', 20)
|
|
277
|
+
max_evals_iter = opt_params.get('max_evals', 50000)
|
|
278
|
+
max_iters = int(max_evals_iter/es.popsize)
|
|
279
|
+
old_ys = None
|
|
280
|
+
last_improve = 0
|
|
281
|
+
best_x = None
|
|
282
|
+
best_y = np.inf
|
|
283
|
+
for iter in range(max_iters):
|
|
284
|
+
xs = es.ask()
|
|
285
|
+
ys, real_ys = update_archive(archive, xs, fitness)
|
|
286
|
+
evals.value += es.popsize
|
|
287
|
+
# update best real fitness
|
|
288
|
+
yi = np.argmin(real_ys)
|
|
289
|
+
ybest = real_ys[yi]
|
|
290
|
+
if ybest < best_y:
|
|
291
|
+
best_y = ybest
|
|
292
|
+
best_x = xs[yi]
|
|
293
|
+
if not old_ys is None:
|
|
294
|
+
if (np.sort(ys) < old_ys).any():
|
|
295
|
+
last_improve = iter
|
|
296
|
+
if last_improve + stall_criterion < iter:
|
|
297
|
+
break
|
|
298
|
+
stop = es.tell(ys)
|
|
299
|
+
if stop != 0 or evals.value >= max_evals:
|
|
300
|
+
break
|
|
301
|
+
old_ys = np.sort(ys)
|
|
302
|
+
return best_x # real best solution
|
|
303
|
+
|
|
304
|
+
from fcmaes import cmaes, cmaescpp, crfmnescpp, pgpecpp, decpp, crfmnes, de, bitecpp
|
|
305
|
+
|
|
306
|
+
def run_bite_(archive, fitness, bounds, rg, evals, max_evals, opt_params, x0 = None):
|
|
307
|
+
# BiteOpt doesn't support ask/tell, so we have to "patch" fitness. Note that Voronoi
|
|
308
|
+
# tesselation is more expensive if called for single behavior vectors and not for batches.
|
|
309
|
+
|
|
310
|
+
def fit(x: Callable[[ArrayLike], float]):
|
|
311
|
+
if evals.value >= max_evals:
|
|
312
|
+
return np.inf
|
|
313
|
+
evals.value += 1
|
|
314
|
+
ys, _ = update_archive(archive, [x], fitness)
|
|
315
|
+
return ys[0]
|
|
316
|
+
|
|
317
|
+
max_evals_iter = opt_params.get('max_evals', 50000)
|
|
318
|
+
stall_criterion = opt_params.get('stall_criterion', 20)
|
|
319
|
+
#popsize = opt_params.get('popsize', 0)
|
|
320
|
+
ret = bitecpp.minimize(fit, bounds, x0 = x0, M = 1,
|
|
321
|
+
stall_criterion = stall_criterion,
|
|
322
|
+
max_evaluations = max_evals_iter, rg = rg)
|
|
323
|
+
return ret.x
|
|
324
|
+
|
|
325
|
+
def get_solver_(bounds, opt_params, rg, x0 = None):
|
|
326
|
+
dim = len(bounds.lb)
|
|
327
|
+
popsize = opt_params.get('popsize', 31)
|
|
328
|
+
#sigma = opt_params.get('sigma',rg.uniform(0.03, 0.3)**2)
|
|
329
|
+
sigma = opt_params.get('sigma',rg.uniform(0.1, 0.5)**2)
|
|
330
|
+
#sigma = opt_params.get('sigma',rg.uniform(0.2, 0.5)**2)
|
|
331
|
+
#sigma = opt_params.get('sigma',rg.uniform(0.1, 0.5))
|
|
332
|
+
mean = opt_params.get('mean', rg.uniform(bounds.lb, bounds.ub)) \
|
|
333
|
+
if x0 is None else x0
|
|
334
|
+
name = opt_params.get('solver', 'CMA_CPP')
|
|
335
|
+
if name == 'CMA':
|
|
336
|
+
return cmaes.Cmaes(bounds, x0 = mean,
|
|
337
|
+
popsize = popsize, input_sigma = sigma, rg = rg)
|
|
338
|
+
elif name == 'CMA_CPP':
|
|
339
|
+
return cmaescpp.ACMA_C(dim, bounds, x0 = mean, #stop_hist = 0,
|
|
340
|
+
popsize = popsize, input_sigma = sigma, rg = rg)
|
|
341
|
+
elif name == 'CRMFNES':
|
|
342
|
+
return crfmnes.CRFMNES(dim, bounds, x0 = mean,
|
|
343
|
+
popsize = popsize, input_sigma = sigma, rg = rg)
|
|
344
|
+
elif name == 'CRMFNES_CPP':
|
|
345
|
+
return crfmnescpp.CRFMNES_C(dim, bounds, x0 = mean,
|
|
346
|
+
popsize = popsize, input_sigma = sigma, rg = rg)
|
|
347
|
+
elif name == 'DE':
|
|
348
|
+
return de.DE(dim, bounds, popsize = popsize, rg = rg)
|
|
349
|
+
elif name == 'DE_CPP':
|
|
350
|
+
return decpp.DE_C(dim, bounds, popsize = popsize, rg = rg)
|
|
351
|
+
elif name == 'PGPE':
|
|
352
|
+
return pgpecpp.PGPE_C(dim, bounds, x0 = mean,
|
|
353
|
+
popsize = popsize, input_sigma = sigma, rg = rg)
|
|
354
|
+
else:
|
|
355
|
+
print ("invalid solver")
|
|
356
|
+
return None
|
|
357
|
+
|