ribs.archives.SlidingBoundariesArchive

class ribs.archives.SlidingBoundariesArchive(dims, ranges, seed=None, dtype=<class 'numpy.float64'>, remap_frequency=100, buffer_capacity=1000)[source]

An archive with a fixed number of sliding boundaries on each dimension.

This archive is the container described in Fontaine 2019. Just like the GridArchive, it can be visualized as an n-dimensional grid in the behavior space that is divided into a certain number of bins in each dimension. Internally, this archive stores a buffer with the buffer_capacity most recent solutions and uses them to determine the boundaries of the behavior characteristics along each dimension. After every remap_frequency solutions are inserted, the archive remaps the boundaries based on the solutions in the buffer.

Initially, the archive has no solutions, so it cannot automatically calculate the boundaries. Thus, until the first remap, this archive divides the behavior space defined by ranges into equally sized bins.

Overall, this archive attempts to make the distribution of the space illuminated by the archive more accurately match the true distribution of the behavior characteristics when they are not uniformly distributed.

Parameters
  • dims (array-like) – Number of bins in each dimension of the behavior space, e.g. [20, 30, 40] indicates there should be 3 dimensions with 20, 30, and 40 bins. (The number of dimensions is implicitly defined in the length of this argument).

  • ranges (array-like of (float, float)) – Initial upper and lower bound of each dimension of the behavior space, e.g. [(-1, 1), (-2, 2)] indicates the first dimension should have bounds \([-1,1]\) (inclusive), and the second dimension should have bounds \([-2,2]\) (inclusive). ranges should be the same length as dims.

  • seed (int) – Value to seed the random number generator. Set to None to avoid a fixed seed.

  • dtype (str or data-type) – Data type of the solutions, objective values, and behavior values. We only support "f" / np.float32 and "d" / np.float64.

  • remap_frequency (int) – Frequency of remapping. Archive will remap once after remap_frequency number of solutions has been found.

  • buffer_capacity (int) – Number of solutions to keep in the buffer. Solutions in the buffer will be reinserted into the archive after remapping.

Methods

__iter__()

Creates an iterator over the Elite’s in the archive.

__len__()

Number of elites in the archive.

add(solution, objective_value, behavior_values)

Attempts to insert a new solution into the archive.

as_pandas([include_solutions, include_metadata])

Converts the archive into an ArchiveDataFrame (a child class of pandas.DataFrame).

clear()

Removes all elites from the archive.

elite_with_behavior(behavior_values)

Gets the elite with behavior vals in the same bin as those specified.

get_index(behavior_values)

Returns indices of the behavior values within the archive’s grid.

get_random_elite()

Selects an elite uniformly at random from one of the archive’s bins.

initialize(solution_dim)

Initializes the archive by allocating storage space.

Attributes

behavior_dim

Dimensionality of the behavior space.

bins

Total number of bins in the archive.

boundaries

The dynamic boundaries of the bins in each dimension.

buffer_capacity

Maximum capacity of the buffer.

dims

Number of bins in each dimension.

dtype

The dtype of the solutions, objective values, and behavior values.

empty

Whether the archive is empty.

initialized

Whether the archive has been initialized by a call to initialize()

interval_size

The size of each dim (upper_bounds - lower_bounds).

lower_bounds

Lower bound of each dimension.

remap_frequency

Frequency of remapping.

solution_dim

Dimensionality of the solutions in the archive.

stats

Statistics about the archive.

upper_bounds

Upper bound of each dimension.

__iter__()

Creates an iterator over the Elite’s in the archive.

Example

for elite in archive:
    elite.sol
    elite.obj
    ...
__len__()

Number of elites in the archive.

add(solution, objective_value, behavior_values, metadata=None)[source]

Attempts to insert a new solution into the archive.

This method remaps the archive after every remap_frequency solutions are added. Remapping involves changing the boundaries of the archive to the percentage marks of the behavior values stored in the buffer and re-adding all of the solutions stored in the buffer and the current archive.

Parameters
Returns

See ArchiveBase.add()

as_pandas(include_solutions=True, include_metadata=False)

Converts the archive into an ArchiveDataFrame (a child class of pandas.DataFrame).

The implementation of this method in ArchiveBase creates a dataframe consisting of:

  • len(self._storage_dims) columns for the index, named index_0, index_1, ... In GridArchive and SlidingBoundariesArchive, there are behavior_dim columns. In CVTArchive, there is just one column. See get_index() for more info.

  • behavior_dim columns for the behavior characteristics, named behavior_0, behavior_1, ...

  • 1 column for the objective values, named objective

  • solution_dim columns for the solution vectors, named solution_0, solution_1, ...

  • 1 column for the metadata objects, named metadata

