Source code for metaheuristic_designer.initializers.seed_initializer
"""
Initializers that insert predefined solutions into the population.
"""
from __future__ import annotations
from typing import Iterable, Optional
from ..population import Population
from ..utils import MatrixLike, VectorLike
from ..initializer import Initializer
[docs]
class SeedProbInitializer(Initializer):
"""
Initializer that inserts a predefined solution with a given probability.
With probability `insert_prob`, a randomly chosen solution from the
provided set is used; otherwise a random individual is generated
by the fallback initializer.
Parameters
----------
default_init : Initializer
Fallback initializer for random individuals.
solutions : Population, Iterable[VectorLike] or MatrixLike
Set of predefined solutions to draw from.
insert_prob : float, optional
Probability of using a predefined solution (default 0.1).
random_state : RNGLike, optional
Random number generator.
"""
def __init__(
self, default_init: Initializer, solutions: Population | Iterable[VectorLike] | MatrixLike, insert_prob: float = 0.1, random_state=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)
self.default_init = default_init
self.solutions = solutions
self.insert_prob = insert_prob
[docs]
def generate_random(self) -> VectorLike:
"""Generate a random individual using the fallback initializer.
Returns
-------
VectorLike
A 1-D array generated by the fallback initializer.
"""
return self.default_init.generate_random()
[docs]
def generate_individual(self) -> VectorLike:
"""Generate an individual, possibly replacing it with a seeded solution.
With probability `insert_prob` a randomly chosen predefined solution
is returned; otherwise a new random individual is created by the
fallback initializer.
Returns
-------
ndarray
A 1-D array representing the individual.
"""
new_indiv = None
if self.random_state.random() < self.insert_prob:
new_solution = self.random_state.choice(self.solutions, axis=0)
new_indiv = new_solution
else:
new_indiv = self.default_init.generate_individual()
return new_indiv
[docs]
class SeedDetermInitializer(Initializer):
"""
Initializer that inserts a fixed number of predefined solutions.
The first `n_to_insert` individuals generated are taken from the
solution set (cycled if necessary); the remaining are created by
the fallback initializer.
Parameters
----------
default_init : Initializer
Fallback initializer for random individuals.
solutions : Population, Iterable[VectorLike] or MatrixLike
Set of predefined solutions to draw from.
n_to_insert : int, optional
Exact number of predefined solutions to insert. Defaults to
the size of the solution set.
random_state : RNGLike, optional
Random number generator.
"""
def __init__(
self, default_init: Initializer, solutions: Population | Iterable[VectorLike] | MatrixLike, n_to_insert: int = None, random_state=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)
self.default_init = default_init
self.solutions = solutions
self.number_to_insert = n_to_insert
if n_to_insert is None:
self.number_to_insert = len(solutions)
self.inserted = 0
[docs]
def generate_random(self) -> VectorLike:
"""Generate a random individual using the fallback initializer.
Returns
-------
VectorLike
A 1-D array generated by the fallback initializer.
"""
return self.default_init.generate_random()
[docs]
def generate_individual(self) -> VectorLike:
"""Return a predefined solution until the insertion quota is met.
The first `n_to_insert` individuals are taken from the solution set
(cycling if necessary). After that, random individuals are generated
by the fallback initializer.
Returns
-------
VectorLike
A 1-D array representing the individual.
"""
new_indiv = None
if self.inserted < self.number_to_insert:
new_solution = self.solutions[self.inserted % len(self.solutions)]
new_indiv = new_solution
else:
new_indiv = self.default_init.generate_individual()
self.inserted += 1
return new_indiv
[docs]
def generate_population(self, objfunc, n_individuals: Optional[int] = None) -> Population:
"""Create the population, resetting the insertion counter first.
Parameters
----------
objfunc : ObjectiveFunc
The objective function.
n_individuals : int, optional
Number of individuals to generate. Defaults to
:attr:`population_size`.
Returns
-------
Population
A population with the predefined solutions inserted at the
beginning.
"""
self.inserted = 0
return super().generate_population(objfunc, n_individuals)