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 |
|
---|