ribs.emitters.EvolutionStrategyEmitter

class ribs.emitters.EvolutionStrategyEmitter(archive: ArchiveBase, *, x0: ArrayLike, sigma0: Float, ranker: collections.abc.Callable[[Int | None], RankerBase] | str = '2imp', es: collections.abc.Callable[..., EvolutionStrategyBase] | str = 'cma_es', es_kwargs: dict | None = None, selection_rule: 'mu' | 'filter' = 'filter', restart_rule: 'no_improvement' | 'basic' | int = 'no_improvement', bounds: Collection[tuple[None | Float, None | Float]] | None = None, lower_bounds: ArrayLike | None = None, upper_bounds: ArrayLike | None = None, batch_size: Int | None = None, seed: Int | None = None)[source]

Adapts a distribution of solutions with an ES.

This emitter originates in Fontaine 2020. The multivariate Gaussian solution distribution begins at x0 with standard deviation sigma0. Based on how the generated solutions are ranked (see ranker), the ES then adapts the mean and covariance of the distribution.

Parameters:
archive: ArchiveBase

Archive of solutions, e.g., ribs.archives.GridArchive.

x0: ArrayLike

Initial solution. Must be 1-dimensional.

sigma0: Float

Initial step size / standard deviation of the distribution from which solutions are sampled.

ranker: collections.abc.Callable[[Int | None], RankerBase] | str = '2imp'

The ranker is a RankerBase object that orders the solutions after they have been evaluated in the environment. This parameter may be a callable (e.g. a class or a lambda function) that takes in no parameters and returns an instance of RankerBase, or it may be a full or abbreviated ranker name as described in ribs.emitters.rankers.

es: collections.abc.Callable[..., EvolutionStrategyBase] | str = 'cma_es'

The evolution strategy is an EvolutionStrategyBase object that is used to adapt the distribution from which new solutions are sampled. This parameter may be a callable (e.g. a class or a lambda function) that takes in the parameters of EvolutionStrategyBase along with kwargs provided by the es_kwargs argument, or it may be a full or abbreviated optimizer name as described in ribs.emitters.opt.

es_kwargs: dict | None = None

Additional arguments to pass to the evolution strategy optimizer. See the evolution-strategy-based optimizers in ribs.emitters.opt for the arguments allowed by each optimizer.

selection_rule: 'mu' | 'filter' = 'filter'

Method for selecting parents for the evolution strategy. With “mu” selection, the first half of the solutions will be selected as parents, while in “filter”, any solutions that were added to the archive will be selected.

restart_rule: 'no_improvement' | 'basic' | int = 'no_improvement'

Method to use when checking for restarts. If given an integer, then the emitter will restart after this many iterations, where each iteration is a call to tell(). With “basic”, only the default CMA-ES convergence rules will be used, while with “no_improvement”, the emitter will restart when none of the proposed solutions were added to the archive.

bounds: Collection[tuple[None | Float, None | Float]] | None = None

Bounds of the solution space. Pass None to indicate there are no bounds. Alternatively, pass an array-like to specify the bounds for each dim. Each element in this array-like can be None to indicate no bound, or a tuple of (lower_bound, upper_bound), where lower_bound or upper_bound may be None to indicate no bound. Unbounded upper bounds are set to +inf, and unbounded lower bounds are set to -inf.

lower_bounds: ArrayLike | None = None

Instead of specifying bounds, lower_bounds and upper_bounds may be specified. This is useful if, for instance, solutions are multi-dimensional. Here, pass None to indicate there are no bounds (i.e., bounds are set to -inf), or pass an array specifying the lower bounds of the solution space.

upper_bounds: ArrayLike | None = None

Upper bounds of the solution space; see lower_bounds above. Pass None to indicate there are no bounds (i.e., bounds are set to inf).

batch_size: Int | None = None

Number of solutions to return in ask(). If not passed in, a batch size will be automatically calculated using the default CMA-ES rules.

seed: Int | None = None

Value to seed the random number generator. Set to None to avoid a fixed seed.

Raises:
  • ValueError – There is an error in x0 or initial_solutions.

  • ValueError – There is an error in the bounds configuration.

  • ValueError – If restart_rule, selection_rule, or ranker is invalid.

Methods

