Solution

Solution#

class Solution#

Python SDK domain type for evaluated optimization results.

This class contains annotations persisted in protobuf payloads and mirrored to OMMX Artifact descriptors.

__copy__() Solution#
__deepcopy__(_memo: Any) Solution#
add_user_annotation(key: str, value: str, *, annotation_namespace: str = 'org.ommx.user.') None#
add_user_annotations(annotations: Mapping[str, str], *, annotation_namespace: str = 'org.ommx.user.') None#
constraint_context_df(kind: Literal["regular", "indicator", "one_hot", "sos1"] = 'regular') DataFrame#

Constraint context DataFrame (id-indexed). See ommx.Instance.constraint_context_df() for column / kind= semantics. Reads from the evaluated collection’s context store.

constraint_parameters_df(kind: Literal["regular", "indicator", "one_hot", "sos1"] = 'regular') DataFrame#

Constraint parameters DataFrame (long format).

constraint_provenance_df(kind: Literal["regular", "indicator", "one_hot", "sos1"] = 'regular') DataFrame#

Constraint provenance DataFrame (long format).

constraint_removed_reasons_df(kind: Literal["regular", "indicator", "one_hot", "sos1"] = 'regular') DataFrame#

Removed-constraint reasons DataFrame (long format).

constraint_violation(constraint_id: int, *, kind: Literal["regular", "indicator", "one_hot", "sos1"] = 'regular') float#

Get one constraint’s nonnegative scalar violation.

Uses the definitions in total_violation(), including for removed constraints. IDs are independent for each kind. Raises KeyError when the ID is absent from that constraint family.

constraints_df(kind: Literal["regular", "indicator", "one_hot", "sos1"] = 'regular', include: Optional[Sequence[str]] = None) DataFrame#

DataFrame of evaluated constraints, including feasible and violation for every kind.

The violation column uses constraint_violation(). Dispatched on kind=. See ommx.Instance.constraints_df() for column / kind= / include= semantics.

Solution has no removed= parameter (no active/removed distinction at the evaluated stage); reason data is gated by "removed_reason" in include=. When the flag is on, rows for constraints removed before evaluation get removed_reason / removed_reason.{key} columns populated; other rows have NA.

decision_variables_df(include: Optional[Sequence[str]] = None) DataFrame#

DataFrame of evaluated decision variables

Columns: id (index), kind, lower, upper, name, subscripts, description, substituted_value, value

extract_all_decision_variables() dict#

Extract all decision variables grouped by name.

Returns a mapping from variable name to a mapping from subscripts to values. This is useful for extracting all variables at once in a structured format. Variables without names are not included in the result.

Raises ValueError if the same name and subscript combination is found multiple times.

Examples#

>>> from ommx import DecisionVariable, Instance, Sense
>>> x = [DecisionVariable.binary(i, name="x", subscripts=[i]) for i in range(3)]
>>> y = [DecisionVariable.binary(i+3, name="y", subscripts=[i]) for i in range(2)]
>>> instance = Instance.from_components(
...     decision_variables=x + y,
...     objective=sum(x) + sum(y),
...     constraints={},
...     sense=Sense.Maximize,
... )
>>> solution = instance.evaluate({i: 1 for i in range(5)})
>>> all_vars = solution.extract_all_decision_variables()
>>> all_vars["x"]
{(0,): 1.0, (1,): 1.0, (2,): 1.0}
>>> all_vars["y"]
{(0,): 1.0, (1,): 1.0}
extract_all_named_functions() dict#

Extract all named functions grouped by name (returns a Python dict).

Raises ValueError if the same name and subscript combination is found multiple times.

extract_constraints(name: str) dict#

Extract the values of constraints based on the name with subscripts key.

Raises KeyError if no constraint has the requested name. Raises ValueError if a matching constraint has parameters or if the same subscript is found more than once.

Examples#

