Source code for metaheuristic_designer.operators.factories.mutation

"""
Mutation operator registry and factory.
"""

from __future__ import annotations
from typing import Optional

from ...encoding import Encoding
from ..operator_functions.utils import OperatorFnDef
from ..operator_functions.mutation import (
    xor_mask,
    rand_noise,
    mutate_noise,
    mutate_sample,
    rand_sample,
    mutate_1_sigma,
    mutate_n_sigmas,
    sample_1_sigma,
)
from ...operator import OperatorFromLambda

# fmt: off
mutation_ops_map = {
    # XOR and bitflip mutation
    "xor":                  OperatorFnDef(xor_mask),
    "byte_xor":             OperatorFnDef(xor_mask, forced_params={"mode": "byte"}),
    "int_xor":              OperatorFnDef(xor_mask, forced_params={"mode": "int"}),
    "bit_xor":              OperatorFnDef(xor_mask, forced_params={"mode": "bin"}),
    "bitflip":              OperatorFnDef(xor_mask, forced_params={"mode": "bin"}),

    # Gaussian distribution
    "gaussian_noise":       OperatorFnDef(rand_noise, forced_params={"distribution": "normal"}),
    "normal_noise":         OperatorFnDef(rand_noise, forced_params={"distribution": "normal"}),
    "gauss_noise":          OperatorFnDef(rand_noise, forced_params={"distribution": "normal"}),
    "gauss":                OperatorFnDef(rand_noise, forced_params={"distribution": "normal"}),
    "normal":               OperatorFnDef(rand_noise, forced_params={"distribution": "normal"}),
    "gaussian":             OperatorFnDef(rand_noise, forced_params={"distribution": "normal"}),
    
    "gaussian_mutation":    OperatorFnDef(mutate_noise, forced_params={"distribution": "normal"}),
    "normal_mutation":      OperatorFnDef(mutate_noise, forced_params={"distribution": "normal"}),
    "gauss_mutation":       OperatorFnDef(mutate_noise, forced_params={"distribution": "normal"}),
    "gaussian_mut":         OperatorFnDef(mutate_noise, forced_params={"distribution": "normal"}),
    "normal_mut":           OperatorFnDef(mutate_noise, forced_params={"distribution": "normal"}),
    "gauss_mut":            OperatorFnDef(mutate_noise, forced_params={"distribution": "normal"}),    

    # Uniform distribution
    "uniform_noise":        OperatorFnDef(rand_noise, forced_params={"distribution": "uniform"}),
    "uniform":              OperatorFnDef(rand_noise, forced_params={"distribution": "uniform"}),

    "uniform_mutation":     OperatorFnDef(mutate_noise, forced_params={"distribution": "uniform"}),
    "uniform_mut":          OperatorFnDef(mutate_noise, forced_params={"distribution": "uniform"}),

    # Laplace distribution
    "laplace_noise":        OperatorFnDef(rand_noise, forced_params={"distribution": "laplace"}),
    "laplace":              OperatorFnDef(rand_noise, forced_params={"distribution": "laplace"}),

    "laplace_mutation":     OperatorFnDef(mutate_noise, forced_params={"distribution": "laplace"}),
    "laplace_mut":          OperatorFnDef(mutate_noise, forced_params={"distribution": "laplace"}),

    # Cauchy distribution
    "cauchy_noise":         OperatorFnDef(rand_noise, forced_params={"distribution": "cauchy"}),
    "cauchy":               OperatorFnDef(rand_noise, forced_params={"distribution": "cauchy"}),

    "cauchy_mutation":      OperatorFnDef(mutate_noise, forced_params={"distribution": "cauchy"}),
    "cauchy_mut":           OperatorFnDef(mutate_noise, forced_params={"distribution": "cauchy"}),

    # Poisson distribution
    "poisson_noise":        OperatorFnDef(rand_noise, forced_params={"distribution": "poisson"}),
    "poisson":              OperatorFnDef(rand_noise, forced_params={"distribution": "poisson"}),

    "poisson_mutation":     OperatorFnDef(mutate_noise, forced_params={"distribution": "poisson"}),
    "poisson_mut":          OperatorFnDef(mutate_noise, forced_params={"distribution": "poisson"}),

    # Bernoulli distribution
    "bernoulli_noise":      OperatorFnDef(rand_noise, forced_params={"distribution": "bernoulli"}),
    "bernoulli":            OperatorFnDef(rand_noise, forced_params={"distribution": "bernoulli"}),

    "bernoulli_mutation":   OperatorFnDef(mutate_noise, forced_params={"distribution": "bernoulli"}),
    "bernoulli_mut":        OperatorFnDef(mutate_noise, forced_params={"distribution": "bernoulli"}),

    "bernoulli_sample":     OperatorFnDef(rand_sample, forced_params={"distribution": "bernoulli"}),
    "coinflip":             OperatorFnDef(rand_sample, forced_params={"distribution": "bernoulli"}),

    "bernoulli_reset":      OperatorFnDef(mutate_sample, forced_params={"distribution": "bernoulli"}),
    "coinflip_reset":       OperatorFnDef(mutate_sample, forced_params={"distribution": "bernoulli"}),

    # Additive noise mutation
    "additive_noise_mutation": OperatorFnDef(mutate_noise),
    "noise_mutation":       OperatorFnDef(mutate_noise),
    "mutnoise":             OperatorFnDef(mutate_noise),

    # Resampling mutation
    "replacement_mutation": OperatorFnDef(mutate_sample),
    "sampling_mutation":    OperatorFnDef(mutate_sample),
    "mutsample":            OperatorFnDef(mutate_sample),
    
    # Full additive noise
    "full_additive_noise":  OperatorFnDef(rand_noise),
    "additive_noise":       OperatorFnDef(rand_noise),
    "full_mutation":        OperatorFnDef(rand_noise),
    "random_noise":         OperatorFnDef(rand_noise),
    "randnoise":            OperatorFnDef(rand_noise),

    # Full resampling
    "full_random_sampling": OperatorFnDef(rand_sample),
    "full_resampling":      OperatorFnDef(rand_sample),
    "random_sampling":      OperatorFnDef(rand_sample),
    "randsample":           OperatorFnDef(rand_sample),
    "regenerate":           OperatorFnDef(rand_sample),

    # Adaptative operators
    "mutate1sigma":         OperatorFnDef(mutate_1_sigma),
    "mutate_1_sigma":       OperatorFnDef(mutate_1_sigma),

    "mutatensigmas":        OperatorFnDef(mutate_n_sigmas),
    "mutate_n_sigmas":      OperatorFnDef(mutate_n_sigmas),

    "sample1sigma":         OperatorFnDef(sample_1_sigma),
    "sample_1_sigma":       OperatorFnDef(sample_1_sigma),
}
# fmt: on


[docs] def create_mutation_operator( method: str, encoding: Optional[Encoding] = None, name: Optional[str] = None, **kwargs ) -> OperatorFromLambda: """ Create a mutation operator by name. Parameters ---------- method : str Key into :data:`mutation_ops_map`. encoding : Encoding, optional Encoding applied to the genotype after mutation. name : str, optional Display name; defaults to *method*. **kwargs Parameters forwarded to the mutation function (e.g., ``N``, ``F``, ``distribution``). Returns ------- OperatorFromLambda The wrapped mutation operator. """ if name is None: name = method return OperatorFromLambda(operator_fn=mutation_ops_map[method.lower()], name=method, encoding=encoding, preserves_order=True, **kwargs)