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

Last change on this file since 126 was 126, checked in by Aron Hammond, 6 years ago

Added function to calculate opposition to MultiLateralAnalysis.java

Moved code to add RLBOA listeners to RLBOAUtils is misc package

Added input for strategyParameters to SessionPanel (gui)

!! close SessionInfo after tournament; this caused /tmp/ to fill up with GeniusData files

Our own package:

  • Added opponents and strategies that are mentioned in the report
  • Change class hierarchy, agents can now extend from RLBOAagentBilateral to inherit RL functionality.
  • States extend from AbstractState
File size: 7.3 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.