The core evolution loop follows the ask, eval, and tell pattern. To implement restarts (e.g., for IPOP-style algorithms), you can monitor a condition (like fitness convergence) and re-initialize the algorithm's state using the current mean solution when the condition is met.
Note: When calling es.tell, fitness is typically passed as a negative value (-fitness) if the algorithm expects minimization, or vice versa depending on the specific implementation requirements.
# 1. Instantiate algorithm
from evosax.algorithms import Open_ES as ES
import optax
es = ES(
population_size=16,
solution=solution,
optimizer=optax.adam(learning_rate=0.01),
std_schedule=optax.constant_schedule(0.1),
)
params = es.default_params
# 2. Initialize state
state = es.init(subkey, solution, params)
# 3. Run loop with restart logic
def fitness_std_cond(population, fitness, state, params):
return jnp.std(fitness) < 0.001
for i in range(num_generations):
# Ask
population, state = es.ask(key_ask, state, params)
# Eval
fitness, problem_state, info = problem.eval(key_eval, population, problem_state)
# Tell
state, metrics = es.tell(key_tell, population, -fitness, state, params)
# Restart Condition
if fitness_std_cond(population, fitness, state, params):
mean = es.get_mean(state)
state = es.init(subkey, mean, params)
for i in range(num_generations):
population, state = es.ask(key_ask, state, params)
fitness, problem_state, info = problem.eval(key_eval, population, problem_state)
state, metrics = es.tell(key_tell, population, -fitness, state, params)
if fitness_std_cond(population, fitness, state, params):
mean = es.get_mean(state)
state = es.init(subkey, mean, params)