ommx.v1
Submodules
- ommx.v1.annotation
- ommx.v1.constraint_hints_pb2
- ommx.v1.constraint_pb2
- ommx.v1.decision_variables_pb2
- ommx.v1.function_pb2
- ommx.v1.instance_pb2
- ommx.v1.linear_pb2
- ommx.v1.one_hot_pb2
- ommx.v1.parametric_instance_pb2
- ommx.v1.polynomial_pb2
- ommx.v1.quadratic_pb2
- ommx.v1.sample_set_pb2
- ommx.v1.solution_pb2
- ommx.v1.sos1_pb2
Attributes
Type alias for convertible types to |
|
Type alias for convertible types to |
Classes
Constraints |
|
Idiomatic wrapper of |
|
Helper class that provides a standard way to create an ABC using |
|
Idiomatic wrapper of |
|
Modeler API for linear function |
|
Idiomatic wrapper of |
|
Idiomatic wrapper of |
|
Helper class that provides a standard way to create an ABC using |
|
Helper class that provides a standard way to create an ABC using |
|
The output of sampling-based optimization algorithms, e.g. simulated annealing (SA). |
|
Idiomatic wrapper of |
Package Contents
- class ommx.v1.Constraint(*, function: int | float | DecisionVariable | Linear | Quadratic | Polynomial | Function, equality: constraint_pb2.Equality.ValueType, id: int | None = None, name: str | None = None, description: str | None = None, subscripts: list[int] | None = None, parameters: dict[str, str] | None = None)
Constraints
Examples
>>> x = DecisionVariable.integer(1) >>> y = DecisionVariable.integer(2) >>> x + y == 1 Constraint(Function(x1 + x2 - 1) == 0) To set the name or other attributes, use methods like :py:meth:`add_name`. >>> (x + y <= 5).add_name("constraint 1") Constraint(Function(x1 + x2 - 5) <= 0)
- add_description(description: str) Constraint
- add_name(name: str) Constraint
- add_parameters(parameters: dict[str, str]) Constraint
- add_subscripts(subscripts: list[int]) Constraint
- static from_bytes(data: bytes) Constraint
- static from_raw(raw: constraint_pb2.Constraint) Constraint
- set_id(id: int) Constraint
Overwrite the constraint ID.
- to_bytes() bytes
- EQUAL_TO_ZERO
- LESS_THAN_OR_EQUAL_TO_ZERO
- property description: str | None
- property equality: constraint_pb2.Equality.ValueType
- property id: int
- property name: str | None
- property parameters: dict[str, str]
- property subscripts: list[int]
- class ommx.v1.DecisionVariable
Idiomatic wrapper of
ommx.v1.DecisionVariableprotobuf message.Note that this object overloads == for creating a constraint, not for equality comparison for better integration to mathematical programming.
>>> x = DecisionVariable.integer(1) >>> x == 1 Constraint(...)
To compare two objects, use
equals_to()method.>>> y = DecisionVariable.integer(2) >>> x.equals_to(y) False
- static binary(id: int, *, name: str | None = None, subscripts: list[int] | None = None, parameters: dict[str, str] | None = None, description: str | None = None) DecisionVariable
- static continuous(id: int, *, lower: float = float('-inf'), upper: float = float('inf'), name: str | None = None, subscripts: list[int] | None = None, parameters: dict[str, str] | None = None, description: str | None = None) DecisionVariable
- equals_to(other: DecisionVariable) bool
Alternative to
==operator to compare two decision variables.
- static from_bytes(data: bytes) DecisionVariable
- static integer(id: int, *, lower: float = float('-inf'), upper: float = float('inf'), name: str | None = None, subscripts: list[int] | None = None, parameters: dict[str, str] | None = None, description: str | None = None) DecisionVariable
- static of_type(kind: Kind, id: int, *, lower: float, upper: float, name: str | None = None, subscripts: list[int] | None = None, parameters: dict[str, str] | None = None, description: str | None = None) DecisionVariable
- static semi_continuous(id: int, *, lower: float = float('-inf'), upper: float = float('inf'), name: str | None = None, subscripts: list[int] | None = None, parameters: dict[str, str] | None = None, description: str | None = None) DecisionVariable
- static semi_integer(id: int, *, lower: float = float('-inf'), upper: float = float('inf'), name: str | None = None, subscripts: list[int] | None = None, parameters: dict[str, str] | None = None, description: str | None = None) DecisionVariable
- to_bytes() bytes
- BINARY
- CONTINUOUS
- INTEGER
- Kind
- SEMI_CONTINUOUS
- SEMI_INTEGER
- property bound: decision_variables_pb2.Bound
- property description: str
- property id: int
- property name: str
- property parameters: dict[str, str]
- property subscripts: list[int]
- class ommx.v1.Function(inner: int | float | DecisionVariable | Linear | Quadratic | Polynomial | function_pb2.Function)
Helper class that provides a standard way to create an ABC using inheritance.
- almost_equal(other: Function, *, atol: float = 1e-10) bool
Compare two functions have almost equal coefficients as a polynomial
- evaluate(state: ToState) tuple[float, set]
Evaluate the function with the given state.
Examples
Evaluate `2 x1 x2 + 3 x2 x3 + 1` with `x1 = 3, x2 = 4, x3 = 5` >>> x1 = DecisionVariable.integer(1) >>> x2 = DecisionVariable.integer(2) >>> x3 = DecisionVariable.integer(3) >>> f = Function(2*x1*x2 + 3*x2*x3 + 1) >>> f Function(2*x1*x2 + 3*x2*x3 + 1) >>> f.evaluate({1: 3, 2: 4, 3: 5}) (85.0, {1, 2, 3}) Missing ID raises an error >>> f.evaluate({1: 3}) Traceback (most recent call last): ... RuntimeError: Variable id (2) is not found in the solution
- partial_evaluate(state: ToState) tuple[Function, set]
Partially evaluate the function with the given state.
Examples
Evaluate `2 x1 x2 + 3 x2 x3 + 1` with `x1 = 3`, yielding `3 x2 x3 + 6 x2 + 1` >>> x1 = DecisionVariable.integer(1) >>> x2 = DecisionVariable.integer(2) >>> x3 = DecisionVariable.integer(3) >>> f = Function(2*x1*x2 + 3*x2*x3 + 1) >>> f Function(2*x1*x2 + 3*x2*x3 + 1) >>> f.partial_evaluate({1: 3}) (Function(3*x2*x3 + 6*x2 + 1), {1})
- to_bytes() bytes
- property terms: dict[tuple[int, Ellipsis], float]
- class ommx.v1.Instance
Idiomatic wrapper of
ommx.v1.Instanceprotobuf message.Note that this class also contains annotations like
titlewhich are not contained in protobuf message but stored in OMMX artifact. These annotations are loaded from annotations while reading from OMMX artifact.Examples
Create an instance for KnapSack Problem
>>> from ommx.v1 import Instance, DecisionVariable Profit and weight of items >>> p = [10, 13, 18, 31, 7, 15] >>> w = [11, 15, 20, 35, 10, 33] Decision variables >>> x = [DecisionVariable.binary(i) for i in range(6)] Objective and constraint >>> objective = sum(p[i] * x[i] for i in range(6)) >>> constraint = sum(w[i] * x[i] for i in range(6)) <= 47 Compose as an instance >>> instance = Instance.from_components( ... decision_variables=x, ... objective=objective, ... constraints=[constraint], ... sense=Instance.MAXIMIZE, ... )
- add_user_annotation(key: str, value: str, *, annotation_namespace: str = 'org.ommx.user.')
Add a user annotation to the instance.
Examples
>>> instance = Instance.empty() >>> instance.add_user_annotation("author", "Alice") >>> instance.get_user_annotations() {'author': 'Alice'} >>> instance.annotations {'org.ommx.user.author': 'Alice'}
- add_user_annotations(annotations: dict[str, str], *, annotation_namespace: str = 'org.ommx.user.')
- as_minimization_problem()
Convert the instance to a minimization problem.
If the instance is already a minimization problem, this does nothing.
Examples
>>> from ommx.v1 import Instance, DecisionVariable >>> x = [DecisionVariable.binary(i) for i in range(3)] >>> instance = Instance.from_components( ... decision_variables=x, ... objective=sum(x), ... constraints=[sum(x) == 1], ... sense=Instance.MAXIMIZE, ... ) >>> instance.sense == Instance.MAXIMIZE True >>> instance.objective Function(x0 + x1 + x2) Convert to a minimization problem >>> instance.as_minimization_problem() >>> instance.sense == Instance.MINIMIZE True >>> instance.objective Function(-x0 - x1 - x2)
- as_parametric_instance() ParametricInstance
Convert the instance to a
ParametricInstance.
- as_pubo_format() dict[tuple[int, Ellipsis], float]
Convert unconstrained polynomial instance to simple PUBO format.
This method is designed for better composability rather than easy-to-use. This does not execute any conversion of the instance, only translates the data format.
- as_qubo_format() tuple[dict[tuple[int, int], float], float]
Convert unconstrained quadratic instance to PyQUBO-style format.
This method is designed for better composability rather than easy-to-use. This does not execute any conversion of the instance, only translates the data format.
- static empty() Instance
Create trivial empty instance of minimization with zero objective, no constraints, and no decision variables.
- static from_components(*, objective: int | float | DecisionVariable | Linear | Quadratic | Polynomial | function_pb2.Function, constraints: Iterable[Constraint | constraint_pb2.Constraint], sense: instance_pb2.Instance.Sense.ValueType, decision_variables: Iterable[DecisionVariable | decision_variables_pb2.DecisionVariable], description: instance_pb2.Instance.Description | None = None) Instance
- get_constraint(constraint_id: int) Constraint
Get a constraint by ID.
- get_constraints() list[Constraint]
Get constraints as a list of
Constraintinstances.
- get_decision_variable(variable_id: int) DecisionVariable
Get a decision variable by ID.
- get_decision_variables() list[DecisionVariable]
Get decision variables as a list of
DecisionVariableinstances.
- get_removed_constraint(removed_constraint_id: int) RemovedConstraint
Get a removed constraint by ID.
- get_removed_constraints() list[RemovedConstraint]
Get removed constraints as a list of
RemovedConstraintinstances.
- get_user_annotation(key: str, *, annotation_namespace: str = 'org.ommx.user.')
Get a user annotation from the instance.
Examples
>>> instance = Instance.empty() >>> instance.add_user_annotation("author", "Alice") >>> instance.get_user_annotation("author") 'Alice'
- get_user_annotations(*, annotation_namespace: str = 'org.ommx.user.') dict[str, str]
Get user annotations from the instance.
See also
add_user_annotation().
- penalty_method() ParametricInstance
Convert to a parametric unconstrained instance by penalty method.
Roughly, this converts a constrained problem
\[\begin{split}\begin{align*} \min_x & \space f(x) & \\ \text{ s.t. } & \space g_i(x) = 0 & (\forall i) \end{align*}\end{split}\]to an unconstrained problem with parameters
\[\min_x f(x) + \sum_i \lambda_i g_i(x)^2\]where \(\lambda_i\) are the penalty weight parameters for each constraint. If you want to use single weight parameter, use
uniform_penalty_method()instead.The removed constrains are stored in
removed_constraints.- Raises:
RuntimeError – If the instance contains inequality constraints.
Examples
>>> from ommx.v1 import Instance, DecisionVariable, Constraint >>> x = [DecisionVariable.binary(i) for i in range(3)] >>> instance = Instance.from_components( ... decision_variables=x, ... objective=sum(x), ... constraints=[x[0] + x[1] == 1, x[1] + x[2] == 1], ... sense=Instance.MAXIMIZE, ... ) >>> instance.objective Function(x0 + x1 + x2) >>> pi = instance.penalty_method() The constraint is put in `removed_constraints` >>> pi.get_constraints() [] >>> len(pi.get_removed_constraints()) 2 >>> pi.get_removed_constraints()[0] RemovedConstraint(Function(x0 + x1 - 1) == 0, reason=penalty_method, parameter_id=3) >>> pi.get_removed_constraints()[1] RemovedConstraint(Function(x1 + x2 - 1) == 0, reason=penalty_method, parameter_id=4) There are two parameters corresponding to the two constraints >>> len(pi.get_parameters()) 2 >>> p1 = pi.get_parameters()[0] >>> p1.id, p1.name (3, 'penalty_weight') >>> p2 = pi.get_parameters()[1] >>> p2.id, p2.name (4, 'penalty_weight') Substitute all parameters to zero to get the original objective >>> instance0 = pi.with_parameters({p1.id: 0.0, p2.id: 0.0}) >>> instance0.objective Function(x0 + x1 + x2) Substitute all parameters to one >>> instance1 = pi.with_parameters({p1.id: 1.0, p2.id: 1.0}) >>> instance1.objective Function(x0*x0 + 2*x0*x1 + 2*x1*x1 + 2*x1*x2 + x2*x2 - x0 - 3*x1 - x2 + 2)
- relax_constraint(constraint_id: int, reason: str, **parameters)
Remove a constraint from the instance. The removed constraint is stored in
removed_constraints, and can be restored byrestore_constraint().- Parameters:
constraint_id – The ID of the constraint to remove.
reason – The reason why the constraint is removed.
parameters – Additional parameters to describe the reason.
Examples
Relax constraint, and restore it.
>>> from ommx.v1 import Instance, DecisionVariable >>> x = [DecisionVariable.binary(i) for i in range(3)] >>> instance = Instance.from_components( ... decision_variables=x, ... objective=sum(x), ... constraints=[(sum(x) == 3).set_id(1)], ... sense=Instance.MAXIMIZE, ... ) >>> instance.get_constraints() [Constraint(Function(x0 + x1 + x2 - 3) == 0)] >>> instance.relax_constraint(1, "manual relaxation") >>> instance.get_constraints() [] >>> instance.get_removed_constraints() [RemovedConstraint(Function(x0 + x1 + x2 - 3) == 0, reason=manual relaxation)] >>> instance.restore_constraint(1) >>> instance.get_constraints() [Constraint(Function(x0 + x1 + x2 - 3) == 0)] >>> instance.get_removed_constraints() []
Evaluate relaxed instance, and show
feasible_unrelaxed.>>> from ommx.v1 import Instance, DecisionVariable >>> x = [DecisionVariable.binary(i) for i in range(3)] >>> instance = Instance.from_components( ... decision_variables=x, ... objective=sum(x), ... constraints=[ ... (x[0] + x[1] == 2).set_id(0), ... (x[1] + x[2] == 2).set_id(1), ... ], ... sense=Instance.MINIMIZE, ... ) For x0=0, x1=1, x2=1 - x0 + x1 == 2 is not feasible - x1 + x2 == 2 is feasible >>> solution = instance.evaluate({0: 0, 1: 1, 2: 1}) >>> solution.feasible_relaxed False >>> solution.feasible_unrelaxed False Relax the constraint: x0 + x1 == 2 >>> instance.relax_constraint(0, "testing") >>> solution = instance.evaluate({0: 0, 1: 1, 2: 1}) >>> solution.feasible_relaxed True >>> solution.feasible_unrelaxed False
- restore_constraint(constraint_id: int)
Restore a removed constraint to the instance.
- Parameters:
constraint_id – The ID of the constraint to restore.
Note that this drops the removed reason and associated parameters. See
relax_constraint()for details.
- to_bytes() bytes
- uniform_penalty_method() ParametricInstance
Convert to a parametric unconstrained instance by penalty method with uniform weight.
Roughly, this converts a constrained problem
\[\begin{split}\begin{align*} \min_x & \space f(x) & \\ \text{ s.t. } & \space g_i(x) = 0 & (\forall i) \end{align*}\end{split}\]to an unconstrained problem with a parameter
\[\min_x f(x) + \lambda \sum_i g_i(x)^2\]where \(\lambda\) is the uniform penalty weight parameter for all constraints.
The removed constrains are stored in
removed_constraints.- Raises:
RuntimeError – If the instance contains inequality constraints.
Examples
>>> from ommx.v1 import Instance, DecisionVariable >>> x = [DecisionVariable.binary(i) for i in range(3)] >>> instance = Instance.from_components( ... decision_variables=x, ... objective=sum(x), ... constraints=[sum(x) == 3], ... sense=Instance.MAXIMIZE, ... ) >>> instance.objective Function(x0 + x1 + x2) >>> pi = instance.uniform_penalty_method() The constraint is put in `removed_constraints` >>> pi.get_constraints() [] >>> len(pi.get_removed_constraints()) 1 >>> pi.get_removed_constraints()[0] RemovedConstraint(Function(x0 + x1 + x2 - 3) == 0, reason=uniform_penalty_method) There is only one parameter in the instance >>> len(pi.get_parameters()) 1 >>> p = pi.get_parameters()[0] >>> p.id 3 >>> p.name 'uniform_penalty_weight' Substitute `p = 0` to get the original objective >>> instance0 = pi.with_parameters({p.id: 0.0}) >>> instance0.objective Function(x0 + x1 + x2) Substitute `p = 1` >>> instance1 = pi.with_parameters({p.id: 1.0}) >>> instance1.objective Function(x0*x0 + 2*x0*x1 + 2*x0*x2 + x1*x1 + 2*x1*x2 + x2*x2 - 5*x0 - 5*x1 - 5*x2 + 9)
- write_mps(path: str)
Outputs the instance as an MPS file.
The outputted file is compressed by gzip.
Only linear problems are supported.
Various forms of metadata, like problem description and variable/constraint names, are not preserved.
- Description
- MAXIMIZE
- MINIMIZE
- annotation_namespace = 'org.ommx.v1.instance'
- annotations: dict[str, str]
Arbitrary annotations stored in OMMX artifact. Use
titleor other specific attributes if possible.
- authors
Authors of this instance, stored as
org.ommx.v1.instance.authorsannotation in OMMX artifact.
- property constraints: pandas.DataFrame
- created
The creation date of the instance, stored as
org.ommx.v1.instance.createdannotation in RFC3339 format in OMMX artifact.
- dataset
Dataset name which this instance belongs to, stored as
org.ommx.v1.instance.datasetannotation in OMMX artifact.
- property decision_variables: pandas.DataFrame
- property description: instance_pb2.Instance.Description
- license
License of this instance in the SPDX license identifier. This is stored as
org.ommx.v1.instance.licenseannotation in OMMX artifact.
- num_constraints
Number of constraints in this instance, stored as
org.ommx.v1.instance.constraintsannotation in OMMX artifact.
- num_variables
Number of variables in this instance, stored as
org.ommx.v1.instance.variablesannotation in OMMX artifact.
- raw: instance_pb2.Instance
The raw protobuf message.
- property removed_constraints: pandas.DataFrame
- property sense: instance_pb2.Instance.Sense.ValueType
- title
The title of the instance, stored as
org.ommx.v1.instance.titleannotation in OMMX artifact.
- class ommx.v1.Linear(*, terms: dict[int, float | int], constant: float | int = 0)
Modeler API for linear function
This is a wrapper of
linear_pb2.Linearprotobuf message.Examples
Create a linear function :math:`f(x_1, x_2) = 2 x_1 + 3 x_2 + 1` >>> f = Linear(terms={1: 2, 2: 3}, constant=1) Or create via DecisionVariable >>> x1 = DecisionVariable.integer(1) >>> x2 = DecisionVariable.integer(2) >>> g = 2*x1 + 3*x2 + 1 Compare two linear functions are equal in terms of a polynomial with tolerance >>> assert f.almost_equal(g, atol=1e-12) Note that `f == g` becomes an equality `Constraint` >>> assert isinstance(f == g, Constraint)
- almost_equal(other: Linear, *, atol: float = 1e-10) bool
Compare two linear functions have almost equal coefficients and constant.
- evaluate(state: ToState) tuple[float, set]
Evaluate the linear function with the given state.
Examples
Evaluate `2 x1 + 3 x2 + 1` with `x1 = 3, x2 = 4, x3 = 5` >>> f = Linear(terms={1: 2, 2: 3}, constant=1) >>> value, used_ids = f.evaluate({1: 3, 2: 4, 3: 5}) # Unused ID `3` can be included 2*3 + 3*4 + 1 = 19 >>> value 19.0 Since the value of ID `3` of `state` is not used, the it is not included in `used_ids`. >>> used_ids {1, 2} Missing ID raises an error >>> f.evaluate({1: 3}) Traceback (most recent call last): ... RuntimeError: Variable id (2) is not found in the solution
- static from_raw(raw: linear_pb2.Linear) Linear
- partial_evaluate(state: ToState) tuple[Linear, set]
Partially evaluate the linear function with the given state.
Examples
Evaluate `2 x1 + 3 x2 + 1` with `x1 = 3`, yielding `3 x2 + 7` >>> f = Linear(terms={1: 2, 2: 3}, constant=1) >>> new_f, used_ids = f.partial_evaluate({1: 3}) >>> new_f Linear(3*x2 + 7) >>> used_ids {1} >>> new_f.partial_evaluate({2: 4}) (Linear(19), {2})
- to_bytes() bytes
- property constant: float
Get the constant term of the linear function
- property linear_terms: dict[int, float]
Get the terms of the linear function as a dictionary
- raw: linear_pb2.Linear
- property terms: dict[tuple[int, Ellipsis], float]
Linear terms and constant as a dictionary
- class ommx.v1.Parameter
Idiomatic wrapper of
ommx.v1.Parameterprotobuf message.- static new(id: int, *, name: str | None = None, subscripts: Iterable[int] = [], description: str | None = None)
- to_bytes() bytes
- property description: str
- property id: int
- property name: str
- property parameters: dict[str, str]
- property subscripts: list[int]
- class ommx.v1.ParametricInstance
Idiomatic wrapper of
ommx.v1.ParametricInstanceprotobuf message.Examples
Create an instance for KnapSack Problem with parameters
>>> from ommx.v1 import ParametricInstance, DecisionVariable, Parameter Decision variables >>> x = [DecisionVariable.binary(i, name="x", subscripts=[i]) for i in range(6)] Profit and weight of items as parameters >>> p = [Parameter.new(id=i+6, name="Profit", subscripts=[i]) for i in range(6)] >>> w = [Parameter.new(id=i+12, name="Weight", subscripts=[i]) for i in range(6)] >>> W = Parameter.new(id=18, name="Capacity") Objective and constraint >>> objective = sum(p[i] * x[i] for i in range(6)) >>> constraint = sum(w[i] * x[i] for i in range(6)) <= W Compose as an instance >>> parametric_instance = ParametricInstance.from_components( ... decision_variables=x, ... parameters=p + w + [W], ... objective=objective, ... constraints=[constraint], ... sense=Instance.MAXIMIZE, ... ) Substitute parameters to get an instance >>> p_values = { x.id: value for x, value in zip(p, [10, 13, 18, 31, 7, 15]) } >>> w_values = { x.id: value for x, value in zip(w, [11, 15, 20, 35, 10, 33]) } >>> W_value = { W.id: 47 } >>> instance = parametric_instance.with_parameters({**p_values, **w_values, **W_value})
- add_user_annotation(key: str, value: str, *, annotation_namespace: str = 'org.ommx.user.')
- add_user_annotations(annotations: dict[str, str], *, annotation_namespace: str = 'org.ommx.user.')
- static empty() ParametricInstance
Create trivial empty instance of minimization with zero objective, no constraints, and no decision variables and parameters.
- static from_bytes(data: bytes) ParametricInstance
- static from_components(*, objective: int | float | DecisionVariable | Linear | Quadratic | Polynomial | function_pb2.Function, constraints: Iterable[Constraint | constraint_pb2.Constraint], sense: instance_pb2.Instance.Sense.ValueType, decision_variables: Iterable[DecisionVariable | decision_variables_pb2.DecisionVariable], parameters: Iterable[Parameter | parametric_instance_pb2.Parameter], description: instance_pb2.Instance.Description | None = None) ParametricInstance
- get_constraint(constraint_id: int) Constraint
Get a constraint by ID.
- get_constraints() list[Constraint]
Get constraints as a list of :class:`Constraint
- get_decision_variable(variable_id: int) DecisionVariable
Get a decision variable by ID.
- get_decision_variables() list[DecisionVariable]
Get decision variables as a list of
DecisionVariableinstances.
- get_removed_constraint(removed_constraint_id: int) RemovedConstraint
Get a removed constraint by ID.
- get_removed_constraints() list[RemovedConstraint]
Get removed constraints as a list of
RemovedConstraintinstances.
- get_user_annotation(key: str, *, annotation_namespace: str = 'org.ommx.user.')
- get_user_annotations(*, annotation_namespace: str = 'org.ommx.user.') dict[str, str]
- to_bytes() bytes
- with_parameters(parameters: instance_pb2.Parameters | Mapping[int, float]) Instance
Substitute parameters to yield an instance.
- annotation_namespace = 'org.ommx.v1.parametric-instance'
- annotations: dict[str, str]
- authors
Authors of this instance, stored as
org.ommx.v1.parametric-instance.authorsannotation in OMMX artifact.
- property constraints: pandas.DataFrame
- created
The creation date of the instance, stored as
org.ommx.v1.parametric-instance.createdannotation in RFC3339 format in OMMX artifact.
- dataset
Dataset name which this instance belongs to, stored as
org.ommx.v1.parametric-instance.datasetannotation in OMMX artifact.
- property decision_variables: pandas.DataFrame
- license
License of this instance in the SPDX license identifier. This is stored as
org.ommx.v1.parametric-instance.licenseannotation in OMMX artifact.
- num_constraints
Number of constraints in this instance, stored as
org.ommx.v1.parametric-instance.constraintsannotation in OMMX artifact.
- num_variables
Number of variables in this instance, stored as
org.ommx.v1.parametric-instance.variablesannotation in OMMX artifact.
- property parameters: pandas.DataFrame
- property removed_constraints: pandas.DataFrame
- title
The title of the instance, stored as
org.ommx.v1.parametric-instance.titleannotation in OMMX artifact.
- class ommx.v1.Polynomial(*, terms: dict[Iterable[int], float | int] = {})
Helper class that provides a standard way to create an ABC using inheritance.
- almost_equal(other: Polynomial, *, atol: float = 1e-10) bool
Compare two polynomial have almost equal coefficients
- evaluate(state: ToState) tuple[float, set]
Evaluate the polynomial with the given state.
Examples
Evaluate `2 x1 x2 x3 + 3 x2 x3 + 1` with `x1 = 3, x2 = 4, x3 = 5` >>> x1 = DecisionVariable.integer(1) >>> x2 = DecisionVariable.integer(2) >>> x3 = DecisionVariable.integer(3) >>> f = 2*x1*x2*x3 + 3*x2*x3 + 1 >>> f Polynomial(2*x1*x2*x3 + 3*x2*x3 + 1) >>> f.evaluate({1: 3, 2: 4, 3: 5}) (181.0, {1, 2, 3}) Missing ID raises an error >>> f.evaluate({1: 3}) Traceback (most recent call last): ... RuntimeError: Variable id (2) is not found in the solution
- static from_bytes(data: bytes) Polynomial
- static from_raw(raw: polynomial_pb2.Polynomial) Polynomial
- partial_evaluate(state: ToState) tuple[Polynomial, set]
Partially evaluate the polynomial with the given state.
Examples
Evaluate `2 x1 x2 x3 + 3 x2 x3 + 1` with `x1 = 3`, yielding `9 x2 x3 + 1` >>> x1 = DecisionVariable.integer(1) >>> x2 = DecisionVariable.integer(2) >>> x3 = DecisionVariable.integer(3) >>> f = 2*x1*x2*x3 + 3*x2*x3 + 1 >>> f Polynomial(2*x1*x2*x3 + 3*x2*x3 + 1) >>> f.partial_evaluate({1: 3}) (Polynomial(9*x2*x3 + 1), {1})
- to_bytes() bytes
- property terms: dict[tuple[int, Ellipsis], float]
- class ommx.v1.Quadratic(*, columns: Iterable[int], rows: Iterable[int], values: Iterable[float | int], linear: Linear | None = None)
Helper class that provides a standard way to create an ABC using inheritance.
- almost_equal(other: Quadratic, *, atol: float = 1e-10) bool
Compare two quadratic functions have almost equal coefficients
- evaluate(state: ToState) tuple[float, set]
Evaluate the quadratic function with the given state.
Examples
Evaluate `2 x1 x2 + 3 x2 x3 + 1` with `x1 = 3, x2 = 4, x3 = 5` >>> x1 = DecisionVariable.integer(1) >>> x2 = DecisionVariable.integer(2) >>> x3 = DecisionVariable.integer(3) >>> f = 2*x1*x2 + 3*x2*x3 + 1 >>> f Quadratic(2*x1*x2 + 3*x2*x3 + 1) >>> f.evaluate({1: 3, 2: 4, 3: 5}) (85.0, {1, 2, 3}) Missing ID raises an error >>> f.evaluate({1: 3}) Traceback (most recent call last): ... RuntimeError: Variable id (2) is not found in the solution
- static from_raw(raw: quadratic_pb2.Quadratic) Quadratic
- partial_evaluate(state: ToState) tuple[Quadratic, set]
Partially evaluate the quadratic function with the given state.
Examples
Evaluate `2 x1 x2 + 3 x2 x3 + 1` with `x1 = 3`, yielding `3 x2 x3 + 6 x2 + 1` >>> x1 = DecisionVariable.integer(1) >>> x2 = DecisionVariable.integer(2) >>> x3 = DecisionVariable.integer(3) >>> f = 2*x1*x2 + 3*x2*x3 + 1 >>> f Quadratic(2*x1*x2 + 3*x2*x3 + 1) >>> f.partial_evaluate({1: 3}) (Quadratic(3*x2*x3 + 6*x2 + 1), {1})
- to_bytes() bytes
- property quad_terms: dict[tuple[int, int], float]
- property terms: dict[tuple[int, Ellipsis], float]
- class ommx.v1.SampleSet
The output of sampling-based optimization algorithms, e.g. simulated annealing (SA).
Similar to
Solutionrather thansolution_pb2.State. This class contains the sampled values of decision variables with the objective value, constraint violations, feasibility, and metadata of constraints and decision variables.This class is usually created via
Instance.evaluate_samples().
Examples
Let’s consider a simple optimization problem:
\[\begin{split}\begin{align*} \max &\quad x_1 + 2 x_2 + 3 x_3 \\ \text{s.t.} &\quad x_1 + x_2 + x_3 = 1 \\ &\quad x_1, x_2, x_3 \in \{0, 1\} \end{align*}\end{split}\]>>> x = [DecisionVariable.binary(i) for i in range(3)] >>> instance = Instance.from_components( ... decision_variables=x, ... objective=x[0] + 2*x[1] + 3*x[2], ... constraints=[sum(x) == 1], ... sense=Instance.MAXIMIZE, ... )
with three samples:
>>> samples = { ... 0: {0: 1, 1: 0, 2: 0}, # x1 = 1, x2 = x3 = 0 ... 1: {0: 0, 1: 0, 2: 1}, # x3 = 1, x1 = x2 = 0 ... 2: {0: 1, 1: 1, 2: 0}, # x1 = x2 = 1, x3 = 0 (infeasible) ... } # ^ sample ID
Note that this will be done by sampling-based solvers, but we do it manually here. We can evaluate the samples with via
Instance.evaluate_samples():>>> sample_set = instance.evaluate_samples(samples) >>> sample_set.summary objective feasible sample_id 1 3.0 True 0 1.0 True 2 3.0 False
The
summaryattribute shows the objective value, feasibility of each sample. Note that this feasible column represents the feasibility of the original constraints, not the relaxed constraints. You can get each samples byget()as aSolutionformat:>>> solution = sample_set.get(sample_id=0) >>> solution.objective 1.0 >>> solution.decision_variables kind lower upper name subscripts description substituted_value value id 0 binary 0.0 1.0 <NA> [] <NA> <NA> 1.0 1 binary 0.0 1.0 <NA> [] <NA> <NA> 0.0 2 binary 0.0 1.0 <NA> [] <NA> <NA> 0.0
best_feasible()returns the best feasible sample, i.e. the largest objective value among feasible samples:>>> solution = sample_set.best_feasible() >>> solution.objective 3.0 >>> solution.decision_variables kind lower upper name subscripts description substituted_value value id 0 binary 0.0 1.0 <NA> [] <NA> <NA> 0.0 1 binary 0.0 1.0 <NA> [] <NA> <NA> 0.0 2 binary 0.0 1.0 <NA> [] <NA> <NA> 1.0
Of course, the sample of smallest objective value is returned for minimization problems.
- add_user_annotation(key: str, value: str, *, annotation_namespace: str = 'org.ommx.user.')
- add_user_annotations(annotations: dict[str, str], *, annotation_namespace: str = 'org.ommx.user.')
- extract_constraints(name: str, sample_id: int) dict[tuple[int, Ellipsis], float]
Extract evaluated constraint violations for a given constraint name and sample ID.
- extract_decision_variables(name: str, sample_id: int) dict[tuple[int, Ellipsis], float]
Extract sampled decision variable values for a given name and sample ID.
- get_user_annotation(key: str, *, annotation_namespace: str = 'org.ommx.user.')
- get_user_annotations(*, annotation_namespace: str = 'org.ommx.user.') dict[str, str]
- to_bytes() bytes
- annotation_namespace = 'org.ommx.v1.sample-set'
- annotations: dict[str, str]
Arbitrary annotations stored in OMMX artifact. Use
parametersor other specific attributes if possible.
- property constraints: pandas.DataFrame
- property decision_variables: pandas.DataFrame
- end
When the optimization ended, stored as
org.ommx.v1.sample-set.endannotation in RFC3339 format in OMMX artifact.
- property feasible: dict[int, bool]
Feasibility in terms of the original constraints, an alias to
feasible_unrelaxed.Compatibility
The meaning of this property has changed from Python SDK 1.7.0. Previously, this property represents the feasibility of the remaining constraints only, i.e. excluding relaxed constraints. From Python SDK 1.7.0, this property represents the feasibility of all constraints, including relaxed constraints.
- property feasible_relaxed: dict[int, bool]
Feasibility in terms of the remaining (non-removed) constraints.
For each sample_id, this property shows whether the sample is feasible for the all
Instance.constraints
- property feasible_unrelaxed: dict[int, bool]
Feasibility in terms of the original constraints without relaxation.
For each sample_id, this property shows whether the sample is feasible both for the all
Instance.constraintsand allInstance.removed_constraints.
- instance
The digest of the instance layer, stored as
org.ommx.v1.sample-set.instanceannotation in OMMX artifact.
- property objectives: dict[int, float]
- parameters
The parameters used in the optimization, stored as
org.ommx.v1.sample-set.parametersannotation as a JSON in OMMX artifact.
- property sample_ids: list[int]
- solver
The solver which generated this sample set, stored as
org.ommx.v1.sample-set.solverannotation as a JSON in OMMX artifact.
- start
When the optimization started, stored as
org.ommx.v1.sample-set.startannotation in RFC3339 format in OMMX artifact.
- property summary: pandas.DataFrame
- property summary_with_constraints: pandas.DataFrame
- class ommx.v1.Solution
Idiomatic wrapper of
ommx.v1.Solutionprotobuf message.This also contains annotations not contained in protobuf message, and will be stored in OMMX artifact.
- add_user_annotation(key: str, value: str, *, annotation_namespace: str = 'org.ommx.user.')
- add_user_annotations(annotations: dict[str, str], *, annotation_namespace: str = 'org.ommx.user.')
- extract_constraints(name: str) dict[tuple[int, Ellipsis], float]
Extract the values of constraints based on the name with subscripts key.
- Raises:
ValueError – If the constraint with parameters is found, or if the same subscript is found.
Examples
>>> from ommx.v1 import Instance, DecisionVariable >>> x = [DecisionVariable.binary(i) for i in range(3)] >>> c0 = (x[0] + x[1] == 1).add_name("c").add_subscripts([0]) >>> c1 = (x[1] + x[2] == 1).add_name("c").add_subscripts([1]) >>> instance = Instance.from_components( ... decision_variables=x, ... objective=sum(x), ... constraints=[c0, c1], ... sense=Instance.MAXIMIZE, ... ) >>> solution = instance.evaluate({0: 1, 1: 0, 2: 1}) >>> solution.extract_constraints("c") {(0,): 0.0, (1,): 0.0}
- extract_decision_variables(name: str) dict[tuple[int, Ellipsis], float]
Extract the values of decision variables based on the name with subscripts key.
- Raises:
ValueError – If the decision variable with parameters is found, or if the same subscript is found.
Examples
>>> from ommx.v1 import Instance, DecisionVariable >>> x = [DecisionVariable.binary(i, name="x", subscripts=[i]) for i in range(3)] >>> instance = Instance.from_components( ... decision_variables=x, ... objective=sum(x), ... constraints=[sum(x) == 1], ... sense=Instance.MAXIMIZE, ... ) >>> solution = instance.evaluate({i: 1 for i in range(3)}) >>> solution.extract_decision_variables("x") {(0,): 1.0, (1,): 1.0, (2,): 1.0}
- get_user_annotation(key: str, *, annotation_namespace: str = 'org.ommx.user.')
- get_user_annotations(*, annotation_namespace: str = 'org.ommx.user.') dict[str, str]
- to_bytes() bytes
- annotation_namespace = 'org.ommx.v1.solution'
- annotations: dict[str, str]
Arbitrary annotations stored in OMMX artifact. Use
parametersor other specific attributes if possible.
- property constraints: pandas.DataFrame
- property decision_variables: pandas.DataFrame
- end
When the optimization ended, stored as
org.ommx.v1.solution.endannotation in RFC3339 format in OMMX artifact.
- property feasible: bool
Feasibility of the solution in terms of all constraints, including
removed_constraints.This is an alias for
feasible_unrelaxed.Compatibility
The meaning of this property has changed from Python SDK 1.7.0. Previously, this property represents the feasibility of the remaining constraints only, i.e. excluding relaxed constraints. From Python SDK 1.7.0, this property represents the feasibility of all constraints, including relaxed constraints.
- property feasible_relaxed: bool
Feasibility of the solution in terms of remaining constraints, not including relaxed (removed) constraints.
- property feasible_unrelaxed: bool
Feasibility of the solution in terms of all constraints, including relaxed (removed) constraints.
- instance
The digest of the instance layer, stored as
org.ommx.v1.solution.instanceannotation in OMMX artifact.This
Solutionis the solution of the mathematical programming problem described by the instance.
- property objective: float
- property optimality: solution_pb2.Optimality.ValueType
- parameters
The parameters used in the optimization, stored as
org.ommx.v1.solution.parametersannotation as a JSON in OMMX artifact.
- raw: solution_pb2.Solution
The raw protobuf message.
- property relaxation: solution_pb2.Relaxation.ValueType
- solver
The solver which generated this solution, stored as
org.ommx.v1.solution.solverannotation as a JSON in OMMX artifact.
- start
When the optimization started, stored as
org.ommx.v1.solution.startannotation in RFC3339 format in OMMX artifact.
- property state: solution_pb2.State
- ommx.v1.ToSamples: typing_extensions.TypeAlias
Type alias for convertible types to
Samples.
- ommx.v1.ToState: typing_extensions.TypeAlias
Type alias for convertible types to
State.