def _remap(self): """Remaps the archive. The boundaries are relocated to the percentage marks of the distribution of solutions stored in the archive. Also re-adds all of the solutions to the archive. Returns: tuple: The result of calling :meth:`ArchiveBase.add` on the last item in the buffer. """ # Sort all behavior values along the axis of each bc. sorted_bc = self._buffer.sorted_behavior_values # Calculate new boundaries. SlidingBoundariesArchive._remap_numba_helper(sorted_bc, self._buffer.size, self._boundaries, self._behavior_dim, self.dims) index_columns = tuple(map(list, zip(*self._occupied_indices))) old_sols = self._solutions[index_columns].copy() old_objs = self._objective_values[index_columns].copy() old_behs = self._behavior_values[index_columns].copy() self._reset_archive() for sol, obj, beh in zip(old_sols, old_objs, old_behs): # Add solutions from old archive. status, value = ArchiveBase.add(self, sol, obj, beh) for sol, obj, beh in self._buffer: # Add solutions from buffer. status, value = ArchiveBase.add(self, sol, obj, beh) return status, value
def add(self, solution, objective_value, behavior_values): """Attempts to insert a new solution into the archive. This method remaps the archive after every ``self.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. Args: solution (array-like): See :meth:`ArchiveBase.add` objective_value (float): See :meth:`ArchiveBase.add` behavior_values (array-like): See :meth:`ArchiveBase.add` Returns: See :meth:`ArchiveBase.add` """ solution = np.asarray(solution) behavior_values = np.asarray(behavior_values) self._buffer.add(solution, objective_value, behavior_values) self._total_num_sol += 1 if self._total_num_sol % self._remap_frequency == 0: status, value = self._remap() self._lower_bounds = np.array( [bound[0] for bound in self._boundaries]) self._upper_bounds = np.array([ bound[dim] for bound, dim in zip(self._boundaries, self._dims) ]) else: status, value = ArchiveBase.add(self, solution, objective_value, behavior_values) return status, value
def _remap(self): """Remaps the archive. The boundaries are relocated to the percentage marks of the distribution of solutions stored in the archive. Also re-adds all of the solutions to the archive. Returns: tuple: The result of calling :meth:`ArchiveBase.add` on the last item in the buffer. """ # Sort all behavior values along the axis of each bc. sorted_bc = self._buffer.sorted_behavior_values # Calculate new boundaries. SlidingBoundariesArchive._remap_numba_helper(sorted_bc, self._buffer.size, self._boundaries, self._behavior_dim, self.dims) # TODO (btjanaka): Add an option that allows adding solutions from the # previous archive that are not in the buffer. # Add all solutions to the new empty archive. self._reset_archive() for solution, objective_value, behavior_value in self._buffer: status, value = ArchiveBase.add(self, solution, objective_value, behavior_value) return status, value