source: src/main/java/genius/core/Bid.java@ 184

Last change on this file since 184 was 181, checked in by Tim Baarslag, 6 years ago

Extended UncertaintyAgentExample

File size: 8.0 KB
Line 
1package genius.core;
2
3import java.util.List;
4
5import java.util.ArrayList;
6import java.util.Collection;
7import java.util.HashMap;
8import java.util.Iterator;
9import java.util.Map;
10import java.util.Map.Entry;
11import java.util.Set;
12
13import java.io.Serializable;
14
15import javax.xml.bind.annotation.XmlAttribute;
16import javax.xml.bind.annotation.XmlElement;
17import javax.xml.bind.annotation.XmlElementRef;
18import javax.xml.bind.annotation.XmlRootElement;
19import javax.xml.bind.annotation.adapters.XmlAdapter;
20import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
21
22import genius.core.analysis.pareto.IssueValue;
23import genius.core.issue.Issue;
24import genius.core.issue.Value;
25
26/**
27 * A bid is a set of tuples [idnumber,value], where idnumber is the unique
28 * number of the issue, and value is the picked alternative.
29 * <p>
30 * Bid is a immutable. But you can create modified copies using
31 * {@link #putValue(int, Value)}.
32 *
33 * Bid should be considered final so do not extend this.
34 *
35 * @author Dmytro Tykhonov, Koen Hindriks
36 */
37@XmlRootElement
38public class Bid implements Serializable {
39
40 /**
41 *
42 */
43 private static final long serialVersionUID = -7723017380013100614L;
44
45 private final Domain fDomain;
46
47 /**
48 * the bid values for each IssueID
49 */
50 @XmlElement(name = "values")
51 @XmlJavaTypeAdapter(MyMapAdapter.class)
52 private HashMap<Integer, Value> fValues;
53
54 /**
55 * Only for (de)serialization
56 */
57 private Bid() {
58 fDomain = null; // keep Java happy. Serializer shall overwrite anyway
59 }
60
61 /**
62 * Create a new empty bid of which the values still must be set.
63 *
64 * @param domain
65 * the domain for this bid
66 */
67 public Bid(Domain domain) {
68 fDomain = domain;
69 fValues = new HashMap<Integer, Value>();
70 }
71
72 /**
73 * createFrom a new bid in a domain. There is only this constructor because we require that ALL
74 * values in the domain get assigned a value.
75 *
76 * @param domainP
77 * the domain in which the bid is done
78 * @param bidP
79 * HashMap, which is a set of pairs [issueID,value]
80 */
81 public Bid(Domain domainP, HashMap<Integer, Value> bidP) {
82 this.fDomain = domainP;
83 fValues = bidP;
84 }
85
86 /**
87 * create bid from set of {@link IssueValue}s
88 *
89 * @param domain
90 * the {@link Domain}
91 * @param values
92 * a {@link Collection} of {@link IssueValue}s
93 */
94 public Bid(Domain domain, Collection<IssueValue> values) {
95 if (domain == null)
96 throw new NullPointerException("null domain");
97 if (values == null)
98 throw new NullPointerException("null values");
99
100 this.fDomain = domain;
101 fValues = new HashMap<>();
102 for (IssueValue iv : values) {
103 fValues.put(iv.getIssue().getNumber(), iv.getValue());
104 }
105 }
106
107 /**
108 * This method clones the given bid.
109 *
110 * @param bid
111 * the bid to clone
112 */
113 public Bid(Bid bid) {
114
115 fDomain = bid.fDomain;
116 fValues = (HashMap<Integer, Value>) bid.fValues.clone();
117 }
118
119 /**
120 * @param issueNr
121 * number of an issue.
122 * @return the picked value for given issue idnumber
123 * @throws IllegalArgumentException
124 * if there exist no issue with the given number.
125 */
126 public Value getValue(int issueNr) {
127 Value v = fValues.get(issueNr);
128 if (v == null) {
129 if (fDomain.getIssues().get(issueNr) == null)
130 throw new IllegalArgumentException("Bid.getValue: issue " + issueNr + " does not exist at all");
131 throw new IllegalStateException("There is no evaluator for issue " + issueNr);
132 }
133 return v;
134 }
135
136 /**
137 * @param issue the issue
138 * @return the picked value for given issue
139 * @throws IllegalArgumentException
140 * if there exist no issue with the given number.
141 */
142 public Value getValue(Issue issue)
143 {
144 return getValue(issue.getNumber());
145 }
146
147 /**
148 * @param issue the issue corresponding to the value.
149 * This is needed because the same values can occur multiple times in a bid
150 * @param value
151 * @return Whether this bid has a value selected for an issue
152 */
153 public boolean containsValue(Issue issue, Value value)
154 {
155 return getValue(issue).equals(value);
156 }
157
158 /**
159 * @param issueId
160 * unique ID of an issue.
161 * @param pValue
162 * value of the issue.
163 * @return new Bid as the current bid but with the value of the issue with
164 * the given issueID to the given value
165 * @throws IllegalArgumentException
166 * if there exist no issue with the given number.
167 */
168 public Bid putValue(int issueId, Value pValue) {
169 if (fValues.get(issueId).getType() != pValue.getType()) {
170 // FIXME
171 // if (fDomain.getIssue(issueId).getType() != pValue.getType()) {
172 throw new IllegalArgumentException("expected value of type " + fDomain.getIssues().get(issueId).getType()
173 + " but got " + pValue + " of type " + pValue.getType());
174 }
175 HashMap<Integer, Value> newValues = new HashMap<Integer, Value>(fValues);
176 newValues.put(issueId, pValue);
177 return new Bid(fDomain, newValues);
178 }
179
180 public String toString() {
181 String s = "Bid[";
182 Set<Entry<Integer, Value>> value_set = fValues.entrySet();
183 Iterator<Entry<Integer, Value>> value_it = value_set.iterator();
184 int i = 0;
185 while (value_it.hasNext()) {
186 int ind = ((Entry<Integer, Value>) value_it.next()).getKey();
187 Object tmpobj = fDomain.getObjectivesRoot().getObjective(ind);
188 if (tmpobj != null) {
189 String issueName = fDomain.getObjectivesRoot().getObjective(ind).getName();
190 s += (i++ > 0 ? ", " : "") + issueName + ": " + fValues.get(ind);
191 } else {
192 System.out.println("objective with index " + ind + " does not exist");
193 }
194 }
195 s = s + "]";
196 return s;
197 }
198
199 /**
200 * @param pBid
201 * to which this bid must be compared.
202 * @return true if the values of this and the given bid are equal.
203 */
204 public boolean equals(Bid pBid) {
205 if (pBid == null)
206 return false;
207 return fValues.equals(pBid.fValues);
208 }
209
210 /*
211 * (non-Javadoc)
212 *
213 * @see java.lang.Object#equals(java.lang.Object)
214 */
215 @Override
216 public boolean equals(Object obj) {
217 if (obj instanceof Bid)
218 return equals((Bid) obj);
219 return false;
220 }
221
222 /**
223 * @return a (copy of ) the list of all values in this bid. FIXME we really
224 * should return an immutable {@link Map} here but that may break
225 * many agents.
226 */
227
228 public HashMap<Integer, Value> getValues() {
229 return new HashMap<Integer, Value>(fValues);
230 }
231
232 // Reyhan: add this method
233 public List<Issue> getIssues() {
234 return fDomain.getIssues();
235 }
236
237 public Domain getDomain() {
238 return fDomain;
239 }
240
241 /**
242 * Counts the number of equal values with another bid (assuming they are defined on the same domain)
243 */
244 public int countEqualValues(Bid b)
245 {
246 int count = 0;
247 for (Integer v : fValues.keySet())
248 {
249 if (this.fValues.get(v).equals(b.fValues.get(v)))
250 count++;
251 }
252 return count;
253 }
254
255 @Override
256 public int hashCode() {
257 int code = 0;
258 for (Entry<Integer, Value> lEntry : fValues.entrySet()) {
259 code = code + lEntry.getValue().hashCode();
260 }
261 return code;// fValues.hashCode();
262 }
263
264}
265
266class MyMapAdapter extends XmlAdapter<Temp, Map<Integer, Value>> {
267
268 @Override
269 public Temp marshal(Map<Integer, Value> arg0) throws Exception {
270 Temp temp = new Temp();
271 for (Entry<Integer, Value> entry : arg0.entrySet()) {
272 temp.entry.add(new Item(entry.getKey(), entry.getValue()));
273 }
274 return temp;
275 }
276
277 @Override
278 public Map<Integer, Value> unmarshal(Temp arg0) throws Exception {
279 Map<Integer, Value> map = new HashMap<Integer, Value>();
280 for (Item item : arg0.entry) {
281 map.put(item.key, item.value);
282 }
283 return map;
284 }
285
286}
287
288class Temp {
289 @XmlElement(name = "issue")
290 public List<Item> entry;
291
292 public Temp() {
293 entry = new ArrayList<Item>();
294 }
295
296}
297
298@XmlRootElement
299class Item {
300 @XmlAttribute(name = "index")
301 public Integer key;
302
303 @XmlElementRef
304 public Value value;
305
306 public Item() {
307 }
308
309 public Item(Integer key, Value val) {
310 this.key = key;
311 this.value = val;
312 }
313}
Note: See TracBrowser for help on using the repository browser.