Source code for discrete_optimization.tsptw.solvers.ortools_routing

from typing import Any, Optional

from ortools.constraint_solver import routing_enums_pb2

from discrete_optimization.generic_tools.callbacks.callback import (
    Callback,
    CallbackList,
)
from discrete_optimization.generic_tools.do_solver import SolverDO
from discrete_optimization.generic_tools.result_storage.result_storage import (
    ResultStorage,
)
from discrete_optimization.gpdp.problem import GpdpProblem, GpdpSolution, ProxyClass
from discrete_optimization.gpdp.solvers import GpdpSolver
from discrete_optimization.gpdp.solvers.ortools_routing import (
    OrtoolsGpdpSolver,
    ParametersCost,
)
from discrete_optimization.tsptw.problem import TSPTWProblem, TSPTWSolution


[docs] class OrtoolsTspTwSolver(SolverDO): problem: TSPTWProblem gpdp_problem: GpdpProblem solver: OrtoolsGpdpSolver
[docs] def init_model(self, time_limit=10, scaling: float = 100, **kwargs: Any) -> None: gpdp_problem = ProxyClass.from_tsptw_to_gpdp(self.problem, True) solver = OrtoolsGpdpSolver(problem=gpdp_problem, factor_multiplier_time=scaling) solver.init_model( one_visit_per_node=True, include_time_windows=True, include_time_dimension=True, local_search_metaheuristic=routing_enums_pb2.LocalSearchMetaheuristic.SIMULATED_ANNEALING, first_solution_strategy=routing_enums_pb2.FirstSolutionStrategy.SAVINGS, time_limit=time_limit, parameters_cost=[ParametersCost(dimension_name="Time", global_span=True)], ) self.solver = solver
[docs] def solve( self, callbacks: Optional[list[Callback]] = None, **kwargs: Any ) -> ResultStorage: callback = CallbackList(callbacks) callback.on_solve_start(self) result_storage = self.create_result_storage([]) res = self.solver.solve() sol: GpdpSolution = res[-1][0] tsp_tw_sol = TSPTWSolution( problem=self.problem, permutation=[i + 1 for i in sol.trajectories[0][1:-1]] ) fit = self.aggreg_from_sol(tsp_tw_sol) result_storage.append((tsp_tw_sol, fit)) callback.on_solve_end(result_storage, self) return result_storage