PreparationPolicy

PreparationPolicy#

class PreparationPolicy#

Select optional transformations applied by prepare().

Invariants#

A default policy selects no Preparation phase.

>>> from ommx import PreparationPolicy
>>> policy = PreparationPolicy()
>>> assert (
...     policy.special_constraints,
...     policy.objective,
...     policy.integer_slack,
...     policy.integer_encoding,
...     policy.fixed_penalty,
...     policy.binary_power_reduction,
... ) == (None, None, None, None, None, None)
__eq__(other: object, /) bool#
__new__(*, special_constraints: Optional[SpecialConstraintPreparation] = None, objective: Optional[ObjectivePreparation] = None, integer_slack: Optional[IntegerSlackPreparation] = None, integer_encoding: Optional[IntegerEncodingPreparation] = None, fixed_penalty: Optional[FixedPenaltyPreparation] = None, binary_power_reduction: Optional[BinaryPowerPreparation] = None) PreparationPolicy#
for_hubo(*, uniform_penalty_weight: Optional[float] = None, penalty_weights: Optional[Mapping[int, float]] = None, inequality_integer_slack_max_range: int = 31) PreparationPolicy#

Return a fresh policy for preparing an instance for HUBO formatting.

uniform_penalty_weight and penalty_weights override the default uniform penalty weight of 1.0 and are mutually exclusive. The keyed form must cover exactly the active regular constraints at the penalty phase. inequality_integer_slack_max_range defaults to 31 and configures both the exact Integer-slack range and the fallback slack upper bound. Unlike for_qubo(), this policy leaves Binary-power reduction disabled because HUBO accepts arbitrary polynomial degree.

Postconditions#

Each call returns a fresh complete HUBO policy with no Binary-power reduction and exact overrides.

>>> from ommx import (
...     FixedPenaltyPreparation, IntegerEncodingPreparation,
...     IntegerSlackPreparation, ObjectivePreparation,
...     PreparationPolicy, Sense, SpecialConstraintKind,
...     SpecialConstraintPreparation,
... )
>>> expected_special = SpecialConstraintPreparation.lower_special_constraints(
...     kinds={
...         SpecialConstraintKind.Indicator,
...         SpecialConstraintKind.OneHot,
...         SpecialConstraintKind.Sos1,
...     }
... )
>>> first = PreparationPolicy.for_hubo(inequality_integer_slack_max_range=17)
>>> second = PreparationPolicy.for_hubo(inequality_integer_slack_max_range=17)
>>> assert first is not second
>>> assert first.special_constraints == expected_special
>>> assert first.objective == ObjectivePreparation(target=Sense.Minimize)
>>> assert first.integer_slack == IntegerSlackPreparation(max_integer_range=17, slack_upper_bound=17)
>>> assert first.integer_encoding == IntegerEncodingPreparation.log_encode_all_used_integers()
>>> assert first.fixed_penalty == FixedPenaltyPreparation.uniform_penalty_method_with_fixed_weight(weight=1.0)
>>> assert first.binary_power_reduction is None
>>> first.fixed_penalty = None
>>> assert second.fixed_penalty == FixedPenaltyPreparation.uniform_penalty_method_with_fixed_weight(weight=1.0)
>>> uniform = PreparationPolicy.for_hubo(uniform_penalty_weight=4.0)
>>> assert uniform.fixed_penalty == FixedPenaltyPreparation.uniform_penalty_method_with_fixed_weight(weight=4.0)

Errors#

Supplying uniform and keyed penalty weights together raises ValueError.

>>> try:
...     PreparationPolicy.for_hubo(uniform_penalty_weight=1.0, penalty_weights={3: 2.0})
... except ValueError as error:
...     assert "Both uniform_penalty_weight" in str(error)
... else:
...     raise AssertionError("mutually exclusive penalty options were accepted")
for_qubo(*, uniform_penalty_weight: Optional[float] = None, penalty_weights: Optional[Mapping[int, float]] = None, inequality_integer_slack_max_range: int = 31) PreparationPolicy#

Return a fresh policy for preparing an instance for QUBO formatting.

uniform_penalty_weight and penalty_weights override the default uniform penalty weight of 1.0 and are mutually exclusive. The keyed form must cover exactly the active regular constraints at the penalty phase. inequality_integer_slack_max_range defaults to 31 and configures both the exact Integer-slack range and the fallback slack upper bound. This QUBO policy also reduces powers of Binary variables before checking the quadratic target.

Postconditions#

Each call returns a fresh complete QUBO policy whose optional weights and slack range are applied exactly.

>>> from ommx import (
...     BinaryPowerPreparation, FixedPenaltyPreparation,
...     IntegerEncodingPreparation, IntegerSlackPreparation,
...     ObjectivePreparation, PreparationPolicy, Sense,
...     SpecialConstraintKind, SpecialConstraintPreparation,
... )
>>> expected_special = SpecialConstraintPreparation.lower_special_constraints(
...     kinds={
...         SpecialConstraintKind.Indicator,
...         SpecialConstraintKind.OneHot,
...         SpecialConstraintKind.Sos1,
...     }
... )
>>> expected_penalty = FixedPenaltyPreparation.uniform_penalty_method_with_fixed_weight(weight=1.0)
>>> first = PreparationPolicy.for_qubo(inequality_integer_slack_max_range=17)
>>> second = PreparationPolicy.for_qubo(inequality_integer_slack_max_range=17)
>>> assert first is not second
>>> assert first.special_constraints == expected_special
>>> assert first.objective == ObjectivePreparation(target=Sense.Minimize)
>>> assert first.integer_slack == IntegerSlackPreparation(max_integer_range=17, slack_upper_bound=17)
>>> assert first.integer_encoding == IntegerEncodingPreparation.log_encode_all_used_integers()
>>> assert first.fixed_penalty == expected_penalty
>>> assert first.binary_power_reduction == BinaryPowerPreparation()
>>> first.fixed_penalty = None
>>> first.binary_power_reduction = None
>>> assert second.fixed_penalty == expected_penalty
>>> assert second.binary_power_reduction == BinaryPowerPreparation()
>>> keyed = PreparationPolicy.for_qubo(penalty_weights={3: 2.0})
>>> assert keyed.fixed_penalty == FixedPenaltyPreparation.penalty_method_with_fixed_weights(weights={3: 2.0})

Errors#

Supplying uniform and keyed penalty weights together raises ValueError.

>>> try:
...     PreparationPolicy.for_qubo(uniform_penalty_weight=1.0, penalty_weights={3: 2.0})
... except ValueError as error:
...     assert "Both uniform_penalty_weight" in str(error)
... else:
...     raise AssertionError("mutually exclusive penalty options were accepted")
property binary_power_reduction: Optional[BinaryPowerPreparation]#
property fixed_penalty: Optional[FixedPenaltyPreparation]#
property integer_encoding: Optional[IntegerEncodingPreparation]#
property integer_slack: Optional[IntegerSlackPreparation]#
property objective: Optional[ObjectivePreparation]#
property special_constraints: Optional[SpecialConstraintPreparation]#