Problem ABC and native conversion¶
sezgi.Problem is the subclassable ABC for authoring your own search
problem; as_native_problem converts any Problem subclass instance (or
an already-native handle, unchanged) into the native handle every entry
point (solve, Algorithm.run, EvalSession.for_problem, ...) accepts.
problem ¶
sezgi.Problem -- subclassable Python ABC for a search-space problem (M4-1 Task 1).
Sits on top of the block-typed callable-problem bridge
(_sezgi.from_callable_spaced, py-sezgi/src/lib.rs), the widening of the
existing sezgi.from_callable(...) bridge to any sezgi.Space (not just a
single Float block). A subclass declares its search space (space()) and
objective (evaluate(x)); _to_native() builds the native Problem handle
every existing entry point (sezgi.solve, EvalSession.for_problem, ...)
already accepts.
Genotype -> Python conversion table (PINNED; block_value_to_py/
genotype_to_py in py-sezgi/src/lib.rs):
Float block -> list[float]
Int block -> list[int]
Categorical block -> list[int] (category INDICES 0..k, not labels)
Binary block -> list[bool]
Permutation block -> list[int]
A single-block space's x is that one block's own converted value, passed
BARE. A multi-block space's x is a Python tuple of per-block converted
values, in space()'s block order.
Problem ¶
Bases: abc.ABC
Subclass and implement evaluate/space; optimum/batch_evaluate
are optional overrides.
Genotype -> Python conversion table (PINNED; block_value_to_py/
genotype_to_py in py-sezgi/src/lib.rs), applied to evaluate's own
x argument:
Float block -> list[float]
Int block -> list[int]
Categorical block -> list[int] (category INDICES 0..k, not labels)
Binary block -> list[bool]
Permutation block -> list[int]
A single-block space's x is that one block's own converted value,
passed BARE. A multi-block space's x is a Python tuple of per-block
converted values, in space()'s block order.
A subclass instance is usable anywhere a native Problem handle is
(sezgi.solve, EvalSession.for_problem, Algorithm.run, ...) --
every such entry point routes it through as_native_problem, which
calls _to_native() once to build the actual handle passed to the
Rust engine.
__abstractmethods__
class-attribute
¶
__abstractmethods__ = frozenset({'evaluate', 'space'})
frozenset() -> empty frozenset object frozenset(iterable) -> frozenset object
Build an immutable unordered collection of unique elements.
__doc__
class-attribute
¶
__doc__ = "Subclass and implement `evaluate`/`space`; `optimum`/`batch_evaluate`\n are optional overrides.\n\n Genotype -> Python conversion table (PINNED; `block_value_to_py`/\n `genotype_to_py` in `py-sezgi/src/lib.rs`), applied to `evaluate`'s own\n `x` argument:\n\n Float block -> list[float]\n Int block -> list[int]\n Categorical block -> list[int] (category INDICES 0..k, not labels)\n Binary block -> list[bool]\n Permutation block -> list[int]\n\n A single-block space's `x` is that one block's own converted value,\n passed BARE. A multi-block space's `x` is a Python tuple of per-block\n converted values, in `space()`'s block order.\n\n A subclass instance is usable anywhere a native `Problem` handle is\n (`sezgi.solve`, `EvalSession.for_problem`, `Algorithm.run`, ...) --\n every such entry point routes it through `as_native_problem`, which\n calls `_to_native()` once to build the actual handle passed to the\n Rust engine."
str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
__module__
class-attribute
¶
__module__ = 'sezgi.problem'
str(object='') -> str str(bytes_or_buffer[, encoding[, errors]]) -> str
Create a new string object from the given object. If encoding or errors is specified, then the object must expose a data buffer that will be decoded using the given encoding and error handler. Otherwise, returns the result of object.str() (if defined) or repr(object). encoding defaults to sys.getdefaultencoding(). errors defaults to 'strict'.
evaluate ¶
evaluate(x)
x -> float (the fitness/objective value at x).
For a single-block space, x is that block's own converted value,
passed bare. For a multi-block space, x is a tuple of per-block
values, in space()'s block order. See the module docstring's
conversion table for each block kind's exact Python type.
space ¶
space()
Declares the search space: a sezgi.Space(...), or a bare block
(sezgi.Float(...), sezgi.Binary(...), ...) -- see as_space,
which accepts either.
Called once, from _to_native(), when this Problem is converted
to a native handle (e.g. at the start of sezgi.solve(...) or
Algorithm.run(...)) -- not re-evaluated per generation, so the
returned space must not depend on mutable instance state that
changes during a run.
optimum ¶
optimum()
The problem's known optimum (a float), or None (default) if it
has none.
Design decision (M4-1 Task 1): plumbed through to the native
handle's own .optimum() accessor (_to_native() passes this
value to _sezgi.from_callable_spaced(..., optimum=...)), so
problem._to_native().optimum() and problem.optimum() agree --
the native surface DOES support carrying an arbitrary Python-
supplied optimum for a callable-bridge handle (a one-field addition
to Inner::CallableSpaced, no core change), so there was no reason
to leave it Python-side only.
batch_evaluate ¶
batch_evaluate(xs)
xs -> list[float], one entry per x in xs (default: loop
evaluate). Override for a vectorized objective; called ONCE per
generation with the whole population as xs (see
_sezgi.from_callable_spaced's own doc).
as_native_problem ¶
as_native_problem(obj)
Accepts anything sezgi's entry points (solve, future .run()
methods, ...) should accept as "a problem": a native Problem handle
passes through unchanged; a sezgi.Problem subclass instance is
converted via _to_native(); anything else raises TypeError.