Source code for jinete.algorithms.metaheuristics.sequential

"""Sequential algorithm class definitions."""

from __future__ import (
    annotations,
)

import logging
from random import (
    Random,
)
from typing import (
    TYPE_CHECKING,
)

from ...models import (
    MAX_INT,
    Planning,
)
from ..abc import (
    Algorithm,
)

if TYPE_CHECKING:
    from ...models import Result
    from typing import (
        Dict,
        Any,
        Sequence,
        Tuple,
        Type,
    )

logger = logging.getLogger(__name__)


[docs]class SequentialAlgorithm(Algorithm): """Sequential algorithm implementation. This implementation is based on the application of a sequence of algorithm implementations. It's mostly used as a component of more complicated metaheuristics. """
[docs] def __init__( self, initial: Result = None, algorithms_cls: Sequence[Tuple[Type[Algorithm], Dict[str, Any]]] = None, seed: int = 56, *args, **kwargs ): """Construct a new instance. :param initial: The initial result from to start the optimization process. :param algorithms_cls: The sequence of algorithm classes to be applied. :param seed: A seed to manage randomness. :param args: Additional positional arguments. :param kwargs: Additional named arguments. """ super().__init__(*args, **kwargs) if algorithms_cls is None: from ..heuristics import ( InsertionAlgorithm, LocalSearchAlgorithm, ReallocationLocalSearchStrategy, ) algorithms_cls = [ (LocalSearchAlgorithm, {**kwargs, "strategy_cls": ReallocationLocalSearchStrategy}), (InsertionAlgorithm, kwargs), ] self.random = Random(seed) self.initial = initial self.algorithms_cls = algorithms_cls
def _build_algorithm(self, cls, **kwargs) -> Algorithm: assert issubclass(cls, Algorithm) kwargs = kwargs.copy() if "fleet" not in kwargs: kwargs["fleet"] = self.fleet if "job" not in kwargs: kwargs["job"] = self.job if "seed" not in kwargs: kwargs["seed"] = self.random.randint(0, MAX_INT) return cls(**kwargs) def _optimize(self) -> Planning: current = self.initial for algorithm_cls, algorithm_kwargs in self.algorithms_cls: current = self._build_algorithm(algorithm_cls, **algorithm_kwargs, initial=current).optimize() return current.planning