Source code for negmas.outcomes.protocols

from __future__ import annotations
from typing import (
    TYPE_CHECKING,
    Collection,
    Container,
    Iterable,
    Protocol,
    runtime_checkable,
)


if TYPE_CHECKING:
    from .base_issue import DiscreteIssue, Issue
    from .common import Outcome
    from .outcome_space import CartesianOutcomeSpace

__all__ = [
    "OutcomeSpace",
    "DiscreteOutcomeSpace",
    "IndependentIssuesOS",
    "IndependentDiscreteIssuesOS",
]


[docs] @runtime_checkable class OutcomeSpace(Container, Protocol): """ The base protocol for all outcome spaces. """
[docs] def is_valid(self, outcome: Outcome) -> bool: """Checks if the given outcome is valid for that outcome space""" ...
[docs] def are_types_ok(self, outcome: Outcome) -> bool: """Checks if the type of each value in the outcome is correct for the given issue""" ...
[docs] def ensure_correct_types(self, outcome: Outcome) -> Outcome: """Returns an outcome that is guaratneed to have correct types or raises an exception""" ...
@property def cardinality(self) -> int | float: """The space cardinality = the number of outcomes""" ...
[docs] def is_numeric(self) -> bool: """Checks whether all values in all outcomes are numeric""" ...
[docs] def is_integer(self) -> bool: """Checks whether all values in all outcomes are integers""" ...
[docs] def is_float(self) -> bool: """Checks whether all values in all outcomes are real""" ...
[docs] def to_discrete( self, levels: int | float = 5, max_cardinality: int | float = float("inf") ) -> DiscreteOutcomeSpace: """ Returns a **stable** finite outcome space. If the outcome-space is already finite. It shoud return itself. Args: levels: The levels of discretization of any continuous dimension (or subdimension) max_cardintlity: The maximum cardinality allowed for the resulting outcomespace (if the original OS was infinite). This limitation is **NOT** applied for outcome spaces that are alredy discretized. See `limit_cardinality()` for a method to limit the cardinality of an already discrete space If called again, it should return the same discrete outcome space every time. """ ...
[docs] def sample( self, n_outcomes: int, with_replacement: bool = False, fail_if_not_enough=False ) -> Iterable[Outcome]: """Samples up to n_outcomes with or without replacement""" ...
[docs] def random_outcome(self) -> Outcome: """Returns a single random outcome.""" return list(self.sample(1))[0]
[docs] def to_largest_discrete( self, levels: int, max_cardinality: int | float = float("inf"), **kwargs ) -> DiscreteOutcomeSpace: ...
[docs] def cardinality_if_discretized( self, levels: int, max_cardinality: int | float = float("inf") ) -> int: """ Returns the cardinality if discretized the given way. """ ...
[docs] def enumerate_or_sample( self, levels: int | float = float("inf"), max_cardinality: int | float = float("inf"), ) -> Iterable[Outcome]: """Enumerates all outcomes if possible (i.e. discrete space) or returns `max_cardinality` different outcomes otherwise""" ...
[docs] def is_discrete(self) -> bool: """Checks whether there are no continua components of the space""" ...
[docs] def is_finite(self) -> bool: """Checks whether the space is finite""" return self.is_discrete()
def __contains__(self, item: Outcome | OutcomeSpace | Issue) -> bool: # type: ignore ...
[docs] @runtime_checkable class DiscreteOutcomeSpace(OutcomeSpace, Collection, Protocol): """ The base protocol for all outcome spaces with a finite number of items. This type of outcome-space acts as a standard python `Collection` which means that its length can be found using `len()` and it can be iterated over to return outcomes. """ @property def cardinality(self) -> int: """The space cardinality = the number of outcomes""" ...
[docs] def enumerate(self) -> Iterable[Outcome]: """ Enumerates the outcome space returning all its outcomes (or up to max_cardinality for infinite ones) """ ...
[docs] def limit_cardinality( self, max_cardinality: int | float = float("inf"), levels: int | float = float("inf"), ) -> DiscreteOutcomeSpace: """ Limits the cardinality of the outcome space to the given maximum (or the number of levels for each issue to `levels`) Args: max_cardinality: The maximum number of outcomes in the resulting space levels: The maximum levels allowed per issue (if issues are defined for this outcome space) """ ...
[docs] def to_single_issue( self, numeric: bool = False, stringify: bool = True ) -> CartesianOutcomeSpace: ...
[docs] def sample( self, n_outcomes: int, with_replacement: bool = False, fail_if_not_enough=True ) -> Iterable[Outcome]: ...
[docs] def is_discrete(self) -> bool: """Checks whether there are no continua components of the space""" return True
[docs] def to_discrete(self, *args, **kwargs) -> DiscreteOutcomeSpace: return self
def __iter__(self): return self.enumerate().__iter__() def __len__(self) -> int: return self.cardinality
[docs] @runtime_checkable class IndependentIssuesOS(Protocol): """ An Outcome-Space that is constructed from a tuple of `Issue` objects. """ issues: tuple[Issue, ...]
[docs] @runtime_checkable class IndependentDiscreteIssuesOS(Protocol): """ An Outcome-Space that is constructed from a tuple of `DiscreteIssue` objects. """ issues: tuple[DiscreteIssue, ...]