In short, the dataframe looks like this:

index_0

behavior_0

objective

solution_0

metadata

Compared to pandas.DataFrame, the ArchiveDataFrame adds methods and attributes which make it easier to manipulate archive data. For more information, refer to the ArchiveDataFrame documentation.

Parameters
  • include_solutions (bool) – Whether to include solution columns.

  • include_metadata (bool) – Whether to include the metadata column. Note that methods like to_csv() may not properly save the dataframe since the metadata objects may not be representable in a CSV.

Returns

See above.

Return type

ArchiveDataFrame

clear()

Removes all elites from the archive.

After this method is called, the archive will be empty.

elite_with_behavior(behavior_values)

Gets the elite with behavior vals in the same bin as those specified.

Since Elite is a namedtuple, the result can be unpacked (here we show how to ignore some of the fields):

sol, obj, beh, *_ = archive.elite_with_behavior(...)

Or the fields may be accessed by name:

elite = archive.elite_with_behavior(...)
elite.sol
elite.obj
...
Parameters

behavior_values (array-like) – Coordinates in behavior space.

Returns

  • If there is an elite with behavior values in the same bin as those specified, this Elite holds the info for that elite. In that case, beh (the behavior values) may not be exactly the same as the behavior values specified since the elite is only guaranteed to be in the same archive bin.

  • If no such elite exists, then all fields of the Elite are set to None. This way, tuple unpacking (e.g. sol, obj, beh, idx, meta = archive.elite_with_behavior(...)) still works.

Return type

Elite

get_index(behavior_values)[source]

Returns indices of the behavior values within the archive’s grid.

First, values are clipped to the bounds of the behavior space. Then, the values are mapped to bins via a binary search along the boundaries in each dimension.

The indices can be used to access boundaries of a behavior value’s bin. For example, the following retrieves the lower and upper bounds of the bin along dimension 0:

idx = archive.get_index(...)  # Other methods also return indices.
lower = archive.boundaries[0][idx[0]]
upper = archive.boundaries[0][idx[0] + 1]

See boundaries for more info.

Parameters

behavior_values (numpy.ndarray) – (behavior_dim,) array of coordinates in behavior space.

Returns

The grid indices.

Return type

tuple of int

get_random_elite()

Selects an elite uniformly at random from one of the archive’s bins.

Since Elite is a namedtuple, the result can be unpacked (here we show how to ignore some of the fields):

sol, obj, beh, *_ = archive.get_random_elite()

Or the fields may be accessed by name:

elite = archive.get_random_elite()
elite.sol
elite.obj
...
Returns

A randomly selected elite from the archive.

Return type

Elite

Raises

IndexError – The archive is empty.

initialize(solution_dim)

Initializes the archive by allocating storage space.

Child classes should call this method in their implementation if they are overriding it.

Parameters

solution_dim (int) – The dimension of the solution space.

Raises

RuntimeError – The archive is already initialized.

property behavior_dim

Dimensionality of the behavior space.

Type

int

property bins

Total number of bins in the archive.

Type

int

property boundaries

The dynamic boundaries of the bins in each dimension.

Entry i in this list is an array that contains the boundaries of the bins in dimension i. The array contains self.dims[i] + 1 entries laid out like this:

Archive bins:   | 0 | 1 |   ...   |    self.dims[i]    |
boundaries[i]:  0   1   2   self.dims[i] - 1     self.dims[i]

Thus, boundaries[i][j] and boundaries[i][j + 1] are the lower and upper bounds of bin j in dimension i. To access the lower bounds of all the bins in dimension i, use boundaries[i][:-1], and to access all the upper bounds, use boundaries[i][1:].

Type

list of numpy.ndarray

property buffer_capacity

Maximum capacity of the buffer.

Type

int

property dims

Number of bins in each dimension.

Type

(behavior_dim,) numpy.ndarray

property dtype

The dtype of the solutions, objective values, and behavior values.

Type

data-type

property empty

Whether the archive is empty.

Type

bool

property initialized

Whether the archive has been initialized by a call to initialize()

property interval_size

The size of each dim (upper_bounds - lower_bounds).

Type

(behavior_dim,) numpy.ndarray

property lower_bounds

Lower bound of each dimension.

Type

(behavior_dim,) numpy.ndarray

property remap_frequency

Frequency of remapping. Archive will remap once after remap_frequency number of solutions has been found.

Type

int

property solution_dim

Dimensionality of the solutions in the archive.

Type

int

property stats

Statistics about the archive.

See ArchiveStats for more info.

Type

ArchiveStats

property upper_bounds

Upper bound of each dimension.

Type

(behavior_dim,) numpy.ndarray