HyperRectangleUtilityFunction

class negmas.utilities.HyperRectangleUtilityFunction(outcome_ranges: Iterable[Mapping[Union[int, str], Union[int, float, str, List[int], List[float], List[str], Tuple[int, int], Tuple[float, float], List[Tuple[Union[int, float], Union[int, float]]]]]], utilities: Union[List[float], List[Union[Callable[[Union[negmas.outcomes.OutcomeType, Tuple[Union[int, float, str, list]], Dict[Union[int, str], Union[int, float, str, list]], int, str, float]], Union[negmas.helpers.Distribution, float]], Mapping[Union[Sequence, Mapping, int, str, float], Union[negmas.helpers.Distribution, float]]]]], weights: Optional[List[float]] = None, *, ignore_issues_not_in_input=False, ignore_failing_range_utilities=False, name: Optional[str] = None, reserved_value: Union[negmas.helpers.Distribution, float] = - inf, ami: Optional[negmas.common.AgentMechanismInterface] = None, outcome_type: Optional[Type] = None, id=None)[source]

Bases: negmas.utilities.UtilityFunction

A utility function defined as a set of hyper-volumes.

The utility function that is calulated by combining linearly a set of probably nonlinear functions applied in predefined hyper-volumes of the outcome space.

Args:

outcome_ranges: The outcome_ranges for which the mappings are defined weights: The optional weights to use for combining the outputs of the mappings ignore_issues_not_in_input: If a hyper-volumne local function is defined for some issue that is not in the outcome being evaluated ignore it. ignore_failing_range_utilities: If a hyper-volume local function fails, just assume it did not exist for this outcome. name: name of the utility function. If None a random name will be generated.

Examples:

We will use the following issue space of cardinality \(10 imes 5 imes 4\):

>>> issues = [Issue(10), Issue(5), Issue(4)]

Now create the utility function with

>>> f = HyperRectangleUtilityFunction(outcome_ranges=[
...                                        {0: (1.0, 2.0), 1: (1.0, 2.0)},
...                                        {0: (1.4, 2.0), 2: (2.0, 3.0)}]
...                                , utilities= [2.0, lambda x: 2 * x[2] + x[0]])
>>> g = HyperRectangleUtilityFunction(outcome_ranges=[
...                                        {0: (1.0, 2.0), 1: (1.0, 2.0)},
...                                        {0: (1.4, 2.0), 2: (2.0, 3.0)}]
...                                , utilities= [2.0, lambda x: 2 * x[2] + x[0]]
...                                , ignore_issues_not_in_input=True)
>>> h = HyperRectangleUtilityFunction(outcome_ranges=[
...                                        {0: (1.0, 2.0), 1: (1.0, 2.0)},
...                                        {0: (1.4, 2.0), 2: (2.0, 3.0)}]
...                                , utilities= [2.0, lambda x: 2 * x[2] + x[0]]
...                                , ignore_failing_range_utilities=True)

We can now calcualte the utility_function of some outcomes:

  • An outcome that belongs to the both outcome_ranges:

>>> [f({0: 1.5,1: 1.5, 2: 2.5}), g({0: 1.5,1: 1.5, 2: 2.5}), h({0: 1.5,1: 1.5, 2: 2.5})]
[8.5, 8.5, 8.5]
  • An outcome that belongs to the first hypervolume only:

>>> [f({0: 1.5,1: 1.5, 2: 1.0}), g({0: 1.5,1: 1.5, 2: 1.0}), h({0: 1.5,1: 1.5, 2: 1.0})]
[2.0, 2.0, 2.0]
  • An outcome that belongs to and has the first hypervolume only:

>>> [f({0: 1.5}), g({0: 1.5}), h({0: 1.5})]
[None, 0.0, None]
  • An outcome that belongs to the second hypervolume only:

>>> [f({0: 1.5,2: 2.5}), g({0: 1.5,2: 2.5}), h({0: 1.5,2: 2.5})]
[None, 6.5, None]
  • An outcome that has and belongs to the second hypervolume only:

>>> [f({2: 2.5}), g({2: 2.5}), h({2: 2.5})]
[None, 0.0, None]
  • An outcome that belongs to no outcome_ranges:

>>> [f({0: 11.5,1: 11.5, 2: 12.5}), g({0: 11.5,1: 11.5, 2: 12.5}), h({0: 11.5,1: 11.5, 2: 12.5})]
[0.0, 0.0, 0.0]
Remarks:
  • The number of outcome_ranges, mappings, and weights must be the same

  • if no weights are given they are all assumed to equal unity

  • mappings can either by an OutcomeUtilityMapping or a constant.

Methods Summary

adjust_params()

eval(offer)

Calculate the utility value for a given outcome.

from_dict(d)

to_dict()

xml(issues)

Represents the function as XML

Methods Documentation

adjust_params()[source]
eval(offer: Optional[Union[negmas.outcomes.OutcomeType, Tuple[Union[int, float, str, list]], Dict[Union[int, str], Union[int, float, str, list]]]])Optional[Union[negmas.helpers.Distribution, float]][source]

Calculate the utility value for a given outcome.

Parameters

offer – The offer to be evaluated.

Returns

The utility_function value which may be a distribution.

If None it means the utility_function value cannot be calculated.

Return type

UtilityValue

Remarks:
  • You cannot return None from overriden eval() functions but raise an exception (ValueError) if it was not possible to calculate the UtilityValue.

  • Typehint the return type as a UtilityValue instead of a float for the benefit of inspection code.

  • Return the reserved value if the offer was None

  • NEVER call the baseclass using super() when overriding this method. Calling super will lead to an infinite loop.

  • The default implementation assumes that is_better is defined and uses it to do the evaluation. Note that the default implementation of is_better does assume that eval is defined and uses it. This means that failing to define both leads to an infinite loop.

classmethod from_dict(d)[source]
to_dict()[source]
xml(issues: List[negmas.outcomes.Issue])str[source]

Represents the function as XML

Parameters

issues

Examples

>>> f = HyperRectangleUtilityFunction(outcome_ranges=[
...                                        {0: (1.0, 2.0), 1: (1.0, 2.0)},
...                                        {0: (1.4, 2.0), 2: (2.0, 3.0)}]
...                                , utilities= [2.0, 9.0 + 4.0])
>>> print(f.xml([Issue((0.0, 4.0), name='0'), Issue((0.0, 9.0), name='1')
... , Issue((0.0, 9.0), name='2')]).strip())
<issue index="1" name="0" vtype="real" type="real" etype="real">
    <range lowerbound="0.0" upperbound="4.0"></range>
</issue><issue index="2" name="1" vtype="real" type="real" etype="real">
    <range lowerbound="0.0" upperbound="9.0"></range>
</issue><issue index="3" name="2" vtype="real" type="real" etype="real">
    <range lowerbound="0.0" upperbound="9.0"></range>
</issue><utility_function maxutility="-1.0">
    <ufun type="PlainUfun" weight="1" aggregation="sum">
        <hyperRectangle utility_function="2.0">
            <INCLUDES index="0" min="1.0" max="2.0" />
            <INCLUDES index="1" min="1.0" max="2.0" />
        </hyperRectangle>
        <hyperRectangle utility_function="13.0">
            <INCLUDES index="0" min="1.4" max="2.0" />
            <INCLUDES index="2" min="2.0" max="3.0" />
        </hyperRectangle>
    </ufun>
</utility_function>