source: geniuswebcore/geniusweb/bidspace/IssueInfo.py@ 94

Last change on this file since 94 was 90, checked in by Bart Vastenhouw, 3 years ago

Refactor to help reusing partiesserver.

File size: 3.8 KB
RevLine 
[90]1from decimal import Decimal
2from geniusweb.issuevalue.ValueSet import ValueSet
3from geniusweb.profile.utilityspace.ValueSetUtilities import ValueSetUtilities
4from geniusweb.bidspace.Interval import Interval
5from geniusweb.issuevalue.Value import Value
6from typing import List, Dict, Optional
7
8class IssueInfo:
9 '''
10 Tool class to collect all relevant info about one issue (from LinearAdditive)
11 in one class. Used for internally grouping data for more efficient
12 processing. This class may change in the future, not recommended for direct
13 use.
14 <p>
15 immutable
16 '''
17
18 def __init__(self, name:str, values:ValueSet , utils:ValueSetUtilities,
19 weight:Decimal , precision:int ) :
20 '''
21 @param name the issue name
22 @param values the {@link ValueSet} of the issue
23 @param utils the {@link ValueSetUtilities} of the issue profile
24 @param weight the weight of the {@link ValueSetUtilities}
25 @param precision the precision to compute with. Basically the number of
26 decimal places used for the computations.
27 '''
28 self._name = name;
29 self._values = values;
30 self._weightedUtils = self._computeWeightedUtils(utils, weight, precision);
31 self._interval = self._getRange();
32
33 def getValues(self) ->ValueSet :
34 return self._values
35
36 def getName(self)->str:
37 return self._name;
38
39 def getInterval(self)->Interval:
40 '''
41 @return weighted minimum and maximum utility achievable with this issue,
42 rounded to the requested precision.
43 '''
44 return self._interval;
45
46 def getExtreme(self, isMax:bool)->Value :
47 '''
48 @param isMax if true the max {@link Value} is returned, else the min is
49 returned.
50 @return the extreme value, either the minimum if isMax=false or maximum
51 if isMax=true
52 '''
53 extremeutil:Decimal = None #type:ignore
54 extremeval:Decimal = None #type:ignore
55 for val in self._values:
56 util = self._weightedUtils.get(val)
57 if extremeval == None:
58 extremeutil = self._weightedUtils.get(val) #type:ignore
59 extremeval = val
60 else:
61 if isMax:
62 if util > extremeutil: #type:ignore
63 extremeutil = util #type:ignore
64 extremeval = val
65 else:
66 if util<extremeutil: #type:ignore
67 extremeutil = util #type:ignore
68 extremeval = val
69 return extremeval #type:ignore
70
71 def getWeightedUtil(self, val:Value ) -> Decimal :
72 '''
73 @param val the issue value to be evaluated
74 @return weighted utility of given value, rounded to nearest value with
75 the requested precision number of digits.
76 '''
77 return self._weightedUtils.get(val) #type:ignore
78
79 def _subset(self, interval:Interval) -> List[Value]:
80 '''
81 @param interval an {@link Interval} of utility values.
82 @return all values that are inside the interval.
83 '''
84
85 selection:List[Value] = []
86 for value in self._values:
87 if interval.contains(self.getWeightedUtil(value)):
88 selection.append(value);
89 return selection
90
91 def _subsetSize( self, interval:Interval) ->int:
92 '''
93 Faster way to determine subset size, it does not create a list
94
95 @param interval an {@link Interval} of utility values.
96 @return size of the subset that you will get from calling subset
97 '''
98 n = 0
99 for value in self._values:
100 if interval.contains(self.getWeightedUtil(value)):
101 n=n+1
102 return n
103
104 def _getRange(self)->Interval :
105 '''
106 @return the {@link Interval} (minimum and maximum) of the utility of the
107 weighted utility of this issue, properly rounded to the
108 {@link #precision}/
109
110 '''
111 min = Decimal(1)
112 max = Decimal(0)
113 for value in self._values:
114 util = self.getWeightedUtil(value)
115 if util < min:
116 min = util
117 if util > max:
118 max = util
119 return Interval(min, max)
120
121 def _computeWeightedUtils(self, utilities:ValueSetUtilities, w:Decimal, prec:int) \
122 -> Dict[Value, Decimal] :
123 map:Dict[Value, Decimal] = {}
124
125 for val in self._values:
126 map[val] = round(utilities.getUtility(val)* w, prec)
127 return map
Note: See TracBrowser for help on using the repository browser.