Source code for jinete.algorithms.heuristics.local_search.strategies.routes.one_shift

import logging

from ......models import (
    Route,
    Stop,
)
from ..abc import (
    LocalSearchStrategy,
)

logger = logging.getLogger(__name__)


[docs]class OneShiftLocalSearchStrategy(LocalSearchStrategy): def _improve(self) -> None: logger.info(f'Starting to improve "Result" with "{self.__class__.__name__}"...') for route in self._routes: cost = self._objective.optimization_function(route) for i in range(1, len(route.stops) - 1): j = i + 1 k = i + 2 first = route.stops[i] second = route.stops[j] third = route.stops[k] if k < len(route.stops) else None if not set(first.pickup_planned_trips).isdisjoint(second.delivery_planned_trips): continue self._flip(route, first, second, third) if not route.feasible or cost == self._objective.best(cost, route): self._flip(route, second, first, third) continue cost = self._objective.optimization_function(route) logger.info(f'Flipped "{i}"-th and "{j}"-th stops from "{route}".') def _flip(self, route: Route, previous: Stop, other: Stop, following: Stop = None) -> None: assert following is None or following.previous == other assert other.previous == previous self_index = route.stops.index(other) other_index = route.stops.index(previous) route.stops[self_index], route.stops[other_index] = route.stops[other_index], route.stops[self_index] if following is not None: following.previous = previous other.previous = previous.previous previous.previous = other for stop in route.stops[self_index:]: stop.flush()