Source code for discrete_optimization.shop.transformations.to_generic_scheduling

#  Copyright (c) 2026 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.

"""Transformation from CommonShopProblem (JSP/FJSP/OSP) to GenericSchedulingImpl."""

from discrete_optimization.generic_tasks_tools.generic_scheduling_impl import (
    Skill,
    UnaryResource,
)
from discrete_optimization.generic_tasks_tools.generic_scheduling_utils import (
    RawSolution,
)
from discrete_optimization.generic_tasks_tools.transformations.generic_scheduling_impl import (
    ToGenericSchedulingImpl,
)
from discrete_optimization.shop.base import AnyShopSolution, CommonShopProblem, Task


[docs] def transform_solution_from_raw_generic_to_shop( raw_sol: RawSolution[Task, UnaryResource, Skill], problem: CommonShopProblem ) -> AnyShopSolution: schedule_and_machine = [ [ ( (task_var := raw_sol.task_variables[j, k]).start, task_var.end, problem.mode2machine[j, k][task_var.mode], task_var.mode, ) for k, sub_job in enumerate(job.subjobs) ] for j, job in enumerate(problem.list_jobs) ] return AnyShopSolution( problem=problem, schedule=[[(x[0], x[1]) for x in sched_i] for sched_i in schedule_and_machine], machine_index=[[x[2] for x in sched_i] for sched_i in schedule_and_machine], recipe_index=[[x[3] for x in sched_i] for sched_i in schedule_and_machine], )
[docs] class ShopToGenericSchedulingTransformation( ToGenericSchedulingImpl[ CommonShopProblem, AnyShopSolution, ] ): """Transform CommonShopProblem to GenericSchedulingImplProblem. This transformation works for JSP, FJSP, and OSP problems: - JSP: Single mode per task (one recipe per subjob) - FJSP: Multiple modes per task (multiple recipe options per subjob) - OSP: Single mode per task, no precedence constraints Mapping: - Tasks: (job_index, subjob_index) tuples - Modes: Recipe options for each subjob - Cumulative resources: Machines (capacity 1 each) - Precedence: From problem's get_precedence_constraints() - No-overlap: Tasks within same job (from get_no_overlap()) """
[docs] def transform_solution_from_raw_generic_to_specific( self, raw_sol: RawSolution[Task, UnaryResource, Skill], source_problem: CommonShopProblem, ) -> AnyShopSolution: return transform_solution_from_raw_generic_to_shop( raw_sol=raw_sol, problem=source_problem )