negmas.outcomes¶
Defines basic concepts related to outcomes
Outcomes in this package are always assumed to be multi-issue outcomes where single-issue outcomes can be implemented as the special case with a single issue.
Both Continuous and discrete issues are supported. All issue will have names. If none is given, a random name will be used. It is HIGHLY recommended to always name your issues.
Outcomes are dictionaries with issue names as keys and issue values as values.
Examples
Different ways to create issues:
>>> issues = [make_issue((0.5, 2.0), 'price'), make_issue(['2018.10.'+ str(_) for _ in range(1, 4)], 'date')
... , make_issue(20, 'count')]
>>> for _ in issues: print(_)
price: (0.5, 2.0)
date: ['2018.10.1', '2018.10.2', '2018.10.3']
count: (0, 19)
Outcome example compatible with the given set of issues:
>>> a = {'price': 1.2, 'date': '2018.10.04', 'count': 4}
- class negmas.outcomes.CallableIssue(values, name=None)[source]¶
Bases:
IssueAn
Issuewith a callable for generating values. This is a very limited issue type and most operations are not supported on it.- ordered_value_generator(n: int | float | None = 10, grid=True, compact=False, endpoints=True) Generator[Any, None, None][source]¶
Ordered value generator.
- Parameters:
n – Number of items.
grid – Grid.
compact – Compact.
endpoints – Endpoints.
- Returns:
The result.
- Return type:
Generator[Any, None, None]
- class negmas.outcomes.CardinalIssue(values, name=None)[source]¶
Bases:
OrdinalIssueAn
Issuefor which differences between values are meaningful.
- class negmas.outcomes.CartesianOutcomeSpace(issues, name: str | None = None, path: Path | None = None)[source]¶
Bases:
XmlSerializableAn outcome-space that is generated by the cartesian product of a tuple of
Issues.- are_types_ok(outcome: tuple) bool[source]¶
Checks if the type of each value in the outcome is correct for the given issue
- cardinality_if_discretized(levels: int, max_cardinality: int | float = inf) int[source]¶
Cardinality if discretized.
- Parameters:
levels – Levels.
max_cardinality – Max cardinality.
- Returns:
The result.
- Return type:
- contains_issue(x: Issue) bool[source]¶
Cheks that the given issue is in the tuple of issues constituting the outcome space (i.e. it is one of its dimensions)
- contains_os(x: OutcomeSpace) bool[source]¶
Checks whether an outcome-space is contained in this outcome-space
- ensure_correct_types(outcome: tuple) tuple[source]¶
Returns an outcome that is guaratneed to have correct types or raises an exception
- enumerate_or_sample(levels: int | float = inf, max_cardinality: int | float = inf) Iterable[tuple][source]¶
Enumerates all outcomes if possible (i.e. discrete space) or returns
max_cardinalitydifferent outcomes otherwise
- enumerate_or_sample_rational(preferences: Iterable[HasReservedValue | HasReservedOutcome], levels: int | float = inf, max_cardinality: int | float = inf, aggregator: Callable[[Iterable[bool]], bool] = <built-in function any>) Iterable[Outcome][source]¶
Enumerates all outcomes if possible (i.e. discrete space) or returns
max_cardinalitydifferent outcomes otherwise.- Parameters:
preferences – A list of
Preferencesthat is used to judge outcomeslevels – The number of levels to use for discretization if needed
max_cardinality – The maximum cardinality allowed in case of discretization
aggregator – A predicate that takes an
Iterableof booleans representing whether or not an outcome is rational for a givenPreferences(i.e. better than reservation) and returns a single boolean representing the result for all preferences. Default is any but can be all.
- classmethod from_dict(d, python_class_identifier='__python_class__')[source]¶
From dict.
- Parameters:
d –
python_class_identifier – Python class identifier.
- static from_outcomes(outcomes: list[tuple], numeric_as_ranges: bool = False, issue_names: list[str] | None = None, name: str | None = None) DiscreteCartesianOutcomeSpace[source]¶
From outcomes.
- Parameters:
outcomes – Outcomes.
numeric_as_ranges – Numeric as ranges.
issue_names – Issue names.
name – Name.
- Returns:
The result.
- Return type:
- classmethod from_xml_str(xml_str: str, safe_parsing=True, name=None, **kwargs) CartesianOutcomeSpace[source]¶
From xml str.
- Parameters:
xml_str – Xml str.
safe_parsing – Safe parsing.
name – Name.
**kwargs – Additional keyword arguments.
- Returns:
The result.
- Return type:
- is_valid(outcome: tuple) bool[source]¶
Check if valid.
- Parameters:
outcome – Outcome to evaluate.
- Returns:
The result.
- Return type:
- sample(n_outcomes: int, with_replacement: bool = True, fail_if_not_enough=True) Iterable[tuple][source]¶
Sample.
- Parameters:
n_outcomes – N outcomes.
with_replacement – With replacement.
fail_if_not_enough – Fail if not enough.
- Returns:
The result.
- Return type:
Iterable[Outcome]
- to_dict(python_class_identifier='__python_class__')[source]¶
To dict.
- Parameters:
python_class_identifier – Python class identifier.
- to_discrete(levels: int | float = 10, max_cardinality: int | float = inf) DiscreteCartesianOutcomeSpace[source]¶
Discretizes the outcome space by sampling
Logging Levelsvalues for each continuous issue.The result of the discretization is stable in the sense that repeated calls will return the same output.
- to_largest_discrete(levels: int, max_cardinality: int | float = inf, **kwargs) DiscreteCartesianOutcomeSpace[source]¶
To largest discrete.
- Parameters:
levels – Levels.
max_cardinality – Max cardinality.
**kwargs – Additional keyword arguments.
- Returns:
The result.
- Return type:
- to_single_issue(numeric=False, stringify=True, levels: int = 5, max_cardinality: int | float = inf) DiscreteCartesianOutcomeSpace[source]¶
Creates a new outcome space that is a single-issue version of this one discretizing it as needed
- Parameters:
numeric – If given, the output issue will be a
ContiguousIssueotberwise it will be aCategoricalIssuestringify – If given, the output issue will have string values. Checked only if
Numeric and Mathematical ModulesisFalselevels – Number of levels to discretize any continuous issue
max_cardinality – Maximum allowed number of outcomes in the resulting issue.
- Remarks:
Will discretize inifinte outcome spaces
- class negmas.outcomes.CategoricalIssue(values, name=None)[source]¶
Bases:
DiscreteIssueAn
Issuetype representing discrete values that have no ordering or difference defined.
- class negmas.outcomes.ContiguousIssue(values: int | tuple[int, int], name: str | None = None)[source]¶
Bases:
RangeIssue,DiscreteIssueA
RangeIssue(also aDiscreteIssue) representing a contiguous range of integers.- property all: Generator[int, None, None][source]¶
All.
- Returns:
The result.
- Return type:
Generator[int, None, None]
- contains(issue: Issue) bool[source]¶
Checks weather this issue contains the input issue (i.e. every value in the input issue is in this issue)
- ordered_value_generator(n: int | float | None = None, grid=True, compact=False, endpoints=True) Generator[int, None, None][source]¶
Ordered value generator.
- Parameters:
n – Number of items.
grid – Grid.
compact – Compact.
endpoints – Endpoints.
- Returns:
The result.
- Return type:
Generator[int, None, None]
- rand_outcomes(n: int, with_replacement=False, fail_if_not_enough=False) list[int][source]¶
Picks a random valid value.
- to_discrete(n: int | None, grid=True, compact=False, endpoints=True) DiscreteIssue[source]¶
To discrete.
- Parameters:
n – Number of items.
grid – Grid.
compact – Compact.
endpoints – Endpoints.
- Returns:
The result.
- Return type:
- class negmas.outcomes.ContinuousInfiniteIssue(values, name=None, n_levels=10)[source]¶
Bases:
ContinuousIssue,InfiniteIssueAn issue that can represent all real numbers
- class negmas.outcomes.ContinuousIssue(values, name=None, n_levels=10)[source]¶
Bases:
RangeIssueA
RangeIssuerepresenting a continous range of real numbers with finite limits.- contains(issue: Issue) bool[source]¶
Checks weather this issue contains the input issue (i.e. every value in the input issue is in this issue)
- ordered_value_generator(n: int | float | None = 10, grid=True, compact=False, endpoints=True) Generator[float, None, None][source]¶
Ordered value generator.
- Parameters:
n – Number of items.
grid – Grid.
compact – Compact.
endpoints – Endpoints.
- Returns:
The result.
- Return type:
Generator[float, None, None]
- rand_outcomes(n: int, with_replacement=False, fail_if_not_enough=False) list[float][source]¶
Rand outcomes.
- class negmas.outcomes.CountableInfiniteIssue(values: tuple[int | float, int | float], *args, **kwargs)[source]¶
Bases:
ContiguousIssue,InfiniteIssueAn issue that can have all integer values.
- Remarks:
Actually, inifinties are replace with +- INFINITE_INT which is a very large number
- class negmas.outcomes.DiscreteCardinalIssue(values, name=None)[source]¶
Bases:
DiscreteOrdinalIssue,CardinalIssueAn issue that has an ordering and for which differences between values is defined (i.e. subtraction)
- class negmas.outcomes.DiscreteCartesianOutcomeSpace(issues, name: str | None = None, path: Path | None = None)[source]¶
Bases:
CartesianOutcomeSpaceA discrete outcome-space that is generated by the cartesian product of a tuple of
Issues (i.e. with finite number of outcomes).- cardinality_if_discretized(levels: int, max_cardinality: int | float = inf) int[source]¶
Cardinality if discretized.
- Parameters:
levels – Levels.
max_cardinality – Max cardinality.
- Returns:
The result.
- Return type:
- limit_cardinality(max_cardinality: int | float = inf, levels: int | float = inf) DiscreteCartesianOutcomeSpace[source]¶
Limits the cardinality of the outcome space to the given maximum (or the number of levels for each issue to
Logging Levels)- Parameters:
max_cardinality – The maximum number of outcomes in the resulting space
levels – The maximum number of levels for each issue/subissue
- to_discrete(levels: int | float = 10, max_cardinality: int | float = inf) DiscreteCartesianOutcomeSpace[source]¶
To discrete.
- Parameters:
levels – Levels.
max_cardinality – Max cardinality.
- Returns:
The result.
- Return type:
- to_largest_discrete(levels: int, max_cardinality: int | float = inf, **kwargs) DiscreteCartesianOutcomeSpace[source]¶
To largest discrete.
- Parameters:
levels – Levels.
max_cardinality – Max cardinality.
**kwargs – Additional keyword arguments.
- Returns:
The result.
- Return type:
- to_single_issue(numeric=False, stringify=True, levels: int = 5, max_cardinality: int | float = inf) DiscreteCartesianOutcomeSpace[source]¶
Creates a new outcome space that is a single-issue version of this one
- Parameters:
numeric – If given, the output issue will be a
ContiguousIssueotherwise it will be aCategoricalIssuestringify – If given, the output issue will have string values. Checked only if
Numeric and Mathematical ModulesisFalse
- Remarks:
maps the agenda and ufuns to work correctly together
Only works if the outcome space is finite
- class negmas.outcomes.DiscreteIssue(values, name: str | None = None)[source]¶
Bases:
IssueAn
Issuewith a discrete set of values.- abstract property all: Generator[Any, None, None][source]¶
A generator that generates all possible values.
- Remarks:
This function returns a generator for the case when the number of values is very large.
If you need a list then use something like:
>>> from negmas.outcomes import make_issue >>> list(make_issue(5).all) [0, 1, 2, 3, 4]
- property cardinality: int[source]¶
The number of possible outcomes for the issue. Guaranteed to be fininte
- ordered_value_generator(n: int | float | None = 10, grid=True, compact=True, endpoints=True) Generator[Any, None, None][source]¶
Ordered value generator.
- Parameters:
n – Number of items.
grid – Grid.
compact – Compact.
endpoints – Endpoints.
- Returns:
The result.
- Return type:
Generator[Any, None, None]
- class negmas.outcomes.DiscreteOrdinalIssue(values, name=None)[source]¶
Bases:
DiscreteIssue,OrdinalIssueA
DiscreteIssuethat have some defined ordering of outcomes but not necessarily a meaningful difference function between its values.- property all: Generator[Any, None, None][source]¶
All.
- Returns:
The result.
- Return type:
Generator[Any, None, None]
- ordered_value_generator(n: int = 10, grid=True, compact=False, endpoints=True) Generator[Any, None, None][source]¶
A generator that generates at most
nvalues (in order)- Remarks:
This function returns a generator for the case when the number of values is very large.
If you need a list then use something like:
>>> from negmas.outcomes import make_issue >>> list(make_issue(5).ordered_value_generator()) [0, 1, 2, 3, 4] >>> list( ... int(10 * _) for _ in make_issue((0.0, 1.0)).ordered_value_generator(11) ... ) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- class negmas.outcomes.DiscreteOutcomeSpace(*args, **kwargs)[source]¶
Bases:
OutcomeSpace,Collection,ProtocolThe base protocol for all outcome spaces with a finite number of items.
This type of outcome-space acts as a standard python
Collectionwhich means that its length can be found usinglen()and it can be iterated over to return outcomes.- enumerate() Iterable[Outcome][source]¶
Enumerates the outcome space returning all its outcomes (or up to max_cardinality for infinite ones)
- limit_cardinality(max_cardinality: int | float = inf, levels: int | float = inf) DiscreteOutcomeSpace[source]¶
Limits the cardinality of the outcome space to the given maximum (or the number of levels for each issue to
Logging Levels)- Parameters:
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)
- sample(n_outcomes: int, with_replacement: bool = False, fail_if_not_enough=True) Iterable[Outcome][source]¶
Sample.
- Parameters:
n_outcomes – N outcomes.
with_replacement – With replacement.
fail_if_not_enough – Fail if not enough.
- Returns:
The result.
- Return type:
Iterable[Outcome]
- to_discrete(*args, **kwargs) DiscreteOutcomeSpace[source]¶
To discrete.
- Parameters:
*args – Additional positional arguments.
**kwargs – Additional keyword arguments.
- Returns:
The result.
- Return type:
- to_single_issue(numeric: bool = False, stringify: bool = True) CartesianOutcomeSpace[source]¶
To single issue.
- Parameters:
numeric – Numeric.
stringify – Stringify.
- Returns:
The result.
- Return type:
- class negmas.outcomes.EnumeratingOutcomeSpace(invalid: set[tuple] = NOTHING, baseset: set[tuple] = NOTHING, name: str | None = None, path: Path | None = None)[source]¶
Bases:
DiscreteOutcomeSpace,OSWithValidityAn outcome space representing the enumeration of some outcomes. No issues defined
- are_types_ok(outcome: tuple) bool[source]¶
Checks if the type of each value in the outcome is correct for the given issue
- cardinality_if_discretized(levels: int, max_cardinality: int | float = inf) int[source]¶
Returns the cardinality if discretized the given way.
- ensure_correct_types(outcome: tuple) tuple[source]¶
Returns an outcome that is guaratneed to have correct types or raises an exception
- enumerate() Iterable[tuple][source]¶
Enumerates the outcome space returning all its outcomes (or up to max_cardinality for infinite ones)
- enumerate_or_sample(levels: int | float = inf, max_cardinality: int | float = inf) Iterable[tuple][source]¶
Enumerates all outcomes if possible (i.e. discrete space) or returns
max_cardinalitydifferent outcomes otherwise
- limit_cardinality(max_cardinality: int | float = inf, levels: int | float = inf) DiscreteOutcomeSpace[source]¶
Limits the cardinality of the outcome space to the given maximum (or the number of levels for each issue to
Logging Levels)- Parameters:
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)
- sample(n_outcomes: int, with_replacement: bool = False, fail_if_not_enough=False) Iterable[tuple][source]¶
Samples up to n_outcomes with or without replacement
- to_discrete(levels: int | float = 5, max_cardinality: int | float = inf) DiscreteOutcomeSpace[source]¶
Returns a stable finite outcome space. If the outcome-space is already finite. It shoud return itself.
- Parameters:
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.
- to_largest_discrete(levels: int, max_cardinality: int | float = inf, **kwargs) DiscreteOutcomeSpace[source]¶
To largest discrete.
- Parameters:
levels – Levels.
max_cardinality – Max cardinality.
**kwargs – Additional keyword arguments.
- Returns:
The result.
- Return type:
- to_single_issue(numeric: bool = False, stringify: bool = True) CartesianOutcomeSpace[source]¶
To single issue.
- Parameters:
numeric – Numeric.
stringify – Stringify.
- Returns:
The result.
- Return type:
- class negmas.outcomes.ExtendedOutcome(outcome: tuple, data: dict[str, Any] | None = None)[source]¶
Bases:
objectAn outcome with optional data fields.
This class allows offering policies to return additional data alongside the proposed outcome, such as text explanations, reasoning, or metadata.
- data[source]¶
Optional dictionary of additional data. Can contain: - “text”: A text message explaining the offer or providing context. - Any other key-value pairs for custom metadata.
Example
>>> from negmas.outcomes.common import ExtendedOutcome >>> outcome = (5, 10) # price=5, quantity=10 >>> extended = ExtendedOutcome( ... outcome=outcome, ... data={"text": "I propose this fair price", "confidence": 0.9}, ... ) >>> extended.outcome (5, 10) >>> extended.data["text"] 'I propose this fair price'
See also
negmas.gb.common.ExtendedResponseType: For extending acceptance responses.negmas.sao.common.SAOResponse.from_extended(): For creating SAOResponse from extended types.
- class negmas.outcomes.IndependentDiscreteIssuesOS(*args, **kwargs)[source]¶
Bases:
ProtocolAn Outcome-Space that is constructed from a tuple of
DiscreteIssueobjects.- issues: tuple[DiscreteIssue, ...][source]¶
- class negmas.outcomes.IndependentIssuesOS(*args, **kwargs)[source]¶
Bases:
ProtocolAn Outcome-Space that is constructed from a tuple of
Issueobjects.
- class negmas.outcomes.InfiniteIssue[source]¶
Bases:
objectIndicates that the issue is infinite (i.e. one or more of its limits is infinity)
- class negmas.outcomes.Issue(values, name: str | None = None)[source]¶
Bases:
HasMinMax,Iterable,ABCBase class of all issues in NegMAS
- property cardinality: int | float[source]¶
The number of possible outcomes for the issue. Returns infinity for continuous and uncountable spaces
- contains(issue: Issue) bool[source]¶
Checks weather this issue contains the input issue (i.e. every value in the input issue is in this issue)
- classmethod from_dict(d, python_class_identifier='__python_class__')[source]¶
Constructs an issue from a dict generated using
to_dict()
- has_finite_limits() bool[source]¶
Checks whether the minimum and maximum values of the issue are known and are finite
- intersect(other: Issue)[source]¶
Returns an issue which is the intersection of the two issues and otherwise is the same as this one
- abstractmethod is_continuous() bool[source]¶
The issue has a continuous set of values. Note that this is different from having values that are real (which is tested using
is_float)
- is_discrete() bool[source]¶
Checks whether the issue has a discrete set of values. This is different from
is_integerwhich checks that the values themselves are integers andis_discrete_valuedwhich checks that they are discrete.
- abstractmethod ordered_value_generator(n: int | float | None = None, grid=True, compact=False, endpoints=True) Generator[int, None, None][source]¶
A generator that generates at most
nvalues (in a stable order)- Parameters:
n – The number of samples. If inf or None, all values will be generated but when the issue is infinite, it will just fail
grid – Sample on a grid (equally distanced as much as possible)
compact – If True, the samples will be chosen near each other (see endpoints though)
endpoints – If given, the first and last index are guaranteed to be in the samples
- Remarks:
This function returns a generator for the case when the number of values is very large.
If the order is not defined for this issue, this generator will still generate values in the same order every time it is called.
If you need a list then use something like:
>>> from negmas.outcomes import make_issue >>> list(make_issue(5).value_generator()) [0, 1, 2, 3, 4] >>> list(int(10 * _) for _ in make_issue((0.0, 1.0)).value_generator(11)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- abstractmethod rand_outcomes(n: int, with_replacement=False, fail_if_not_enough=False) list[source]¶
Picks n random valid value (at most).
- Parameters:
- Returns:
A list of sampled values
- to_dict(python_class_identifier='__python_class__')[source]¶
Converts the issue to a dictionary from which it can be constructed again using
Issue.from_dict()
- to_discrete(n: int | float | None = 10, grid=True, compact=True, endpoints=True) DiscreteIssue[source]¶
Converts the issue to a discrete issue by samling from it.
If the issue is already discret it will just return itself. This method cannot be used to reduce the cardinality of a discrete issue.
- Parameters:
n (int | float | None) – Number of values in the resulting discrete issue. This will be ignored if the issue is already discrete. The only allowed float value is
float("inf"). If any other float is passed, it will be silently cast to an intgrid (bool) – Sample on a grid
compact (bool) – Sample around the center
endpoints (bool) – Always incllude minimum and maximum values
- abstractmethod value_at(index: int)[source]¶
Returns the value at the given index of the issue. The same index will have the same values always indepdendent of whether the values of the issue have defined ordering.
- abstractmethod value_generator(n: int | float | None = None, grid=True, compact=True, endpoints=True) Generator[Any, None, None][source]¶
A generator that generates at most
nvalues (in any order)- Parameters:
grid – Sample on a grid (equally distanced as much as possible)
compact – If True, the samples will be choosen near each other (see endpoints though)
endpoints – If given, the first and last index are guaranteed to be in the samples
- Remarks:
This function returns a generator for the case when the number of values is very large.
If you need a list then use something like:
>>> from negmas.outcomes import make_issue >>> list(make_issue(5).value_generator()) [0, 1, 2, 3, 4] >>> list(int(10 * _) for _ in make_issue((0.0, 1.0)).value_generator(11)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- class negmas.outcomes.OrdinalIssue(values, name: str | None = None)[source]¶
-
An
Issuethat have some defined ordering of outcomes but not necessarily a meaningful difference function between its values.- abstractmethod ordered_value_generator(n: int = 10, grid=True, compact=False, endpoints=True) Generator[Any, None, None][source]¶
Ordered value generator.
- Parameters:
n – Number of items.
grid – Grid.
compact – Compact.
endpoints – Endpoints.
- Returns:
The result.
- Return type:
Generator[Any, None, None]
- class negmas.outcomes.OutcomeSpace(*args, **kwargs)[source]¶
-
The base protocol for all outcome spaces.
- are_types_ok(outcome: Outcome) bool[source]¶
Checks if the type of each value in the outcome is correct for the given issue
- cardinality_if_discretized(levels: int, max_cardinality: int | float = inf) int[source]¶
Returns the cardinality if discretized the given way.
- ensure_correct_types(outcome: Outcome) Outcome[source]¶
Returns an outcome that is guaratneed to have correct types or raises an exception
- enumerate_or_sample(levels: int | float = inf, max_cardinality: int | float = inf) Iterable[Outcome][source]¶
Enumerates all outcomes if possible (i.e. discrete space) or returns
max_cardinalitydifferent outcomes otherwise
- is_valid(outcome: Outcome) bool[source]¶
Checks if the given outcome is valid for that outcome space
- sample(n_outcomes: int, with_replacement: bool = False, fail_if_not_enough=False) Iterable[Outcome][source]¶
Samples up to n_outcomes with or without replacement
- to_discrete(levels: int | float = 5, max_cardinality: int | float = inf) DiscreteOutcomeSpace[source]¶
Returns a stable finite outcome space. If the outcome-space is already finite. It shoud return itself.
- Parameters:
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.
- class negmas.outcomes.RangeIssue(values, name=None)[source]¶
Bases:
CardinalIssueAn issue representing a range of values (can be continuous or discrete)
- negmas.outcomes.check_one_and_only(outcome_space, issues, outcomes) None[source]¶
Ensures that one and only one of the three inputs is given (i.e. not None)
- negmas.outcomes.check_one_at_most(outcome_space, issues, outcomes) None[source]¶
Ensures that at most one of the three inputs is given (i.e. not None)
- negmas.outcomes.combine_issues(issues: Sequence[Issue], name: str | None = None, keep_value_names=True, issue_sep='_', value_sep='-') Issue | None[source]¶
Combines multiple issues into a single issue.
- Parameters:
issues – The issues to be combined
name – The name of the resulting issue (If not given, combines input issue names)
keep_value_names – If true, the values for the generated issue will be a concatenation of values from earlier issues separated by
value_sep.issue_sep – Separator for the issue name (used only if
keep_issue_names)value_sep – Separator for the issue name (used only if
keep_value_names)
Remarks:
Only works if the issues have finite cardinality
- negmas.outcomes.dict2outcome(d: dict[str, Any] | tuple | None, issues: tuple[str | Issue, ...]) Outcome | None[source]¶
Converts the outcome to a tuple no matter what was its type
- Parameters:
d – the dictionary to be converted
issues – A list of issues or issue names (as strings) to order the tuple
- Remarks:
If called with a tuple outcome, it will issue a warning
- negmas.outcomes.discretize_and_enumerate_issues(issues: Iterable[Issue], n_discretization: int | None = 10, max_cardinality: int | float | None = None) list[Outcome][source]¶
Enumerates the outcomes of a list of issues.
- Parameters:
issues – The list of issues.
max_cardinality – The maximum number of outcomes to return
- Returns:
list of outcomes of the given type.
- negmas.outcomes.ensure_os(outcome_space, issues, outcomes) OutcomeSpace[source]¶
Returns an outcome space from either an outcome-space, a list of issues, a list of outcomes, or the number of outcomes
- Remakrs:
Precedence is in the order of paramters
outcome_space>issues> negmas.outcomes.If neither is given, a
ValueErrorexception will be raised.Will not copy the outcome-space if it is given
A
CartesianOutcomeSpacewill be created if an outcome-space is not givenIf outcomes is given or all issues are discrete, a
DiscreteCartesianOutcomeSpacewill be created
- negmas.outcomes.enumerate_discrete_issues(issues: Sequence[DiscreteIssue]) list[Outcome][source]¶
Enumerates all outcomes of this set of discrete issues if possible.
- Parameters:
issues – A list of issues
- Returns:
list of outcomes
- negmas.outcomes.enumerate_issues(issues: Sequence[Issue], max_cardinality: int | float | None = None) list[Outcome][source]¶
Enumerates the outcomes of a list of issues.
- Parameters:
issues – The list of issues.
max_cardinality – The maximum number of outcomes to return
- Returns:
list of outcomes of the given type.
- negmas.outcomes.generalized_minkowski_distance(a: Outcome, b: Outcome, outcome_space: OutcomeSpace | None, *, weights: Sequence[float] | None = None, dist_power: float = 2) float[source]¶
Calculates the difference between two outcomes given an outcome-space (optionally with issue weights). This is defined as the distance.
- Parameters:
outcome_space – The outcome space used for comparison (If None an apporximate implementation is provided)
a – first outcome
b – second outcome
weights – Issue weights
dist_power – The exponent used when calculating the distance
Remarks:
Implements the following distance measure:
\[d(a, b) = \left( \sum_{i=1}^{N} w_i {\left| a_i - b_i \right|}^p \right)^{frac{1}{p}}\]where $a, b$ are the outocmes, $x_i$ is value for issue $i$ of outcoem $x$, $w_i$ is the weight of issue $i$ and $p$ is the
dist_powerpasssed. Categorical issue differences is defined as $1$ if the values are not equal and $0$ otherwise.Becomes the Euclidean distance if all issues are numeric and no weights are given
You can control the power:
Setting it to 1 is the city-block distance
Setting it to 0 is the maximum issue difference
- negmas.outcomes.generate_issues(params: Sequence[int | list[str] | tuple[int, int] | Callable | tuple[float, float]], counts: list[int] | None = None, names: list[str] | None = None) tuple[Issue, ...][source]¶
Generates a set of issues with given parameters. Each is optionally repeated.
- Parameters:
params – The parameters of the issues
counts – The number of times to repeat each of the
issuesnames – The names to assign to the issues. If None, then string representations of integers starting from zero will be used.
- Returns:
The list of issues with given conditions
- Return type:
list[‘Issue’]
- negmas.outcomes.issues_from_genius(file_name: PathLike | str, safe_parsing=True, n_discretization: int | None = None) tuple[Sequence[Issue] | None, Sequence[str] | None][source]¶
Imports a the domain issues from a GENIUS XML file.
- Parameters:
file_name (str) – File name to import from
safe_parsing – Add more checks to parsing
n_discretization – Number of discretization levels per issue
- Returns:
tuple[Issue, …] containing the issues
list[str] containing agent names (that are sometimes stored in the genius domain)
- Return type:
A tuple of two optional lists
Examples
>>> import pkg_resources >>> issues, _ = issues_from_genius( ... file_name=pkg_resources.resource_filename( ... "negmas", resource_name="tests/data/Laptop/Laptop-C-domain.xml" ... ) ... ) >>> print([_.name for _ in issues]) ['Laptop', 'Harddisk', 'External Monitor']
- Remarks:
See
from_xml_strfor all the parameters
- negmas.outcomes.issues_from_geniusweb(file_name: PathLike | str, safe_parsing=True, n_discretization: int | None = None) tuple[Sequence[Issue] | None, Sequence[str] | None][source]¶
Imports a the domain issues from a GENIUS XML file.
- Parameters:
file_name (str) – File name to import from
safe_parsing – Add more checks to parsing
n_discretization – Number of discretization levels per issue
- Returns:
tuple[Issue, …] containing the issues
list[str] containing agent names (that are sometimes stored in the genius domain)
- Return type:
A tuple of two optional lists
Examples
>>> import pkg_resources >>> issues, _ = issues_from_genius( ... file_name=pkg_resources.resource_filename( ... "negmas", resource_name="tests/data/Laptop/Laptop-C-domain.xml" ... ) ... ) >>> print([_.name for _ in issues]) ['Laptop', 'Harddisk', 'External Monitor']
- Remarks:
See
from_xml_strfor all the parameters
- negmas.outcomes.issues_from_geniusweb_json_str(json_str: str, safe_parsing=True, n_discretization: int | None = None) tuple[Sequence[Issue] | None, Sequence[str] | None][source]¶
Exports a list/dict of issues from a GeniusWeb json file.
- Parameters:
json_str (str) – The string containing GENIUS style XML domain issue definitions
safe_parsing (bool) – Turn on extra checks
n_discretization (Optional[int]) – If not None, real valued issues are discretized with the given
values (number of)
max_cardinality (int) – Maximum number of outcomes allowed (effective only if force_single_issue is True)
- Returns:
tuple[Issue, …] The issues (note that issue names will be stored in the name attribute of each issue if keep_issue_names)
list[dict] A list of agent information dicts each contains ‘agent’, ‘class’, ‘utility_file_name’
- negmas.outcomes.issues_from_outcomes(outcomes: Sequence[Outcome] | int, numeric_as_ranges: bool = True, issue_names: list[str] | None = None) tuple[DiscreteIssue][source]¶
Create a set of issues given some outcomes.
- Parameters:
outcomes – A list of outcomes or the number of outcomes
issue_names – If given, will be used as issue names, otherwise random issue names will be used
numeric_as_ranges – If True, all numeric issues generated will have ranges that are defined by the minimum and maximum values of that issue in the given outcomes instead of a list of the values that appeared in them.
- Returns:
a list of issues that include the given outcomes.
Remarks:
The outcome space spanned by the generated issues can in principle contain many more possible outcomes than the ones given
- negmas.outcomes.issues_from_xml_str(xml_str: str, safe_parsing=True, n_discretization: int | None = None) tuple[Sequence[Issue] | None, Sequence[str] | None][source]¶
Exports a list/dict of issues from a GENIUS XML file.
- Parameters:
xml_str (str) – The string containing GENIUS style XML domain issue definitions
safe_parsing (bool) – Turn on extra checks
n_discretization (Optional[int]) – If not None, real valued issues are discretized with the given
values (number of)
max_cardinality (int) – Maximum number of outcomes allowed (effective only if force_single_issue is True)
- Returns:
tuple[Issue, …] The issues (note that issue names will be stored in the name attribute of each issue if keep_issue_names)
list[dict] A list of agent information dicts each contains ‘agent’, ‘class’, ‘utility_file_name’
Examples
>>> import pkg_resources >>> domain_file_name = pkg_resources.resource_filename( ... "negmas", resource_name="tests/data/Laptop/Laptop-C-domain.xml" ... ) >>> with open(domain_file_name, "r") as ff: ... issues, _ = issues_from_xml_str(ff.read()) >>> print([_.cardinality for _ in issues]) [3, 3, 3]
>>> domain_file_name = pkg_resources.resource_filename( ... "negmas", resource_name="tests/data/fuzzyagent/single_issue_domain.xml" ... ) >>> with open(domain_file_name, "r") as ff: ... issues, _ = issues_from_xml_str(ff.read()) >>> len(issues) 1 >>> type(issues) <class 'tuple'> >>> str(issues[0]).split(": ")[-1] '(10.0, 40.0)' >>> print([_.cardinality for _ in issues]) [inf]
- negmas.outcomes.issues_to_genius(issues: Sequence[Issue], file_name: PathLike | str) None[source]¶
Exports a the domain issues to a GENIUS XML file.
- Parameters:
issues – The issues to be exported
file_name (str) – File name to export to
- Returns:
A tuple[Issue, …] or dict[Issue]
Examples
>>> import pkg_resources >>> issues, _ = issues_from_genius( ... file_name=pkg_resources.resource_filename( ... "negmas", resource_name="tests/data/Laptop/Laptop-C-domain.xml" ... ) ... ) >>> issues_to_genius( ... issues=issues, ... file_name=pkg_resources.resource_filename( ... "negmas", resource_name="tests/data/LaptopConv/Laptop-C-domain.xml" ... ), ... ) >>> issues2, _ = issues_from_genius( ... file_name=pkg_resources.resource_filename( ... "negmas", resource_name="tests/data/LaptopConv/Laptop-C-domain.xml" ... ) ... ) >>> print("\n".join([" ".join(list(issue.all)) for issue in issues])) Dell Macintosh HP 60 Gb 80 Gb 120 Gb 19'' LCD 20'' LCD 23'' LCD >>> print("\n".join([" ".join(list(issue.all)) for issue in issues2])) Dell Macintosh HP 60 Gb 80 Gb 120 Gb 19'' LCD 20'' LCD 23'' LCD
Forcing Single outcome
>>> issues, _ = issues_from_genius( ... file_name=pkg_resources.resource_filename( ... "negmas", resource_name="tests/data/Laptop/Laptop-C-domain.xml" ... ) ... ) >>> print([list(issue.all) for issue in issues]) [['Dell', 'Macintosh', 'HP'], ['60 Gb', '80 Gb', '120 Gb'], ["19'' LCD", "20'' LCD", "23'' LCD"]]
- Remarks:
See
from_xml_strfor all the parameters
- negmas.outcomes.issues_to_xml_str(issues: Sequence[Issue]) str[source]¶
Converts the list of issues into a well-formed xml string.
Examples
>>> issues = [ ... make_issue(values=10, name="i1"), ... make_issue(values=["a", "b", "c"], name="i2"), ... make_issue(values=(2.5, 3.5), name="i3"), ... ] >>> s = issues_to_xml_str(issues) >>> print(s.strip()) <negotiation_template> <utility_space number_of_issues="3"> <objective description="" etype="objective" index="0" name="root" type="objective"> <issue etype="discrete" index="1" name="i1" type="discrete" vtype="integer"> <item index="1" value="0" cost="0" description="0"> </item> <item index="2" value="1" cost="0" description="1"> </item> <item index="3" value="2" cost="0" description="2"> </item> <item index="4" value="3" cost="0" description="3"> </item> <item index="5" value="4" cost="0" description="4"> </item> <item index="6" value="5" cost="0" description="5"> </item> <item index="7" value="6" cost="0" description="6"> </item> <item index="8" value="7" cost="0" description="7"> </item> <item index="9" value="8" cost="0" description="8"> </item> <item index="10" value="9" cost="0" description="9"> </item> </issue> <issue etype="discrete" index="2" name="i2" type="discrete" vtype="discrete"> <item index="1" value="a" cost="0" description="a"> </item> <item index="2" value="b" cost="0" description="b"> </item> <item index="3" value="c" cost="0" description="c"> </item> </issue> <issue etype="real" index="3" name="i3" type="real" vtype="real"> <range lowerbound="2.5" upperbound="3.5"></range> </issue> </objective> </utility_space> </negotiation_template>
>>> issues2, _ = issues_from_xml_str(s) >>> print([_.__class__.__name__ for _ in issues2]) ['CategoricalIssue', 'CategoricalIssue', 'ContinuousIssue']
>>> print(len(issues2)) 3 >>> print([str(_) for _ in issues2]) ["i1: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']", "i2: ['a', 'b', 'c']", 'i3: (2.5, 3.5)'] >>> print([_.values for _ in issues2]) [['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], ['a', 'b', 'c'], (2.5, 3.5)]
- negmas.outcomes.make_issue(values, *args, optional: bool = False, **kwargs)[source]¶
A factory for creating issues based on
valuestype as well as the base class of all issues- Parameters:
values – Possible values for the issue
name – Name of the issue. If not given, a random name will be generated
optional – If given an
OptionalIssuewill be created
Remarks:
Issues can be initialized by either an iterable of strings, an integer or a tuple of two values with the following meanings:
list of anything: This is an issue that can any value within the given set of values (strings, ints, floats, etc). Depending on the types in the list, a different issue type will be created:integers -> CardinalIssue
a type that supports subtraction -> OrdinalIssue (with defined order and defined difference between values)
otherwise -> CategoricalIssue (without defined order or difference between values)
int: This is a ContiguousIssue that takes any value from 0 to the given value -1 (int)Tuple[
int,int] : This is a ContiguousIssue that can take any integer value in the given limits (min, max)Tuple[
float,float] : This is a ContinuousIssue that can take any real value in the given limits (min, max)Tuple[
int,inf] : This is a CountableInfiniteIssue that can take any integer value in the given limitsTuple[
-inf,int] : This is a CountableInfiniteIssue that can take any integer value in the given limitsTuple[
float,inf] : This is a ContinuousInfiniteIssue that can take any real value in the given limitsTuple[
-inf,float] : This is a ContinuousInfiniteIssue that can take any real value in the given limitsCallableThe callable should take no parameters and should act as a generator of issue values. Thistype of issue is always assumed to be neither countable nor continuous and are called uncountable. For example, you can use this type to make an issue that generates all integers from 0 to infinity. Most operations are not supported on this issue type.
If a list is given, min, max must be callable on it.
- negmas.outcomes.make_os(issues: Sequence[Issue] | None = None, outcomes: Sequence[tuple] | None = None, name: str | None = None, path: Path | None = None) CartesianOutcomeSpace[source]¶
A factory to create outcome-spaces from lists of
Issues orOutcomes.Remarks:
must pass one and exactly one of
issuesand negmas.outcomes
- negmas.outcomes.min_dist(test_outcome: Outcome, outcomes: Sequence[Outcome], outcome_space: OutcomeSpace | None, distance_fun: DistanceFun = <function generalized_minkowski_distance>, **kwargs) float[source]¶
Minimum distance between an outcome and a set of outcomes in an outcome-spaceself.
- Parameters:
test_outcome – The outcome tested
outcomes – A sequence of outcomes to compare to
outcome_space – The outcomespace used for comparison
distance_fun – The distance function
kwargs – Paramters to pass to the distance function
See also
generalized_euclidean_distance
- negmas.outcomes.num_outcomes(issues: Sequence[Issue]) int | float[source]¶
Returns the total number of outcomes in a set of issues.
- negmas.outcomes.os_or_none(outcome_space, issues, outcomes) OutcomeSpace | None[source]¶
Returns an outcome space from either an outcome-space, a list of issues, a list of outcomes, or the number of outcomes
- Remakrs:
Precedence is in the order of paramters
outcome_space>issues> negmas.outcomes.If nothing is given, it will just return None
Will not copy the outcome-space if it is given
A
CartesianOutcomeSpacewill be created if an outcome-space is not givenIf outcomes is given or all issues are discrete, a
DiscreteCartesianOutcomeSpacewill be created
- negmas.outcomes.outcome2dict(outcome: None, issues: Sequence[str | Issue]) None[source]¶
- negmas.outcomes.outcome2dict(outcome: Outcome, issues: Sequence[str | Issue]) dict[str, Any]
Converts the outcome to a dict no matter what was its type.
- Parameters:
outcome – The outcome to be converted (as a tuple)
issues – The issues/issue names used as dictionary keys in the output
- Remarks:
If called with a dict that is already converted, it will just return it.
None is converted to None
Examples
>>> from negmas import make_issue >>> issues = [make_issue(10, "price"), make_issue(5, "quantity")] >>> outcome2dict((3, 4), issues=issues) {'price': 3, 'quantity': 4}
You can also use issue names without creating Issue objects >>> issues = [“price”, “quantity”] >>> outcome2dict((3, 4), issues=issues) {‘price’: 3, ‘quantity’: 4}
Trying to convert an already converted outcome does nothing >>> issues = [“price”, “quantity”] >>> outcome2dict(outcome2dict((3, 4), issues=issues), issues=issues) {‘price’: 3, ‘quantity’: 4}
- negmas.outcomes.outcome_in_range(outcome: Outcome, outcome_range: OutcomeRange, *, strict=False, fail_incomplete=False) bool[source]¶
Tests that the outcome is contained within the given range of outcomes.
An outcome range defines a value or a range of values for each issue.
- Parameters:
outcome – “Outcome” being tested
outcome_range – “Outcome” range being tested against
strict – Whether to enforce that all issues in the outcome must be mentioned in the outcome_range
fail_incomplete – If True then outcomes that do not sepcify a value for all keys in the outcome_range
falling (will be considered not falling within it. If False then these outcomes will be considered)
range (within the range given that the values for the issues mentioned in the outcome satisfy the)
constraints.
Examples
>>> outcome_range = { ... "price": (0.0, 2.0), ... "distance": [0.3, 0.4], ... "type": ["a", "b"], ... "area": 3, ... } >>> outcome_range_2 = {"price": [(0.0, 1.0), (1.5, 2.0)], "area": [(3, 4), (7, 9)]} >>> outcome_in_range({"price": 3.0}, outcome_range) False >>> outcome_in_range({"date": "2018.10.4"}, outcome_range) True >>> outcome_in_range({"date": "2018.10.4"}, outcome_range, strict=True) False >>> outcome_in_range({"area": 3}, outcome_range, fail_incomplete=True) False >>> outcome_in_range({"area": 3}, outcome_range) True >>> outcome_in_range({"type": "c"}, outcome_range) False >>> outcome_in_range({"type": "a"}, outcome_range) True >>> outcome_in_range({"date": "2018.10.4"}, outcome_range_2) True >>> outcome_in_range({"area": 3.1}, outcome_range_2) True >>> outcome_in_range({"area": 3}, outcome_range_2) False >>> outcome_in_range({"area": 5}, outcome_range_2) False >>> outcome_in_range({"price": 0.4}, outcome_range_2) True >>> outcome_in_range({"price": 0.4}, outcome_range_2, fail_incomplete=True) False >>> outcome_in_range({"price": 1.2}, outcome_range_2) False >>> outcome_in_range({"price": 0.4, "area": 3.9}, outcome_range_2) True >>> outcome_in_range({"price": 0.4, "area": 10}, outcome_range_2) False >>> outcome_in_range({"price": 1.2, "area": 10}, outcome_range_2) False >>> outcome_in_range({"price": 1.2, "area": 4}, outcome_range_2) False >>> outcome_in_range({"type": "a"}, outcome_range_2) True >>> outcome_in_range({"type": "a"}, outcome_range_2, strict=True) False >>> outcome_range = {"price": 10} >>> outcome_in_range({"price": 10}, outcome_range) True >>> outcome_in_range({"price": 11}, outcome_range) False
- Returns:
Success or failure
- Return type:
- Remarks:
Outcome ranges specify regions in an outcome space. They can have any of the following conditions:
A key/issue not mentioned in the outcome range does not add any constraints meaning that All values are acceptable except if strict == True. If strict == True then NO value will be accepted for issues not in the outcome_range.
A key/issue with the value None in the outcome range means All values on this issue are acceptable. This is the same as having this key/issue removed from the outcome space
A key/issue withe the value [] (empty list) accepts NO outcomes
A key/issue with a single value means that it is the only one acceptable
A key/issue with a single 2-items tuple (min, max) means that any value within that range is acceptable.
A key/issue with a list of values means an output is acceptable if it falls within the condition specified by any of the values in the list (list == union). Each such value can be a single value, a 2-items tuple or another list. Notice that lists of lists can always be combined into a single list of values
- negmas.outcomes.outcome_is_complete(outcome: Outcome, issues: tuple[Issue, ...]) bool[source]¶
Tests that the outcome is valid and complete.
Examples
>>> from negmas.outcomes import make_issue >>> issues = [make_issue((0.5, 2.0), 'price'), make_issue(['2018.10.'+ str(_) for _ in range(1, 4)], 'date') , make_issue(20, 'count')] >>> for _ in issues: print(_) price: (0.5, 2.0) date: ['2018.10.1', '2018.10.2', '2018.10.3'] count: (0, 19) >>> print([outcome_is_complete({'price':3.0}, issues), outcome_is_complete({'date': '2018.10.4'}, issues) , outcome_is_complete({'count': 21}, issues)]) [False, False, False] >>> valid_incomplete = {'price': 1.9} >>> print(outcome_is_complete(valid_incomplete, issues)) False >>> valid_incomplete.update({'date': '2018.10.2', 'count': 5}) >>> print(outcome_is_complete(valid_incomplete, issues)) True >>> invalid = {'price': 2000, 'date': '2018.10.2', 'count': 5} >>> print(outcome_is_complete(invalid, issues)) False >>> invalid = {'unknown': 2000, 'date': '2018.10.2', 'count': 5} >>> print(outcome_is_complete(invalid, issues)) False
- Args:
outcome: outcome tested which much contain valid values all issues if it is to be considered complete. issues: issues
- negmas.outcomes.outcome_is_valid(outcome: Outcome, issues: tuple[Issue, ...]) bool[source]¶
Test validity of an outcome given a set of issues.
Examples
>>> from negmas.outcomes import make_issue >>> issues = [make_issue((0.5, 2.0), 'price'), make_issue(['2018.10.'+ str(_) for _ in range(1, 4)], 'date') , make_issue(20, 'count')] >>> for _ in issues: print(_) price: (0.5, 2.0) date: ['2018.10.1', '2018.10.2', '2018.10.3'] count: (0, 19) >>> print([outcome_is_valid({'price':3.0}, issues), outcome_is_valid({'date': '2018.10.4'}, issues) , outcome_is_valid({'count': 21}, issues)]) [False, False, False] >>> valid_incomplete = {'price': 1.9} >>> print(outcome_is_valid(valid_incomplete, issues)) False >>> print(outcome_is_complete(valid_incomplete, issues)) False >>> valid_incomplete.update({'date': '2018.10.2', 'count': 5}) >>> print(outcome_is_complete(valid_incomplete, issues)) True
- Parameters:
outcome – outcome tested.
issues – issues
- negmas.outcomes.outcome_types_are_ok(outcome: Outcome, issues: tuple[Issue, ...]) bool[source]¶
Checks that the types of all issue values in the outcome are correct
- negmas.outcomes.sample_issues(issues: Sequence[Issue], n_outcomes: int, with_replacement: bool = True, fail_if_not_enough=True) Iterable[Outcome][source]¶
Samples some outcomes from the outcome space defined by the list of issues.
- Parameters:
issues – list of issues to sample from
n_outcomes – The number of outcomes required
with_replacement – Whether sampling is with replacement (allowing repetition)
fail_if_not_enough – IF given then an exception is raised if not enough outcomes are available
- Returns:
a list of outcomes
Examples
>>> from negmas.outcomes import make_issue >>> issues = [ ... make_issue(name="price", values=(0.0, 3.0)), ... make_issue(name="quantity", values=10), ... ]
Sampling outcomes as tuples
>>> samples = sample_issues(issues=issues, n_outcomes=10) >>> len(samples) == 10 True >>> type(samples[0]) == tuple True
- negmas.outcomes.sample_outcomes(issues: Sequence[Issue], n_outcomes: int | None = None, min_per_dim: int = 5, expansion_policy=None) list[Outcome][source]¶
Discretizes the issue space and returns either a predefined number of outcomes or uniform samples.
- Parameters:
issues – The issues describing the issue space to be discretized
n_outcomes – If None then exactly
min_per_dimbins will be used for every continuous dimension and all outcomesreturned (will be)
min_per_dim – Max levels of discretization per dimension
expansion_policy – None or ‘repeat’ or ‘null’ or ‘no’. If repeat, then some of the outcomes will be repeated
than (if None or 'no' then no expansion will happen if the total number of outcomes is less)
n_outcomes – If ‘null’ then expansion will be with None values
- Returns:
list of outcomes
Examples
enumberate the whole space
>>> from negmas.outcomes import make_issue >>> issues = [ ... make_issue(values=(0.0, 1.0), name="Price"), ... make_issue(values=["a", "b"], name="Name"), ... ] >>> sample_outcomes(issues=issues) [(0.0, 'a'), (0.0, 'b'), (0.25, 'a'), (0.25, 'b'), (0.5, 'a'), (0.5, 'b'), (0.75, 'a'), (0.75, 'b'), (1.0, 'a'), (1.0, 'b')]
enumerate with sampling for very large space (we have 10 outcomes in the discretized space)
>>> from negmas.outcomes import make_issue >>> issues = [ ... make_issue(values=(0.0, 1.0), name="Price"), ... make_issue(values=["a", "b"], name="Name"), ... ] >>> issues[0].is_continuous() True >>> sampled = sample_outcomes(issues=issues, n_outcomes=5) >>> len(sampled) 5 >>> len(set(sampled)) 5
>>> from negmas.outcomes import make_issue >>> issues = [ ... make_issue(values=(0, 1), name="Price"), ... make_issue(values=["a", "b"], name="Name"), ... ] >>> issues[0].is_continuous() False >>> sampled = sample_outcomes(issues=issues, n_outcomes=5) >>> len(sampled) 4 >>> len(set(sampled)) 4