source: src/main/java/agents/ai2014/group6/Group6.java@ 61

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

Initial import : Genius 9.0.0

File size: 9.2 KB
Line 
1package agents.ai2014.group6;
2
3import java.util.ArrayList;
4import java.util.Comparator;
5import java.util.HashMap;
6import java.util.List;
7import java.util.Map;
8import java.util.Map.Entry;
9
10import genius.core.AgentID;
11import genius.core.Bid;
12import genius.core.actions.Accept;
13import genius.core.actions.Action;
14import genius.core.actions.DefaultAction;
15import genius.core.actions.Offer;
16import genius.core.issue.Issue;
17import genius.core.issue.Value;
18import genius.core.issue.ValueDiscrete;
19import genius.core.parties.AbstractNegotiationParty;
20import genius.core.parties.NegotiationInfo;
21import genius.core.timeline.DiscreteTimeline;
22import genius.core.timeline.TimeLineInfo;
23import genius.core.utility.AdditiveUtilitySpace;
24import genius.core.utility.EvaluatorDiscrete;
25
26import java.util.PriorityQueue;
27import java.util.Queue;
28
29/**
30 * This is your negotiation party. Theis agent is juggling weights so only can
31 * be used with {@link AdditiveUtilitySpace}.
32 */
33public class Group6 extends AbstractNegotiationParty {
34
35 private HashMap<Object, Action> history;
36 private Map<Object, IOpponentModel> opponentModels;
37
38 // The most recent bid that has been done (either by us or by another agent)
39 private Bid mostRecentBid;
40 private Bid ourPreviousBid;
41
42 private double reservationValue;
43
44 /**
45 * Please keep this constructor. This is called by genius.
46 *
47 * @param utilitySpace
48 * Your utility space.
49 * @param deadlines
50 * The deadlines set for this negotiation.
51 * @param timeline
52 * Value counting from 0 (start) to 1 (end).
53 * @param randomSeed
54 * If you use any randomization, use this seed for it.
55 */
56 @Override
57 public void init(NegotiationInfo info) {
58 super.init(info);
59
60 reservationValue = utilitySpace.getReservationValue();
61 history = new HashMap<Object, Action>();
62 opponentModels = new HashMap<Object, IOpponentModel>();
63 ourPreviousBid = getMaximumUtilityBid();
64 }
65
66 /**
67 * Each round this method gets called and ask you to accept or offer. The
68 * first party in the first round is a bit different, it can only propose an
69 * offer.
70 *
71 * @param validActions
72 * Either a list containing both accept and offer or only offer.
73 * @return The chosen action.
74 */
75 @Override
76 public Action chooseAction(List<Class<? extends Action>> validActions) {
77 try {
78 // If there is a most recent bid and the agent is allowed to accept
79 if (mostRecentBid != null && validActions.contains(Accept.class) && isAcceptable(mostRecentBid)) {
80 return new Accept(getPartyId(), mostRecentBid);
81 }
82
83 // If there are no previous bids or the agent is not allowed to
84 // accept, generate an offer
85 mostRecentBid = generateBid();
86 } catch (Exception e) {
87 e.printStackTrace();
88
89 // If something goes wrong, just accept the offer or create one at
90 // random
91 if (validActions.contains(Accept.class))
92 return new Accept(getPartyId(), mostRecentBid);
93 else
94 mostRecentBid = generateRandomBid();
95 }
96
97 ourPreviousBid = mostRecentBid;
98 return new Offer(getPartyId(), mostRecentBid);
99 }
100
101 /**
102 * Checks the acceptability of the Bid. Only works as planned if at least
103 * one bidding round has passed.
104 *
105 * @param bid
106 * to check
107 * @throws Exception
108 */
109 private boolean isAcceptable(Bid bid) throws Exception {
110 double currentTime = timeline.getTime();
111 double bidUtilityValue = this.utilitySpace.getUtility(bid);
112
113 double minimalAcceptableUtility = calculateMinimalAcceptableUtility(currentTime, this.reservationValue);
114
115 TimeLineInfo localTime = this.timeline;
116 switch (localTime.getType()) {
117 case Rounds:
118 if (((DiscreteTimeline) localTime).getOwnRoundsLeft() == 0)
119 return true;
120 break;
121 default:
122 break;
123 }
124
125 if (bidUtilityValue >= minimalAcceptableUtility)
126 return true;
127
128 return false;
129 }
130
131 /**
132 * Function: max(u_r, 0.5)^(t^3)
133 *
134 * @param time
135 * (t)
136 * @param reservationValue
137 * (u_r)
138 * @param nrAccepts
139 * (n_a)
140 * @param nrOpponents
141 * (n)
142 * @return minimal acceptable utility value given it's parameters
143 * @throws Exception
144 * outside boundaries
145 */
146 private double calculateMinimalAcceptableUtility(double time, double reservationValue) throws Exception {
147 if (time < 0 || time > 1)
148 throw new Exception("time " + time + " outside [0,1]");
149 if (reservationValue < 0 || reservationValue > 1)
150 throw new Exception("reservationValue " + time + " outside [0,1]");
151
152 return Math.pow(Math.max(reservationValue, 0.1), Math.pow(time, 3));
153 }
154
155 /**
156 * All offers proposed by the other parties will be received as a message.
157 * You can use this information to your advantage, for example to predict
158 * their utility.
159 *
160 * @param sender
161 * The party that did the action.
162 * @param action
163 * The action that party did.
164 */
165 @Override
166 public void receiveMessage(AgentID sender, Action action) {
167 super.receiveMessage(sender, action);
168
169 history.put(sender, action);
170
171 // If a bid has been done, get the bid
172 Bid bid = DefaultAction.getBidFromAction(action);
173
174 if (bid != null) {
175 mostRecentBid = bid;
176
177 if (!opponentModels.containsKey(sender))
178 opponentModels.put(sender, new FrequencyAnalysisOpponentModel());
179
180 opponentModels.get(sender).learnWeights(mostRecentBid);
181 }
182 }
183
184 private Queue<Issue> getOrderedIssues() {
185 final AdditiveUtilitySpace utilspace1 = (AdditiveUtilitySpace) utilitySpace;
186 PriorityQueue<Issue> issues = new PriorityQueue<Issue>(this.utilitySpace.getDomain().getIssues().size(),
187 new Comparator<Issue>() {
188 @Override
189 public int compare(Issue i1, Issue i2) {
190 return (int) (utilspace1.getWeight(i1.getNumber()) - utilspace1.getWeight(i2.getNumber()));
191 }
192 });
193 issues.addAll(this.utilitySpace.getDomain().getIssues());
194 return issues;
195 }
196
197 private Map<Issue, List<Value>> getOpponentMajorityValues() {
198 Map<Issue, List<Value>> majorityValues = new HashMap<Issue, List<Value>>();
199
200 for (Issue issue : this.utilitySpace.getDomain().getIssues()) {
201 // Map each value to the number of agents that agree on it
202 Map<Value, Integer> opponentValues = new HashMap<Value, Integer>();
203
204 for (IOpponentModel oppModel : opponentModels.values()) {
205 int n = 0;
206
207 // If there is no entry in the opponent model for this issue,
208 // continue
209 if (oppModel.getValue(issue.getNumber()) == null)
210 continue;
211
212 if (opponentValues.get(oppModel.getValue(issue.getNumber())) != null)
213 n = opponentValues.get(oppModel.getValue(issue.getNumber()));
214
215 opponentValues.put(oppModel.getValue(issue.getNumber()), n + 1);
216 }
217
218 List<Value> maxValues = new ArrayList<Value>();
219 int largestMajority = 0;
220
221 for (Entry<Value, Integer> entry : opponentValues.entrySet()) {
222 if (entry.getValue() > largestMajority) {
223 maxValues.removeAll(maxValues);
224 maxValues.add(entry.getKey());
225 } else if (entry.getValue() == largestMajority) {
226 maxValues.add(entry.getKey());
227 }
228 }
229
230 majorityValues.put(issue, maxValues);
231 }
232
233 return majorityValues;
234 }
235
236 private Bid generateBid() throws Exception {
237 // For the other issues, start with own maximum possible bid
238 Bid maxBid = getMaximumUtilityBid();
239 Bid resBid = maxBid;
240
241 // Sort all issues in from low to high weight
242 Queue<Issue> issues = getOrderedIssues();
243 Map<Issue, List<Value>> majorityValues = getOpponentMajorityValues();
244
245 // Remove all issues for which the majority agrees with us
246 List<Issue> toBeRemoved = new ArrayList<Issue>();
247 for (Issue issue : issues) {
248 if (majorityValues.get(issue).contains(maxBid.getValue(issue.getNumber()))) {
249 toBeRemoved.add(issue);
250 }
251 }
252 issues.removeAll(toBeRemoved);
253
254 // Do a concession on the least important issue(s)
255 AdditiveUtilitySpace utilitySpace1 = (AdditiveUtilitySpace) utilitySpace;
256 for (Issue leastImportantIssue : issues) {
257 List<Value> majorityValue = majorityValues.get(leastImportantIssue);
258
259 double maxUtility = 0;
260 Value majorityMaxValue = null;
261
262 for (Value value : majorityValue) {
263 double valueUtility = ((EvaluatorDiscrete) utilitySpace1.getEvaluator(leastImportantIssue.getNumber()))
264 .getEvaluation((ValueDiscrete) value);
265
266 if (valueUtility > maxUtility) {
267 maxUtility = valueUtility;
268 majorityMaxValue = value;
269 }
270 }
271
272 if (majorityMaxValue == null)
273 break;
274
275 // Only concede on issues that we did not concede on in the previous
276 // bid
277 if (ourPreviousBid.getValue(leastImportantIssue.getNumber()).equals(majorityMaxValue))
278 continue;
279
280 resBid = resBid.putValue(leastImportantIssue.getNumber(), majorityMaxValue);
281
282 if (!isAcceptable(resBid)) {
283 resBid = resBid.putValue(leastImportantIssue.getNumber(),
284 maxBid.getValue(leastImportantIssue.getNumber()));
285 break;
286 }
287 }
288
289 return resBid;
290 }
291
292 private Bid getMaximumUtilityBid() {
293 Bid resBid = generateRandomBid();
294 AdditiveUtilitySpace utilitySpace1 = (AdditiveUtilitySpace) utilitySpace;
295
296 for (Issue issue : utilitySpace.getDomain().getIssues()) {
297 Value value = ((EvaluatorDiscrete) utilitySpace1.getEvaluator(issue.getNumber())).getMaxValue();
298 if (value == null)
299 break;
300 resBid = resBid.putValue(issue.getNumber(), value);
301 }
302
303 return resBid;
304 }
305
306 protected AgentID partyId = new AgentID("Group 6");
307
308 @Override
309 public String getDescription() {
310 return "ai2014 group6";
311 }
312
313}
Note: See TracBrowser for help on using the repository browser.