source: src/main/java/agents/ai2014/group11/OpponentUtilityModel.java@ 127

Last change on this file since 127 was 127, checked in by Wouter Pasman, 6 years ago

#41 ROLL BACK of rev.126 . So this version is equal to rev. 125

File size: 7.6 KB
Line 
1package agents.ai2014.group11;
2
3import java.util.HashMap;
4import java.util.Map.Entry;
5
6import agents.ai2014.group11.OpponentBidHistory.BidModificationStrategy;
7import genius.core.Bid;
8import genius.core.Domain;
9import genius.core.issue.ISSUETYPE;
10import genius.core.issue.Issue;
11import genius.core.issue.IssueDiscrete;
12import genius.core.issue.Value;
13import genius.core.issue.ValueDiscrete;
14
15/**
16 * A model of an opponent, which tries to estimate the utility for each bid.
17 *
18 * NOTE: Only supports (explicitly) Discrete Issue values
19 */
20public class OpponentUtilityModel {
21
22 private OpponentBidHistory allBids;
23 private OpponentBidHistory acceptedBids;
24
25 private HashMap<IssueDiscrete, Double> issueWeights;
26 private HashMap<IssueDiscrete, HashMap<ValueDiscrete, Integer>> valueCounts;
27
28 public OpponentUtilityModel(Domain d) throws InvalidDomainException {
29
30 allBids = new OpponentBidHistory();
31 acceptedBids = new OpponentBidHistory();
32
33 issueWeights = new HashMap<IssueDiscrete, Double>();
34 valueCounts = new HashMap<IssueDiscrete, HashMap<ValueDiscrete, Integer>>();
35
36 double defaultIssueWeight = 1.0 / d.getIssues().size();
37
38 for (Issue i : d.getIssues()) {
39 switch (i.getType()) {
40 case DISCRETE:
41 IssueDiscrete id = (IssueDiscrete) i;
42 issueWeights.put(id, defaultIssueWeight);
43
44 HashMap<ValueDiscrete, Integer> valueCount = new HashMap<ValueDiscrete, Integer>();
45 for (int j = 0; j < id.getNumberOfValues(); j++)
46 valueCount.put(id.getValue(j), 0);
47
48 valueCounts.put(id, valueCount);
49 break;
50 default:
51 throw new InvalidDomainException(i.getType());
52 }
53 }
54 }
55
56 /**
57 * Try to determine what kind of strategy the opponent is using.
58 *
59 * This is done by checking the difference in values between the
60 * opponent's current and the opponent's own last offer,
61 * and between the opponent's current and the overall last offer.
62 *
63 * @return the strategy the opponent is most likely using.
64 */
65 public BidModificationStrategy getMostLikelyStrategy() {
66 return allBids.getMostLikelyStrategy();
67 }
68
69 /**
70 * Add a bid that is accepted by this opponent
71 *
72 * @param acceptBid
73 * @throws InvalidBidException
74 */
75 public void addAccept(Bid acceptBid) throws InvalidBidException {
76 acceptedBids.add(acceptBid, acceptBid);
77 updateCountersFromBid(acceptBid);
78 updateCountersFromBid(acceptBid);
79 }
80
81 /**
82 * Add a bid that is offered by this opponent
83 *
84 * @param previousBid the bid that was done before
85 * @param offerBid the bid that was offered
86 * @throws InvalidBidException
87 */
88 public void addOffer(Bid previousBid, Bid offerBid)
89 throws InvalidBidException {
90 allBids.add(previousBid, offerBid);
91 updateCountersFromBid(offerBid);
92 }
93
94 /**
95 * Update the internal parameters that count
96 * how many times each value is offered by this opponent
97 *
98 * @param b the new bid
99 * @throws InvalidBidException
100 */
101 private void updateCountersFromBid(Bid b) throws InvalidBidException {
102 for (Issue i : b.getIssues()) {
103 switch (i.getType()) {
104 case DISCRETE:
105 try {
106 HashMap<ValueDiscrete, Integer> valueCount = valueCounts
107 .get((IssueDiscrete) i);
108 ValueDiscrete v = (ValueDiscrete) b.getValue(i.getNumber());
109 if (v == null) {
110 throw new InvalidBidException(i.getType());
111 } else {
112 int currentCount = valueCount.get(v);
113 currentCount++;
114 valueCount.put(v, currentCount);
115 }
116 } catch (Exception e) {
117 e.printStackTrace();
118 }
119 break;
120 default:
121 throw new InvalidBidException(i.getType());
122 }
123 }
124 updateWeightsFromCounters();
125 }
126
127 /**
128 * Update the model of value weights that is determined from the counters
129 */
130 private void updateWeightsFromCounters() {
131 double totalAmountOfMeasurementsPerIssue = allBids.getSize();
132
133 HashMap<IssueDiscrete, Double> issueVariances = new HashMap<IssueDiscrete, Double>();
134
135 for (Entry<IssueDiscrete, HashMap<ValueDiscrete, Integer>> e : valueCounts
136 .entrySet()) {
137 HashMap<ValueDiscrete, Integer> valueCount = e.getValue();
138
139 double[] issueValueCounts = new double[valueCount.size()];
140 int counter = 0;
141 for (Entry<ValueDiscrete, Integer> entry : valueCount.entrySet()) {
142 // dividing by the total to ensure that the result and total sum
143 // < 1;
144 issueValueCounts[counter] = entry.getValue()
145 / totalAmountOfMeasurementsPerIssue;
146 counter++;
147 }
148
149 issueVariances.put(e.getKey(),
150 Statistics.getVariance(issueValueCounts));
151
152 }
153
154 double totalVariance = 0;
155 for (Entry<IssueDiscrete, Double> e : issueVariances.entrySet()) {
156 totalVariance += e.getValue();
157 }
158
159 double amountOfRoomLeftToMakeVarancesSumUpToOne = 1 - totalVariance;
160 double extraFreeVariancePointsPerIssue = amountOfRoomLeftToMakeVarancesSumUpToOne
161 / issueVariances.size();
162
163 for (Entry<IssueDiscrete, Double> e : issueVariances.entrySet()) {
164 double weight = e.getValue() + extraFreeVariancePointsPerIssue;
165 issueWeights.put(e.getKey(), weight);
166 }
167 }
168
169 /**
170 * Determine the utility for a bid based on the modeled opponent
171 * @param b the input bid
172 * @return the utility for the input bid for this opponent model
173 * @throws InvalidBidException
174 */
175 public double getUtility(Bid b) throws InvalidBidException {
176 double utility = 0;
177 for (Issue i : b.getIssues()) {
178 switch (i.getType()) {
179 case DISCRETE:
180 IssueDiscrete id = (IssueDiscrete) i;
181 utility += issueWeights.get(id) * getIssueEvaluation(id, b);
182 break;
183 default:
184 throw new InvalidBidException(i.getType());
185 }
186 }
187
188 return utility;
189 }
190
191 /**
192 * Get the valuation of issue in a certain bid, based on the opponent model
193 * @param i
194 * @param b
195 * @return
196 * @throws InvalidBidException
197 */
198 private double getIssueEvaluation(IssueDiscrete i, Bid b)
199 throws InvalidBidException {
200 try {
201 Value v = b.getValue(i.getNumber());
202 switch (v.getType()) {
203 case DISCRETE:
204 ValueDiscrete vd = (ValueDiscrete) v;
205 HashMap<ValueDiscrete, Integer> valueCount = valueCounts.get(i);
206 double max = getMaxValue(valueCount);
207 return valueCount.get(vd) / max;
208 default:
209 throw new InvalidBidException(v.getType());
210 }
211 } catch (Exception e) {
212 if (e instanceof InvalidBidException)
213 throw (InvalidBidException) e;
214 else
215 e.printStackTrace();
216 return 0;
217 }
218 }
219
220 /**
221 * Get the maximum chosen value
222 * @param counts
223 * @return
224 */
225 private double getMaxValue(HashMap<ValueDiscrete, Integer> counts) {
226 double max = 0;
227 for (Entry<ValueDiscrete, Integer> e : counts.entrySet())
228 max = Math.max(max, e.getValue());
229 return max;
230 }
231
232 class InvalidDomainException extends Exception {
233 private static final long serialVersionUID = -6947113453964713361L;
234
235 public InvalidDomainException(ISSUETYPE issueType) {
236 super("Domains with issues of type " + issueType
237 + " are not supported!");
238 }
239 }
240
241 class InvalidBidException extends Exception {
242 private static final long serialVersionUID = -801096984481420822L;
243
244 public InvalidBidException(ISSUETYPE issueType) {
245 super("Bids with issues of type " + issueType
246 + " are not supported!");
247 }
248 }
249
250 public String toString() {
251 String result = "";
252 for(Entry<IssueDiscrete, Double> e : issueWeights.entrySet()) {
253 IssueDiscrete issue = e.getKey();
254 result += issue + " (" + ((double) Math.round(e.getValue() * 1000) / 1000) + ") : ";
255 for(Entry<ValueDiscrete, Integer> e2 : valueCounts.get(issue).entrySet()) {
256 result += "<\"" + e2.getKey() + "\", " + e2.getValue() + "> ";
257 }
258 result += "\n";
259 }
260
261 return result;
262 }
263}
Note: See TracBrowser for help on using the repository browser.