Source code for discrete_optimization.rcpsp.solvers_map

#  Copyright (c) 2022 AIRBUS and its affiliates.
#  This source code is licensed under the MIT license found in the
#  LICENSE file in the root directory of this source tree.

from typing import Any, Union

from discrete_optimization.generic_rcpsp_tools.solvers import GenericRcpspSolver
from discrete_optimization.generic_rcpsp_tools.solvers.gphh import (
    GphhGenericRcpspSolver,
)
from discrete_optimization.generic_rcpsp_tools.solvers.lns_cp import (
    LnsCpMznGenericRcpspSolver,
)
from discrete_optimization.generic_rcpsp_tools.solvers.ls import (
    LsGenericRcpspSolver,
    LsSolverType,
)
from discrete_optimization.generic_rcpsp_tools.typing import ANY_CLASSICAL_RCPSP
from discrete_optimization.generic_tools.cp_tools import CpSolverName, ParametersCp
from discrete_optimization.generic_tools.ea.ga_tools import (
    ParametersAltGa,
    ParametersGa,
)
from discrete_optimization.generic_tools.result_storage.result_storage import (
    ResultStorage,
)
from discrete_optimization.rcpsp.problem import RcpspProblem
from discrete_optimization.rcpsp.problem_preemptive import PreemptiveRcpspProblem
from discrete_optimization.rcpsp.problem_specialized_constraints import (
    SpecialConstraintsPreemptiveRcpspProblem,
)
from discrete_optimization.rcpsp.solvers import RcpspSolver
from discrete_optimization.rcpsp.solvers.cp_mzn import (
    CpMultimodePreemptiveRcpspSolver,
    CpMultimodeRcpspSolver,
    CpPreemptiveRcpspSolver,
    CpRcpspSolver,
)
from discrete_optimization.rcpsp.solvers.cpm import CpmRcpspSolver
from discrete_optimization.rcpsp.solvers.cpsat import CpSatRcpspSolver
from discrete_optimization.rcpsp.solvers.ga import GaMultimodeRcpspSolver, GaRcpspSolver
from discrete_optimization.rcpsp.solvers.lp import (
    MathOptMultimodeRcpspSolver,
    MathOptRcpspSolver,
)
from discrete_optimization.rcpsp.solvers.pile import (
    PileCalendarRcpspSolver,
    PileRcpspSolver,
)

solvers: dict[
    str, list[tuple[Union[type[RcpspSolver], type[GenericRcpspSolver]], dict[str, Any]]]
] = {
    "lp": [
        (
            MathOptRcpspSolver,
            {},
        ),
        (
            MathOptMultimodeRcpspSolver,
            {},
        ),
    ],
    "greedy": [
        (PileRcpspSolver, {}),
        (PileCalendarRcpspSolver, {}),
    ],
    "cp": [
        (CpSatRcpspSolver, {"parameters_cp": ParametersCp.default()}),
        (
            CpRcpspSolver,
            {},
        ),
        (
            CpMultimodeRcpspSolver,
            {},
        ),
        (
            CpPreemptiveRcpspSolver,
            {},
        ),
        (
            CpMultimodePreemptiveRcpspSolver,
            {},
        ),
    ],
    "critical-path": [(CpmRcpspSolver, {})],
    "lns-scheduling": [
        (
            LnsCpMznGenericRcpspSolver,
            {
                "nb_iteration_lns": 100,
                "nb_iteration_no_improvement": 100,
                "parameters_cp": ParametersCp.default_fast_lns(),
                "cp_solver_name": CpSolverName.CHUFFED,
            },
        )
    ],
    "ls": [
        (LsGenericRcpspSolver, {"ls_solver": LsSolverType.SA, "nb_iteration_max": 2000})
    ],
    "ga": [
        (GaRcpspSolver, {"parameters_ga": ParametersGa.default_rcpsp()}),
        (GaMultimodeRcpspSolver, {"parameters_ga": ParametersAltGa.default_mrcpsp()}),
    ],
    "gphh": [(GphhGenericRcpspSolver, {})],
}

