discrete_optimization.workforce.scheduling.transformations package

Submodules

discrete_optimization.workforce.scheduling.transformations.generic_scheduling_impl module

Transformation from RCPSP to RCPSP Multiskill.

class discrete_optimization.workforce.scheduling.transformations.generic_scheduling_impl.GenericSchedulingToWfSchedulingTransformation[source]

Bases: FromGenericSchedulingImpl[AllocSchedulingProblem, AllocSchedulingSolution]

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) AllocSchedulingProblem[source]
Parameters:

source_problem

Returns:

class discrete_optimization.workforce.scheduling.transformations.generic_scheduling_impl.WfSchedulingToGenericSchedulingTransformation[source]

Bases: ToGenericSchedulingImpl[AllocSchedulingProblem, AllocSchedulingSolution]

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: AllocSchedulingProblem) AllocSchedulingSolution[source]

Convert a raw solution (from generic problem) into a specific solution to the source problem.

Parameters:

source_problem

Returns:

discrete_optimization.workforce.scheduling.transformations.generic_scheduling_impl.transform_solution_from_raw_generic_to_wf_sched(raw_sol: RawSolution[Hashable, Hashable, Hashable], problem: AllocSchedulingProblem) AllocSchedulingSolution[source]

Convert generic solution to workforce/scheduling solution.

Parameters:
  • solution

  • problem

Returns:

discrete_optimization.workforce.scheduling.transformations.to_fjsp module

Transformation from Workforce Scheduling to Flexible Job Shop (FJSP).

Teams are mapped to machines, tasks to operations.

class discrete_optimization.workforce.scheduling.transformations.to_fjsp.WorkforceSchedulingToFjspTransformation[source]

Bases: ProblemTransformation[AllocSchedulingProblem, AllocSchedulingSolution, FJobShopProblem, AnyShopSolution]

Transform Workforce Scheduling to Flexible Job Shop.

Mapping: - Tasks → Operations (each task becomes a single-operation job) - Teams → Machines - Available teams for task → Eligible machines for operation - Team calendars → Machine availability - Precedence → Job/operation precedence

This transformation is LOSSY: - Jobs are artificially created (one per task) - Some workforce-specific constraints lost - Cumulative resources ignored

back_transform_solution(solution: AnyShopSolution, source_problem: AllocSchedulingProblem) AllocSchedulingSolution[source]

Transform FJSP solution back to Workforce Scheduling.

Parameters:
  • solution – FJobShopSolution

  • source_problem – Original AllocSchedulingProblem

Returns:

Equivalent AllocSchedulingSolution

forward_transform_solution(solution: AllocSchedulingSolution, target_problem: FJobShopProblem) AnyShopSolution | None[source]

Transform Workforce Scheduling solution to FJSP (for warmstart).

Parameters:
  • solution – AllocSchedulingSolution

  • target_problem – Target FJobShopProblem

Returns:

Equivalent FJobShopSolution

get_forward_metadata() TransformationMetadata[source]

Metadata for forward problem transformation (WorkforceScheduling → FJSP).

This direction is LOSSY.

transform_problem(source_problem: AllocSchedulingProblem) FJobShopProblem[source]

Transform Workforce Scheduling to FJSP.

Parameters:

source_problem – AllocSchedulingProblem instance

Returns:

Equivalent FJobShopProblem

discrete_optimization.workforce.scheduling.transformations.to_multiskill module

Transformation from Workforce Scheduling to Multiskill RCPSP.

This provides an alternative to the standard RCPSP transformation, mapping teams directly to employees (workers) in multiskill RCPSP.

class discrete_optimization.workforce.scheduling.transformations.to_multiskill.WorkforceSchedulingToMultiskillTransformation[source]

Bases: ProblemTransformation[AllocSchedulingProblem, AllocSchedulingSolution, MultiskillRcpspProblem, MultiskillRcpspSolution]

Transform Workforce Scheduling to Multiskill RCPSP.

Mapping: - Tasks → Tasks - Teams → Employees/Workers (dict indexed by team name) - Team availability → Employee calendars - Task duration → Task duration - Precedence → Task successors - Available teams for activity → Skills (ONE skill per unique eligibility pattern)

Skill Mapping Strategy: Each unique set of eligible teams gets ONE skill. All teams in that set possess that skill. When a task requires that skill, ANY employee (team) with the skill can perform it. This correctly models “task needs one team from eligible set”.

Example: - Task A can be done by Team1 OR Team2 → Skill_A - Task B can be done by Team1 OR Team2 → Skill_A (same eligibility) - Task C can be done by Team3 → Skill_C - Team1 and Team2 have Skill_A; Team3 has Skill_C

This transformation is LOSSY: - Same_allocation constraints are approximated - Cumulative resource consumption may be lost

