discrete_optimization.workforce.allocation.solvers package

Submodules

discrete_optimization.workforce.allocation.solvers.cpmpy module

class discrete_optimization.workforce.allocation.solvers.cpmpy.CPMpyTeamAllocationSolver(problem: TeamAllocationProblem, params_objective_function: ParamsObjectiveFunction | None = None, solver_name: str | None = None, **kwargs: Any)[source]

Bases: CpmpySolver, CpSolver, TeamAllocationSolver

add_lexico_constraint(obj: str, 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_multiobj(key_objective: str, allocation_binary: list[dict[int, NDVarArray]], used: NDVarArray, modelisation_dispersion: ModelisationDispersion = ModelisationDispersion.EXACT_MODELING_WITH_IMPLICATION)[source]
add_symm_breaking_constraint(model: Model, used_variable: NDVarArray)[source]
add_symm_waterfall_binary(model: Model, allocation_binary: list[dict[int, Expression]])[source]
add_symm_waterfall_integer(model: Model, allocation_integer: list[Expression])[source]
additional_constraint(additional_constraint: AllocationAdditionalConstraint)[source]
get_lexico_objective_value(obj: str, 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] = [EnumHyperparameter(name='modelisation_allocation', default=<ModelisationAllocationCP.BINARY: 1>, depends_on=None, name_in_kwargs='modelisation_allocation'), EnumHyperparameter(name='modelisation_dispersion', default=<ModelisationDispersion.EXACT_MODELING_WITH_IMPLICATION: 0>, depends_on=('modelisation_allocation', [<ModelisationAllocationCP.BINARY: 1>, <ModelisationAllocationCP.CNF_COMPATIBLE: 2>]), name_in_kwargs='modelisation_dispersion'), CategoricalHyperparameter(name='include_all_binary_vars', default=False, depends_on=('modelisation_allocation', [<ModelisationAllocationCP.BINARY: 1>, <ModelisationAllocationCP.CNF_COMPATIBLE: 2>]), name_in_kwargs='include_all_binary_vars'), CategoricalHyperparameter(name='include_pair_overlap', default=False, depends_on=None, name_in_kwargs='include_pair_overlap'), CategoricalHyperparameter(name='overlapping_advanced', default=True, depends_on=None, name_in_kwargs='overlapping_advanced'), CategoricalHyperparameter(name='symmbreak_on_used', default=True, depends_on=None, name_in_kwargs='symmbreak_on_used'), CategoricalHyperparameter(name='add_lower_bound_nb_teams', default=False, depends_on=None, name_in_kwargs='add_lower_bound_nb_teams')]

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(**args: Any) None[source]

Instantiate a CP model instance

Afterwards, self.instance should not be None anymore.

init_model_binary(**kwargs)[source]
init_model_integer(**kwargs)[source]
problem: TeamAllocationProblem
retrieve_current_solution() Solution[source]

Construct a do solution from the cpmpy solver internal solution.

It will be called after self.model.solve()

Returns:

the solution, at do format.

retrieve_solutions(result: Any, parameters_cp: ParametersCp) ResultStorage[source]
set_lexico_objective(obj: str) None[source]

Update internal model objective.

Parameters:

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

Returns:

store_objective_and_time(verbose=False)[source]
class discrete_optimization.workforce.allocation.solvers.cpmpy.CPMpyTeamAllocationSolverStoreConstraintInfo(problem: TeamAllocationProblem, params_objective_function: ParamsObjectiveFunction | None = None, solver_name: str | None = None, **kwargs: Any)[source]

Bases: CPMpyTeamAllocationSolver

get_types_of_meta_constraints()[source]
init_model(**args: Any) None[source]

Instantiate a CP model instance

Afterwards, self.instance should not be None anymore.

init_model_binary(**kwargs)[source]
class discrete_optimization.workforce.allocation.solvers.cpmpy.CallbackWithBound(verbose=False)[source]

Bases: OrtSolutionCounter

on_solution_callback()[source]

Called on each new solution.

class discrete_optimization.workforce.allocation.solvers.cpmpy.ModelisationAllocationCP(value)[source]

Bases: Enum

An enumeration.

BINARY = 1
CNF_COMPATIBLE = 2
INTEGER = 0
discrete_optimization.workforce.allocation.solvers.cpmpy.adding_all_diff_allocation_binary(solver: CPMpyTeamAllocationSolver | CPMpyTeamAllocationSolverStoreConstraintInfo, all_diff_allocation: list[set[Hashable]], variables: list[dict[int, Expression]], problem: TeamAllocationProblem) list[Expression][source]
discrete_optimization.workforce.allocation.solvers.cpmpy.adding_allowed_allocation_binary(solver: CPMpyTeamAllocationSolver | CPMpyTeamAllocationSolverStoreConstraintInfo, allowed_allocation: dict[Hashable, set[Hashable]], variables: list[dict[int, Expression]], problem: TeamAllocationProblem) list[Expression][source]
discrete_optimization.workforce.allocation.solvers.cpmpy.adding_disjunction_binary(solver: CPMpyTeamAllocationSolver | CPMpyTeamAllocationSolverStoreConstraintInfo, disjunction: list[list[tuple[Hashable, Hashable]]], variables: list[dict[int, Expression]], problem: TeamAllocationProblem) list[Expression][source]
discrete_optimization.workforce.allocation.solvers.cpmpy.adding_forbidden_allocation_binary(solver: CPMpyTeamAllocationSolver | CPMpyTeamAllocationSolverStoreConstraintInfo, forbidden_allocation: dict[Hashable, set[Hashable]], variables: list[dict[int, Expression]], problem: TeamAllocationProblem) list[Expression][source]
discrete_optimization.workforce.allocation.solvers.cpmpy.adding_forced_allocation_binary(solver: CPMpyTeamAllocationSolver | CPMpyTeamAllocationSolverStoreConstraintInfo, forced_allocation: dict[Hashable, Hashable], variables: list[dict[int, Expression]], problem: TeamAllocationProblem) list[Expression][source]
discrete_optimization.workforce.allocation.solvers.cpmpy.adding_max_nb_teams(solver: CPMpyTeamAllocationSolver | CPMpyTeamAllocationSolverStoreConstraintInfo, nb_max_teams: int | None, variables: list[Expression], problem: TeamAllocationProblem)[source]
discrete_optimization.workforce.allocation.solvers.cpmpy.adding_precedence_channeling_constraint(solver: CPMpyTeamAllocationSolver | CPMpyTeamAllocationSolverStoreConstraintInfo, precedences: dict[Hashable, set[Hashable]], variables: list[dict[int, Expression]], problem: TeamAllocationProblem)[source]
discrete_optimization.workforce.allocation.solvers.cpmpy.adding_same_allocation_constraint_binary(solver: CPMpyTeamAllocationSolver | CPMpyTeamAllocationSolverStoreConstraintInfo, same_allocation: list[set[Hashable]], variables: list[dict[int, Expression]], problem: TeamAllocationProblem) list[Expression][source]
discrete_optimization.workforce.allocation.solvers.cpmpy.adding_same_allocation_constraint_cnf(solver: CPMpyTeamAllocationSolver | CPMpyTeamAllocationSolverStoreConstraintInfo, same_allocation: list[set[Hashable]], variables: list[dict[int, Expression]], problem: TeamAllocationProblem) list[Expression][source]
discrete_optimization.workforce.allocation.solvers.cpmpy.adding_same_allocation_constraint_integer(solver: CPMpyTeamAllocationSolver | CPMpyTeamAllocationSolverStoreConstraintInfo, same_allocation: list[set[Hashable]], variables: NDVarArray, problem: TeamAllocationProblem) list[Expression][source]
discrete_optimization.workforce.allocation.solvers.cpmpy.compute_soft_and_hard_set_of_constraint(cpmpy_solver: CPMpyTeamAllocationSolverStoreConstraintInfo, dictionnary_soft_hard: dict[str, str] | None = None)[source]
discrete_optimization.workforce.allocation.solvers.cpmpy.from_solver_status_cpmpy_to_status_solver(solver_status: SolverStatus) StatusSolver[source]

discrete_optimization.workforce.allocation.solvers.cpsat module

class discrete_optimization.workforce.allocation.solvers.cpsat.CpsatTeamAllocationSolver(problem: TeamAllocationProblem, params_objective_function: ParamsObjectiveFunction | None = None, **kwargs: Any)[source]

Bases: OrtoolsCpSatSolver, TeamAllocationSolver, WarmstartMixin

add_lexico_constraint(obj: str, 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_multiobj(key_objective: str, allocation_binary: list[dict[int, NDVarArray]], used: NDVarArray, modelisation_dispersion: ModelisationDispersion, **kwargs)[source]
additional_constraint(additional_constraint: AllocationAdditionalConstraint)[source]
compute_sufficient_assumptions(parameters_cp: ParametersCp | None = None, time_limit: float | None = 100.0, **kwargs)[source]
compute_task_relaxation_alternatives(callbacks: list[Callback] | None = None, parameters_cp: ParametersCp | None = None, time_limit: float | None = 100.0, time_limit_per_iteration: float | None = 10.0, **kwargs)[source]
create_delta_to_base_solution_binary(base_solution: TeamAllocationSolution, base_problem: TeamAllocationProblem | None = None)[source]
create_delta_to_base_solution_integer(base_solution: TeamAllocationSolution, base_problem: TeamAllocationProblem | None = None)[source]
get_lexico_objective_value(obj: str, 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] = [EnumHyperparameter(name='modelisation_allocation', default=<ModelisationAllocationOrtools.BINARY: 1>, depends_on=None, name_in_kwargs='modelisation_allocation'), EnumHyperparameter(name='modelisation_dispersion', default=<ModelisationDispersion.EXACT_MODELING_WITH_IMPLICATION: 0>, depends_on=('modelisation_allocation', [<ModelisationAllocationOrtools.BINARY: 1>, <ModelisationAllocationOrtools.BINARY_OPTIONAL_ACTIVITIES: 2>]), name_in_kwargs='modelisation_dispersion'), CategoricalHyperparameter(name='include_all_binary_vars', default=False, depends_on=('modelisation_allocation', [<ModelisationAllocationOrtools.BINARY: 1>, <ModelisationAllocationOrtools.BINARY_OPTIONAL_ACTIVITIES: 2>]), name_in_kwargs='include_all_binary_vars'), CategoricalHyperparameter(name='include_pair_overlap', default=True, depends_on=None, name_in_kwargs='include_pair_overlap'), CategoricalHyperparameter(name='overlapping_advanced', default=True, depends_on=None, name_in_kwargs='overlapping_advanced'), CategoricalHyperparameter(name='symmbreak_on_used', default=True, depends_on=None, name_in_kwargs='symmbreak_on_used'), CategoricalHyperparameter(name='add_lower_bound_nb_teams', default=False, depends_on=None, name_in_kwargs='add_lower_bound_nb_teams')]

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(modelisation_allocation: ModelisationAllocationOrtools = ModelisationAllocationOrtools.BINARY, **args)[source]

Instantiate a CP model instance

Afterwards, self.instance should not be None anymore.

init_model_binary(**kwargs)[source]
init_model_integer(**kwargs)[source]
problem: TeamAllocationProblem
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) 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, float]])[source]
set_warm_start(solution: TeamAllocationSolution) None[source]