solvers_map = {}
for key in solvers:
    for solver, param in solvers[key]:
        solvers_map[solver] = (key, param)

solvers_compatibility: dict[
    Union[type[RcpspSolver], type[GenericRcpspSolver]], list[type[ANY_CLASSICAL_RCPSP]]
] = {
    MathOptRcpspSolver: [RcpspProblem],
    MathOptMultimodeRcpspSolver: [
        RcpspProblem,
    ],
    PileRcpspSolver: [RcpspProblem],
    PileCalendarRcpspSolver: [
        RcpspProblem,
    ],
    CpRcpspSolver: [RcpspProblem],
    CpMultimodeRcpspSolver: [
        RcpspProblem,
    ],
    CpPreemptiveRcpspSolver: [PreemptiveRcpspProblem],
    CpMultimodePreemptiveRcpspSolver: [PreemptiveRcpspProblem],
    LsGenericRcpspSolver: [
        PreemptiveRcpspProblem,
        SpecialConstraintsPreemptiveRcpspProblem,
        RcpspProblem,
    ],
    GaRcpspSolver: [
        PreemptiveRcpspProblem,
        SpecialConstraintsPreemptiveRcpspProblem,
        RcpspProblem,
    ],
    GaMultimodeRcpspSolver: [
        PreemptiveRcpspProblem,
        SpecialConstraintsPreemptiveRcpspProblem,
        RcpspProblem,
    ],
    LnsCpMznGenericRcpspSolver: [
        PreemptiveRcpspProblem,
        SpecialConstraintsPreemptiveRcpspProblem,
        RcpspProblem,
    ],
    CpmRcpspSolver: [
        PreemptiveRcpspProblem,
        SpecialConstraintsPreemptiveRcpspProblem,
        RcpspProblem,
    ],
    GphhGenericRcpspSolver: [
        PreemptiveRcpspProblem,
        SpecialConstraintsPreemptiveRcpspProblem,
        RcpspProblem,
    ],
}


[docs] def look_for_solver( domain: ANY_CLASSICAL_RCPSP, ) -> list[Union[type[RcpspSolver], type[GenericRcpspSolver]]]: class_domain = domain.__class__ return look_for_solver_class(class_domain)
[docs] def look_for_solver_class( class_domain: type[ANY_CLASSICAL_RCPSP], ) -> list[Union[type[RcpspSolver], type[GenericRcpspSolver]]]: available = [] for solver in solvers_compatibility: if class_domain in solvers_compatibility[solver]: available += [solver] return available
[docs] def solve( method: Union[type[RcpspSolver], type[GenericRcpspSolver]], problem: ANY_CLASSICAL_RCPSP, **kwargs: Any, ) -> ResultStorage: solver = return_solver(method=method, problem=problem, **kwargs) return solver.solve(**kwargs)
[docs] def solve_return_solver( method: Union[type[RcpspSolver], type[GenericRcpspSolver]], problem: ANY_CLASSICAL_RCPSP, **kwargs: Any, ) -> tuple[ResultStorage, Union[RcpspSolver, GenericRcpspSolver]]: solver = return_solver(method=method, problem=problem, **kwargs) return solver.solve(**kwargs), solver
[docs] def return_solver( method: Union[type[RcpspSolver], type[GenericRcpspSolver]], problem: ANY_CLASSICAL_RCPSP, **kwargs: Any, ) -> Union[RcpspSolver, GenericRcpspSolver]: solver: Union[RcpspSolver, GenericRcpspSolver] solver = method(problem=problem, **kwargs) try: solver.init_model(**kwargs) except: pass return solver
[docs] def get_solver_default_arguments( method: Union[type[RcpspSolver], type[GenericRcpspSolver]] ) -> dict[str, Any]: try: return solvers_map[method][1] except KeyError: raise KeyError(f"{method} is not in the list of available solvers for RCPSP.")