back_transform_solution(solution: MultiskillRcpspSolution, source_problem: AllocSchedulingProblem) AllocSchedulingSolution[source]

Transform Multiskill RCPSP solution back to Workforce Scheduling.

Parameters:
  • solution – MultiskillRcpspSolution

  • source_problem – Original AllocSchedulingProblem

Returns:

Equivalent AllocSchedulingSolution

forward_transform_solution(solution: AllocSchedulingSolution, target_problem: MultiskillRcpspProblem) MultiskillRcpspSolution | None[source]

Transform Workforce Scheduling solution to Multiskill RCPSP (for warmstart).

Parameters:
  • solution – AllocSchedulingSolution

  • target_problem – Target MultiskillRcpspProblem

Returns:

Equivalent MultiskillRcpspSolution

get_forward_metadata() TransformationMetadata[source]

Metadata for forward problem transformation (WorkforceScheduling → MultiskillRCPSP).

This direction is LOSSY but provides access to multiskill RCPSP solvers.

transform_problem(source_problem: AllocSchedulingProblem) MultiskillRcpspProblem[source]

Transform Workforce Scheduling to Multiskill RCPSP.

Parameters:

source_problem – AllocSchedulingProblem instance

Returns:

Equivalent MultiskillRcpspProblem

discrete_optimization.workforce.scheduling.transformations.to_rcpsp module

Transformation from Workforce Scheduling to RCPSP.

class discrete_optimization.workforce.scheduling.transformations.to_rcpsp.WorkforceSchedulingToRcpspTransformation(build_calendar: bool = True, add_window_time_constraint: bool = True, add_additional_constraint: bool = True)[source]

Bases: ProblemTransformation[AllocSchedulingProblem, AllocSchedulingSolution, RcpspProblem, RcpspSolution]

Transform Workforce Scheduling to RCPSP (Resource-Constrained Project Scheduling).

Mapping: - Tasks → RCPSP tasks - Teams → Modes for each task - Team availability calendars → Resource calendars - Task duration → Task duration in each mode - Precedence constraints → RCPSP successors - Time windows → Start/end time windows

This transformation is EXACT: - All workforce scheduling constraints are preserved in RCPSP formulation - Team assignment becomes mode selection in RCPSP

back_transform_solution(solution: RcpspSolution, source_problem: AllocSchedulingProblem) AllocSchedulingSolution[source]

Transform RCPSP solution back to Workforce Scheduling solution.

Parameters:
  • solution – RCPSP solution

  • source_problem – Original AllocSchedulingProblem

Returns:

Equivalent AllocSchedulingSolution

forward_transform_solution(solution: AllocSchedulingSolution, target_problem: RcpspProblem) RcpspSolution | None[source]

Transform Workforce Scheduling solution to RCPSP solution (for warmstart).

Parameters:
  • solution – AllocSchedulingSolution

  • target_problem – Target RCPSP problem

Returns:

Equivalent RCPSP solution for warmstart

get_forward_metadata() TransformationMetadata[source]

Metadata for forward problem transformation (WorkforceScheduling → RCPSP).

This direction is EXACT: all workforce constraints map to RCPSP constraints.

transform_problem(source_problem: AllocSchedulingProblem) RcpspProblem[source]

Transform Workforce Scheduling to RCPSP.

Parameters:

source_problem – AllocSchedulingProblem instance

Returns:

Equivalent RCPSP problem

Module contents

Transformations from Workforce Scheduling to other problems.

class discrete_optimization.workforce.scheduling.transformations.WorkforceSchedulingToFjspTransformation[source]

Bases: ProblemTransformation[AllocSchedulingProblem, AllocSchedulingSolution, FJobShopProblem, AnyShopSolution]

Transform Workforce Scheduling to Flexible Job Shop.

Mapping: - Tasks → Operations (each task becomes a single-operation job) - Teams → Machines - Available teams for task → Eligible machines for operation - Team calendars → Machine availability - Precedence → Job/operation precedence

This transformation is LOSSY: - Jobs are artificially created (one per task) - Some workforce-specific constraints lost - Cumulative resources ignored

back_transform_solution(solution: AnyShopSolution, source_problem: AllocSchedulingProblem) AllocSchedulingSolution[source]

Transform FJSP solution back to Workforce Scheduling.

Parameters:
  • solution – FJobShopSolution

  • source_problem – Original AllocSchedulingProblem

Returns:

Equivalent AllocSchedulingSolution

forward_transform_solution(solution: AllocSchedulingSolution, target_problem: FJobShopProblem) AnyShopSolution | None[source]

Transform Workforce Scheduling solution to FJSP (for warmstart).

Parameters:
  • solution – AllocSchedulingSolution

  • target_problem – Target FJobShopProblem

Returns:

Equivalent FJobShopSolution

