[100] | 1 | from copy import copy
|
---|
| 2 | from decimal import Decimal
|
---|
| 3 | from typing import Dict, cast, Optional
|
---|
| 4 |
|
---|
| 5 | from pyson.JsonGetter import JsonGetter
|
---|
| 6 |
|
---|
| 7 | from geniusweb.issuevalue.DiscreteValue import DiscreteValue
|
---|
| 8 | from geniusweb.issuevalue.DiscreteValueSet import DiscreteValueSet
|
---|
| 9 | from geniusweb.issuevalue.Value import Value
|
---|
| 10 | from geniusweb.issuevalue.ValueSet import ValueSet
|
---|
| 11 | from geniusweb.profile.utilityspace.ValueSetUtilities import ValueSetUtilities
|
---|
| 12 | from geniusweb.utils import toStr
|
---|
| 13 |
|
---|
| 14 |
|
---|
| 15 | class DiscreteValueSetUtilities (ValueSetUtilities) :
|
---|
| 16 | '''
|
---|
| 17 | Links a set of values to utilities for that value. Does not link to some
|
---|
| 18 | issue so may need further checking when used for an actual issue. Constructor
|
---|
| 19 | guarantees that
|
---|
| 20 | <ul>
|
---|
| 21 | <li>All values in the provided map (the utilities) are in [0,1]
|
---|
| 22 | <li>All keys are proper {@link DiscreteValue}s
|
---|
| 23 | </ul>
|
---|
| 24 | '''
|
---|
| 25 |
|
---|
| 26 | def __init__(self, valueUtilities: Dict[DiscreteValue, Decimal] ):
|
---|
| 27 | '''
|
---|
| 28 | create new object based on the given mapping from values to utilities.
|
---|
| 29 |
|
---|
| 30 | @param valueUtils map with key {@link DiscreteValue}s and value a Double
|
---|
| 31 | in the range [0,1].
|
---|
| 32 | @throws NullPointerException if one of the args is null
|
---|
| 33 | @throws IllegalArgumentException if values are not in range [0,1].
|
---|
| 34 |
|
---|
| 35 | '''
|
---|
| 36 |
|
---|
| 37 | if valueUtilities == None:
|
---|
| 38 | raise ValueError("valueUtils==null")
|
---|
| 39 |
|
---|
| 40 | if None in valueUtilities.keys():
|
---|
| 41 | raise ValueError("one of the keys in valueUtils is null")
|
---|
| 42 |
|
---|
| 43 | for v in valueUtilities.values():
|
---|
| 44 | if v==None or v<Decimal("0") or v>Decimal("1"):
|
---|
| 45 | raise ValueError("Weights in valueUtils must all be in [0,1]")
|
---|
| 46 |
|
---|
| 47 | self._valueUtilities = copy(valueUtilities);
|
---|
| 48 |
|
---|
| 49 | #Override
|
---|
| 50 | def getUtility(self, value:Optional[Value]) -> Decimal:
|
---|
| 51 | if not value in self._valueUtilities:
|
---|
| 52 | return Decimal("0")
|
---|
| 53 | return self._valueUtilities[value] # type: ignore
|
---|
| 54 |
|
---|
| 55 | @JsonGetter("valueUtilities")
|
---|
| 56 | def getUtilities(self) -> Dict[DiscreteValue, Decimal] :
|
---|
| 57 | '''
|
---|
| 58 | @return copy of the value-utility pair map.
|
---|
| 59 | '''
|
---|
| 60 | return copy(self._valueUtilities)
|
---|
| 61 |
|
---|
| 62 |
|
---|
| 63 | #Override
|
---|
| 64 | def isFitting(self, valueset:ValueSet ) ->str:
|
---|
| 65 | if not isinstance(valueset, DiscreteValueSet):
|
---|
| 66 | return "The utilities are for a discrete valueset but the given values are "\
|
---|
| 67 | + str(valueset);
|
---|
| 68 |
|
---|
| 69 | discvalueset = cast(DiscreteValueSet, valueset)
|
---|
| 70 | if self._valueUtilities.keys() != set(discvalueset.getValues()):
|
---|
| 71 | return "The values in the set " + str(valueset) \
|
---|
| 72 | + " do not match the values mapped to utilities " \
|
---|
| 73 | + str(self._valueUtilities.keys());
|
---|
| 74 | return cast(str,None)
|
---|
| 75 |
|
---|
| 76 | def __repr__(self):
|
---|
| 77 | return "DiscreteValueSetUtilities" + toStr(self._valueUtilities)
|
---|
| 78 |
|
---|
| 79 |
|
---|
| 80 | def __hash__(self):
|
---|
| 81 | return hash(tuple(self._valueUtilities.items()))
|
---|
| 82 |
|
---|
| 83 | def __eq__(self, other):
|
---|
| 84 | return isinstance(other, self.__class__) and \
|
---|
| 85 | self._valueUtilities == other._valueUtilities
|
---|
| 86 |
|
---|