discrete_optimization.workforce.scheduling.solvers package

Submodules

discrete_optimization.workforce.scheduling.solvers.alloc_scheduling_lb module

class discrete_optimization.workforce.scheduling.solvers.alloc_scheduling_lb.ApproximateBoundAllocScheduling(problem: AllocSchedulingProblem)[source]

Bases: BaseAllocSchedulingLowerBoundProvider

get_lb_nb_teams(**args) int[source]
class discrete_optimization.workforce.scheduling.solvers.alloc_scheduling_lb.BaseAllocSchedulingLowerBoundProvider(problem: AllocSchedulingProblem)[source]

Bases: Hyperparametrizable, ABC

abstract get_lb_nb_teams(**kwargs: Any) int[source]
status: str | None = None
class discrete_optimization.workforce.scheduling.solvers.alloc_scheduling_lb.BoundResourceViaRelaxedProblem(problem: AllocSchedulingProblem)[source]

Bases: BaseAllocSchedulingLowerBoundProvider

See add_lower_bound_nb_teams function in cpmpy_alloc_scheduling_solver

get_lb_nb_teams(**kwargs) int[source]
hyperparameters: list[Hyperparameter] = [CategoricalHyperparameter(name='adding_precedence_constraint', default=False, depends_on=None, name_in_kwargs='adding_precedence_constraint')]

Hyperparameters available for this solver.

These hyperparameters are to be feed to **kwargs found in
  • __init__()

  • init_model() (when available)

  • solve()

class discrete_optimization.workforce.scheduling.solvers.alloc_scheduling_lb.LBoundAllocScheduling(problem: AllocSchedulingProblem)[source]

Bases: BaseAllocSchedulingLowerBoundProvider

get_lb_nb_teams(**args) int[source]

discrete_optimization.workforce.scheduling.solvers.cpsat module

class discrete_optimization.workforce.scheduling.solvers.cpsat.AdditionalCPConstraints(nb_teams_bounds: tuple[int | None, int | None] | None = None, team_used_constraint: dict[int, bool] | None = None, set_tasks_ignore_reallocation: set[int] | None = None, forced_allocation: dict[int, int] | None = None, adding_margin_on_sequence: tuple[bool, int] | None = (False, 0))[source]

Bases: object

class discrete_optimization.workforce.scheduling.solvers.cpsat.CPSatAllocSchedulingSolver(problem: Problem, params_objective_function: ParamsObjectiveFunction | None = None, **kwargs: Any)[source]

Bases: OrtoolsCpSatSolver, SolverAllocScheduling, WarmstartMixin

add_lexico_constraint(obj: str | ObjectivesEnum, value: float) Iterable[Any][source]

Add a constraint on a computed sub-objective

Parameters:
  • obj – a string representing the desired objective. Should be one of self.get_lexico_objectives_available().

  • value – the limiting value. If the optimization direction is maximizing, this is a lower bound, else this is an upper bound.

Returns:

the created constraints.

add_objective_functions_on_cumul(objectives: list[ObjectivesEnum] | None = None, **args)[source]
create_delta_objectives(base_solution: AllocSchedulingSolution, base_problem: AllocSchedulingProblem, additional_constraints: AdditionalCPConstraints | None = None)[source]
create_makespan_obj(ends_var: dict[int, IntVar], st_lb: list[tuple[int, int, int, int]] | None = None)[source]
create_used_variable(is_present_var: dict[int, dict[int, IntVar]], key_per_team: dict[int, list[tuple[int, int]]])[source]
get_lexico_objective_value(obj: str | ObjectivesEnum, res: ResultStorage) float[source]

Get best internal model objective value found by last call to solve().

The default implementation consists in using the fit of the last solution in result_storage. This assumes: - that the last solution is the best one for the objective considered - that no aggregation was performed but rather that the fitness is a TupleFitness

with values in the same order as self.problem.get_objective_names().

Parameters:
  • obj – a string representing the desired objective. Should be one of self.get_lexico_objectives_available().

  • res – result storage returned by last call to solve().

Returns:

get_lexico_objectives_available() list[str][source]

List objectives available for lexico optimization

It corresponds to the labels accepted for obj argument for - set_lexico_objective() - add_lexico_constraint() - get_lexico_objective_value()

Default to self.problem.get_objective_names().

Returns:

