discrete_optimization.rcpsp.transformations package
Submodules
discrete_optimization.rcpsp.transformations.generic_scheduling_impl module
Transformation from/to generic scheduling to/from RCPSP.
- class discrete_optimization.rcpsp.transformations.generic_scheduling_impl.GenericSchedulingToRcpspTransformation[source]
Bases:
FromGenericSchedulingImpl[RcpspProblem,RcpspSolution]Transform GenericSchedulingImplProblem to RCPSP.
- get_forward_metadata() TransformationMetadata[source]
Get metadata for problem transformation (P1 → P2).
Documents what information is lost when transforming the PROBLEM.
Override this method to provide detailed information about: - Constraints that cannot be represented in target problem - Objectives that are ignored or approximated - Assumptions made during transformation
- Returns:
TransformationMetadata documenting losses in problem transformation
- Default:
Returns exact_transformation() (no losses documented)
Note
Solutions from the target problem always map back MECHANICALLY via back_transform_solution(), but may not satisfy all constraints from the original source problem if this transformation is lossy.
- Example: BinPack → SALBP loses incompatibility constraints.
Solutions from SALBP solvers map back to BinPack allocations, but may violate incompatibility if that constraint was present.
Always verify solutions in the original problem after solving via transformation!
- transform_problem(source_problem: GenericSchedulingImplProblem) RcpspProblem[source]
- Parameters:
source_problem
Returns:
- class discrete_optimization.rcpsp.transformations.generic_scheduling_impl.RcpspToGenericSchedulingTransformation[source]
Bases:
ToGenericSchedulingImpl[RcpspProblem,RcpspSolution]Transform RCPSP to GenericSchedulingImplProblem.
- get_forward_metadata() TransformationMetadata[source]
Get metadata for problem transformation (P1 → P2).
Documents what information is lost when transforming the PROBLEM.
Override this method to provide detailed information about: - Constraints that cannot be represented in target problem - Objectives that are ignored or approximated - Assumptions made during transformation
- Returns:
TransformationMetadata documenting losses in problem transformation
- Default:
Returns exact_transformation() (no losses documented)
Note
Solutions from the target problem always map back MECHANICALLY via back_transform_solution(), but may not satisfy all constraints from the original source problem if this transformation is lossy.
- Example: BinPack → SALBP loses incompatibility constraints.
Solutions from SALBP solvers map back to BinPack allocations, but may violate incompatibility if that constraint was present.
Always verify solutions in the original problem after solving via transformation!
- transform_solution_from_raw_generic_to_specific(raw_sol: RawSolution[Hashable, Hashable, Hashable], source_problem: RcpspProblem) RcpspSolution[source]
Convert a raw solution (from generic problem) into a specific solution to the source problem.
- Parameters:
source_problem
Returns:
- discrete_optimization.rcpsp.transformations.generic_scheduling_impl.transform_solution_from_raw_generic_to_rcpsp(raw_sol: RawSolution[Hashable, Hashable, Hashable], problem: RcpspProblem) RcpspSolution[source]
Convert generic solution to RCPSP solution.
- Parameters:
solution
problem
Returns:
discrete_optimization.rcpsp.transformations.to_multiskill module
Transformation from RCPSP to RCPSP Multiskill.
- class discrete_optimization.rcpsp.transformations.to_multiskill.RcpspToMultiskillTransformation[source]
Bases:
ProblemTransformation[RcpspProblem,RcpspSolution,MultiskillRcpspProblem,MultiskillRcpspSolution]Transform RCPSP to RCPSPMultiskill.
Mapping strategy: - RCPSP resources map directly to MultiskillRCPSP cumulative resources - No employees or skills needed (MultiskillRCPSP can work with just resources) - Same mode details and precedence constraints
Example
# >>> problem = RcpspProblem( # … resources={“R1”: 5, “R2”: 2}, # … … # … ) # >>> transformation = RcpspToMultiskillTransformation() # >>> ms_problem = transformation.transform_problem(problem) # >>> # ms_problem uses resources R1, R2 directly (no fake employees)
- back_transform_solution(solution: MultiskillRcpspSolution, source_problem: RcpspProblem) RcpspSolution[source]
Convert Multiskill solution back to RCPSP solution.
We only need the schedule (start times) and modes. Employee assignments are not relevant (empty in this transformation).
- Parameters:
solution – Solution in multiskill problem space
source_problem – Original RCPSP problem
- Returns:
Corresponding RCPSP solution
- forward_transform_solution(solution: RcpspSolution, target_problem: MultiskillRcpspProblem) MultiskillRcpspSolution[source]
Convert RCPSP solution to Multiskill solution.
Since we don’t use employees, this is straightforward.
- Parameters:
solution – Solution in RCPSP problem space
target_problem – Transformed multiskill problem
- Returns:
Corresponding multiskill solution (without employee assignments)
- transform_problem(source_problem: RcpspProblem) MultiskillRcpspProblem[source]
Convert RCPSP to Multiskill RCPSP.
- Parameters:
source_problem – Original RCPSP problem
- Returns:
Equivalent MultiskillRcpspProblem
discrete_optimization.rcpsp.transformations.to_preemptive module
Transformation from RCPSP to Preemptive RCPSP.
- class discrete_optimization.rcpsp.transformations.to_preemptive.RcpspToPreemptiveTransformation[source]
Bases:
ProblemTransformation[RcpspProblem,RcpspSolution,PreemptiveRcpspProblem,PreemptiveRcpspSolution]Transform RCPSP to Preemptive RCPSP.
Mapping: - All tasks → Preemptive tasks (can be interrupted) - All resources and constraints preserved - Same mode details and precedence - All tasks marked as preemptive
RCPSP is a special case of Preemptive RCPSP where tasks cannot be preempted. The reverse is also true when solutions don’t use preemption.
- back_transform_solution(solution: PreemptiveRcpspSolution, source_problem: RcpspProblem) RcpspSolution[source]
Transform Preemptive RCPSP solution back to RCPSP solution.
- Parameters:
solution – Preemptive RCPSP solution
source_problem – Original RCPSP problem
- Returns:
Equivalent RCPSP solution
Note
If the preemptive solution uses preemption (tasks with multiple parts), the RCPSP solution will use the first start time and last end time, potentially with idle time in between. This may not be feasible in the non-preemptive problem if resources are occupied during idle periods.
- forward_transform_solution(solution: RcpspSolution, target_problem: PreemptiveRcpspProblem) PreemptiveRcpspSolution | None[source]
Transform RCPSP solution to Preemptive RCPSP solution (for warmstart).
- Parameters:
solution – RCPSP solution
target_problem – Target Preemptive RCPSP problem
- Returns:
Equivalent Preemptive RCPSP solution (without preemption)
- get_forward_metadata() TransformationMetadata[source]
Metadata for forward problem transformation (RCPSP → Preemptive RCPSP).
This direction is EXACT: RCPSP is a subset of Preemptive RCPSP.
- transform_problem(source_problem: RcpspProblem) PreemptiveRcpspProblem[source]
Transform RCPSP to Preemptive RCPSP.
- Parameters:
source_problem – RCPSP problem instance
- Returns:
Equivalent Preemptive RCPSP problem
Module contents
Transformations for RCPSP problems.
- class discrete_optimization.rcpsp.transformations.RcpspToMultiskillTransformation[source]
Bases:
ProblemTransformation[RcpspProblem,RcpspSolution,MultiskillRcpspProblem,MultiskillRcpspSolution]Transform RCPSP to RCPSPMultiskill.
Mapping strategy: - RCPSP resources map directly to MultiskillRCPSP cumulative resources - No employees or skills needed (MultiskillRCPSP can work with just resources) - Same mode details and precedence constraints
Example
# >>> problem = RcpspProblem( # … resources={“R1”: 5, “R2”: 2}, # … … # … ) # >>> transformation = RcpspToMultiskillTransformation() # >>> ms_problem = transformation.transform_problem(problem) # >>> # ms_problem uses resources R1, R2 directly (no fake employees)
- back_transform_solution(solution: MultiskillRcpspSolution, source_problem: RcpspProblem) RcpspSolution[source]
Convert Multiskill solution back to RCPSP solution.
We only need the schedule (start times) and modes. Employee assignments are not relevant (empty in this transformation).
- Parameters:
solution – Solution in multiskill problem space
source_problem – Original RCPSP problem
- Returns:
Corresponding RCPSP solution
- forward_transform_solution(solution: RcpspSolution, target_problem: MultiskillRcpspProblem) MultiskillRcpspSolution[source]
Convert RCPSP solution to Multiskill solution.
Since we don’t use employees, this is straightforward.
- Parameters:
solution – Solution in RCPSP problem space
target_problem – Transformed multiskill problem
- Returns:
Corresponding multiskill solution (without employee assignments)
- transform_problem(source_problem: RcpspProblem) MultiskillRcpspProblem[source]
Convert RCPSP to Multiskill RCPSP.
- Parameters:
source_problem – Original RCPSP problem
- Returns:
Equivalent MultiskillRcpspProblem
- class discrete_optimization.rcpsp.transformations.RcpspToPreemptiveTransformation[source]
Bases:
ProblemTransformation[RcpspProblem,RcpspSolution,PreemptiveRcpspProblem,PreemptiveRcpspSolution]Transform RCPSP to Preemptive RCPSP.
Mapping: - All tasks → Preemptive tasks (can be interrupted) - All resources and constraints preserved - Same mode details and precedence - All tasks marked as preemptive
RCPSP is a special case of Preemptive RCPSP where tasks cannot be preempted. The reverse is also true when solutions don’t use preemption.
- back_transform_solution(solution: PreemptiveRcpspSolution, source_problem: RcpspProblem) RcpspSolution[source]
Transform Preemptive RCPSP solution back to RCPSP solution.
- Parameters:
solution – Preemptive RCPSP solution
source_problem – Original RCPSP problem
- Returns:
Equivalent RCPSP solution
Note
If the preemptive solution uses preemption (tasks with multiple parts), the RCPSP solution will use the first start time and last end time, potentially with idle time in between. This may not be feasible in the non-preemptive problem if resources are occupied during idle periods.
- forward_transform_solution(solution: RcpspSolution, target_problem: PreemptiveRcpspProblem) PreemptiveRcpspSolution | None[source]
Transform RCPSP solution to Preemptive RCPSP solution (for warmstart).
- Parameters:
solution – RCPSP solution
target_problem – Target Preemptive RCPSP problem
- Returns:
Equivalent Preemptive RCPSP solution (without preemption)
- get_forward_metadata() TransformationMetadata[source]
Metadata for forward problem transformation (RCPSP → Preemptive RCPSP).
This direction is EXACT: RCPSP is a subset of Preemptive RCPSP.
- transform_problem(source_problem: RcpspProblem) PreemptiveRcpspProblem[source]
Transform RCPSP to Preemptive RCPSP.
- Parameters:
source_problem – RCPSP problem instance
- Returns:
Equivalent Preemptive RCPSP problem