1 | package agents.ai2014.group8;
|
---|
2 |
|
---|
3 | import java.util.ArrayList;
|
---|
4 | import java.util.Comparator;
|
---|
5 | import java.util.HashMap;
|
---|
6 | import java.util.Iterator;
|
---|
7 | import java.util.List;
|
---|
8 | import java.util.Map;
|
---|
9 | import java.util.TreeMap;
|
---|
10 |
|
---|
11 | import genius.core.AgentID;
|
---|
12 | import genius.core.Bid;
|
---|
13 | import genius.core.issue.Issue;
|
---|
14 | import genius.core.issue.Value;
|
---|
15 |
|
---|
16 | /**
|
---|
17 | * Class that models opponent preference profile
|
---|
18 | *
|
---|
19 | */
|
---|
20 | public class OpponentModel {
|
---|
21 |
|
---|
22 | // agent being modeled
|
---|
23 | public AgentID agent;
|
---|
24 |
|
---|
25 | // list of bids made by agent
|
---|
26 | private List<Bid> bidsMadeByAgent;
|
---|
27 |
|
---|
28 | // list of issues and their associated weights
|
---|
29 | private Map<Issue, Double> issueWeights;
|
---|
30 |
|
---|
31 | // mapping of Issues to their values and number of bids made for each value
|
---|
32 | private Map<Issue, Map<Value, Integer>> issueValueFrequencies;
|
---|
33 |
|
---|
34 | // mapping of Issues to their values and number of bids made for each value
|
---|
35 | private Map<Issue, Map<Value, Integer>> sortedIssueValueFrequencies;
|
---|
36 |
|
---|
37 | // mapping of Issues to their values and number of bids made for each value
|
---|
38 | private Map<Issue, Map<Value, Double>> issueEvaluationValues;
|
---|
39 |
|
---|
40 | /**
|
---|
41 | * class constructor
|
---|
42 | *
|
---|
43 | * @param opponentAgent
|
---|
44 | * agent whose preference is being modeled
|
---|
45 | */
|
---|
46 | public OpponentModel(AgentID opponentAgent, List<Issue> issues) {
|
---|
47 |
|
---|
48 | this.agent = opponentAgent;
|
---|
49 |
|
---|
50 | this.bidsMadeByAgent = new ArrayList<Bid>();
|
---|
51 |
|
---|
52 | // get the issues that are in the domain
|
---|
53 | List<Issue> issuesInDomain = issues;
|
---|
54 |
|
---|
55 | this.issueWeights = new HashMap<Issue, Double>();
|
---|
56 | this.issueValueFrequencies = new HashMap<Issue, Map<Value, Integer>>();
|
---|
57 | this.issueEvaluationValues = new HashMap<Issue, Map<Value, Double>>();
|
---|
58 |
|
---|
59 | // for each issue in domain, add an entry in list of preferences
|
---|
60 | // initialize each issue with the initial weights
|
---|
61 | for (Issue issue : issuesInDomain) {
|
---|
62 | this.issueWeights.put(issue, 0.0);
|
---|
63 |
|
---|
64 | this.issueValueFrequencies
|
---|
65 | .put(issue, new HashMap<Value, Integer>());
|
---|
66 |
|
---|
67 | this.issueEvaluationValues.put(issue, new HashMap<Value, Double>());
|
---|
68 | }
|
---|
69 | }
|
---|
70 |
|
---|
71 | /**
|
---|
72 | * store bids made by this opponent for preference analysis
|
---|
73 | *
|
---|
74 | * @param bid
|
---|
75 | */
|
---|
76 | public void AddBid(Bid bid) {
|
---|
77 | if (bid != null) {
|
---|
78 | this.bidsMadeByAgent.add(bid);
|
---|
79 |
|
---|
80 | this.UpdateIssueValueFrequencies(bid);
|
---|
81 | }
|
---|
82 |
|
---|
83 | this.AnalyzeIssueValuePreferences();
|
---|
84 | }
|
---|
85 |
|
---|
86 | /**
|
---|
87 | * update the count of bids made for every issue value
|
---|
88 | *
|
---|
89 | * @param newBid
|
---|
90 | * the bid based on which to update frequencies
|
---|
91 | */
|
---|
92 | public void UpdateIssueValueFrequencies(Bid newBid) {
|
---|
93 | for (int i = 0; i < newBid.getIssues().size(); i++) {
|
---|
94 | Issue issue = newBid.getIssues().get(i);
|
---|
95 | Value issueValue = null;
|
---|
96 |
|
---|
97 | try {
|
---|
98 | issueValue = newBid.getValue(i + 1);
|
---|
99 | } catch (Exception e) {
|
---|
100 | e.printStackTrace();
|
---|
101 | return;
|
---|
102 | }
|
---|
103 |
|
---|
104 | Map<Value, Integer> valueMapping = issueValueFrequencies.get(issue);
|
---|
105 |
|
---|
106 | int currentFrequency = 0;
|
---|
107 | if (valueMapping.containsKey(issueValue)) {
|
---|
108 | currentFrequency = valueMapping.get(issueValue);
|
---|
109 | currentFrequency++;
|
---|
110 |
|
---|
111 | valueMapping.put(issueValue, currentFrequency);
|
---|
112 | } else {
|
---|
113 | currentFrequency++;
|
---|
114 | valueMapping.put(issueValue, currentFrequency);
|
---|
115 | }
|
---|
116 | }
|
---|
117 | }
|
---|
118 |
|
---|
119 | /**
|
---|
120 | * method to analyze agent issue value preferences by bid frequency analysis
|
---|
121 | */
|
---|
122 | public void AnalyzeIssueValuePreferences() {
|
---|
123 | Iterator it = this.issueValueFrequencies.entrySet().iterator();
|
---|
124 |
|
---|
125 | sortedIssueValueFrequencies = new HashMap<Issue, Map<Value, Integer>>();
|
---|
126 |
|
---|
127 | while (it.hasNext()) {
|
---|
128 | Map.Entry<Issue, Map<Value, Integer>> pair = (Map.Entry<Issue, Map<Value, Integer>>) it
|
---|
129 | .next();
|
---|
130 | Issue issue = pair.getKey();
|
---|
131 | Map<Value, Integer> valueFrequencies = pair.getValue();
|
---|
132 |
|
---|
133 | // assign issue weights as inverse of number of different choices
|
---|
134 | // made for the issue
|
---|
135 | double issueWeight = 1 / (double) valueFrequencies.size();
|
---|
136 | this.issueWeights.put(issue, issueWeight);
|
---|
137 |
|
---|
138 | // sort the issue values by frequency of bids that target the
|
---|
139 | // particular value
|
---|
140 | ValueComparator bvc = new ValueComparator(valueFrequencies);
|
---|
141 | TreeMap<Value, Integer> sorted_map = new TreeMap<Value, Integer>(
|
---|
142 | bvc);
|
---|
143 | sorted_map.putAll(valueFrequencies);
|
---|
144 |
|
---|
145 | int highestFrequency = sorted_map.firstEntry().getValue();
|
---|
146 | Iterator valueIterator = sorted_map.entrySet().iterator();
|
---|
147 | Map<Value, Double> evals = new HashMap<Value, Double>();
|
---|
148 |
|
---|
149 | // evaluation value of an issue value is the number of times the
|
---|
150 | // value was bid for
|
---|
151 | // divided by the number of times the highest bid value was bid for
|
---|
152 | while (valueIterator.hasNext()) {
|
---|
153 | Map.Entry<Value, Integer> valuePair = (Map.Entry<Value, Integer>) valueIterator
|
---|
154 | .next();
|
---|
155 |
|
---|
156 | int valueFrequency = valuePair.getValue();
|
---|
157 |
|
---|
158 | double evaluationValue = valueFrequency
|
---|
159 | / (double) highestFrequency;
|
---|
160 |
|
---|
161 | evals.put(valuePair.getKey(), evaluationValue);
|
---|
162 | }
|
---|
163 |
|
---|
164 | this.issueEvaluationValues.put(issue, evals);
|
---|
165 | this.sortedIssueValueFrequencies.put(issue, sorted_map);
|
---|
166 | }
|
---|
167 |
|
---|
168 | this.UpdateIssueWeights();
|
---|
169 | }
|
---|
170 |
|
---|
171 | /**
|
---|
172 | * method to estimate issue weights
|
---|
173 | */
|
---|
174 | public void UpdateIssueWeights() {
|
---|
175 | Iterator it = this.issueWeights.entrySet().iterator();
|
---|
176 | double weightSum = 0.0;
|
---|
177 |
|
---|
178 | while (it.hasNext()) {
|
---|
179 | Map.Entry<Value, Double> weightPair = (Map.Entry<Value, Double>) it
|
---|
180 | .next();
|
---|
181 |
|
---|
182 | weightSum += weightPair.getValue();
|
---|
183 | }
|
---|
184 |
|
---|
185 | it = this.issueWeights.entrySet().iterator();
|
---|
186 |
|
---|
187 | while (it.hasNext()) {
|
---|
188 | Map.Entry<Value, Double> weightPair = (Map.Entry<Value, Double>) it
|
---|
189 | .next();
|
---|
190 |
|
---|
191 | weightPair.setValue(weightPair.getValue() / weightSum);
|
---|
192 | }
|
---|
193 | }
|
---|
194 |
|
---|
195 | /**
|
---|
196 | * method to evaluate the utility of a bid for this agent
|
---|
197 | *
|
---|
198 | * @param bidToEvaluate
|
---|
199 | * bid whose utility to evaluate
|
---|
200 | * @return utility of bid for this agent
|
---|
201 | */
|
---|
202 | public double EvaluateBidUtility(Bid bidToEvaluate) {
|
---|
203 | double utilityValue = 0.0;
|
---|
204 |
|
---|
205 | // utility value = u1 * w1 + u2 * w2 + ...
|
---|
206 | for (int i = 0; i < bidToEvaluate.getIssues().size(); i++) {
|
---|
207 | Issue issue = bidToEvaluate.getIssues().get(i);
|
---|
208 | Value issueValue = null;
|
---|
209 |
|
---|
210 | try {
|
---|
211 | issueValue = bidToEvaluate.getValue(i + 1);
|
---|
212 | } catch (Exception e) {
|
---|
213 | e.printStackTrace();
|
---|
214 | }
|
---|
215 |
|
---|
216 | if (issueValue != null) {
|
---|
217 | double issueWeight = this.issueWeights.get(issue);
|
---|
218 |
|
---|
219 | Map<Value, Double> evaluationValues = this.issueEvaluationValues
|
---|
220 | .get(issue);
|
---|
221 | double evaluationValue = 0.0;
|
---|
222 |
|
---|
223 | if (evaluationValues.isEmpty() == false
|
---|
224 | && evaluationValues.containsKey(issueValue)) {
|
---|
225 | evaluationValue = evaluationValues.get(issueValue);
|
---|
226 | }
|
---|
227 |
|
---|
228 | utilityValue += issueWeight * evaluationValue;
|
---|
229 | }
|
---|
230 | }
|
---|
231 |
|
---|
232 | return utilityValue;
|
---|
233 | }
|
---|
234 |
|
---|
235 | /**
|
---|
236 | * overridden equals method to compare two OpponentModel objects they are
|
---|
237 | * equal if they model the same agent, determined by agentID
|
---|
238 | *
|
---|
239 | * @param object
|
---|
240 | * object being compared
|
---|
241 | */
|
---|
242 | @Override
|
---|
243 | public boolean equals(Object object) {
|
---|
244 | boolean result = false;
|
---|
245 |
|
---|
246 | if (object instanceof OpponentModel) {
|
---|
247 | OpponentModel toCompare = (OpponentModel) object;
|
---|
248 |
|
---|
249 | if (this.agent.equals(toCompare.agent)) {
|
---|
250 | result = true;
|
---|
251 | }
|
---|
252 | }
|
---|
253 |
|
---|
254 | return result;
|
---|
255 | }
|
---|
256 |
|
---|
257 | /**
|
---|
258 | * Class that is used to compare issue values
|
---|
259 | *
|
---|
260 | */
|
---|
261 | class ValueComparator implements Comparator<Value> {
|
---|
262 | Map<Value, Integer> base;
|
---|
263 |
|
---|
264 | public ValueComparator(Map<Value, Integer> base) {
|
---|
265 | this.base = base;
|
---|
266 | }
|
---|
267 |
|
---|
268 | // Note: this comparator imposes orderings that are inconsistent with
|
---|
269 | // equals.
|
---|
270 | public int compare(Value a, Value b) {
|
---|
271 | if (base.get(a) >= base.get(b)) {
|
---|
272 | return -1;
|
---|
273 | } else {
|
---|
274 | return 1;
|
---|
275 | }
|
---|
276 | }
|
---|
277 | }
|
---|
278 | }
|
---|