ommx_pyscipopt_adapter.adapter

Attributes

HintMode

Classes

OMMXPySCIPOptAdapter

An abstract interface for OMMX Solver Adapters, defining how solvers should be used with OMMX.

Module Contents

class ommx_pyscipopt_adapter.adapter.OMMXPySCIPOptAdapter(ommx_instance: ommx.v1.Instance, *, use_sos1: Literal['disabled', 'auto', 'forced'] = 'auto', initial_state: ommx.v1.ToState | None = None)

An abstract interface for OMMX Solver Adapters, defining how solvers should be used with OMMX.

See the implementation guide for more details.

decode(data: pyscipopt.Model) ommx.v1.Solution

Convert optimized pyscipopt.Model and ommx.v1.Instance to ommx.v1.Solution.

This method is intended to be used if the model has been acquired with solver_input for further adjustment of the solver parameters, and separately optimizing the model.

Note that alterations to the model may make the decoding process incompatible – decoding will only work if the model still describes effectively the same problem as the OMMX instance used to create the adapter.

Examples

>>> from ommx_pyscipopt_adapter import OMMXPySCIPOptAdapter
>>> from ommx.v1 import Instance, DecisionVariable

>>> p = [10, 13, 18, 32, 7, 15]
>>> w = [11, 15, 20, 35, 10, 33]
>>> x = [DecisionVariable.binary(i) for i in range(6)]
>>> instance = Instance.from_components(
...     decision_variables=x,
...     objective=sum(p[i] * x[i] for i in range(6)),
...     constraints=[sum(w[i] * x[i] for i in range(6)) <= 47],
...     sense=Instance.MAXIMIZE,
... )

>>> adapter = OMMXPySCIPOptAdapter(instance)
>>> model = adapter.solver_input
>>> # ... some modification of model's parameters
>>> model.optimize()

>>> solution = adapter.decode(model)
>>> solution.raw.objective
42.0
decode_to_state(data: pyscipopt.Model) ommx.v1.State

Create an ommx.v1.State from an optimized PySCIPOpt Model.

Examples

The following example shows how to solve an unconstrained linear optimization problem with `x1` as the objective function.

>>> from ommx_pyscipopt_adapter import OMMXPySCIPOptAdapter
>>> from ommx.v1 import Instance, DecisionVariable

>>> x1 = DecisionVariable.integer(1, lower=0, upper=5)
>>> ommx_instance = Instance.from_components(
...     decision_variables=[x1],
...     objective=x1,
...     constraints=[],
...     sense=Instance.MINIMIZE,
... )
>>> adapter = OMMXPySCIPOptAdapter(ommx_instance)
>>> model = adapter.solver_input
>>> model.optimize()

>>> ommx_state = adapter.decode_to_state(model)
>>> ommx_state.entries
{1: 0.0}
classmethod solve(ommx_instance: ommx.v1.Instance, *, use_sos1: Literal['disabled', 'auto', 'forced'] = 'auto', initial_state: ommx.v1.ToState | None = None) ommx.v1.Solution

Solve the given ommx.v1.Instance using PySCIPopt, returning an ommx.v1.Solution.

Parameters:
  • ommx_instance – The ommx.v1.Instance to solve.

  • use_sos1 – Strategy for handling SOS1 constraints.Options: - “disabled”: Do not use SOS1 constraints. - “auto”: Use SOS1 constraints if hints are provided, otherwise solve without them.(default) - “forced”: Require SOS1 constraints and raise an error if no SOS1 constraint hints are found.

  • initial_state – Optional initial solution state.

Examples

KnapSack Problem

>>> from ommx.v1 import Instance, DecisionVariable
>>> from ommx.v1 import Solution
>>> from ommx_pyscipopt_adapter import OMMXPySCIPOptAdapter

>>> p = [10, 13, 18, 32, 7, 15]
>>> w = [11, 15, 20, 35, 10, 33]
>>> x = [DecisionVariable.binary(i) for i in range(6)]
>>> instance = Instance.from_components(
...     decision_variables=x,
...     objective=sum(p[i] * x[i] for i in range(6)),
...     constraints=[(sum(w[i] * x[i] for i in range(6)) <= 47).set_id(0)],
...     sense=Instance.MAXIMIZE,
... )

Solve it

>>> solution = OMMXPySCIPOptAdapter.solve(instance)

Check output

>>> sorted([(id, value) for id, value in solution.state.entries.items()])
[(0, 1.0), (1, 0.0), (2, 0.0), (3, 1.0), (4, 0.0), (5, 0.0)]
>>> solution.feasible
True
>>> assert solution.optimality == Solution.OPTIMAL

p[0] + p[3] = 42
w[0] + w[3] = 46 <= 47

>>> solution.objective
42.0
>>> solution.get_constraint_value(0)
-1.0

Infeasible Problem

>>> from ommx.v1 import Instance, DecisionVariable
>>> from ommx_pyscipopt_adapter import OMMXPySCIPOptAdapter

>>> x = DecisionVariable.integer(0, upper=3, lower=0)
>>> instance = Instance.from_components(
...     decision_variables=[x],
...     objective=x,
...     constraints=[x >= 4],
...     sense=Instance.MAXIMIZE,
... )

>>> OMMXPySCIPOptAdapter.solve(instance)
Traceback (most recent call last):
    ...
ommx.adapter.InfeasibleDetected: Model was infeasible

Unbounded Problem

>>> from ommx.v1 import Instance, DecisionVariable
>>> from ommx_pyscipopt_adapter import OMMXPySCIPOptAdapter

>>> x = DecisionVariable.integer(0, lower=0)
>>> instance = Instance.from_components(
...     decision_variables=[x],
...     objective=x,
...     constraints=[],
...     sense=Instance.MAXIMIZE,
... )

>>> OMMXPySCIPOptAdapter.solve(instance)
Traceback (most recent call last):
    ...
ommx.adapter.UnboundedDetected: Model was unbounded
instance
model
property solver_input: pyscipopt.Model

The PySCIPOpt model generated from this OMMX instance

use_sos1: HintMode
ommx_pyscipopt_adapter.adapter.HintMode