source: java2python/geniuswebtranslator/geniuswebsrc/geniusweb/bidspace/IssueInfo.java@ 818

Last change on this file since 818 was 814, checked in by wouter, 6 months ago

#278 more NonNull annotations

File size: 5.3 KB
RevLine 
[519]1package geniusweb.bidspace;
2
3import java.math.BigDecimal;
[810]4import java.math.BigInteger;
[519]5import java.math.RoundingMode;
6import java.util.ArrayList;
7import java.util.HashMap;
8import java.util.List;
9import java.util.Map;
10
[810]11import org.eclipse.jdt.annotation.NonNull;
12
[519]13import geniusweb.issuevalue.Value;
14import geniusweb.issuevalue.ValueSet;
15import geniusweb.profile.utilityspace.ValueSetUtilities;
16
17/**
18 * Tool class to collect all relevant info about one issue (from LinearAdditive)
19 * in one class. Used for internally grouping data for more efficient
20 * processing. This class may change in the future, not recommended for direct
21 * use.
22 * <p>
23 * immutable
24 */
25public class IssueInfo {
[810]26 private final @NonNull String name;
27 private final @NonNull ValueSet values;
28 private final @NonNull Interval interval;
29 private final @NonNull Map<@NonNull Value, @NonNull BigDecimal> weightedUtils;
[519]30
31 /**
32 *
33 * @param name the issue name
34 * @param values the {@link ValueSet} of the issue
[814]35 * @param utils the {@link ValueSetUtilities} of the issue profile.
36 * FIXME is it required that all values have a utility?
[519]37 * @param weight the weight of the {@link ValueSetUtilities}
38 * @param precision the precision to compute with. Basically the number of
39 * decimal places used for the computations.
40 *
41 */
[810]42 public IssueInfo(@NonNull String name, @NonNull ValueSet values,
43 @NonNull ValueSetUtilities utils, @NonNull BigDecimal weight,
44 int precision) {
45 if (name == null || values == null || utils == null || weight == null)
46 throw new NullPointerException(
47 "name values utils and weight must be not null.");
48 if (values.size() == BigInteger.ZERO)
49 throw new IllegalArgumentException("Values must not be empty");
[519]50 this.name = name;
51 this.values = values;
52 this.weightedUtils = computeWeightedUtils(utils, weight, precision);
53 this.interval = getRange();
54 }
55
[810]56 public @NonNull ValueSet getValues() {
[519]57 return values;
58 }
59
[810]60 public @NonNull String getName() {
[519]61 return name;
62 }
63
64 /**
65 *
66 * @return weighted minimum and maximum utility achievable with this issue,
67 * rounded to the requested precision.
68 */
[810]69 public @NonNull Interval getInterval() {
[519]70 return interval;
71 }
72
73 /**
74 *
75 * @param isMax if true the max {@link Value} is returned, else the min is
76 * returned.
77 * @return the extreme value, either the minimum if isMax=false or maximum
[810]78 * if isMax=true.
79 * @throws IllegalStateException if there are no values
[519]80 */
[810]81 public @NonNull Value getExtreme(boolean isMax) {
[519]82 BigDecimal extremeutil = null;
83 Value extremeval = null;
[814]84 for (final @NonNull Value val : values) {
85 final @NonNull BigDecimal util = weightedUtils.get(val);
[519]86 if (extremeval == null) {
87 extremeutil = weightedUtils.get(val);
88 extremeval = val;
89 } else {
90 if (isMax) {
91 if (util.compareTo(extremeutil) > 0) {
92 extremeutil = util;
93 extremeval = val;
94 }
95 } else {
96 if (util.compareTo(extremeutil) < 0) {
97 extremeutil = util;
98 extremeval = val;
99 }
100
101 }
102 }
103 }
[810]104 if (extremeval == null)
105 throw new IllegalStateException(
106 "Extreme does not exist as IssueInfo values is empty");
107
[519]108 return extremeval;
109 }
110
111 /**
112 * @param val the issue value to be evaluated
113 * @return weighted utility of given value, rounded to nearest value with
[814]114 * the requested precision number of digits. returns 0 if value is
115 * unknown.
[519]116 */
[814]117 public @NonNull BigDecimal getWeightedUtil(@NonNull Value val) {
118 BigDecimal util = weightedUtils.get(val);
119 return util == null ? BigDecimal.ZERO : util;
[519]120 }
121
122 /**
123 *
124 * @param interval an {@link Interval} of utility values.
125 * @return all values that are inside the interval.
126 */
[810]127 protected @NonNull List<@NonNull Value> subset(@NonNull Interval interval) {
[519]128
[814]129 final @NonNull List<@NonNull Value> selection = new ArrayList<>();
130 for (final @NonNull Value value : values) {
[519]131 if (interval.contains(getWeightedUtil(value)))
132 selection.add(value);
133 }
134 return selection;
135 }
136
137 /**
138 * Faster way to determine subset size, it does not create a list
139 *
140 * @param interval an {@link Interval} of utility values.
141 * @return size of the subset that you will get from calling subset
142 */
[810]143 protected int subsetSize(@NonNull Interval interval) {
[519]144 int n = 0;
[814]145 for (final @NonNull Value value : values)
[519]146 if (interval.contains(getWeightedUtil(value)))
[579]147 n = n + 1;
[519]148 return n;
149 }
150
151 /**
152 * @return the {@link Interval} (minimum and maximum) of the utility of the
153 * weighted utility of this issue, properly rounded to the
154 * {@link #precision}/
155 *
156 */
[810]157 private @NonNull Interval getRange() {
[814]158 @NonNull
[519]159 BigDecimal min = BigDecimal.ONE;
[814]160 @NonNull
[519]161 BigDecimal max = BigDecimal.ZERO;
[814]162 for (final @NonNull Value value : values) {
163 final @NonNull BigDecimal util = getWeightedUtil(value);
[519]164 if (util.compareTo(min) < 0)
165 min = util;
166 if (util.compareTo(max) > 0)
167 max = util;
168 }
169 return new Interval(min, max);
170
171 }
172
[810]173 private @NonNull Map<@NonNull Value, @NonNull BigDecimal> computeWeightedUtils(
[814]174 @NonNull ValueSetUtilities utilities, @NonNull BigDecimal w,
175 int prec) {
176 final @NonNull Map<@NonNull Value, @NonNull BigDecimal> map = new HashMap<>();
[519]177
[814]178 for (final @NonNull Value val : values) {
[519]179 map.put(val, utilities.getUtility(val).multiply(w).setScale(prec,
180 RoundingMode.HALF_UP));
181 }
182 return map;
183 }
184
185}
Note: See TracBrowser for help on using the repository browser.