get_forward_metadata() TransformationMetadata[source]

Metadata for forward problem transformation (WorkforceScheduling → FJSP).

This direction is LOSSY.

transform_problem(source_problem: AllocSchedulingProblem) FJobShopProblem[source]

Transform Workforce Scheduling to FJSP.

Parameters:

source_problem – AllocSchedulingProblem instance

Returns:

Equivalent FJobShopProblem

class discrete_optimization.workforce.scheduling.transformations.WorkforceSchedulingToMultiskillTransformation[source]

Bases: ProblemTransformation[AllocSchedulingProblem, AllocSchedulingSolution, MultiskillRcpspProblem, MultiskillRcpspSolution]

Transform Workforce Scheduling to Multiskill RCPSP.

Mapping: - Tasks → Tasks - Teams → Employees/Workers (dict indexed by team name) - Team availability → Employee calendars - Task duration → Task duration - Precedence → Task successors - Available teams for activity → Skills (ONE skill per unique eligibility pattern)

Skill Mapping Strategy: Each unique set of eligible teams gets ONE skill. All teams in that set possess that skill. When a task requires that skill, ANY employee (team) with the skill can perform it. This correctly models “task needs one team from eligible set”.

Example: - Task A can be done by Team1 OR Team2 → Skill_A - Task B can be done by Team1 OR Team2 → Skill_A (same eligibility) - Task C can be done by Team3 → Skill_C - Team1 and Team2 have Skill_A; Team3 has Skill_C

This transformation is LOSSY: - Same_allocation constraints are approximated - Cumulative resource consumption may be lost

back_transform_solution(solution: MultiskillRcpspSolution, source_problem: AllocSchedulingProblem) AllocSchedulingSolution[source]

Transform Multiskill RCPSP solution back to Workforce Scheduling.

Parameters:
  • solution – MultiskillRcpspSolution

  • source_problem – Original AllocSchedulingProblem

Returns:

Equivalent AllocSchedulingSolution

forward_transform_solution(solution: AllocSchedulingSolution, target_problem: MultiskillRcpspProblem) MultiskillRcpspSolution | None[source]

Transform Workforce Scheduling solution to Multiskill RCPSP (for warmstart).

Parameters:
  • solution – AllocSchedulingSolution

  • target_problem – Target MultiskillRcpspProblem

Returns:

Equivalent MultiskillRcpspSolution

get_forward_metadata() TransformationMetadata[source]

Metadata for forward problem transformation (WorkforceScheduling → MultiskillRCPSP).

This direction is LOSSY but provides access to multiskill RCPSP solvers.

transform_problem(source_problem: AllocSchedulingProblem) MultiskillRcpspProblem[source]

Transform Workforce Scheduling to Multiskill RCPSP.

Parameters:

source_problem – AllocSchedulingProblem instance

Returns:

Equivalent MultiskillRcpspProblem

class discrete_optimization.workforce.scheduling.transformations.WorkforceSchedulingToRcpspTransformation(build_calendar: bool = True, add_window_time_constraint: bool = True, add_additional_constraint: bool = True)[source]

Bases: ProblemTransformation[AllocSchedulingProblem, AllocSchedulingSolution, RcpspProblem, RcpspSolution]

Transform Workforce Scheduling to RCPSP (Resource-Constrained Project Scheduling).

Mapping: - Tasks → RCPSP tasks - Teams → Modes for each task - Team availability calendars → Resource calendars - Task duration → Task duration in each mode - Precedence constraints → RCPSP successors - Time windows → Start/end time windows

This transformation is EXACT: - All workforce scheduling constraints are preserved in RCPSP formulation - Team assignment becomes mode selection in RCPSP

back_transform_solution(solution: RcpspSolution, source_problem: AllocSchedulingProblem) AllocSchedulingSolution[source]

Transform RCPSP solution back to Workforce Scheduling solution.

Parameters:
  • solution – RCPSP solution

  • source_problem – Original AllocSchedulingProblem

Returns:

Equivalent AllocSchedulingSolution

forward_transform_solution(solution: AllocSchedulingSolution, target_problem: RcpspProblem) RcpspSolution | None[source]

Transform Workforce Scheduling solution to RCPSP solution (for warmstart).

Parameters:
  • solution – AllocSchedulingSolution

  • target_problem – Target RCPSP problem

Returns:

Equivalent RCPSP solution for warmstart

get_forward_metadata() TransformationMetadata[source]

Metadata for forward problem transformation (WorkforceScheduling → RCPSP).

This direction is EXACT: all workforce constraints map to RCPSP constraints.

transform_problem(source_problem: AllocSchedulingProblem) RcpspProblem[source]

Transform Workforce Scheduling to RCPSP.

Parameters:

source_problem – AllocSchedulingProblem instance

Returns:

Equivalent RCPSP problem