source: src/main/java/parties/in4010/q12015/group5/OpponentModel.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.3 KB
Line 
1package parties.in4010.q12015.group5;
2
3import java.util.ArrayList;
4import java.util.HashMap;
5import java.util.List;
6import java.util.Map;
7
8import genius.core.Bid;
9import genius.core.Domain;
10import genius.core.issue.Issue;
11import genius.core.issue.IssueDiscrete;
12import genius.core.issue.Objective;
13import genius.core.issue.Value;
14import genius.core.issue.ValueDiscrete;
15import genius.core.utility.AdditiveUtilitySpace;
16import genius.core.utility.Evaluator;
17import genius.core.utility.EvaluatorDiscrete;
18
19/**
20 * This class represents a model of the issue and value weights of an Opponent.
21 * This model is built using the Frequency analysis method.
22 */
23public class OpponentModel {
24
25 /**
26 * The history of bids this opponent has made
27 */
28 public List<Bid> bidHistory;
29
30 /**
31 * The domain we are negotiating in.
32 */
33 private Domain domain;
34
35 /**
36 * Map containing the modeled issue weight for each issue.
37 */
38 public Map<IssueDiscrete, Double> issueModel;
39
40 /**
41 * n used in the Frequency Analysis.
42 */
43 private final double n = 0.1;
44
45 /**
46 * Map containing the observed count every value has been bid.
47 */
48 public Map<IssueDiscrete, Map<ValueDiscrete, Integer>> valueCountModel;
49
50 /**
51 * Map containing the modeled value weight for each value in each issue.
52 */
53 public Map<IssueDiscrete, Map<ValueDiscrete, Double>> valueWeightModel;
54
55 /**
56 * Constructs an new OpponentModel based on the first bid.
57 *
58 * @param domain
59 * The domain we are negotiating in.
60 * @param bid
61 * The opponent's first bid.
62 * @throws Exception
63 */
64 public OpponentModel(Domain domain, Bid bid) throws Exception {
65 issueModel = new HashMap<IssueDiscrete, Double>();
66 valueCountModel = new HashMap<IssueDiscrete, Map<ValueDiscrete, Integer>>();
67 valueWeightModel = new HashMap<IssueDiscrete, Map<ValueDiscrete, Double>>();
68
69 bidHistory = new ArrayList<Bid>();
70 bidHistory.add(bid);
71 this.domain = domain;
72
73 List<Issue> issues = bid.getIssues();
74 for (Issue issue : issues) {
75 // Initialize weights evenly
76 IssueDiscrete issueDiscrete = (IssueDiscrete) issue;
77 issueModel.put(issueDiscrete, 1. / issues.size());
78
79 List<ValueDiscrete> values = issueDiscrete.getValues();
80 HashMap<ValueDiscrete, Integer> valueCountMap = new HashMap<ValueDiscrete, Integer>();
81 HashMap<ValueDiscrete, Double> valueWeightMap = new HashMap<ValueDiscrete, Double>();
82 ValueDiscrete bidValue = (ValueDiscrete) bid.getValue(issueDiscrete
83 .getNumber());
84 for (ValueDiscrete value : values) {
85 if (value.equals(bidValue)) {
86 valueCountMap.put(value, 1);
87 valueWeightMap.put(value, 1.);
88 } else {
89 valueCountMap.put(value, 0);
90 valueWeightMap.put(value, 0.);
91 }
92 }
93 valueCountModel.put(issueDiscrete, valueCountMap);
94 valueWeightModel.put(issueDiscrete, valueWeightMap);
95 }
96 }
97
98 /**
99 * @param percentage
100 * The percentage (between 0 and 1) of the list, starting from
101 * the end, that should be returned.
102 * @return Returns the last few bids from this opponent, based on the
103 * percentage.
104 */
105 public List<Bid> getBidHistory(double percentage) {
106 int historySize = bidHistory.size();
107 int fromIndex = (int) Math.floor(historySize
108 - (historySize * percentage));
109 List<Bid> newList = new ArrayList<Bid>(historySize - fromIndex);
110 for (int i = fromIndex - 1; i < historySize; i++) { // Make sure to
111 // always return one
112 newList.add(bidHistory.get(fromIndex));
113 }
114 return newList;
115 }
116
117 /**
118 * Generates an UtilitySpace that represents the modeled UtilitySpace of
119 * this opponent.
120 *
121 * @return An UtilitySpace that represents the modeled UtilitySpace of this
122 * opponent.
123 * @throws Exception
124 */
125 public AdditiveUtilitySpace getUtilitySpace() throws Exception {
126 Map<Objective, Evaluator> evaluatorMap = new HashMap<Objective, Evaluator>();
127 for (IssueDiscrete issue : issueModel.keySet()) {
128 EvaluatorDiscrete evaluator = new EvaluatorDiscrete();
129 evaluator.setWeight(issueModel.get(issue));
130 Map<ValueDiscrete, Double> valueWeightMap = valueWeightModel
131 .get(issue);
132 for (ValueDiscrete value : valueWeightMap.keySet()) {
133 evaluator.setEvaluationDouble(value, valueWeightMap.get(value));
134 }
135 evaluatorMap.put(issue, evaluator);
136 }
137 return new AdditiveUtilitySpace(domain, evaluatorMap);
138 }
139
140 /**
141 * Normalizes the issue weights in the issueModel.
142 */
143 private void normalizeWeights() {
144 double sum = 0;
145 for (IssueDiscrete v : issueModel.keySet()) {
146 sum += issueModel.get(v);
147 }
148
149 // Divide every issue weight with the sum of the weights to obtain a sum
150 // of 1.
151 for (IssueDiscrete v : issueModel.keySet()) {
152 double issueWeight = issueModel.get(v);
153 issueModel.put(v, issueWeight / sum);
154 }
155 }
156
157 /*
158 * (non-Javadoc)
159 *
160 * @see java.lang.Object#toString()
161 */
162 @Override
163 public String toString() {
164 String ret = "";
165 for (Issue issue : valueWeightModel.keySet()) {
166 ret += "Issue: " + issue.getName() + " - weight: "
167 + issueModel.get(issue) + "\n";
168 for (Value value : valueWeightModel.get(issue).keySet()) {
169 ret += "Value: " + value.toString();
170 ret += " - weight: " + valueWeightModel.get(issue).get(value)
171 + " (" + valueCountModel.get(issue).get(value) + ")\n";
172 }
173 }
174
175 return ret;
176 }
177
178 /**
179 * Updates the model with a new bid that has been received.
180 *
181 * @param bid
182 * The newest bid of our opponent.
183 * @throws Exception
184 */
185 public void updateModel(Bid bid) throws Exception {
186 Bid lastBid = bidHistory.get(bidHistory.size() - 1);
187 for (Issue issue : issueModel.keySet()) {
188 // Increase the issue weight if its value didn't change.
189 ValueDiscrete newValue = (ValueDiscrete) bid.getValue(issue
190 .getNumber());
191 ValueDiscrete oldValue = (ValueDiscrete) lastBid.getValue(issue
192 .getNumber());
193 if (newValue.equals(oldValue)) {
194 double issueWeight = issueModel.get(issue);
195 issueModel.put((IssueDiscrete) issue, issueWeight + n);
196 }
197
198 // Increase the count for the values that have been bid.
199 Map<ValueDiscrete, Integer> valueCountMap = valueCountModel
200 .get(issue);
201 int valueCount = valueCountMap.get(newValue);
202 valueCountMap.put(newValue, valueCount + 1);
203
204 // Recalculate the weights based on the counts.
205 updateValueWeights((IssueDiscrete) issue);
206 }
207
208 // Normalize the weights again so the sum is again 1.
209 normalizeWeights();
210 bidHistory.add(bid);
211 }
212
213 /**
214 * Updates the valueWeightModel based on the valueCountModel for the given
215 * issue.
216 *
217 * @param issue
218 * The issue for which the value weights should be updated.
219 */
220 private void updateValueWeights(IssueDiscrete issue) {
221 Map<ValueDiscrete, Integer> valueCountMap = valueCountModel.get(issue);
222 Map<ValueDiscrete, Double> valueWeightMap = valueWeightModel.get(issue);
223
224 int max = 0;
225 for (ValueDiscrete v : valueCountMap.keySet()) {
226 int valueCount = valueCountMap.get(v);
227 if (valueCount > max)
228 max = valueCount;
229 }
230
231 // Divide every value count with the maximum count to obtain values
232 // between 0 and 1.
233 for (ValueDiscrete v : valueCountMap.keySet()) {
234 int valueCount = valueCountMap.get(v);
235 double valueWeight = valueCount / (double) max;
236 valueWeightMap.put(v, valueWeight);
237 }
238 }
239}
Note: See TracBrowser for help on using the repository browser.