discrete_optimization.multibatching.solvers package

Submodules

discrete_optimization.multibatching.solvers.asp module

class discrete_optimization.multibatching.solvers.asp.ClingconMultibatchingSolver(problem: MultibatchingProblem, params_objective_function: ParamsObjectiveFunction | None = None, **kwargs: Any)[source]

Bases: SolverDO

all_dataframes = {}
extract_clingo_number(val) float[source]

Extract numeric value from Clingo symbols or convert to number.

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

Initialize internal model used to solve.

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

modelAggregateTemplates = [{'columns': ['from', 'to', 'transportresource', 'freq', 'total'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'route_freq_cap'}, {'columns': ['product', 'location', 'amount'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'flow_out'}, {'columns': ['product', 'location', 'amount'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'flow_in'}, {'columns': ['product', 'location', 'amount'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'req'}, {'columns': ['from', 'to', 'transportresource', 'cost'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'route_cost_total'}, {'columns': ['from', 'to', 'transportresource', 'product', 'amount'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'load'}, {'columns': ['from', 'to', 'transportresource', 'val'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'active_flow'}]
modelAtomTemplates = [{'columns': ['product', 'amount'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'totalSupply'}, {'columns': ['idx', 'from', 'to', 'transportresource', 'distance', 'cost'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'route'}, {'columns': ['from', 'to', 'transportresource', 'cost'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'routeCostTotal'}, {'columns': ['from', 'to', 'transportresource', 'freq', 'maxcapacity'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'routeFreq'}, {'columns': ['from', 'to', 'transportresource', 'product'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'activeFlow'}, {'columns': ['product', 'location', 'amount'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'demandOffer'}, {'columns': ['product', 'location', 'amount'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'requiredNet'}, {'columns': ['product', 'transportresource'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'productTR'}, {'columns': ['product', 'size'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'productSize'}, {'columns': ['from', 'to', 'transportresource', 'product'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'possibleFlow'}, {'columns': ['transportresource', 'capacity'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'transportCapacity'}, {'columns': ['transportresource', 'transportationCost'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'transportCost'}, {'columns': ['transportresource', 'CO2'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'transportCO2'}, {'columns': ['from', 'to', 'transportresource', 'product', 'amount'], 'filter': <function ClingconMultibatchingSolver.<lambda>>, 'name': 'productOnFlow'}]
modelIndex = 0
problem: MultibatchingProblem
retrieve_solution(model: Model) MultibatchingSolution[source]
sanitize(s: str) str[source]
sanitize_num(val) int[source]

Ensures input is a valid integer for Clingcon constraints.

solve(callbacks: List[Callback] | None = None, time_limit: float | None = None, **kwargs: Any) ResultStorage[source]

Generic solving function.

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

  • **kwargs – any argument specific to the solver

Solvers deriving from SolverDo should use callbacks methods .on_step_end(), … during solve(). But some solvers are not yet updated and are just ignoring it.

Returns (ResultStorage): a result object containing potentially a pool of solutions to a discrete-optimization problem

start_solving = 0

discrete_optimization.multibatching.solvers.benders module

class discrete_optimization.multibatching.solvers.benders.CpsatBendersMultibatchingSolver(problem: MultibatchingProblem, **kwargs: Any)[source]

Bases: SolverDO

hyperparameters: list[Hyperparameter] = [SubBrickHyperparameter(name='packing_solver', default=SubBrick(cls=<class 'discrete_optimization.multibatching.solvers.packing_subproblem.GreedyPackingForMultibatching'>, kwargs=None, kwargs_from_solution=None), depends_on=None, name_in_kwargs='packing_solver')]

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.

problem: MultibatchingProblem
solve(callbacks: list[Callback] | None = None, time_limit_first_iter: int = 100, params_solver_master: dict = None, nb_iteration: int = 10, **kwargs: Any) ResultStorage[source]

Generic solving function.

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

  • **kwargs – any argument specific to the solver

Solvers deriving from SolverDo should use callbacks methods .on_step_end(), … during solve(). But some solvers are not yet updated and are just ignoring it.

Returns (ResultStorage): a result object containing potentially a pool of solutions to a discrete-optimization problem

update_model_master(changed: list[tuple[TransportLink, dict[Product, int], int, int]], best_lb: int)[source]

discrete_optimization.multibatching.solvers.cp_mzn module

class discrete_optimization.multibatching.solvers.cp_mzn.CpMultibatchingSolver(problem: MultibatchingProblem, params_objective_function: ParamsObjectiveFunction | None = None, silent_solve_error: bool = False, **kwargs: Any)[source]

Bases: MinizincCpSolver, MultibatchingSolver

CP solver for the Multibatching problem using MiniZinc.

This solver uses a flow formulation with network_flow constraints to model the multibatching problem. It computes the number of trips and the flow of each product on each transport link.

problem

The multibatching problem instance to solve.

Type:

MultibatchingProblem

params_objective_function

Parameters for objective function.

Type:

ParamsObjectiveFunction

cp_solver_name

Backend CP solver to use with MiniZinc.

Type:

CpSolverName

silent_solve_error

If True, raise warning instead of error on solve crashes.

Type:

bool

hyperparameters: list[Hyperparameter] = [EnumHyperparameter(name='cp_solver_name', default=<CpSolverName.CHUFFED: 0>, depends_on=None, name_in_kwargs='cp_solver_name'), CategoricalHyperparameter(name='restrict_to_shortest_paths', default=False, depends_on=None, name_in_kwargs='restrict_to_shortest_paths'), FloatHyperparameter(name='shortest_path_tolerance', default=0.1, depends_on=[('restrict_to_shortest_paths', [True])], name_in_kwargs='shortest_path_tolerance', low=0, high=5, suggest_low=False, suggest_high=False, step=None, log=False)]

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 the MiniZinc model with problem data.

Parameters:
  • cp_solver_name (CpSolverName) – CP solver to use (default: CHUFFED)

  • **kwargs – Additional keyword arguments

problem: MultibatchingProblem
retrieve_solution(_output_item: str | None = None, **kwargs: Any) MultibatchingSolution[source]

Convert MiniZinc solution to MultibatchingSolution.

Parameters:
  • _output_item – MiniZinc output string (unused)

  • **kwargs – Contains ‘nb_trips’ and ‘flow’ arrays from MiniZinc

Returns:

The solution object

Return type:

MultibatchingSolution

discrete_optimization.multibatching.solvers.cpsat module

class discrete_optimization.multibatching.solvers.cpsat.CpsatMultibatchingSolver(problem: MultibatchingProblem, params_objective_function: ParamsObjectiveFunction | None = None, **kwargs: Any)[source]

Bases: OrtoolsCpSatSolver, WarmstartMixin

add_advanced_capacity_constraints(model, flows_variables, nb_trips_per_link, solver_type='cpsat')[source]

Adds improved lower bounds on the number of trips based on bin packing dual feasible functions. Adapted from the DP bounds for SALBP/BinPacking.

add_advanced_capacity_constraints2(model, flows_variables, nb_trips_per_link, solver_type='cpsat', max_k=30)[source]

Adds generalized lower bound constraints on the number of trips. For each k in [2..max_k], we consider items with size > Capacity/k. Since at most k-1 such items fit in one vehicle, we add the cut:

(k-1) * NbTrips >= Sum(Flows of these items)

add_global_flow_limit_constraints(model, flows_variables, solver_type='cpsat', factor=2)[source]

Limits the total volume of flow for each product across the entire network. Constraint: Sum(Flows_of_Product_P) <= factor * TotalDemand_of_Product_P

  • A factor of 1.0 implies direct shipments only (shortest path in terms of hops).

  • A factor of 2.0 implies that, on average, each unit can traverse 2 links (1 transshipment).

  • This prevents excessive detours without using binary variables.

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.

Limits the number of transport links where a given product flows. Limit = factor * (Number of nodes with non-zero supply/demand for that product). This helps pruning the search space by forcing sparser paths (e.g. tree-like).

compute_nb_trips_min(product: Product, demand_of_product: int)[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='modeling', default=<ModelingMultiBatch.FLOW: 0>, depends_on=None, name_in_kwargs='modeling'), CategoricalHyperparameter(name='detailed_capacity_constraint', default=False, depends_on=[('modeling', [<ModelingMultiBatch.FLOW: 0>])], name_in_kwargs='detailed_capacity_constraint'), CategoricalHyperparameter(name='add_lb_constraint_nb_trips', default=False, depends_on=[('modeling', [<ModelingMultiBatch.FLOW: 0>])], name_in_kwargs='add_lb_constraint_nb_trips'), CategoricalHyperparameter(name='restrict_to_shortest_paths', default=False, depends_on=None, name_in_kwargs='restrict_to_shortest_paths'), FloatHyperparameter(name='shortest_path_tolerance', default=1.0, depends_on=[('restrict_to_shortest_paths', True)], name_in_kwargs='shortest_path_tolerance', low=0.0, high=30, suggest_low=False, suggest_high=False, step=None, log=False), CategoricalHyperparameter(name='prevent_incoming_at_source', default=None, depends_on=None, name_in_kwargs='prevent_incoming_at_source')]

Hyperparameters available for this solver.

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

  • init_model() (when available)

  • solve()

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(single_batching: bool = False, **args: Any) None[source]

Init cp model and reset stored variables if any.

init_model_detailed_trips(**args: Any) None[source]
init_model_flows(**args: Any) None[source]
init_model_flows_single_batching(**args: Any) None[source]
logs_solution(cpsolvercb: CpSolverSolutionCallback) Solution[source]
problem: MultibatchingProblem
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_warm_start(solution: MultibatchingSolution) None[source]

Make the solver warm start from the given solution.

set_warm_start_flow(solution: MultibatchingSolution) None[source]
set_warm_start_from_prev_solve()[source]
set_warm_start_unit_flow(solution: MultibatchingSolution) None[source]

Provides a warm start for the UNIT_FLOW modeling by hinting individual trip contents.

class discrete_optimization.multibatching.solvers.cpsat.ModelingMultiBatch(*values)[source]

Bases: Enum

FLOW = 0
UNIT_FLOW = 1

discrete_optimization.multibatching.solvers.dp module

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

Bases: DpSolver, MultibatchingSolver

Dynamic Programming solver for multibatching problem.

Simplified approach: - State: Current supply/demand at each (product, location) pair - Transitions: Send a batch on a transport link with specific products/quantities - Base case: All supply/demand balanced (net = 0) - Cost: Transport cost for each batch

Note: This models each product flow separately and aggregates in solution retrieval.

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

Initialize DP model for multibatching.

problem: MultibatchingProblem
retrieve_solution(sol: Solution) Solution[source]

Extract MultibatchingSolution from DP solution.

Parses transition sequence: open_{link} -> send_{product}_{link} -> close and aggregates into batches. Simulates state changes to determine quantities for send_all transitions.

transitions: dict

discrete_optimization.multibatching.solvers.lp module

class discrete_optimization.multibatching.solvers.lp.GurobiLazyCallback(do_solver: GurobiMultibatchingSolver, callback: Callback)[source]

Bases: object

Custom Gurobi callback to generate valid, flow-dependent cuts for the multibatching problem.

class discrete_optimization.multibatching.solvers.lp.GurobiMultibatchingSolver(problem: MultibatchingProblem, **kwargs: Any)[source]

Bases: GurobiMilpSolver, _BaseLpMultibatchingSolver

Gurobi solver for the Multibatching problem, based on a flow formulation.

convert_to_variable_values(solution: Solution) dict[gurobipy.Var, float][source]

Convert a solution to a mapping between model variables and their values.

Will be used by set_warm_start().

Override it in subclasses to have a proper warm start. You can also override set_warm_start() if default behaviour is not sufficient.

hyperparameters = [CategoricalHyperparameter(name='add_lb_constraint_nb_trips', default=False, depends_on=None, name_in_kwargs='add_lb_constraint_nb_trips'), CategoricalHyperparameter(name='restrict_to_shortest_paths', default=False, depends_on=None, name_in_kwargs='restrict_to_shortest_paths'), FloatHyperparameter(name='shortest_path_tolerance', default=0.2, depends_on=[('restrict_to_shortest_paths', True)], name_in_kwargs='shortest_path_tolerance', low=0, high=30, suggest_low=False, suggest_high=False, step=None, log=False)]

Hyperparameters available for this solver.

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

  • init_model() (when available)

  • solve()

init_model(single_batching: bool = False, **kwargs: Any) None[source]

Initialize internal model used to solve.

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

class discrete_optimization.multibatching.solvers.lp.GurobiMultibatchingSolverUnitFlow(problem: MultibatchingProblem, **kwargs: Any)[source]

Bases: GurobiMilpSolver, _BaseLpMultibatchingSolverUnitFlow

Gurobi solver for the Multibatching problem using unit flow formulation.

convert_to_variable_values(solution: MultibatchingSolution)[source]

Convert a solution to a mapping between model variables and their values.

Will be used by set_warm_start().

Override it in subclasses to have a proper warm start. You can also override set_warm_start() if default behaviour is not sufficient.

init_model(max_trips_per_link: int = 15, **kwargs: Any) None[source]

Initialize internal model used to solve.

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

class discrete_optimization.multibatching.solvers.lp.GurobiMultibatchingSolverWithLazyConstraint(problem: MultibatchingProblem, **kwargs: Any)[source]

Bases: GurobiMultibatchingSolver

A Gurobi solver for the multi-batching problem that uses lazy constraints to iteratively refine the packing model.

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

Initializes the standard multi-batching flow model and enables lazy constraints.

solve(callbacks: list[Callback] = None, parameters_milp: ParametersMilp = None, time_limit: float = 30, **kwargs: Any) ResultStorage[source]

Overrides the default solve method to use a custom callback for generating lazy constraints.

class discrete_optimization.multibatching.solvers.lp.MathOptMultibatchingSolver(problem: MultibatchingProblem, **kwargs: Any)[source]

Bases: OrtoolsMathOptMilpSolver, _BaseLpMultibatchingSolver

MathOpt solver for the Multibatching problem, based on a flow formulation.

convert_to_variable_values(solution: Solution) dict[gurobipy.Var, float][source]

Convert a solution to a mapping between model variables and their values.

Will be used by set_warm_start() to provide a suitable SolutionHint.variable_values. See https://or-tools.github.io/docs/pdoc/ortools/math_opt/python/model_parameters.html#SolutionHint for more information.

Implement it in subclasses to have a proper warm start.

hyperparameters: list[Hyperparameter] = [EnumHyperparameter(name='mathopt_solver_type', default=None, depends_on=None, name_in_kwargs='mathopt_solver_type'), CategoricalHyperparameter(name='add_lb_constraint_nb_trips', default=False, depends_on=None, name_in_kwargs='add_lb_constraint_nb_trips'), CategoricalHyperparameter(name='restrict_to_shortest_paths', default=False, depends_on=None, name_in_kwargs='restrict_to_shortest_paths'), FloatHyperparameter(name='shortest_path_tolerance', default=0.2, depends_on=[('restrict_to_shortest_paths', True)], name_in_kwargs='shortest_path_tolerance', low=0, high=30, suggest_low=False, suggest_high=False, step=None, log=False)]

Hyperparameters available for this solver.

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

  • init_model() (when available)

  • solve()

class discrete_optimization.multibatching.solvers.lp.MathOptMultibatchingSolverUnitFlow(problem: MultibatchingProblem, **kwargs: Any)[source]

Bases: OrtoolsMathOptMilpSolver, _BaseLpMultibatchingSolverUnitFlow

MathOpt solver for the Multibatching problem using unit flow formulation.

convert_to_variable_values(solution: MultibatchingSolution)[source]

Convert a solution to a mapping between model variables and their values.

Will be used by set_warm_start() to provide a suitable SolutionHint.variable_values. See https://or-tools.github.io/docs/pdoc/ortools/math_opt/python/model_parameters.html#SolutionHint for more information.

Implement it in subclasses to have a proper warm start.

discrete_optimization.multibatching.solvers.netx module

class discrete_optimization.multibatching.solvers.netx.NetxMultibatchingSolver(problem: Problem, params_objective_function: ParamsObjectiveFunction | None = None, **kwargs: Any)[source]

Bases: SolverDO

compute_optimal_flow_for_product(product: Product, weight_on_transport: float, weight_on_emission: float)[source]
hyperparameters: list[Hyperparameter] = [CategoricalHyperparameter(name='restrict_to_shortest_paths', default=False, depends_on=None, name_in_kwargs='restrict_to_shortest_paths'), FloatHyperparameter(name='shortest_path_tolerance', default=1.2, depends_on=[('restrict_to_shortest_paths', [True])], name_in_kwargs='shortest_path_tolerance', low=0, high=5, suggest_low=False, suggest_high=False, step=None, log=False), FloatHyperparameter(name='weight_on_transport', default=1, depends_on=None, name_in_kwargs='weight_on_transport', low=0, high=1000, suggest_low=False, suggest_high=False, step=None, log=False), FloatHyperparameter(name='weight_on_emission', default=1, depends_on=None, name_in_kwargs='weight_on_emission', low=0, high=1000, suggest_low=False, suggest_high=False, step=None, log=False)]

Hyperparameters available for this solver.

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

  • init_model() (when available)

  • solve()

problem: MultibatchingProblem
solve(callbacks: list[Callback] | None = None, **kwargs: Any) ResultStorage[source]

Generic solving function.

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

  • **kwargs – any argument specific to the solver

Solvers deriving from SolverDo should use callbacks methods .on_step_end(), … during solve(). But some solvers are not yet updated and are just ignoring it.

Returns (ResultStorage): a result object containing potentially a pool of solutions to a discrete-optimization problem

discrete_optimization.multibatching.solvers.packing_subproblem module

class discrete_optimization.multibatching.solvers.packing_subproblem.CpsatPackingSubproblem(problem: MultibatchingProblem, **kwargs: Any)[source]

Bases: OrtoolsCpSatSolver, PackingSubproblemSolver

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

Init cp model and reset stored variables if any.

retrieve_solution(cpsolvercb: CpSolverSolutionCallback) MultibatchingSolution[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.

class discrete_optimization.multibatching.solvers.packing_subproblem.GreedyPackingForMultibatching(problem: Problem, params_objective_function: ParamsObjectiveFunction | None = None, **kwargs: Any)[source]

Bases: PackingSubproblemSolver

solve(callbacks: list[Callback] | None = None, single_batching: bool = False, **kwargs: Any) ResultStorage[source]

Generic solving function.

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

  • **kwargs – any argument specific to the solver

Solvers deriving from SolverDo should use callbacks methods .on_step_end(), … during solve(). But some solvers are not yet updated and are just ignoring it.

Returns (ResultStorage): a result object containing potentially a pool of solutions to a discrete-optimization problem

class discrete_optimization.multibatching.solvers.packing_subproblem.PackingSubproblemSolver(problem: Problem, params_objective_function: ParamsObjectiveFunction | None = None, **kwargs: Any)[source]

Bases: MultibatchingSolver

analyse_solution(new_solution: MultibatchingSolution)[source]
base_solution: MultibatchingSolution
helper_analyse_function()[source]
init_from_solution(solution: MultibatchingSolution)[source]
problem: MultibatchingProblem
class discrete_optimization.multibatching.solvers.packing_subproblem.PackingViaBinPacking(problem: MultibatchingProblem, params_objective_function: ParamsObjectiveFunction = None, **args)[source]

Bases: PackingSubproblemSolver

hyperparameters: list[Hyperparameter] = [CategoricalHyperparameter(name='round_flow', default='round', depends_on=None, name_in_kwargs='round_flow'), SubBrickHyperparameter(name='bin_packing_solver', default=SubBrick(cls=<class 'discrete_optimization.binpack.solvers.cpsat.CpSatBinPackBinTypeSolver'>, kwargs={'modeling': <ModelingBinPack.SCHEDULING: 1>, 'parameters_cp': <discrete_optimization.generic_tools.cp_tools.ParametersCp object>}, kwargs_from_solution=None), depends_on=None, name_in_kwargs='bin_packing_solver')]

Hyperparameters available for this solver.

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

  • init_model() (when available)

  • solve()

solve(callbacks: list[Callback] | None = None, time_limit_per_link=2, **kwargs: Any) ResultStorage[source]

Generic solving function.

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

  • **kwargs – any argument specific to the solver

Solvers deriving from SolverDo should use callbacks methods .on_step_end(), … during solve(). But some solvers are not yet updated and are just ignoring it.

Returns (ResultStorage): a result object containing potentially a pool of solutions to a discrete-optimization problem

discrete_optimization.multibatching.solvers.solver_utils module

Utility functions shared across multibatching solvers.

Robust Heuristic: Identifies which transport links are relevant for each product.

This function builds a specific graph G_p for each product P, containing only the TransportLinks compatible with P (i.e. link.transport_type in p.valid_transports).

A link (u, v) is relevant for product P if there exists ANY pair of (Source s, Sink d) for P such that:

dist_p(s, u) + link_len(u, v) + dist_p(v, d) <= (1 + tolerance) * dist_p(s, d)

This heuristic helps reduce the search space by eliminating links that are unlikely to be part of optimal solutions (e.g., links that create long detours).

Parameters:
  • problem – The multibatching problem instance

  • tolerance – Tolerance for path length relaxation (default: 0.1 = 10% longer than optimal) - 0.0 = only shortest paths allowed - 0.2 = paths up to 20% longer than optimal allowed - Higher values = more links considered valid

Returns:

Dictionary mapping product IDs to sets of valid transport link indices. Format: {product.id: {link_index_1, link_index_2, …}}

discrete_optimization.multibatching.solvers.two_steps module

class discrete_optimization.multibatching.solvers.two_steps.TwoStepMultibatchingSolver(problem: MultibatchingProblem, **kwargs: Any)[source]

Bases: SolverDO

hyperparameters: list[Hyperparameter] = [SubBrickHyperparameter(name='flow_solver', default=SubBrick(cls=<class 'discrete_optimization.multibatching.solvers.cpsat.CpsatMultibatchingSolver'>, kwargs={'modeling': <ModelingMultiBatch.FLOW: 0>}, kwargs_from_solution=None), depends_on=None, name_in_kwargs='flow_solver'), SubBrickHyperparameter(name='packing_solver', default=SubBrick(cls=<class 'discrete_optimization.multibatching.solvers.packing_subproblem.GreedyPackingForMultibatching'>, kwargs=None, kwargs_from_solution=None), depends_on=None, name_in_kwargs='packing_solver'), IntegerHyperparameter(name='best_n_flow_solution', default=1, depends_on=None, name_in_kwargs='best_n_flow_solution', low=1, high=10, step=1, log=False)]

Hyperparameters available for this solver.

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

  • init_model() (when available)

  • solve()

problem: MultibatchingProblem
solve(callbacks: list[Callback] = None, **args)[source]

Generic solving function.

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

  • **kwargs – any argument specific to the solver

Solvers deriving from SolverDo should use callbacks methods .on_step_end(), … during solve(). But some solvers are not yet updated and are just ignoring it.

Returns (ResultStorage): a result object containing potentially a pool of solutions to a discrete-optimization problem

Module contents

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

Bases: SolverDO

problem: MultibatchingProblem