Source code for metaheuristic_designer.encoding

"""
Base class for the Encoding module.

This module implements a way to have a different representation in the inner working
of the algorithm and the result of the procedure.
"""

from __future__ import annotations
from typing import Iterable, Callable
from abc import ABC, abstractmethod
from .parametrizable_mixin import ParametrizableMixin
from .utils import MatrixLike


[docs] class Encoding(ParametrizableMixin, ABC): """Translate between internal genotypes and problem-specific phenotypes. An :class:`Encoding` is responsible for converting a population matrix (the internal representation used by operators) into a collection of solutions that the objective function understands, and vice versa. Parameters ---------- decode_as_array : bool, optional If ``True``, :meth:`decode` returns a NumPy array instead of an iterable of arbitrary objects. Default ``False``. name : str, optional Display name for this encoding. **kwargs Additional keyword arguments stored as schedulable parameters. """ def __init__(self, decode_as_array: bool = False, name=None, **kwargs): super().__init__() self.name = name self.decode_as_array = decode_as_array self.store_kwargs(**kwargs)
[docs] def gather_params(self) -> dict: """ Overridable thin wrapper around get_params """ return self.get_params()
[docs] @abstractmethod def encode(self, solutions: Iterable) -> MatrixLike: """ Encodes a list of solutions to our problem to an population matrix. Parameters ---------- solutions: Iterable Solutions that should be encoded. Returns ------- population: ndarray Population array. """
[docs] @abstractmethod def decode(self, population: MatrixLike) -> Iterable: """ Decodes a population matrix into a list/array of solutions. Parameters ---------- population: ndarray Population that should be decoded. Returns ------- solutions: Iterable List/array of solutions. """
[docs] def get_state(self) -> dict: return {}
[docs] class DefaultEncoding(Encoding): """Identity encoding - the internal genotype is used directly. No transformation is applied; :meth:`encode` and :meth:`decode` return their arguments unchanged. This is the encoding used when no other is specified. Parameters ---------- decode_as_array : bool, optional See :class:`Encoding`. Default ``True``. """ def __init__(self, decode_as_array: bool = True): super().__init__(decode_as_array=decode_as_array)
[docs] def encode(self, solution: Iterable) -> MatrixLike: return solution
[docs] def decode(self, population: MatrixLike) -> Iterable: return population
[docs] class EncodingFromLambda(Encoding): """Encoding built from two callables. Parameters ---------- encode_fn : callable ``(solutions) -> population_matrix``. decode_fn : callable ``(population_matrix) -> solutions``. decode_as_array : bool, optional See :class:`Encoding`. **kwargs Forwarded to :class:`Encoding`. """ def __init__(self, encode_fn: Callable, decode_fn: Callable, **kwargs): super().__init__(**kwargs) self.encode_fn = encode_fn self.decode_fn = decode_fn
[docs] def encode(self, solution: Iterable) -> MatrixLike: return self.encode_fn(solution)
[docs] def decode(self, population: MatrixLike) -> Iterable: return self.decode_fn(population)