from typing import List
from ...representations import abstract_representation
from .abstract_operators import AbstractMutationOperator, AbstractMutator
[docs]class SplitAndSwap(AbstractMutationOperator):
"""Returns by spliting the road in half and putting the second part in front of the first one.
e.g. ``[A, B, C, D, E, F, G]`` --> ``[D, E, F, G, A, B, C]``
"""
[docs] def __call__(self, representation: abstract_representation.RoadRepresentation, test):
half = len(test) // 2
return test[half:] + test[:half]
[docs]class ReverseTest(AbstractMutationOperator):
"""Reverses the road.
e.g. ``[A, B, C, D, E, F, G]`` --> ``[G, F, E, D, C, B, A]``
"""
[docs] def __call__(self, representation: abstract_representation.RoadRepresentation, test):
return test[::-1]
[docs]class FlipSign(AbstractMutationOperator):
"""Flips the signs of the road.
e.g. ``[A, -B, -C, D, E, -F, G]`` --> ``[-A, B, C, -D, -E, F, -G]``
"""
[docs] def __call__(self, representation: abstract_representation.RoadRepresentation, test):
return list(map(lambda x: x * -1.0, test))
[docs]class KappaFlipSign(AbstractMutationOperator):
"""Flips the signs of the road, but only curvature (e.g. when road points are kappa-step tuples).
"""
[docs] def __call__(self, representation: abstract_representation.RoadRepresentation, test):
return list(map(lambda x: (x[0] * -1.0, x[1]), test))
[docs]class Exploiter(AbstractMutator):
"""A container class for the exploitation operators.
By default, :class:`ReverseTest`, :class:`SplitAndSwap` and :class:`FlipSign` are used,
if none are provided on instantiation.
"""
def __init__(self, operators: List[AbstractMutationOperator] = None):
operators = operators or [ # default exploiters
ReverseTest(),
SplitAndSwap(),
FlipSign(),
]
super().__init__(operators)