Make the solver warm start from the given solution.

solve_n_best_solution(callbacks: list[Callback] | None = None, parameters_cp: ParametersCp | None = None, n_best_solution: int = 100, time_limit: float | None = 100.0, **kwargs)[source]
class discrete_optimization.workforce.allocation.solvers.cpsat.ModelisationAllocationOrtools(value)[source]

Bases: Enum

An enumeration.

BINARY = 1
BINARY_OPTIONAL_ACTIVITIES = 2
INTEGER = 0
class discrete_optimization.workforce.allocation.solvers.cpsat.ModelisationDispersionOrtools(value)[source]

Bases: Enum

An enumeration.

EPSILON_TO_AVG_V0 = 1
EPSILON_TO_AVG_V1 = 2
EXACT_NAIVE = 0
discrete_optimization.workforce.allocation.solvers.cpsat.adding_all_diff_allocation_binary(all_diff_allocation: list[set[Hashable]], model: CpModel, variables: list[dict[int, IntVar]], problem: TeamAllocationProblem)[source]
discrete_optimization.workforce.allocation.solvers.cpsat.adding_all_diff_allocation_integer(all_diff_allocation: list[set[Hashable]], model: CpModel, variables: list[IntVar], problem: TeamAllocationProblem)[source]
discrete_optimization.workforce.allocation.solvers.cpsat.adding_allowed_allocation_binary(allowed_allocation: dict[Hashable, set[Hashable]], model: CpModel, variables: list[dict[int, IntVar]], problem: TeamAllocationProblem)[source]
discrete_optimization.workforce.allocation.solvers.cpsat.adding_allowed_allocation_integer(allowed_allocation: dict[Hashable, set[Hashable]], model: CpModel, variables: list[IntVar], problem: TeamAllocationProblem)[source]
discrete_optimization.workforce.allocation.solvers.cpsat.adding_disjunction_binary(disjunction: list[list[tuple[Hashable, Hashable]]], model: CpModel, variables: list[dict[int, IntVar]], problem: TeamAllocationProblem)[source]
discrete_optimization.workforce.allocation.solvers.cpsat.adding_disjunction_integer(disjunction: list[list[tuple[Hashable, Hashable]]], model: CpModel, variables: list[IntVar], problem: TeamAllocationProblem)[source]
discrete_optimization.workforce.allocation.solvers.cpsat.adding_forbidden_allocation_binary(forbidden_allocation: dict[Hashable, set[Hashable]], model: CpModel, variables: list[dict[int, IntVar]], problem: TeamAllocationProblem)[source]
discrete_optimization.workforce.allocation.solvers.cpsat.adding_forbidden_allocation_integer(forbidden_allocation: dict[Hashable, set[Hashable]], model: CpModel, variables: list[IntVar], problem: TeamAllocationProblem)[source]
discrete_optimization.workforce.allocation.solvers.cpsat.adding_forced_allocation_binary(forced_allocation: dict[Hashable, Hashable], model: CpModel, variables: list[dict[int, IntVar]], problem: TeamAllocationProblem)[source]
discrete_optimization.workforce.allocation.solvers.cpsat.adding_forced_allocation_integer(forced_allocation: dict[Hashable, Hashable], model: CpModel, variables: list[dict[int, IntVar]], problem: TeamAllocationProblem)[source]
discrete_optimization.workforce.allocation.solvers.cpsat.adding_max_nb_teams(max_nb_teams: int | None, model: CpModel, variables: list[IntVar], problem: TeamAllocationProblem)[source]
discrete_optimization.workforce.allocation.solvers.cpsat.adding_precedence_channeling_constraint(precedences: dict[Hashable, set[Hashable]], model: CpModel, variables: list[IntVar], problem: TeamAllocationProblem)[source]
discrete_optimization.workforce.allocation.solvers.cpsat.adding_same_allocation_constraint_binary(same_allocation: list[set[Hashable]], model: CpModel, variables: list[dict[int, IntVar]], problem: TeamAllocationProblem)[source]
discrete_optimization.workforce.allocation.solvers.cpsat.adding_same_allocation_constraint_integer(same_allocation: list[set[Hashable]], model: CpModel, variables: list[IntVar], problem: TeamAllocationProblem)[source]

