source: src/main/java/agents/anac/y2014/SimpaticoAgent/Simpatico.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: 17.9 KB
Line 
1package agents.anac.y2014.SimpaticoAgent;
2
3import java.util.ArrayList;
4import java.util.HashMap;
5import java.util.List;
6import java.util.Random;
7
8import genius.core.Agent;
9import genius.core.Bid;
10import genius.core.actions.Accept;
11import genius.core.actions.Action;
12import genius.core.actions.Offer;
13import genius.core.issue.Issue;
14import genius.core.issue.IssueDiscrete;
15import genius.core.issue.IssueInteger;
16import genius.core.issue.IssueReal;
17import genius.core.issue.Value;
18import genius.core.issue.ValueDiscrete;
19import genius.core.issue.ValueInteger;
20import genius.core.issue.ValueReal;
21
22/**
23 * @author Bedour Alrayes, Paulo Ricca, Ozgur Kafali, Kostas Stathis
24 * @institution Royal Holloway University of London
25 *
26 *
27 */
28public class Simpatico extends Agent {
29 private Action actionOfPartner = null;
30 private double initialMinimumBidUtility = 0.9;
31 private double minimumBidUtility = initialMinimumBidUtility;
32 private double acceptanceBidUtility = 0.85;
33 private BidTuple bestOpponentOffer = null;
34 private ArrayList<BidTuple> bestOpponentOffers = new ArrayList<Simpatico.BidTuple>();
35 private int bidToSubmitBack = 0; // used in the last moments, we propose
36 // back the best of the opponents bids
37
38 // Search Parameters
39 private int initialSearchDepth = 3;
40 private int maximumSearchDepth = initialSearchDepth;
41 private int maximumSearchDepthForOurBids = 2;
42 private float percentageOfIssuesToChange = 0.5f;
43 private float randomSearchRatio = 0.3f;
44
45 // Decision making parameters
46 double maximumRoundTime = 0;
47 double lastRoundTime = 0;
48 boolean opponentIsCooperative = true;
49
50 int countOpponentOffers = 0;
51 double cooperationthreshold = 0.5;
52 double minimumCooperativeUtility = 0.5;
53 double numberOfCooperativeUtilities;
54
55 @Override
56 public void init() {
57 actionOfPartner = null;
58 initialMinimumBidUtility = 0.9;
59 minimumBidUtility = initialMinimumBidUtility;
60 acceptanceBidUtility = 0.85;
61 bestOpponentOffer = null;
62 bestOpponentOffers = new ArrayList<Simpatico.BidTuple>();
63 bidToSubmitBack = 0; // used in the last moments, we propose back the
64 // best of the opponents bids
65
66 // Search Parameters
67 initialSearchDepth = 3;
68 maximumSearchDepth = initialSearchDepth;
69 maximumSearchDepthForOurBids = 2;
70 percentageOfIssuesToChange = 0.5f;
71 randomSearchRatio = 0.3f;
72
73 // Decision making parameters
74 maximumRoundTime = 0;
75 lastRoundTime = 0;
76 opponentIsCooperative = true;
77
78 countOpponentOffers = 0;
79 cooperationthreshold = 0.5;
80 minimumCooperativeUtility = 0.5;
81 }
82
83 private BidTuple SearchNeighbourhood(BidTuple initialBid) {
84 return SearchNeighbourhood(initialBid, maximumSearchDepth);
85 }
86
87 @Override
88 public String getVersion() {
89 return "1.0";
90 }
91
92 @Override
93 public String getName() {
94 return "Simp�tico";
95 }
96
97 @Override
98 public void ReceiveMessage(Action opponentAction) {
99 actionOfPartner = opponentAction;
100 }
101
102 private BidTuple SearchNeighbourhood(BidTuple initialBid, int depth) {
103 if (depth == 0) {
104 return initialBid;
105 }
106 BidTuple bestBid = initialBid;
107 int nIssues = initialBid.bid.getIssues().size();
108
109 int numberOfIssuesToChange = (int) (nIssues
110 * percentageOfIssuesToChange);
111 if (numberOfIssuesToChange > 5)
112 numberOfIssuesToChange = 5;
113 debug("NUMBER OF ISSUES: " + numberOfIssuesToChange, 3);
114
115 int[] issuesToChange = new int[numberOfIssuesToChange];
116 Random rand = new Random();
117 for (int i = 0; i < issuesToChange.length; i++) {
118 boolean alreadyChosen;
119 boolean assigned = false;
120 do {
121 alreadyChosen = false;
122 int issueIndexChosen = 1 + rand.nextInt(nIssues - 1);
123 for (int j = 0; j <= i - 1; j++) {
124 if (issuesToChange[j] == issueIndexChosen) {
125 alreadyChosen = true;
126 }
127 }
128 if (!alreadyChosen) {
129 issuesToChange[i] = issueIndexChosen;
130 assigned = true;
131 }
132
133 } while (!assigned && alreadyChosen);
134 }
135 try {
136 for (int i = 0; i < issuesToChange.length; i++) {
137 BidTuple bidTupleTmp;
138 switch (initialBid.bid.getIssues().get(issuesToChange[i])
139 .getType()) {
140 case DISCRETE:
141 bidTupleTmp = getDiscreteIssueVariation(initialBid,
142 issuesToChange[i], 1);
143 if (bidTupleTmp != null) {
144 if (bidTupleTmp.utility > bestBid.utility)
145 bestBid = bidTupleTmp;
146 BidTuple returnedBid = SearchNeighbourhood(bidTupleTmp,
147 depth - 1);
148 if (returnedBid.utility > bestBid.utility)
149 bestBid = returnedBid;
150 }
151
152 bidTupleTmp = getDiscreteIssueVariation(initialBid,
153 issuesToChange[i], -1);
154 if (bidTupleTmp != null) {
155 if (bidTupleTmp.utility > bestBid.utility)
156 bestBid = bidTupleTmp;
157 BidTuple returnedBid = SearchNeighbourhood(bidTupleTmp,
158 depth - 1);
159 if (returnedBid.utility > bestBid.utility)
160 bestBid = returnedBid;
161 }
162 break;
163 case REAL:
164 IssueReal issueReal = (IssueReal) initialBid.bid.getIssues()
165 .get(issuesToChange[i]);
166 double range = issueReal.getUpperBound()
167 - issueReal.getLowerBound();
168 double variation = range * 0.05;
169
170 bidTupleTmp = getRealIssueVariation(initialBid,
171 issuesToChange[i], rand.nextFloat() * variation);
172 if (bidTupleTmp != null) {
173 if (bidTupleTmp.utility > bestBid.utility)
174 bestBid = bidTupleTmp;
175 BidTuple returnedBid = SearchNeighbourhood(bidTupleTmp,
176 depth - 1);
177 if (returnedBid.utility > bestBid.utility)
178 bestBid = returnedBid;
179 }
180
181 bidTupleTmp = getRealIssueVariation(initialBid,
182 issuesToChange[i], -rand.nextFloat() * variation);
183 if (bidTupleTmp != null) {
184 if (bidTupleTmp.utility > bestBid.utility)
185 bestBid = bidTupleTmp;
186 BidTuple returnedBid = SearchNeighbourhood(bidTupleTmp,
187 depth - 1);
188 if (returnedBid.utility > bestBid.utility)
189 bestBid = returnedBid;
190 }
191 break;
192 case INTEGER:
193 bidTupleTmp = getIntegerIssueVariation(initialBid,
194 issuesToChange[i], 1);
195 if (bidTupleTmp != null) {
196 if (bidTupleTmp.utility > bestBid.utility)
197 bestBid = bidTupleTmp;
198 BidTuple returnedBid = SearchNeighbourhood(bidTupleTmp,
199 depth - 1);
200 if (returnedBid.utility > bestBid.utility)
201 bestBid = returnedBid;
202 }
203
204 bidTupleTmp = getIntegerIssueVariation(initialBid,
205 issuesToChange[i], -1);
206 if (bidTupleTmp != null) {
207 if (bidTupleTmp.utility > bestBid.utility)
208 bestBid = bidTupleTmp;
209 BidTuple returnedBid = SearchNeighbourhood(bidTupleTmp,
210 depth - 1);
211 if (returnedBid.utility > bestBid.utility)
212 bestBid = returnedBid;
213 }
214 break;
215 default:
216 throw new Exception(
217 "issue type not supported by " + getName());
218 }
219 }
220 } catch (Exception e) {
221 debug(e.getMessage());
222 e.printStackTrace();
223 }
224 return bestBid;
225 }
226
227 private void saveBestOpponentBids(BidTuple bid) {
228 int insertPosition = 0;
229 for (int i = 0; i < bestOpponentOffers.size(); i++) {
230 if (bestOpponentOffers.get(i).utility > bid.utility)
231 insertPosition++;
232 }
233 bestOpponentOffers.add(insertPosition, bid);
234 if (bestOpponentOffers.size() > 10)
235 bestOpponentOffers.remove(10);
236 }
237
238 private BidTuple getDiscreteIssueVariation(BidTuple bid, int issueId,
239 int variation) throws Exception {
240 Bid tmpBid = new Bid(bid.bid);
241 BidTuple bidTupleTmp = null;
242 IssueDiscrete issueDiscrete = (IssueDiscrete) tmpBid.getIssues()
243 .get(issueId);
244 int temIssueIndex = issueDiscrete.getIndex(issueDiscrete);
245 if (issueDiscrete.getNumberOfValues() >= temIssueIndex + variation
246 && temIssueIndex + variation >= 0) {
247 ValueDiscrete value = issueDiscrete
248 .getValue(temIssueIndex + variation);
249 tmpBid = tmpBid.putValue(issueId, value);
250 double util = getUtility(tmpBid);
251 bidTupleTmp = new BidTuple(tmpBid, util);
252 }
253 return bidTupleTmp;
254 }
255
256 private BidTuple getRealIssueVariation(BidTuple bid, int issueId,
257 double variation) throws Exception {
258 Bid tmpBid = new Bid(bid.bid);
259 BidTuple bidTupleTmp = null;
260 IssueReal issueReal = (IssueReal) tmpBid.getIssues().get(issueId);
261 int temIssueValue = ((ValueInteger) tmpBid.getValue(issueId))
262 .getValue();
263 if (issueReal.getUpperBound() >= temIssueValue + variation
264 && issueReal.getLowerBound() <= temIssueValue + variation) {
265 ValueReal value = new ValueReal(temIssueValue + variation);
266 tmpBid = tmpBid.putValue(issueId, value);
267 double util = getUtility(tmpBid);
268 bidTupleTmp = new BidTuple(tmpBid, util);
269 }
270 return bidTupleTmp;
271 }
272
273 private BidTuple getIntegerIssueVariation(BidTuple bid, int issueId,
274 int variation) throws Exception {
275 Bid tmpBid = new Bid(bid.bid);
276 BidTuple bidTupleTmp = null;
277 IssueInteger issueInteger = (IssueInteger) tmpBid.getIssues()
278 .get(issueId);
279 int temIssueValue = ((ValueInteger) tmpBid.getValue(issueId))
280 .getValue();
281 if (issueInteger.getUpperBound() >= temIssueValue + variation
282 && issueInteger.getLowerBound() <= temIssueValue + variation) {
283 ValueInteger value = new ValueInteger(temIssueValue + variation);
284 tmpBid = tmpBid.putValue(issueId, value);
285 double util = getUtility(tmpBid);
286 bidTupleTmp = new BidTuple(tmpBid, util);
287 }
288 return bidTupleTmp;
289 }
290
291 @Override
292 public Action chooseAction() {
293 boolean NeverFoundHighUtilityInNeighbourhood = true;
294 debug("1. choosing action");
295 // get current time
296 double time = timeline.getTime();
297 // calculate maximum round time
298 if (actionOfPartner != null) {
299 if (maximumRoundTime < time - lastRoundTime)
300 maximumRoundTime = time - lastRoundTime;
301 debug("maximumRoundTime: " + maximumRoundTime);
302 lastRoundTime = time;
303 }
304 Action action = null;
305 try {
306 if (actionOfPartner == null) {
307 lastRoundTime = time;
308 debug("OFFER: FIRST RANDOM OFFER", 3);
309 return action = chooseRandomBidAction();
310 }
311 if (actionOfPartner instanceof Offer) {
312 Bid partnerBid = ((Offer) actionOfPartner).getBid();
313 double offeredUtilFromOpponent = getUtility(partnerBid);
314
315 if (time >= 0.99 && offeredUtilFromOpponent >= 0.75) {
316 debug("ime >= 0.99 && offeredUtilFromOpponent>= 0.75");
317 debug("OFFER: STRAIGHT ACCEPT, TIME IS RUNNING OUT, GOOD OFFER",
318 3);
319 return action = new Accept(getAgentID(), partnerBid);
320 }
321
322 BidTuple opponentBid = new BidTuple(partnerBid,
323 offeredUtilFromOpponent);
324 saveBestOpponentBids(opponentBid);
325
326 if (bestOpponentOffer == null
327 || bestOpponentOffer.utility < offeredUtilFromOpponent)
328 bestOpponentOffer = opponentBid;
329
330 // Last moments, submit back the opponents best bids
331 if ((time >= 1 - (maximumRoundTime * 1.09))) {
332 debug("final round:" + maximumRoundTime);
333 debug("(time>=1-(maximumRoundTime*1.05)) && bestOpponentOffer.utility >= 0.5");
334 if (bidToSubmitBack >= bestOpponentOffers.size())
335 bidToSubmitBack = 0;
336 debug("OFFER: BEST OF THE OPPONENTS NR " + bidToSubmitBack,
337 3);
338 return action = new Offer(getAgentID(),
339 bestOpponentOffers.get(bidToSubmitBack++).bid);
340 }
341
342 updateOpponentProfile(partnerBid, offeredUtilFromOpponent);
343 updateMinimumBidUtility(partnerBid, offeredUtilFromOpponent);
344
345 debug("3. searching the vicinity of the opp bid");
346 debug("MINIMUM UTILITY: " + minimumBidUtility, 3);
347 BidTuple bestBidInTheVicinity = SearchNeighbourhood(
348 opponentBid);
349 debug("bestBidInTheVicinity.utility"
350 + bestBidInTheVicinity.utility);
351 if (bestBidInTheVicinity.utility < minimumBidUtility) {
352 debug("4. bad search, going to pick a random");
353 action = chooseRandomBidAction();
354
355 // if the random returned a null, which means we couldnt
356 // find a bid before time ran out,
357 // we offer back the best opponent bid
358 if (((Offer) action).getBid() == null
359 && bestOpponentOffer.utility >= 0.5) {
360 debug("action == null && bestOpponentOffer.utility >= 0.5");
361 return action = new Offer(getAgentID(),
362 bestOpponentOffer.bid);
363 }
364
365 debug("bid Random");
366 debug("OFFER: RANDOM BID", 3);
367
368 } else {
369 debug("5. found a good bid in the vicinity");
370 NeverFoundHighUtilityInNeighbourhood = false;
371 action = new Offer(getAgentID(), bestBidInTheVicinity.bid);
372 debug("Bid in bestBidInTheVicinity");
373 debug("OFFER: OPPONENT VICINITY", 3);
374 }
375
376 if (NeverFoundHighUtilityInNeighbourhood) {
377 if (time > 0.8) {
378 debug("6. time > 0.8, maximumsearchdepth = "
379 + (int) (initialSearchDepth * 1.5));
380 maximumSearchDepth = (int) (initialSearchDepth * 1.5);
381 } else if (time > 0.5) {
382 debug("7. time > 0.5, maximumsearchdepth = "
383 + (int) (initialSearchDepth * 1.2));
384 maximumSearchDepth = (int) (initialSearchDepth * 1.2);
385 }
386 }
387
388 Bid myBid = ((Offer) action).getBid();
389 double myOfferedUtil = getUtility(myBid);
390
391 // accept under certain circumstances
392 if (isAcceptable(offeredUtilFromOpponent, myOfferedUtil,
393 time)) {
394 debug("8. opponents bid is acceptable");
395 debug("Accept");
396 debug("OFFER: STRAIGHT ACCEPT", 3);
397 action = new Accept(getAgentID(), partnerBid);
398 }
399
400 }
401
402 } catch (Exception e) {
403 debug("Exception in ChooseAction:" + e.getMessage());
404 return action = new Offer(getAgentID(), bestOpponentOffer.bid); // best
405 // guess
406 // if
407 // things
408 // go
409 // wrong.
410 }
411 debug("9. end of choose action");
412 return action;
413 }
414
415 private void updateOpponentProfile(Bid partnerBid,
416 double offeredUtilFromOpponent) {
417 countOpponentOffers++;
418 if (offeredUtilFromOpponent > minimumCooperativeUtility) {
419 numberOfCooperativeUtilities++;
420 }
421 if ((numberOfCooperativeUtilities
422 / countOpponentOffers) > cooperationthreshold) {
423 opponentIsCooperative = true;
424 debug("-- OPPONENT IS COOPERATIVE", 1);
425 } else {
426 opponentIsCooperative = false;
427 debug("-- OPPONENT IS HARD HEADED", 1);
428 }
429 }
430
431 private boolean isAcceptable(double offeredUtilFromOpponent,
432 double myOfferedUtil, double time) throws Exception {
433 double discount_utility_factor = utilitySpace.getDiscountFactor();
434 acceptanceBidUtility = initialMinimumBidUtility
435 * Math.pow(discount_utility_factor, time);
436
437 if (time >= 0.9) {
438 initialMinimumBidUtility = 0.85;
439 }
440
441 if (offeredUtilFromOpponent >= acceptanceBidUtility) {
442 debug("offeredUtilFromOpponent >= " + acceptanceBidUtility);
443 return true;
444 }
445
446 if (offeredUtilFromOpponent >= myOfferedUtil) {
447 debug("offeredUtilFromOpponent >= myOfferedUtil");
448 return true;
449 }
450
451 return false;
452 }
453
454 private Action chooseRandomBidAction() {
455 Bid nextBid = null;
456 try {
457 nextBid = getRandomBid();
458 } catch (Exception e) {
459 debug("Problem with received bid:" + e.getMessage()
460 + ". cancelling bidding");
461 }
462 return (new Offer(getAgentID(), nextBid));
463 }
464
465 private Bid getRandomBid() throws Exception {
466 HashMap<Integer, Value> values = new HashMap<Integer, Value>(); // pairs
467 // <issuenumber,chosen
468 // value
469 // string>
470 List<Issue> issues = utilitySpace.getDomain().getIssues();
471 Random randomnr = new Random();
472
473 debug("R 1.beginning Random pick");
474
475 Bid bid = null;
476
477 int tries = 0;
478 int absoluteTries = 0;
479 float minimumUtilTolerance = 0;
480 do {
481 tries++;
482 absoluteTries++;
483 if (tries > 2000)// && minimumUtilTolerance<0.09)
484 {
485 debug("R 1.increasing tolerance");
486 minimumUtilTolerance += 0.001;
487 tries = 0;
488 }
489
490 for (Issue lIssue : issues) {
491 switch (lIssue.getType()) {
492 case DISCRETE:
493 IssueDiscrete lIssueDiscrete = (IssueDiscrete) lIssue;
494 int optionIndex = randomnr
495 .nextInt(lIssueDiscrete.getNumberOfValues());
496 values.put(lIssue.getNumber(),
497 lIssueDiscrete.getValue(optionIndex));
498 break;
499 case REAL:
500 IssueReal lIssueReal = (IssueReal) lIssue;
501 int optionInd = randomnr.nextInt(
502 lIssueReal.getNumberOfDiscretizationSteps() - 1);
503 values.put(lIssueReal.getNumber(), new ValueReal(lIssueReal
504 .getLowerBound()
505 + (lIssueReal.getUpperBound()
506 - lIssueReal.getLowerBound()) * (optionInd)
507 / (lIssueReal
508 .getNumberOfDiscretizationSteps())));
509 break;
510 case INTEGER:
511 IssueInteger lIssueInteger = (IssueInteger) lIssue;
512 int optionIndex2 = lIssueInteger.getLowerBound()
513 + randomnr.nextInt(lIssueInteger.getUpperBound()
514 - lIssueInteger.getLowerBound());
515 values.put(lIssueInteger.getNumber(),
516 new ValueInteger(optionIndex2));
517 break;
518 default:
519 throw new Exception("issue type " + lIssue.getType()
520 + " not supported by SimpleAgent2");
521 }
522 }
523 bid = new Bid(utilitySpace.getDomain(), values);
524
525 } while (getUtility(bid) < minimumBidUtility - minimumUtilTolerance);
526 debug("R 2.Generated a random bid. current utility: " + getUtility(bid)
527 + ", tolerance: " + minimumUtilTolerance + "; tries: "
528 + absoluteTries);
529
530 Bid randomBid = bid;
531
532 // // search the vicinity of the random offer
533 if (randomnr.nextFloat() < randomSearchRatio) {
534 debug("R 3.Going to search the vicinity of the random pick");
535 bid = SearchNeighbourhood(new BidTuple(bid, getUtility(bid)),
536 maximumSearchDepthForOurBids).bid;
537 }
538
539 if (bid != randomBid) {
540 debug("OFFER: RANDOM VICINITY BID", 3);
541 } else {
542 debug("OFFER: RANDOM BID", 3);
543 }
544
545 debug("R 4.Random pick finished");
546 return bid;
547 }
548
549 private void updateMinimumBidUtility(Bid partnerBid,
550 double offeredUtilFromOpponent) {
551
552 double time = timeline.getTime();
553 double discount_utility_factor = utilitySpace.getDiscountFactor();
554 if (time >= 0.5 && opponentIsCooperative) {
555 minimumBidUtility = 0.88 * Math.pow(discount_utility_factor, time);
556 debug("2. ADJUSTING MINIMUM UTILITY: " + minimumBidUtility);
557 }
558 debug("2. MINIMUM UTILITY: " + minimumBidUtility);
559 debug("2. discount factor: " + discount_utility_factor);
560 }
561
562 private void debug(String line) {
563 debug(line, 0);
564 }
565
566 private void debug(String line, int priority) {
567 if (priority >= 4)
568 System.out.println(line);
569 }
570
571 private class BidTuple {
572 public Bid bid;
573 public double utility;
574
575 public BidTuple(Bid bid, double utility) {
576 this.bid = bid;
577 this.utility = utility;
578 }
579 }
580
581 @Override
582 public String getDescription() {
583 return "ANAC2014 compatible with non-linear utility spaces";
584 }
585
586}
Note: See TracBrowser for help on using the repository browser.