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