discrete_optimization.workforce.scheduling package
Subpackages
- discrete_optimization.workforce.scheduling.solvers package
- Submodules
- discrete_optimization.workforce.scheduling.solvers.alloc_scheduling_lb module
- discrete_optimization.workforce.scheduling.solvers.cpsat module
AdditionalCPConstraintsCPSatAllocSchedulingSolverCPSatAllocSchedulingSolver.add_lexico_constraint()CPSatAllocSchedulingSolver.add_objective_functions_on_cumul()CPSatAllocSchedulingSolver.at_most_one_unary_resource_per_taskCPSatAllocSchedulingSolver.create_actually_done_variables()CPSatAllocSchedulingSolver.create_delta_objectives()CPSatAllocSchedulingSolver.create_used_variables_dict()CPSatAllocSchedulingSolver.get_lexico_objective_value()CPSatAllocSchedulingSolver.get_lexico_objectives_available()CPSatAllocSchedulingSolver.get_task_start_or_end_variable()CPSatAllocSchedulingSolver.get_task_unary_resource_is_present_variable()CPSatAllocSchedulingSolver.hyperparametersCPSatAllocSchedulingSolver.implements_lexico_api()CPSatAllocSchedulingSolver.init_model()CPSatAllocSchedulingSolver.problemCPSatAllocSchedulingSolver.retrieve_solution()CPSatAllocSchedulingSolver.set_additional_constraints()CPSatAllocSchedulingSolver.set_lexico_objective()CPSatAllocSchedulingSolver.set_model_obj_aggregated()CPSatAllocSchedulingSolver.set_nb_teams_constraints()CPSatAllocSchedulingSolver.set_team_used_constraint()CPSatAllocSchedulingSolver.set_warm_start()CPSatAllocSchedulingSolver.variables
- discrete_optimization.workforce.scheduling.solvers.cpsat_relaxed module
CPSatAllocSchedulingSolverCumulativeCPSatAllocSchedulingSolverCumulative.add_lexico_constraint()CPSatAllocSchedulingSolverCumulative.create_makespan_obj()CPSatAllocSchedulingSolverCumulative.define_objectives()CPSatAllocSchedulingSolverCumulative.get_lexico_objective_value()CPSatAllocSchedulingSolverCumulative.get_lexico_objectives_available()CPSatAllocSchedulingSolverCumulative.hyperparametersCPSatAllocSchedulingSolverCumulative.implements_lexico_api()CPSatAllocSchedulingSolverCumulative.init_main_vars()CPSatAllocSchedulingSolverCumulative.init_model()CPSatAllocSchedulingSolverCumulative.init_multimode_data()CPSatAllocSchedulingSolverCumulative.not_implemented_objectivesCPSatAllocSchedulingSolverCumulative.problemCPSatAllocSchedulingSolverCumulative.retrieve_solution()CPSatAllocSchedulingSolverCumulative.set_lexico_objective()CPSatAllocSchedulingSolverCumulative.set_model_obj_aggregated()CPSatAllocSchedulingSolverCumulative.set_precedence_constraints()CPSatAllocSchedulingSolverCumulative.set_resource_pool_constraints()CPSatAllocSchedulingSolverCumulative.set_same_allocation_constraints()CPSatAllocSchedulingSolverCumulative.set_warm_start()CPSatAllocSchedulingSolverCumulative.solve()CPSatAllocSchedulingSolverCumulative.variables
- discrete_optimization.workforce.scheduling.solvers.optal module
- discrete_optimization.workforce.scheduling.solvers.tempo module
- Module contents
Submodules
discrete_optimization.workforce.scheduling.parser module
- discrete_optimization.workforce.scheduling.parser.get_data_available(data_folder: str | None = None, data_home: str | None = None) list[str][source]
Get datasets available for tsp.
- Params:
- data_folder: folder where datasets for tsp whould be find.
If None, we look in “tsp” subdirectory of data_home.
- data_home: root directory for all datasets. Is None, set by
default to “~/discrete_optimization_data “
- discrete_optimization.workforce.scheduling.parser.parse_json_to_problem(json_path: str) AllocSchedulingProblem[source]
discrete_optimization.workforce.scheduling.problem module
- class discrete_optimization.workforce.scheduling.problem.AllocSchedulingProblem(team_names: list[Hashable], calendar_team: dict[Hashable, list[tuple[int, int]]], horizon: int, tasks_list: list[Hashable], tasks_data: dict[Hashable, TasksDescription], same_allocation: list[set[Hashable]], precedence_constraints: dict[Hashable, set[Hashable]], available_team_for_activity: dict[Hashable, set[Hashable]], start_window: dict[Hashable, tuple[int | None, int | None]], end_window: dict[Hashable, tuple[int | None, int | None]], original_start: dict[Hashable, int], original_end: dict[Hashable, int], resources_list: list[str] | None = None, resources_capacity: dict[str, int] | None = None, horizon_start_shift: int | None = 0, objective_handling: ObjectiveHandling = ObjectiveHandling.AGGREGATE)[source]
Bases:
SchedulingProblem[Hashable],AllocationProblem[Hashable,Hashable],PrecedenceProblem[Hashable]- evaluate(variable: Solution) dict[str, float][source]
Evaluate a given solution object for the given problem.
This method should return a dictionnary of KPI, that can be then used for mono or multiobjective optimization.
- Parameters:
variable (Solution) – the Solution object to evaluate.
Returns: dictionnary of float kpi for the solution.
- get_all_lb_ub() list[tuple[int, int, int, int]][source]
Return a list of (lb_start, ub_start, lb_end, ub_end) for each task (lower/upper bound on start, lower/upper bound on end)
- get_attribute_register() EncodingRegister[source]
Returns how the Solution should be encoded.
Returns (EncodingRegister): content of the encoding of the solution
- get_makespan_lower_bound() int[source]
Get a lower bound on global makespan.
Default to 0. But can be overriden for problems with more information.
- get_objective_register() ObjectiveRegister[source]
Returns the objective definition.
Returns (ObjectiveRegister): object defining the objective criteria.
- get_precedence_constraints() dict[Hashable, set[Hashable]][source]
Map each task to the tasks that need to be performed after it.
- get_solution_type() type[Solution][source]
Returns the class implementation of a Solution.
Returns (class): class object of the given Problem.
- is_compatible_task_unary_resource(task: Hashable, unary_resource: Hashable) bool[source]
Should return False if the unary_resource can never be allocated to task.
This is only a hint used to reduce the number of variables or constraints generated.
Default to True, to be overriden in subclasses.
- satisfy(variable: Solution) bool[source]
Computes if a solution satisfies or not the constraints of the problem.
- Parameters:
variable – the Solution object to check satisfability
Returns (bool): boolean true if the constraints are fulfilled, false elsewhere.
- set_objective_handling(objective_handling: ObjectiveHandling)[source]
- property unary_resources_list: list[Hashable]
- class discrete_optimization.workforce.scheduling.problem.AllocSchedulingSolution(problem: AllocSchedulingProblem, schedule: ndarray, allocation: ndarray)[source]
Bases:
SchedulingSolution[Hashable],AllocationSolution[Hashable,Hashable]- change_problem(new_problem: Problem) None[source]
If relevant to the optimisation problem, change the underlying problem instance for the solution.
This method can be used to evaluate a solution for different instance of problems.
- Parameters:
new_problem (Problem) – another problem instance from which the solution can be evaluated
Returns: None
- copy() Solution[source]
Deep copy of the solution.
The copy() function should return a new object containing the same input as the current object, that respects the following expected behaviour: -y = x.copy() -if do some inplace change of y, the changes are not done in x.
Returns: a new object from which you can manipulate attributes without changing the original object.
- is_allocated(task: Hashable, unary_resource: Hashable) bool[source]
Return the usage of the unary resource for the given task.
- Parameters:
task
unary_resource
Returns:
- problem: AllocSchedulingProblem
- class discrete_optimization.workforce.scheduling.problem.TasksDescription(duration_task: int, resource_consumption: dict[str, int] | None = None)[source]
Bases:
object
- discrete_optimization.workforce.scheduling.problem.build_calendar_array_from_availability_slot(availability_slots: list[tuple[int, int]], horizon: int, value: int = 1)[source]
- discrete_optimization.workforce.scheduling.problem.build_pair_mode_constraint(problem: AllocSchedulingProblem, rcpsp: RcpspProblem, use_score: bool = False)[source]
- discrete_optimization.workforce.scheduling.problem.compute_stats_per_team(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution) dict[int, float][source]
- discrete_optimization.workforce.scheduling.problem.correct_schedule_avoid_overlap(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution, init_min_starting_date_lb: bool = False)[source]
- discrete_optimization.workforce.scheduling.problem.evaluate_solution(solution: AllocSchedulingSolution, problem: AllocSchedulingProblem) dict[str, float][source]
- discrete_optimization.workforce.scheduling.problem.export_scheduling_problem_json(problem: AllocSchedulingProblem) dict[source]
- discrete_optimization.workforce.scheduling.problem.full_satisfy(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution, partial_solution: bool = False) bool[source]
- discrete_optimization.workforce.scheduling.problem.interval_inside(interval1: tuple[float, float], interval_container: tuple[float, float])[source]
- discrete_optimization.workforce.scheduling.problem.intervals_do_not_overlap(interval1: tuple[float, float], interval2: tuple[float, float])[source]
- discrete_optimization.workforce.scheduling.problem.realign_calendars(calendars_dict: dict[Hashable, list[tuple[int, int]]])[source]
- discrete_optimization.workforce.scheduling.problem.satisfy_all_done(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution, partial_solution: bool = False)[source]
- discrete_optimization.workforce.scheduling.problem.satisfy_available_team(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution, partial_solution: bool = False) bool[source]
Partial solution = True means we ignore variable set to None when we check the constraint.
- discrete_optimization.workforce.scheduling.problem.satisfy_calendars(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution, partial_solution: bool = False)[source]
- discrete_optimization.workforce.scheduling.problem.satisfy_detailed(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution)[source]
- discrete_optimization.workforce.scheduling.problem.satisfy_detailed_all_done(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution)[source]
- discrete_optimization.workforce.scheduling.problem.satisfy_detailed_available_team(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution) list[tuple[str, Hashable, Hashable, int, int]][source]
- discrete_optimization.workforce.scheduling.problem.satisfy_detailed_precedence(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution) list[tuple[str, Hashable, Hashable, int]][source]
- discrete_optimization.workforce.scheduling.problem.satisfy_detailed_same_allocation(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution) list[tuple[str, set[Hashable]], set[int]][source]
- discrete_optimization.workforce.scheduling.problem.satisfy_overlap_teams(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution, **kwargs) bool[source]
- discrete_optimization.workforce.scheduling.problem.satisfy_overlap_teams_detailed(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution) list[tuple[str, int, int, int]][source]
- discrete_optimization.workforce.scheduling.problem.satisfy_precedence(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution, partial_solution: bool = False) bool[source]
Partial solution = True means we ignore variable set to None when we check the constraint.
- discrete_optimization.workforce.scheduling.problem.satisfy_same_allocation(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution, partial_solution: bool = False) bool[source]
Partial solution = True means we ignore variable set to None when we check the constraint. This one is a bit tricky to write when we allow partial solution.
- discrete_optimization.workforce.scheduling.problem.satisfy_time_window(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution, partial_solution: bool = False)[source]
- discrete_optimization.workforce.scheduling.problem.satisfy_time_window_detailed(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution)[source]
- discrete_optimization.workforce.scheduling.problem.transform_alloc_solution_to_rcpsp_solution(alloc_solution: AllocSchedulingSolution, rcpsp_problem: RcpspProblem, ac_mode_to_team: dict[tuple[Hashable, int], Hashable], alloc_scheduling_problem: AllocSchedulingProblem) RcpspSolution[source]
- discrete_optimization.workforce.scheduling.problem.transform_rcpsp_solution_to_alloc_solution(rcpsp_solution: RcpspSolution, rcpsp_problem: RcpspProblem, ac_mode_to_team: dict[tuple[Hashable, int], Hashable], alloc_scheduling_problem: AllocSchedulingProblem) AllocSchedulingSolution[source]
- discrete_optimization.workforce.scheduling.problem.transform_to_monomode_rcpsp(problem: AllocSchedulingProblem, build_calendar: bool = True, add_additional_constraint: bool = True) tuple[RcpspProblem, dict[tuple[Hashable, int], Hashable]][source]
- discrete_optimization.workforce.scheduling.problem.transform_to_multimode_rcpsp(problem: AllocSchedulingProblem, build_calendar: bool = True, add_window_time_constraint: bool = True, add_additional_constraint: bool = True) tuple[RcpspProblem, dict[tuple[Hashable, int], Hashable]][source]
discrete_optimization.workforce.scheduling.utils module
- discrete_optimization.workforce.scheduling.utils.alloc_solution_to_alloc_sched_solution(problem: AllocSchedulingProblem, solution: TeamAllocationSolution)[source]
- discrete_optimization.workforce.scheduling.utils.binary_calendar(list_available: list[tuple[int, int]], horizon: int)[source]
- discrete_optimization.workforce.scheduling.utils.build_allocation_problem_from_scheduling(problem: AllocSchedulingProblem, solution: AllocSchedulingSolution | None = None, problem_alloc: TeamAllocationProblem | None = None, multiobjective: bool = True) TeamAllocationProblem[source]
- discrete_optimization.workforce.scheduling.utils.build_scheduling_problem_from_allocation(problem: TeamAllocationProblem, horizon_start_shift: int = 0) AllocSchedulingProblem[source]
- discrete_optimization.workforce.scheduling.utils.compute_available_teams_per_activities_alloc_problem(problem: TeamAllocationProblem, starts: ndarray, ends: ndarray, calendars_team: dict[Hashable, ndarray])[source]
- discrete_optimization.workforce.scheduling.utils.compute_changes_between_solution(solution_a: AllocSchedulingSolution, solution_b: AllocSchedulingSolution, problem_a: AllocSchedulingProblem | None = None, problem_b: AllocSchedulingProblem | None = None)[source]
- discrete_optimization.workforce.scheduling.utils.compute_changes_between_solution_same_pb(solution_a: AllocSchedulingSolution, solution_b: AllocSchedulingSolution, problem: AllocSchedulingProblem | None = None)[source]
- discrete_optimization.workforce.scheduling.utils.compute_equivalent_teams_scheduling_problem(scheduling_problem: AllocSchedulingProblem) list[list[int]][source]
Return a list of disjoint set of teams index, that can be considered as indistinguishable from a solution point of view. Example : in the pure coloring problem all the colors/team are equivalent In the team allocation problem, due to restricted compatible teams to task, the equivalent class are different Adaptation from the notebook/test_models.ipynb
- discrete_optimization.workforce.scheduling.utils.compute_precedence_graph(problem: AllocSchedulingProblem) DiGraph[source]
- discrete_optimization.workforce.scheduling.utils.estimate_nb_resource_needed(problem: AllocSchedulingProblem)[source]
- discrete_optimization.workforce.scheduling.utils.export_scheduling_problem_json(problem: AllocSchedulingProblem) dict[source]
- discrete_optimization.workforce.scheduling.utils.get_availability_slots(calendar_matrix: ndarray)[source]
- discrete_optimization.workforce.scheduling.utils.get_working_time_teams(problem: AllocSchedulingProblem) dict[source]
- discrete_optimization.workforce.scheduling.utils.natural_explanation_unsat(detailed_output: list[tuple | dict], problem: AllocSchedulingProblem) list[str][source]
- discrete_optimization.workforce.scheduling.utils.natural_explanation_unsat_from_sol(solution: AllocSchedulingSolution) list[str][source]
- discrete_optimization.workforce.scheduling.utils.overlap_interval(interval_1: tuple[int, int], interval_2: tuple[int, int])[source]
- discrete_optimization.workforce.scheduling.utils.plot_schedule_comparison(base_solution: AllocSchedulingSolution, updated_solution: AllocSchedulingSolution, problem: AllocSchedulingProblem)[source]
Nice visu to compare 2 schedules.
- discrete_optimization.workforce.scheduling.utils.plotly_schedule_comparison(base_solution: AllocSchedulingSolution, updated_solution: AllocSchedulingSolution, problem: AllocSchedulingProblem, index_team_to_other_index: dict[int, int] | None = None, display: bool = False, additional_info: dict[Hashable, dict[str, Any]] | None = None, use_color_scale: bool = True, use_color_map_per_task: bool = False, color_map_per_task: dict[int, Any] | None = None, opacity_map_per_task: dict[int, float] | None = None, show_all_changes: bool = True, show_change: dict[int, bool] | None = None, plot_team_breaks: bool = False, plot_xticks: bool = True, plot_text: bool = True, title='Scheduling Comparison (Base vs Updated)')[source]
Nice visu to compare 2 schedules.
- discrete_optimization.workforce.scheduling.utils.template_violated_constraint(satisfy_detailed_output: tuple | dict, problem: AllocSchedulingProblem)[source]