Source code for metaheuristic_designer.initializers.direct_initializer

"""Initializer that uses a set of predefined solutions as the first generation."""

from __future__ import annotations
from copy import copy
from typing import Iterable, List, Optional
import numpy as np
from ..objective_function import ObjectiveFunc
from ..initializer import Initializer
from ..population import Population
from ..encoding import Encoding
from ..utils import RNGLike, VectorLike


[docs] class DirectInitializer(Initializer): """ Initializer that seeds the population with a given set of solutions. If the number of individuals requested exceeds the size of the stored set, individuals are cycled through. Random individuals from a fallback initializer are used when :meth:`generate_random` is called directly. Parameters ---------- default_init : Initializer Fallback initializer for :meth:`generate_random`. solutions : Population, list or ndarray The set of solutions to draw from. encoding : Encoding, optional Encoding attached to the population (used when *solutions* is a ``Population``). rng : RNGLike, optional Random number generator. """ def __init__( self, default_init: Initializer, solutions: Population | List | np.ndarray, encoding: Encoding = None, rng: Optional[RNGLike] = None ): assert len(solutions) > 0, "The solution set should not be empty." if isinstance(solutions, Population): inferred_dimension = solutions.genotype_matrix.shape[1] elif isinstance(solutions, Iterable): solutions = np.asarray(solutions) inferred_dimension = solutions.shape[1] else: raise TypeError("The provided population is not valid. It should be of type Population, numpy array or list of arrays.") self.solutions = solutions self.default_init = default_init self.init_counter = 0 super().__init__(dimension=inferred_dimension, population_size=len(solutions), rng=rng, encoding=encoding)
[docs] def generate_random(self) -> VectorLike: """Return a completely random individual generated from a fallback initializer strategy Returns ------- VectorLike A 1-D array sampled from a fallback distribution. """ return self.default_init.generate_random()
[docs] def generate_individual(self) -> VectorLike: """Return a chosen individual from the stored solution set in cyclic order. Returns ------- VectorLike A 1-D array taken from the predefined solutions. """ if isinstance(self.solutions, Population): population_matrix = self.solutions.genotype_matrix else: population_matrix = self.solutions indiv = population_matrix[self.init_counter] self.init_counter = (self.init_counter + 1) % len(population_matrix) return indiv
[docs] def generate_population(self, n_individuals: Optional[int] = None) -> Population: """Create a population by drawing from the stored solutions. Parameters ---------- objfunc : ObjectiveFunc The objective function. n_individuals : int, optional Number of individuals to generate. Defaults to :attr:`population_size`. Returns ------- Population A population built from the predefined solutions. """ if n_individuals is None: n_individuals = self.population_size if isinstance(self.solutions, Population): population_matrix = self.solutions.genotype_matrix else: population_matrix = self.solutions selection_idx = np.arange(n_individuals) % population_matrix.shape[0] population = Population(population_matrix[selection_idx, :], encoding=self.encoding) return population