discrete_optimization.workforce.allocation.solvers.dp module

class discrete_optimization.workforce.allocation.solvers.dp.DpAllocationSolver(problem: Problem, params_objective_function: ParamsObjectiveFunction | None = None, **kwargs: Any)[source]

Bases: DpSolver, TeamAllocationSolver, WarmstartMixin

hyperparameters: list[Hyperparameter] = [CategoricalHyperparameter(name='solver', default=<class 'builtins.CABS'>, depends_on=None, name_in_kwargs='solver'), CategoricalHyperparameter(name='symmbreak_on_used', default=True, depends_on=None, name_in_kwargs='symmbreak_on_used'), CategoricalHyperparameter(name='force_allocation_when_possible', default=False, depends_on=[('symmbreak_on_used', False)], name_in_kwargs='force_allocation_when_possible')]

Hyperparameters available for this solver.

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

  • init_model() (when available)

  • solve()

init_model(**kwargs: Any) None[source]

Initialize internal model used to solve.

Can initialize a ortools, milp, gurobi, … model.

init_model_mono_objective(**kwargs: Any) None[source]
init_model_multi_objective(**kwargs: Any) None[source]
problem: TeamAllocationProblem
retrieve_solution(sol: Solution) Solution[source]
set_warm_start(solution: TeamAllocationSolution) None[source]

Make the solver warm start from the given solution.

transitions: dict[str, list]

Module contents

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

Bases: SolverDO

problem: TeamAllocationProblem