ask()

Samples new solutions from a multivariate Gaussian.

ask_dqd()

Generates solutions for which gradient information must be computed.

tell(solution, objective, measures, ...)

Gives the emitter results from evaluating solutions.

tell_dqd(solution, objective, measures, ...)

Gives the emitter results from evaluating the gradient of the solutions.

Attributes

archive

Stores solutions generated by this emitter.

batch_size

Number of solutions to return in ask().

itrs

The number of iterations for this emitter.

lower_bounds

(solution_dim,) array with lower bounds of solution space.

restarts

The number of restarts for this emitter.

solution_dim

Dimensionality of solutions produced by this emitter.

upper_bounds

(solution_dim,) array with upper bounds of solution space.

x0

Initial solution for the optimizer.

ask() ndarray[source]

Samples new solutions from a multivariate Gaussian.

The multivariate Gaussian is parameterized by the evolution strategy optimizer self._opt.

Returns:

(batch_size, solution_dim) array – a batch of new solutions to evaluate.

ask_dqd() ndarray

Generates solutions for which gradient information must be computed.

The solutions should be a (batch_size, solution_dim) array.

This method only needs to be implemented by emitters used in DQD. It returns an empty array by default.

tell(solution: numpy.typing.ArrayLike, objective: numpy.typing.ArrayLike, measures: numpy.typing.ArrayLike, add_info: dict[str, ndarray], **fields: numpy.typing.ArrayLike) None[source]

Gives the emitter results from evaluating solutions.

The solutions are ranked based on the rank() function defined by self._ranker. Then, the ranked solutions are passed to CMA-ES for adaptation.

This function also checks for restart condition and restarts CMA-ES when needed.

Parameters:
solution: numpy.typing.ArrayLike

(batch_size, solution_dim) array of solutions generated by this emitter’s ask() method.

objective: numpy.typing.ArrayLike

1D array containing the objective function value of each solution.

measures: numpy.typing.ArrayLike

(batch_size, measure space dimension) array with the measure space coordinates of each solution.

add_info: dict[str, ndarray]

Data returned from the archive add() method.

**fields: numpy.typing.ArrayLike

Additional data for each solution. Each argument should be an array with batch_size as the first dimension.

tell_dqd(solution: numpy.typing.ArrayLike, objective: numpy.typing.ArrayLike, measures: numpy.typing.ArrayLike, jacobian: numpy.typing.ArrayLike, add_info: dict[str, ndarray], **fields: numpy.typing.ArrayLike) None

Gives the emitter results from evaluating the gradient of the solutions.

This method is the counterpart of ask_dqd(). It is only used by DQD emitters.

Parameters:
solution: numpy.typing.ArrayLike

(batch_size, :attr:`solution_dim`) array of solutions generated by this emitter’s ask() method.

objective: numpy.typing.ArrayLike

1-dimensional array containing the objective function value of each solution.

measures: numpy.typing.ArrayLike

(batch_size, measure space dimension) array with the measure space coordinates of each solution.

jacobian: numpy.typing.ArrayLike

(batch_size, 1 + measure_dim, solution_dim) array consisting of Jacobian matrices of the solutions obtained from ask_dqd(). Each matrix should consist of the objective gradient of the solution followed by the measure gradients.

add_info: dict[str, ndarray]

Data returned from the archive add() method.

**fields: numpy.typing.ArrayLike

Additional data for each solution. Each argument should be an array with batch_size as the first dimension.

property archive : ArchiveBase

Stores solutions generated by this emitter.

property batch_size : int | integer

Number of solutions to return in ask().

property itrs : int

The number of iterations for this emitter.

Each iteration is a call to tell().

property lower_bounds : ndarray

(solution_dim,) array with lower bounds of solution space.

For instance, [-1, -1, -1] indicates that every dimension of the solution space has a lower bound of -1.

property restarts : int

The number of restarts for this emitter.

property solution_dim : int | integer | tuple[int | integer, ...]

Dimensionality of solutions produced by this emitter.

property upper_bounds : ndarray

(solution_dim,) array with upper bounds of solution space.

For instance, [1, 1, 1] indicates that every dimension of the solution space has an upper bound of 1.

property x0 : ndarray

Initial solution for the optimizer.