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

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

Bid ranking class + clean-up

File size: 7.4 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 issueId
138 * unique ID of an issue.
139 * @param pValue
140 * value of the issue.
141 * @return new Bid as the current bid but with the value of the issue with
142 * the given issueID to the given value
143 * @throws IllegalArgumentException
144 * if there exist no issue with the given number.
145 */
146 public Bid putValue(int issueId, Value pValue) {
147 if (fValues.get(issueId).getType() != pValue.getType()) {
148 // FIXME
149 // if (fDomain.getIssue(issueId).getType() != pValue.getType()) {
150 throw new IllegalArgumentException("expected value of type " + fDomain.getIssues().get(issueId).getType()
151 + " but got " + pValue + " of type " + pValue.getType());
152 }
153 HashMap<Integer, Value> newValues = new HashMap<Integer, Value>(fValues);
154 newValues.put(issueId, pValue);
155 return new Bid(fDomain, newValues);
156 }
157
158 public String toString() {
159 String s = "Bid[";
160 Set<Entry<Integer, Value>> value_set = fValues.entrySet();
161 Iterator<Entry<Integer, Value>> value_it = value_set.iterator();
162 int i = 0;
163 while (value_it.hasNext()) {
164 int ind = ((Entry<Integer, Value>) value_it.next()).getKey();
165 Object tmpobj = fDomain.getObjectivesRoot().getObjective(ind);
166 if (tmpobj != null) {
167 String issueName = fDomain.getObjectivesRoot().getObjective(ind).getName();
168 s += (i++ > 0 ? ", " : "") + issueName + ": " + fValues.get(ind);
169 } else {
170 System.out.println("objective with index " + ind + " does not exist");
171 }
172 }
173 s = s + "]";
174 return s;
175 }
176
177 /**
178 * @param pBid
179 * to which this bid must be compared.
180 * @return true if the values of this and the given bid are equal.
181 */
182 public boolean equals(Bid pBid) {
183 if (pBid == null)
184 return false;
185 return fValues.equals(pBid.fValues);
186 }
187
188 /*
189 * (non-Javadoc)
190 *
191 * @see java.lang.Object#equals(java.lang.Object)
192 */
193 @Override
194 public boolean equals(Object obj) {
195 if (obj instanceof Bid)
196 return equals((Bid) obj);
197 return false;
198 }
199
200 /**
201 * @return a (copy of ) the list of all values in this bid. FIXME we really
202 * should return an immutable {@link Map} here but that may break
203 * many agents.
204 */
205
206 public HashMap<Integer, Value> getValues() {
207 return new HashMap<Integer, Value>(fValues);
208 }
209
210 // Reyhan: add this method
211 public List<Issue> getIssues() {
212 return fDomain.getIssues();
213 }
214
215 public Domain getDomain() {
216 return fDomain;
217 }
218
219 /**
220 * Counts the number of equal values with another bid (assuming they are defined on the same domain)
221 */
222 public int countEqualValues(Bid b)
223 {
224 int count = 0;
225 for (Integer v : fValues.keySet())
226 {
227 if (this.fValues.get(v).equals(b.fValues.get(v)))
228 count++;
229 }
230 return count;
231 }
232
233 @Override
234 public int hashCode() {
235 int code = 0;
236 for (Entry<Integer, Value> lEntry : fValues.entrySet()) {
237 code = code + lEntry.getValue().hashCode();
238 }
239 return code;// fValues.hashCode();
240 }
241
242}
243
244class MyMapAdapter extends XmlAdapter<Temp, Map<Integer, Value>> {
245
246 @Override
247 public Temp marshal(Map<Integer, Value> arg0) throws Exception {
248 Temp temp = new Temp();
249 for (Entry<Integer, Value> entry : arg0.entrySet()) {
250 temp.entry.add(new Item(entry.getKey(), entry.getValue()));
251 }
252 return temp;
253 }
254
255 @Override
256 public Map<Integer, Value> unmarshal(Temp arg0) throws Exception {
257 Map<Integer, Value> map = new HashMap<Integer, Value>();
258 for (Item item : arg0.entry) {
259 map.put(item.key, item.value);
260 }
261 return map;
262 }
263
264}
265
266class Temp {
267 @XmlElement(name = "issue")
268 public List<Item> entry;
269
270 public Temp() {
271 entry = new ArrayList<Item>();
272 }
273
274}
275
276@XmlRootElement
277class Item {
278 @XmlAttribute(name = "index")
279 public Integer key;
280
281 @XmlElementRef
282 public Value value;
283
284 public Item() {
285 }
286
287 public Item(Integer key, Value val) {
288 this.key = key;
289 this.value = val;
290 }
291}
Note: See TracBrowser for help on using the repository browser.