source: java2python/geniuswebtranslator/geniuswebsrc/geniusweb/profile/utilityspace/PartsUtilities.java@ 839

Last change on this file since 839 was 825, checked in by wouter, 6 months ago

#291 move annotation to above the javadoc

File size: 7.9 KB
Line 
1package geniusweb.profile.utilityspace;
2
3import java.math.BigDecimal;
4import java.util.Collections;
5import java.util.HashMap;
6import java.util.LinkedList;
7import java.util.List;
8import java.util.Map;
9
10import org.eclipse.jdt.annotation.NonNull;
11
12import com.fasterxml.jackson.annotation.JsonAutoDetect;
13import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
14import com.fasterxml.jackson.annotation.JsonCreator;
15import com.fasterxml.jackson.annotation.JsonProperty;
16
17import geniusweb.issuevalue.Value;
18import geniusweb.issuevalue.ValueSet;
19
20/**
21 * Contains utilities of a ProductOfValue of a {@link SumOfGroupsUtilitySpace}.
22 * So this is similar to a {@link DiscreteValueSetUtilities} but instead of
23 * issues this contains an (ordered) list of issues. This object serializes to
24 * something like <code>
25 * {"partsutils":
26 * {"issues":["issue1","issue2"],
27 * "utilslist":[{"values":["low","low"],"util":0.3},{"values":["high","high"],"util":0.9}]}}
28 * </code> The issues field contains a list of N issues in the domain, The
29 * utilslist contains a list of dictionaries, with "values" containing a list of
30 * N issue values, in the same order as the issues list and with "util"
31 * containng the utility value of that set of values.
32 */
33@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, isGetterVisibility = Visibility.NONE)
34public class PartsUtilities implements ValueSetUtilities {
35 private final @NonNull List<@NonNull String> issues;
36 // the real but not-serializable values (because Map can only have String
37 // keys in jackson)
38 private transient final @NonNull Map<@NonNull ProductOfValue, @NonNull BigDecimal> utilities = new HashMap<>();
39 // copy only for serializing
40 private final @NonNull List<@NonNull PartUtil> utilslist = new LinkedList<>();
41
42 /**
43 *
44 * @param issues list of issues
45 * @param utils with keys: list of values and value: utility value for that
46 * list of values. All list-of-values missing from the map are
47 * assumed to have utility 0. This includes partial bids where
48 * list-of-values contain null objects.
49 */
50 public PartsUtilities(@NonNull List<@NonNull String> issues,
51 @NonNull Map<@NonNull ProductOfValue, @NonNull BigDecimal> utils) {
52 if (issues == null || utils == null) {
53 throw new IllegalArgumentException(
54 "issues and utils must be not null");
55 }
56
57 this.issues = issues;
58 this.utilities.putAll(utils);
59
60 checkUtilities();
61 for (final @NonNull ProductOfValue pval : utils.keySet()) {
62 utilslist.add(new PartUtil(pval.getValues(), utils.get(pval)));
63 }
64 }
65
66 @JsonCreator
67 public PartsUtilities(
68 @JsonProperty("issues") @NonNull List<@NonNull String> issues,
69 @JsonProperty("utilslist") @NonNull List<@NonNull PartUtil> utilslist) {
70 this(issues, list2map(utilslist));
71 }
72
73 @Override
74 @NonNull
75 /**
76 *
77 * @param pval the {@link ProductOfValue} value
78 * @return the utility of the value, in the same order as
79 * {@link #getIssues()}. Returns 0 if there is no utility set for
80 * the given combination of values. Notice, partial bids will
81 * usually have utility 0.
82 *
83 */
84 public BigDecimal getUtility(@NonNull Value pval) {
85 final @NonNull BigDecimal val = utilities.get(pval);
86 if (val == null)
87 return BigDecimal.ZERO;
88 return val;
89 }
90
91 @Override
92 public String isFitting(@NonNull ValueSet valueset) {
93 return null; // what can we tests here?
94 }
95
96 @NonNull
97 /**
98 * @return the issues that are contained here.
99 */
100 public List<@NonNull String> getIssues() {
101 return issues;
102 }
103
104 @NonNull
105 /**
106 *
107 * @return map with all available values and their utilities. The map and
108 * its contents should all be immutable.
109 */
110 public Map<@NonNull ProductOfValue, @NonNull BigDecimal> getUtilities() {
111 return Collections.unmodifiableMap(utilities);
112 }
113
114 @NonNull
115 /**
116 *
117 * @param other another {@link PartsUtilities} map. The issues in the other
118 * map must be different from {@link #issues}.
119 * @return new PartsUtils, with the powermap of all combinations of one
120 * element from this and one from the other map, and with the
121 * utilities computed as the sum of thisvalue + othervalue.
122 */
123 public PartsUtilities add(@NonNull PartsUtilities other) {
124 for (@NonNull
125 String issue : issues) {
126 if (other.issues.contains(issue)) {
127 throw new IllegalArgumentException(
128 "Issue " + issue + " exists already");
129 }
130 }
131
132 final @NonNull List<@NonNull String> combinedissues = new LinkedList<>(
133 issues);
134 combinedissues.addAll(other.issues);
135
136 final @NonNull Map<@NonNull ProductOfValue, @NonNull BigDecimal> combinedvalues = new HashMap<>();
137 for (@NonNull
138 ProductOfValue productOfValue : this.utilities.keySet()) {
139 for (@NonNull
140 ProductOfValue otherProductOfValue : other.utilities.keySet()) {
141 final @NonNull BigDecimal combinedutil = getUtility(
142 productOfValue)
143 .add(other.getUtility(otherProductOfValue));
144 combinedvalues.put(productOfValue.merge(otherProductOfValue),
145 combinedutil);
146 }
147 }
148 return new PartsUtilities(combinedissues, combinedvalues);
149
150 }
151
152 @Override
153 public int hashCode() {
154 final int prime = 31;
155 int result = 1;
156 result = prime * result + ((issues == null) ? 0 : issues.hashCode());
157 result = prime * result
158 + ((utilities == null) ? 0 : utilities.hashCode());
159 return result;
160 }
161
162 @Override
163 public boolean equals(Object obj) {
164 if (this == obj)
165 return true;
166 if (obj == null)
167 return false;
168 if (getClass() != obj.getClass())
169 return false;
170 PartsUtilities other = (PartsUtilities) obj;
171 if (issues == null) {
172 if (other.issues != null)
173 return false;
174 } else if (!issues.equals(other.issues))
175 return false;
176 if (utilities == null) {
177 if (other.utilities != null)
178 return false;
179 } else if (!utilities.equals(other.utilities))
180 return false;
181 return true;
182 }
183
184 @Override
185 public @NonNull String toString() {
186 return "PartsUtilities[" + issues + "," + utilities + "]";
187 }
188
189 private void checkUtilities() {
190 /*#PY
191 * if True in (x==None or x<0 pr x>1 for x in self._utilities.values():
192 * raise ValueError("part weights must all be in [0,1]")
193 */
194 if (utilities.values().stream()
195 .anyMatch(v -> v == null || v.compareTo(BigDecimal.ZERO) < 0
196 || v.compareTo(BigDecimal.ONE) > 0)) {
197 throw new IllegalArgumentException(
198 "part weights must all be in [0,1]");
199 }
200 }
201
202 private static @NonNull Map<@NonNull ProductOfValue, @NonNull BigDecimal> list2map(
203 @NonNull List<@NonNull PartUtil> list) {
204 final @NonNull Map<@NonNull ProductOfValue, @NonNull BigDecimal> map = new HashMap<>();
205 for (final @NonNull PartUtil partutil : list) {
206 map.put(new ProductOfValue(partutil.getValues()),
207 partutil.getUtil());
208 }
209 return map;
210 }
211
212 @NonNull
213 /**
214 *
215 * @return the max utility of all values contained here.
216 */
217 public BigDecimal getMaxUtility() {
218 @NonNull
219 BigDecimal maxutil = BigDecimal.ZERO;
220 for (@NonNull
221 ProductOfValue vakye : utilities.keySet()) {
222 if (utilities.get(vakye).compareTo(maxutil) > 0) {
223 maxutil = utilities.get(vakye);
224 }
225 }
226 return maxutil;
227 }
228
229}
230
231@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, isGetterVisibility = Visibility.NONE)
232/**
233 * contains list of values, and the utility for this combi of values. The values
234 * make only sense with a corresponding list of issues, but that is managed in
235 * (see {@link PartsUtilities}.
236 * <p>
237 * immutable.
238 */
239class PartUtil {
240 private final @NonNull List<@NonNull Value> values;
241
242 private final @NonNull BigDecimal util;
243
244 @JsonCreator
245 public PartUtil(
246 @JsonProperty("values") @NonNull List<@NonNull Value> values,
247 @JsonProperty("util") @NonNull BigDecimal util) {
248 this.values = values;
249 this.util = util;
250 }
251
252 public @NonNull List<@NonNull Value> getValues() {
253 return values;
254 }
255
256 public @NonNull BigDecimal getUtil() {
257 return util;
258 }
259}
Note: See TracBrowser for help on using the repository browser.