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 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``). random_state : RNGLike, optional Random number generator. """ def __init__( self, default_init: Initializer, solutions: Population | List | np.ndarray, encoding: Encoding = None, random_state: Optional[RNGLike] = None ): assert len(solutions) > 0, "The solution set should not be empty." if isinstance(solutions, Population): infered_dimension = solutions.genotype_matrix.shape[1] else: infered_dimension = solutions[0].shape[0] super().__init__(dimension=infered_dimension, population_size=default_init.population_size, random_state=random_state, encoding=encoding) self.solutions = solutions self.default_init = default_init
[docs] def generate_random(self) -> VectorLike: return self.default_init.generate_random()
[docs] def generate_individual(self) -> VectorLike: """Return a randomly chosen individual from the stored solution set. Returns ------- VectorLike A 1-D array taken from the predefined solutions. """ indiv = None if isinstance(self.solutions, Population): indiv = self.random_state.choice(self.solutions.genotype_matrix, axis=0) elif isinstance(self.solutions, np.ndarray): indiv = self.random_state.choice(self.solutions, axis=0) else: raise TypeError("The provided population is not valid. It should be of type Population or numpy array.") return indiv
[docs] def generate_population(self, objfunc: ObjectiveFunc, 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): if self.solutions.population_size == n_individuals: population = copy(self.solutions) else: selection_idx = np.arange(n_individuals) % self.solutions.population_size population = self.solutions.take_selection(selection_idx) elif isinstance(self.solutions, np.ndarray): selection_idx = np.arange(n_individuals) % self.solutions.shape[0] population = Population(objfunc, self.solutions[selection_idx, :]) else: raise TypeError("The provided population is not valid. It should be of type Population or numpy array.") return population