didppy.DDLNS
- class didppy.DDLNS(model, f_operator=Ellipsis, primal_bound=None, time_limit=None, quiet=False, initial_solution=None, beam_size=1000, keep_probability=0.1, keep_all_layers=False, seed=2023, cabs_initial_beam_size=1, cabs_max_beam_size=None)
Large Neighborhood Search with Decision Diagrams (DD-LNS) solver.
This performs LNS by constructing restricted multi-valued decision diagrams (MDD).
To apply this solver, the cost must be computed in the form of
x + state_cost,x * state_cost,didppy.max(x, state_cost), ordidppy.min(x, state_cost)where,state_costis either ofIntExpr.state_cost()andFloatExpr.state_cost(), andxis a value independent ofstate_cost. Otherwise, it cannot compute the cost correctly and may not produce the optimal solution. ifxcan be negative, please sethas_negative_costtoTrue.DD-LNS searches layer by layer, where the i th layer contains states that can be reached with i transitions. By default, this solver only keeps states in the current layer to check for duplicates. If
keep_all_layersisTrue, DD-LNS keeps states in all layers to check for duplicates.- Parameters:
model (Model) – DyPDL model to solve.
f_operator (FOperator, default: FOperator.Plus) – Operator to combine a g-value and the dual bound to compute the f-value. If the cost is computed by
+, this should bePlus. If the cost is computed by*, this should beProduct. If the cost is computed bymax, this should beMax. If the cost is computed bymin, this should beMin.primal_bound (int, float, or None, default: None) – Primal bound.
time_limit (int, float, or None, default: None) – Time limit.
quiet (bool, default: False) – Suppress the log output or not.
initial_solution (list of Transition or None, default: None) – Initial feasible solution. If
None, CABS is is performed to find an initial feasible solution.beam_size (int, default: 1000) – Beam size.
keep_probability (float, default: 0.1) – Probability to keep a non-best state.
keep_all_layers (bool, default: False) – Keep all layers of the search graph for duplicate detection in memory.
seed (int, default: 2023) – Random seed.
cabs_initial_beam_size (int, default: 1) – Initial beam size for CABS to find an initial feasible solution.
cabs_max_beam_size (int or None, default: None) – Maximum beam size for CABS to find an initial feasible solution. If
None, the beam size is kept increased until a feasible solution is found.
- Raises:
TypeError – If
primal_boundisfloatandmodelis int cost.PanicException – If
time_limitis negative or CABS raises an exception when finding an initial solution.
References
Xavier Gillard and Pierre Schaus. “Large Neighborhood Search with Decision Diagrams,” Proceedings of the 31st International Joint Conference on Artificial Intelligence (IJCAI), pp. 4754-4760, 2022.
Examples
Example with
+operator.>>> import didppy as dp >>> model = dp.Model() >>> x = model.add_int_var(target=1) >>> model.add_base_case([x == 0]) >>> t = dp.Transition( ... name="decrement", ... cost=1 + dp.IntExpr.state_cost(), ... effects=[(x, x - 1)] ... ) >>> model.add_transition(t) >>> model.add_dual_bound(x) >>> solver = dp.DDLNS(model, quiet=True) >>> solution = solver.search() >>> print(solution.cost) 1
Example with
maxoperator.>>> import didppy as dp >>> model = dp.Model() >>> x = model.add_int_var(target=2) >>> model.add_base_case([x == 0]) >>> t = dp.Transition( ... name="decrement", ... cost=dp.max(x, dp.IntExpr.state_cost()), ... effects=[(x, x - 1)] ... ) >>> model.add_transition(t) >>> model.add_dual_bound(x) >>> solver = dp.DDLNS(model, f_operator=dp.FOperator.Max, quiet=True) >>> solution = solver.search() >>> print(solution.cost) 2
Methods
search()Search for the optimal solution of a DyPDL model.
Search for the next solution of a DyPDL model.
- search()
Search for the optimal solution of a DyPDL model.
- Returns:
Solution.
- Return type:
- Raises:
PanicException – If the model is invalid.
Examples
>>> import didppy as dp >>> model = dp.Model() >>> x = model.add_int_var(target=1) >>> model.add_base_case([x == 0]) >>> t = dp.Transition( ... name="decrement", ... cost=1 + dp.IntExpr.state_cost(), ... effects=[(x, x - 1)] ... ) >>> model.add_transition(t) >>> model.add_dual_bound(x) >>> solver = dp.DDLNS(model, quiet=True) >>> solution = solver.search() >>> solution.cost 1
- search_next()
Search for the next solution of a DyPDL model.
- Returns:
solution (Solution) – Solution.
terminated (bool) – Whether the search is terminated.
- Raises:
PanicException – If the model is invalid.
Examples
>>> import didppy as dp >>> model = dp.Model() >>> x = model.add_int_var(target=1) >>> model.add_base_case([x == 0]) >>> t = dp.Transition( ... name="decrement", ... cost=1 + dp.IntExpr.state_cost(), ... effects=[(x, x - 1)] ... ) >>> model.add_transition(t) >>> model.add_dual_bound(x) >>> solver = dp.DDLNS(model, quiet=True) >>> solution, terminated = solver.search_next() >>> solution.cost 1 >>> terminated True