>>> from ommx import DecisionVariable, Instance, Sense
>>> x = [DecisionVariable.binary(i) for i in range(3)]
>>> c0 = (x[0] + x[1] == 1).set_name("c").add_subscripts([0])
>>> c1 = (x[1] + x[2] == 1).set_name("c").add_subscripts([1])
>>> instance = Instance.from_components(
...     decision_variables=x,
...     objective=sum(x),
...     constraints={0: c0, 1: c1},
...     sense=Sense.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#

Extract the values of decision variables based on the name with subscripts key.

Raises KeyError if no decision variable has the requested name, and ValueError if the same subscript is found more than once.

Examples#

>>> from ommx import DecisionVariable, Instance, Sense
>>> x = [DecisionVariable.binary(i, name="x", subscripts=[i]) for i in range(3)]
>>> instance = Instance.from_components(
...     decision_variables=x,
...     objective=sum(x),
...     constraints={0: sum(x) == 1},
...     sense=Sense.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}
extract_named_functions(name: str) dict#

Extract named functions by name with subscripts as key (returns a Python dict).

Raises KeyError if no named function has the requested name, and ValueError if the same subscript is found more than once.

from_v1_bytes(bytes: bytes) Solution#
from_v2_bytes(bytes: bytes) Solution#
get_constraint_by_id(constraint_id: int) EvaluatedConstraint#

Get a specific evaluated constraint by ID

get_constraint_value(constraint_id: int) float#

Get the evaluated value of a specific constraint by ID

get_decision_variable_by_id(variable_id: int) EvaluatedDecisionVariable#

Get a specific evaluated decision variable by ID

get_dual_variable(constraint_id: int) Optional[float]#

Get the dual variable value for a specific constraint by ID

get_named_function_by_id(named_function_id: int) EvaluatedNamedFunction#

Get a specific evaluated named function by ID

get_user_annotation(key: str, *, annotation_namespace: str = 'org.ommx.user.') str#
get_user_annotations(*, annotation_namespace: str = 'org.ommx.user.') dict[str, str]#
named_functions_df(include: Optional[Sequence[str]] = None) DataFrame#

DataFrame of evaluated named functions

Columns: id (index), value, used_ids, name, subscripts, description, parameters.{key}

replace_annotations(annotations: Mapping[str, str]) None#
set_dual_variable(constraint_id: int, value: Optional[float]) None#

Set the dual variable value for a specific constraint by ID.

Raises KeyError if the constraint ID does not exist.

to_v1_bytes() bytes#
to_v2_bytes() bytes#
total_violation() float#

Sum the nonnegative scalar violation of every constraint, including removed constraints.

  • Equality: abs(f(x)); inequality: max(0, f(x)).

  • Indicator: the inner violation when active, otherwise zero.

  • OneHot: min_i (abs(x_i - 1) + sum_{j != i} abs(x_j)).

  • SOS1: min_i sum_{j != i} abs(x_j).

Each constraint is feasible exactly when its violation is at most the evaluation tolerance. This threshold applies to each constraint separately, not to the total. Zero therefore implies that all constraints are feasible. Variable bound and kind violations are not added. Values use the evaluated state after discrete-value canonicalization. Lowering need not preserve the metric: a retained original and its generated constraints each contribute.

Use constraint_violation() for individual values, also available in the violation column of constraints_df() for every constraint kind.

variable_labels_df() DataFrame#

Decision-variable modeling-label DataFrame (id-indexed).

variable_parameters_df() DataFrame#

Decision-variable parameters DataFrame (long format).

LP_RELAXED: Relaxation#

Class constant for LP-relaxed solutions

NOT_OPTIMAL: Optimality#

Class constant for non-optimal solutions

OPTIMAL: Optimality#

Class constant for optimal solutions

property annotations: MappingProxyType[str, str]#

Read-only property.

Returns a read-only mapping of flat annotations.

Use add_user_annotation(), metadata properties, or replace_annotations() to modify annotations.

property constraint_ids: set[int]#

Read-only property.

property constraints: dict[int, EvaluatedConstraint]#

Read-only property.

Get evaluated constraints as a dict keyed by constraint ID

property decision_variable_ids: set[int]#

Read-only property.

property decision_variable_names: set[str]#

Read-only property.

Get all unique decision variable names in this solution.

Returns a set of all unique variable names. Variables without names are not included.

Examples#

>>> from ommx import DecisionVariable, Instance, Sense
>>> x = [DecisionVariable.binary(i, name="x", subscripts=[i]) for i in range(3)]
>>> y = [DecisionVariable.binary(i+3, name="y", subscripts=[i]) for i in range(2)]
>>> instance = Instance.from_components(
...     decision_variables=x + y,
...     objective=sum(x) + sum(y),
...     constraints={},
...     sense=Sense.Maximize,
... )
>>> solution = instance.evaluate({i: 1 for i in range(5)})
>>> sorted(solution.decision_variable_names)
['x', 'y']
property decision_variables: list[EvaluatedDecisionVariable]#

Read-only property.

Get evaluated decision variables as a list sorted by ID

property end: Optional[datetime]#
property feasibility_atol: float#

Read-only property.

Absolute tolerance associated with the stored evaluation and feasibility results.

Pass this to an extracted constraint’s explicit feasibility query to use the enclosing result’s threshold.

property feasible: bool#

Read-only property.

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#

Read-only property.

Feasibility of the solution in terms of remaining constraints, not including relaxed (removed) constraints.

property feasible_unrelaxed: bool#

Read-only property.

Feasibility of the solution in terms of all constraints, including relaxed (removed) constraints.

property instance: Optional[str]#
property instance_digest: Optional[str]#
property named_function_ids: set[int]#

Read-only property.

property named_function_names: set[str]#

Read-only property.

Get all unique named function names in this solution

property named_functions: list[EvaluatedNamedFunction]#

Read-only property.

Get evaluated named functions as a list sorted by ID

property objective: float#

Read-only property.

Get the objective function value

property optimality: Optimality#

Get the optimality status

property parameters: Optional[Any]#
property parameters_annotation: Optional[Any]#
property relaxation: Relaxation#

Get the relaxation status

property sense: Sense#

Read-only property.

Get the optimization sense (minimize or maximize)

property solver: Optional[Any]#
property solver_annotation: Optional[Any]#
property start: Optional[datetime]#
property state: State#

Read-only property.

Get the solution state containing variable values