hyperparameters: list[Hyperparameter] = [CategoricalHyperparameter(name='symmbreak_on_used', default=False, depends_on=None, name_in_kwargs='symmbreak_on_used'), CategoricalHyperparameter(name='optional_activities', default=False, depends_on=None, name_in_kwargs='optional_activities'), EnumHyperparameter(name='modelisation_dispersion', default=<ModelisationDispersion.EXACT_MODELING_WITH_IMPLICATION: 0>, depends_on=None, name_in_kwargs='modelisation_dispersion'), CategoricalHyperparameter(name='adding_redundant_cumulative', default=False, depends_on=None, name_in_kwargs='adding_redundant_cumulative'), CategoricalHyperparameter(name='add_lower_bound', default=False, depends_on=None, name_in_kwargs='add_lower_bound'), SubBrickHyperparameter(name='lower_bound_method', default=SubBrick(cls=<class 'discrete_optimization.workforce.scheduling.solvers.alloc_scheduling_lb.BoundResourceViaRelaxedProblem'>, kwargs={'adding_precedence_constraint': False}, kwargs_from_solution=None), depends_on=('add_lower_bound', [True]), name_in_kwargs='lower_bound_method')]

Hyperparameters available for this solver.

These hyperparameters are to be feed to **kwargs found in
  • __init__()

  • init_model() (when available)

  • solve()

static implements_lexico_api() bool[source]

Tell whether this solver is implementing the api for lexicographic optimization.

Should return True only if

  • set_lexico_objective()

  • add_lexico_constraint()

  • get_lexico_objective_value()

have been really implemented, i.e. - calling set_lexico_objective() and add_lexico_constraint()

should actually change the next call to solve(),

  • get_lexico_objective_value() should correspond to the internal model objective

init_model(objectives: list[ObjectivesEnum] | None = None, **args: Any) None[source]

Instantiate a CP model instance

Afterwards, self.instance should not be None anymore.

problem: AllocSchedulingProblem
retrieve_solution(cpsolvercb: CpSolverSolutionCallback) Solution[source]

Construct a do solution from the cpsat solver internal solution.

It will be called each time the cpsat solver find a new solution. At that point, value of internal variables are accessible via cpsolvercb.Value(VARIABLE_NAME).

Parameters:

cpsolvercb – the ortools callback called when the cpsat solver finds a new solution.

Returns:

the intermediate solution, at do format.

set_additional_constraints(additional_constraint: AdditionalCPConstraints)[source]
set_lexico_objective(obj: str | ObjectivesEnum) None[source]

Update internal model objective.

Parameters:

obj – a string representing the desired objective. Should be one of self.get_lexico_objectives_available().

Returns:

set_model_obj_aggregated(objs_weights: list[tuple[str | ObjectivesEnum, float]])[source]
set_nb_teams_constraints(additional_constraint: AdditionalCPConstraints)[source]
set_team_used_constraint(additional_constraint: AdditionalCPConstraints)[source]
set_warm_start(solution: AllocSchedulingSolution) None[source]

Make the solver warm start from the given solution.

variables: dict[str, dict[Any, Any]]

discrete_optimization.workforce.scheduling.solvers.cpsat_relaxed module

class discrete_optimization.workforce.scheduling.solvers.cpsat_relaxed.CPSatAllocSchedulingSolverCumulative(problem: Problem, params_objective_function: ParamsObjectiveFunction | None = None, **kwargs: Any)[source]

Bases: OrtoolsCpSatSolver, SolverAllocScheduling, WarmstartMixin

add_lexico_constraint(obj: str | ObjectivesEnum, value: float) Iterable[Any][source]

Add a constraint on a computed sub-objective

Parameters:
  • obj – a string representing the desired objective. Should be one of self.get_lexico_objectives_available().

  • value – the limiting value. If the optimization direction is maximizing, this is a lower bound, else this is an upper bound.

Returns:

the created constraints.

create_makespan_obj(ends_var: dict[int, IntVar], st_lb: list[tuple[int, int, int, int]] | None = None)[source]
define_objectives(objectives: list[ObjectivesEnum], **args)[source]
get_lexico_objective_value(obj: str | ObjectivesEnum, res: ResultStorage) float[source]

Get best internal model objective value found by last call to solve().

The default implementation consists in using the fit of the last solution in result_storage. This assumes: - that the last solution is the best one for the objective considered - that no aggregation was performed but rather that the fitness is a TupleFitness

with values in the same order as self.problem.get_objective_names().

Parameters:
  • obj – a string representing the desired objective. Should be one of self.get_lexico_objectives_available().

  • res – result storage returned by last call to solve().

Returns:

get_lexico_objectives_available() list[str][source]

List objectives available for lexico optimization

It corresponds to the labels accepted for obj argument for - set_lexico_objective() - add_lexico_constraint() - get_lexico_objective_value()

Default to self.problem.get_objective_names().

Returns:

hyperparameters: list[Hyperparameter] = [CategoricalHyperparameter(name='optional_activities', default=False, depends_on=None, name_in_kwargs='optional_activities'), CategoricalHyperparameter(name='adding_redundant_cumulative', default=False, depends_on=None, name_in_kwargs='adding_redundant_cumulative'), CategoricalHyperparameter(name='add_lower_bound', default=False, depends_on=None, name_in_kwargs='add_lower_bound'), SubBrickHyperparameter(name='lower_bound_method', default=SubBrick(cls=<class 'discrete_optimization.workforce.scheduling.solvers.alloc_scheduling_lb.BoundResourceViaRelaxedProblem'>, kwargs={'adding_precedence_constraint': False}, kwargs_from_solution=None), depends_on=('add_lower_bound', [True]), name_in_kwargs='lower_bound_method')]

Hyperparameters available for this solver.

These hyperparameters are to be feed to **kwargs found in
  • __init__()

  • init_model() (when available)

  • solve()

static implements_lexico_api() bool[source]

Tell whether this solver is implementing the api for lexicographic optimization.

Should return True only if

  • set_lexico_objective()

  • add_lexico_constraint()

  • get_lexico_objective_value()

have been really implemented, i.e. - calling set_lexico_objective() and add_lexico_constraint()

should actually change the next call to solve(),

  • get_lexico_objective_value() should correspond to the internal model objective

init_main_vars(**args)[source]
init_model(objectives: list[ObjectivesEnum] | None = None, **args: Any) None[source]

Instantiate a CP model instance

Afterwards, self.instance should not be None anymore.

init_multimode_data(**kwargs)[source]
not_implemented_objectives = [ObjectivesEnum.DELTA_TO_EXISTING_SOLUTION, ObjectivesEnum.DISPERSION, ObjectivesEnum.MIN_WORKLOAD]
problem: AllocSchedulingProblem
retrieve_solution(cpsolvercb: CpSolverSolutionCallback) Solution[source]

Construct a do solution from the cpsat solver internal solution.

It will be called each time the cpsat solver find a new solution. At that point, value of internal variables are accessible via cpsolvercb.Value(VARIABLE_NAME).

Parameters:

cpsolvercb – the ortools callback called when the cpsat solver finds a new solution.

Returns:

the intermediate solution, at do format.

set_lexico_objective(obj: str | ObjectivesEnum) None[source]

Update internal model objective.

Parameters:

obj – a string representing the desired objective. Should be one of self.get_lexico_objectives_available().

Returns:

set_model_obj_aggregated(objs_weights: list[tuple[str | ObjectivesEnum, float]])[source]
set_precedence_constraints()[source]
set_resource_pool_constraints()[source]
set_same_allocation_constraints()[source]
set_warm_start(solution: AllocSchedulingSolution) None[source]

Make the solver warm start from the given solution.

solve(callbacks: list[Callback] | None = None, parameters_cp: ParametersCp | None = None, time_limit: float | None = 100.0, ortools_cpsat_solver_kwargs: dict[str, Any] | None = None, retrieve_stats: bool = False, kwargs_scheduling: dict[str, Any] | None = None, kwargs_allocation: dict[str, Any] | None = None, **kwargs)[source]

Solve the problem with a CpSat scheduling solver chained to a cpsat allocation solver

Parameters:
  • callbacks – list of callbacks used to hook into the various stage of the solve

  • parameters_cp – used by subsolvers if not defined in kwargs_scheduling or kwargs_allocation

  • time_limit – used by subsolvers if not defined in kwargs_scheduling or kwargs_allocation

  • ortools_cpsat_solver_kwargs – used by subsolvers if not defined in kwargs_scheduling or kwargs_allocation

  • retrieve_stats – used by subsolvers if not defined in kwargs_scheduling or kwargs_allocation

  • kwargs_scheduling – kwargs passed to scheduling solver’s solve() (including parameters_cp, callbacks, …)

  • kwargs_allocation – kwargs passed to allocation solver’s solve() (including parameters_cp, callbacks, …)

  • **kwargs – passed to both subsolvers but params are overriden by the one in kwargs_scheduling or kwargs_allocation

Returns:

variables: dict[str, dict[Any, Any]]

Module contents

class discrete_optimization.workforce.scheduling.solvers.ObjectivesEnum(value)[source]

Bases: Enum

An enumeration.

DELTA_TO_EXISTING_SOLUTION = 6
DISPERSION = 2
MAKESPAN = 3
MIN_WORKLOAD = 4
NB_DONE_AC = 5
NB_TEAMS = 1
class discrete_optimization.workforce.scheduling.solvers.SolverAllocScheduling(problem: Problem, params_objective_function: ParamsObjectiveFunction | None = None, **kwargs: Any)[source]

Bases: SolverDO

problem: AllocSchedulingProblem