SampleSet

SampleSet#

class SampleSet#

The output of sampling-based optimization algorithms, e.g. simulated annealing (SA).

  • Similar to Solution rather than the raw State message. 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:

maximize x_1 + 2 x_2 + 3 x_3 subject to x_1 + x_2 + x_3 = 1 x_1, x_2, x_3 in {0, 1}

>>> 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 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 summary attribute 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 sample by get as a Solution format:

>>> solution = sample_set.get(sample_id=0)
>>> solution.objective
1.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

Of course, the sample of smallest objective value is returned for minimization problems.

__copy__() SampleSet#
__deepcopy__(_memo: Any) SampleSet#
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#
extract_all_decision_variables(sample_id: int) dict#

Extract all decision variables grouped by name for a given sample ID.

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 a decision variable with parameters is found, or if the same name and subscript combination is found multiple times, or if the sample ID is invalid.

Examples#

>>> from ommx.v1 import Instance, DecisionVariable
>>> 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=Instance.MAXIMIZE,
... )
>>> sample_set = instance.evaluate_samples({0: {i: 1 for i in range(5)}})
>>> all_vars = sample_set.extract_all_decision_variables(0)
>>> 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(sample_id: int) dict#

Extract all named function values grouped by name for a given sample ID

extract_constraints(name: str, sample_id: int) dict#

Extract constraint values for a given name and sample ID

extract_decision_variables(name: str, sample_id: int) dict#

Extract decision variable values for a given name and sample ID

extract_named_functions(name: str, sample_id: int) dict#

Extract named function values for a given name and sample ID

feasible_ids() set[int]#
feasible_relaxed_ids() set[int]#
feasible_unrelaxed_ids() set[int]#
from_bytes(bytes: bytes) SampleSet#
get(sample_id: int) Solution#
get_constraint_by_id(constraint_id: int) SampledConstraint#

Get a specific sampled constraint by ID

get_decision_variable_by_id(variable_id: int) SampledDecisionVariable#

Get a specific sampled decision variable by ID

get_named_function_by_id(named_function_id: int) SampledNamedFunction#

Get a specific sampled named function by ID

get_sample_by_id(sample_id: int) Solution#

Get sample by ID (alias for get method)

get_user_annotation(key: str, annotation_namespace: str = 'org.ommx.user.') str#
get_user_annotations(annotation_namespace: str = 'org.ommx.user.') dict[str, str]#
num_samples() int#
sample_ids() set[int]#
to_bytes() bytes#
property annotations: dict[str, str]#

Returns a copy of the annotations dictionary.

Mutating the returned dict will not update the object. Use add_user_annotation() or assign to annotations to modify annotations.

property best_feasible: Solution#

Read-only property.

property best_feasible_id: int#

Read-only property.

property best_feasible_relaxed: Solution#

Read-only property.

property best_feasible_relaxed_id: int#

Read-only property.

property best_feasible_unrelaxed: Solution#

Read-only property.

property constraints: list[SampledConstraint]#

Read-only property.

Get constraints for compatibility with existing Python code

property constraints_df: DataFrame#

Read-only property.

DataFrame of constraints with per-sample value and feasibility columns. Static columns: id, equality, used_ids, name, subscripts, description. Dynamic columns: value.{sample_id} and feasible.{sample_id} for each sample.

property decision_variable_names: set[str]#

Read-only property.

Get all unique decision variable names in this sample set.

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

Examples#

>>> from ommx.v1 import Instance, DecisionVariable
>>> 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=Instance.MAXIMIZE,
... )
>>> sample_set = instance.evaluate_samples({0: {i: 1 for i in range(5)}})
>>> sorted(sample_set.decision_variable_names)
['x', 'y']
property decision_variables: list[SampledDecisionVariable]#

Read-only property.

Get decision variables for compatibility with existing Python code

property decision_variables_df: DataFrame#

Read-only property.

DataFrame of decision variables with per-sample value columns. Static columns: id, kind, lower, upper, name, subscripts, description. Dynamic columns: one per sample_id (int) with the variable’s value.

property end: Optional[datetime]#
property feasible: dict[int, bool]#

Read-only property.

Get feasibility status for all samples

property feasible_relaxed: dict[int, bool]#

Read-only property.

Get relaxed feasibility status for all samples

property feasible_unrelaxed: dict[int, bool]#

Read-only property.

Get unrelaxed feasibility status for all samples

property indicator_constraints_df: DataFrame#

Read-only property.

DataFrame of indicator constraints with per-sample value, feasibility, and indicator_active columns. Static columns: id, indicator_variable_id, equality, used_ids, name, subscripts, description. Dynamic columns: value.{sample_id}, feasible.{sample_id}, indicator_active.{sample_id} for each sample.

property indicator_removed_reasons_df: DataFrame#

Read-only property.

DataFrame of removed indicator constraint reasons.

Columns: id (index), removed_reason, removed_reason.{key}

Can be joined with indicator_constraints_df using the id index.

property instance: Optional[str]#
property instance_digest: Optional[str]#
property named_function_names: set[str]#

Read-only property.

Get all unique named function names in this sample set

property named_functions: list[SampledNamedFunction]#

Read-only property.

Get named functions for compatibility with existing Python code

property named_functions_df: DataFrame#

Read-only property.

DataFrame of named functions with per-sample value columns. Static columns: id, used_ids, name, subscripts, description, parameters. Dynamic columns: one per sample_id (int) with the function’s evaluated value.

property objectives: dict[int, float]#

Read-only property.

Get objectives for all samples

property parameters: Optional[Any]#
property parameters_annotation: Optional[Any]#
property removed_reasons_df: DataFrame#

Read-only property.

DataFrame of removed constraint reasons.

Columns: id (index), removed_reason, removed_reason.{key}

Can be joined with constraints_df using the id index.

property sample_ids_list: list[int]#

Read-only property.

Get sample IDs as a list (property version)

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 summary: DataFrame#

Read-only property.

Summary DataFrame with columns: objective, feasible. Sorted by feasible desc then objective. Index is sample_id.

property summary_with_constraints: DataFrame#

Read-only property.

Summary DataFrame with per-constraint feasibility columns. Index is sample_id.