source: src/main/java/agents/anac/y2015/agentBuyogV2/AgentBuyogMain.java

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

Initial import : Genius 9.0.0

File size: 19.1 KB
Line 
1package agents.anac.y2015.agentBuyogV2;
2
3import java.util.HashMap;
4import java.util.List;
5import java.util.Map.Entry;
6import java.util.Random;
7
8import agents.anac.y2015.agentBuyogV2.flanagan.analysis.Regression;
9import genius.core.AgentID;
10import genius.core.Bid;
11import genius.core.BidHistory;
12import genius.core.actions.Accept;
13import genius.core.actions.Action;
14import genius.core.actions.EndNegotiation;
15import genius.core.actions.Offer;
16import genius.core.analysis.BidSpace;
17import genius.core.bidding.BidDetails;
18import genius.core.boaframework.SortedOutcomeSpace;
19import genius.core.issue.Issue;
20import genius.core.issue.IssueDiscrete;
21import genius.core.issue.IssueInteger;
22import genius.core.issue.Objective;
23import genius.core.issue.Value;
24import genius.core.issue.ValueDiscrete;
25import genius.core.issue.ValueInteger;
26import genius.core.misc.Range;
27import genius.core.parties.AbstractNegotiationParty;
28import genius.core.parties.NegotiationInfo;
29import genius.core.utility.AdditiveUtilitySpace;
30import genius.core.utility.Evaluator;
31import genius.core.utility.EvaluatorDiscrete;
32import genius.core.utility.EvaluatorInteger;
33
34public class AgentBuyogMain extends AbstractNegotiationParty {
35
36 // PARAMETER LIST. THIS IS WHAT YOU'RE SUPPOSED TO PLAY AROUND WITH.
37
38 private static final double alphaDefault = 0, betaDefault = 0,
39 issueWeightsConstant = 0.3, issueValuesConstant = 100,
40 minimumHistorySize = 50, learningTimeController = 1.3; // Discount
41 // is
42 // added
43 // to
44 // the
45 // learningTimeController.
46 // So
47 // it's
48 // actually
49 // learningTimeController
50 // +
51 // discount
52 private static final int maxWeightForBidPoint = 300;
53 private static final double leniencyAdjuster = 1,
54 domainWeightController = 1.75, timeConcessionController = 1.8;
55 private static final double lastSecondConcessionFactor = 0.5;
56 private static final double kalaiPointCorrection = 0.1;
57
58 // PARAMETER LIST ENDS HERE. DO NOT TOUCH CODE BELOW THIS POINT.
59
60 private OpponentInfo infoA, infoB;
61 private BidHistory myBidHistory, AandBscommonBids, totalHistory;
62 private boolean initialized = false;
63 private SortedOutcomeSpace sortedUtilitySpace;
64 private int numberOfRounds = 0;
65
66 @Override
67 public void init(NegotiationInfo info) {
68 super.init(info);
69 this.totalHistory = new BidHistory();
70 this.myBidHistory = new BidHistory();
71 this.AandBscommonBids = new BidHistory();
72 this.sortedUtilitySpace = new SortedOutcomeSpace(utilitySpace);
73
74 }
75
76 @Override
77 public Action chooseAction(List<Class<? extends Action>> possibleActions) {
78
79 if (timeline.getTime() >= 1) {
80 return new EndNegotiation(getPartyId());
81 }
82
83 numberOfRounds++;
84 double timePerRound = timeline.getTime() / numberOfRounds;
85 double remainingRounds = (1 - timeline.getTime()) / timePerRound;
86
87 BidDetails bestBid = null;
88 double minimumPoint = utilitySpace.getDiscountFactor() * 0.7
89 + utilitySpace.getReservationValueUndiscounted() * 0.3;
90
91 BidDetails bestAgreeableBidSoFar = null;
92 double bestAgreeableBidsUtility = 0;
93 double mostRecentBidsUtility = 0;
94
95 if (AandBscommonBids != null && AandBscommonBids.size() > 0) {
96 bestAgreeableBidSoFar = AandBscommonBids.getBestBidDetails();
97 bestAgreeableBidsUtility = AandBscommonBids.getBestBidDetails()
98 .getMyUndiscountedUtil();
99 }
100
101 if (totalHistory != null && totalHistory.size() > 0) {
102 mostRecentBidsUtility = totalHistory.getLastBidDetails()
103 .getMyUndiscountedUtil();
104 }
105
106 OpponentInfo difficultAgent = null;
107
108 if (infoA != null && infoB != null && infoA.getAgentDifficulty() != null
109 && infoB.getAgentDifficulty() != null) {
110
111 if (infoA.getAgentDifficulty() <= infoB.getAgentDifficulty()) {
112 difficultAgent = infoA;
113 } else {
114 difficultAgent = infoB;
115 }
116
117 minimumPoint = utilitySpace.getDiscountFactor()
118 * difficultAgent.getAgentDifficulty();
119 }
120
121 double acceptanceThreshold = minimumPoint + (1 - minimumPoint)
122 * (1 - Math.pow(timeline.getTime(), timeConcessionController));
123
124 if (remainingRounds <= 3) {
125 acceptanceThreshold = acceptanceThreshold
126 * lastSecondConcessionFactor;
127 }
128
129 if (acceptanceThreshold < utilitySpace
130 .getReservationValueUndiscounted()) {
131 acceptanceThreshold = utilitySpace
132 .getReservationValueUndiscounted();
133
134 if (utilitySpace.getDiscountFactor() < 1 && remainingRounds > 3) {
135 return new EndNegotiation(getPartyId());
136 }
137 }
138
139 if (possibleActions.contains(Accept.class)) {
140 if (mostRecentBidsUtility >= acceptanceThreshold
141 && mostRecentBidsUtility >= bestAgreeableBidsUtility
142 && remainingRounds <= 3) {
143 return new Accept(getPartyId(),
144 totalHistory.getLastBidDetails().getBid());
145 }
146 }
147
148 if (bestAgreeableBidsUtility > acceptanceThreshold) {
149 bestBid = bestAgreeableBidSoFar;
150 } else {
151 Range range = new Range(acceptanceThreshold, 1);
152 List<BidDetails> bidsInWindow = sortedUtilitySpace
153 .getBidsinRange(range);
154 bestBid = getBestBidFromList(bidsInWindow);
155 }
156
157 if (possibleActions.contains(Accept.class)) {
158 if (mostRecentBidsUtility >= acceptanceThreshold
159 && mostRecentBidsUtility >= bestAgreeableBidsUtility
160 && mostRecentBidsUtility >= bestBid
161 .getMyUndiscountedUtil()) {
162 return new Accept(getPartyId(),
163 totalHistory.getLastBidDetails().getBid());
164 }
165 }
166
167 totalHistory.add(bestBid);
168 return new Offer(getPartyId(), bestBid.getBid());
169
170 }
171
172 private BidDetails getBestBidFromList(List<BidDetails> bidsInWindow) {
173 double bestBidOpponentsUtil = 0;
174 BidDetails bestBid = null;
175
176 if (infoA == null || infoB == null || infoA.getAgentDifficulty() == null
177 || infoB.getAgentDifficulty() == null) {
178 Random random = new Random();
179 return bidsInWindow.get(random.nextInt(bidsInWindow.size()));
180 }
181
182 try {
183 bestBid = findNearestBidToKalai(bidsInWindow, 1D, 1D);
184 } catch (Exception e) {
185 e.printStackTrace();
186 }
187
188 return bestBid;
189 }
190
191 private BidDetails findNearestBidToKalai(List<BidDetails> bidsInWindow,
192 Double infoAKalai, Double infoBKalai) {
193 Double shortestDistance;
194 BidDetails nearestBid;
195
196 nearestBid = bidsInWindow.get(0);
197 shortestDistance = getDistance(nearestBid, infoAKalai, infoBKalai);
198
199 for (BidDetails bid : bidsInWindow) {
200 Double bidDistance = getDistance(bid, infoAKalai, infoBKalai);
201 if (bidDistance < shortestDistance) {
202 shortestDistance = bidDistance;
203 nearestBid = bid;
204 }
205 }
206 return nearestBid;
207 }
208
209 private Double getDistance(BidDetails bid, Double infoAKalai,
210 Double infoBKalai) {
211 try {
212 return Math.sqrt((1 - infoA.getAgentDifficulty())
213 * Math.pow(infoA.getOpponentUtilitySpace()
214 .getUtility(bid.getBid()) - infoAKalai, 2)
215 + (1 - infoB.getAgentDifficulty())
216 * Math.pow(infoB.getOpponentUtilitySpace()
217 .getUtility(bid.getBid()) - infoBKalai, 2));
218 } catch (Exception e) {
219 e.printStackTrace();
220 }
221 return 0D;
222 }
223
224 @Override
225 public void receiveMessage(AgentID sender, Action action) {
226
227 super.receiveMessage(sender, action);
228
229 if (sender == null
230 || !((action instanceof Offer) || (action instanceof Accept))) {
231 return;
232 }
233
234 Bid bid = null;
235
236 if (!initialized) {
237 initializeOpponentInfo(sender);
238 }
239
240 if (action instanceof Offer) {
241 bid = ((Offer) action).getBid();
242 try {
243 totalHistory.add(new BidDetails(bid,
244 utilitySpace.getUtility(bid), timeline.getTime()));
245 } catch (Exception e) {
246 e.printStackTrace();
247 }
248 } else if (action instanceof Accept) {
249 bid = totalHistory.getLastBid();
250 }
251
252 OpponentInfo senderInfo = getOpponentInfoObjectOfSender(sender);
253 OpponentInfo otherInfo = getOpponentInfoObjectOfOther(sender);
254 updateOpponentBidHistory(senderInfo, bid);
255 updateCommonBids(otherInfo, bid);
256 updateOpponentModel(senderInfo);
257 }
258
259 private void updateCommonBids(OpponentInfo otherInfo, Bid bid) {
260 if (otherInfo == null) {
261 return;
262 }
263 if (otherInfo.containsBid(bid)) {
264 try {
265 this.AandBscommonBids
266 .add(new BidDetails(bid, utilitySpace.getUtility(bid)));
267 } catch (Exception e) {
268 e.printStackTrace();
269 }
270 }
271
272 }
273
274 private OpponentInfo getOpponentInfoObjectOfOther(Object sender) {
275
276 if (infoA != null && infoA.getAgentID().equals(sender.toString())) {
277 return infoB;
278 } else if (infoB != null
279 && infoB.getAgentID().equals(sender.toString())) {
280 return infoA;
281 }
282
283 return null;
284
285 }
286
287 private void updateOpponentModel(OpponentInfo senderInfo) {
288
289 if (senderInfo == null) {
290 return;
291 }
292
293 // CODE TO LEARN OPPONENT CONCESSION
294 if (senderInfo.getAgentBidHistory().size() >= minimumHistorySize) {
295 LearningFunction function = new LearningFunction(
296 senderInfo.getAgentBidHistory().getHistory().get(0)
297 .getMyUndiscountedUtil());
298 double xData[] = new double[senderInfo.getBestBids().size()];
299 double yData[] = new double[senderInfo.getBestBids().size()];
300 double yWeights[] = new double[senderInfo.getBestBids().size()];
301 double step[] = { 0.005, 0.005 };
302 double initialEstimates[] = { alphaDefault, betaDefault };
303 for (int i = 0; i < senderInfo.getBestBids().size(); i++) {
304 xData[i] = senderInfo.getBestBids().getHistory().get(i)
305 .getTime();
306 yData[i] = senderInfo.getBestBids().getHistory().get(i)
307 .getMyUndiscountedUtil();
308 yWeights[i] = senderInfo.getBidPointWeights().get(i);
309 }
310 Regression regression = new Regression(xData, yData, yWeights);
311
312 regression.simplex(function, initialEstimates, step);
313
314 double[] bestEstimates = regression.getBestEstimates();
315 double alpha = bestEstimates[0];
316 double beta = bestEstimates[1];
317 double slopeStandardScale = Math.pow(Math.E, alpha) * beta
318 * Math.pow(timeline.getTime(), beta - 1);
319 double slopeFromZeroToOne = Math.atan(slopeStandardScale)
320 / (Math.PI / 2);
321 double adjustedLeniency = slopeFromZeroToOne
322 + slopeFromZeroToOne / leniencyAdjuster;
323 if (adjustedLeniency > 1) {
324 adjustedLeniency = 1;
325 }
326 senderInfo.setLeniency(adjustedLeniency);
327 } else {
328 senderInfo.setLeniency(-1D);
329 }
330
331 // CODE TO LEARN OPPONENT PREFERENCES
332 AdditiveUtilitySpace opponentUtilitySpace = senderInfo
333 .getOpponentUtilitySpace();
334
335 if (senderInfo.getAgentBidHistory().size() < 2) {
336 return;
337 }
338
339 int numberOfUnchanged = 0;
340 int numberOfIssues = opponentUtilitySpace.getDomain().getIssues()
341 .size();
342 BidHistory opponentsBidHistory = senderInfo.getAgentBidHistory();
343 BidDetails opponentsLatestBid = opponentsBidHistory.getLastBidDetails();
344 BidDetails opponentsSecondLastBid = opponentsBidHistory.getHistory()
345 .get(opponentsBidHistory.size() - 2);
346 HashMap<Integer, Boolean> changed = determineDifference(senderInfo,
347 opponentsSecondLastBid, opponentsLatestBid);
348
349 for (Boolean hasChanged : changed.values()) {
350 if (!hasChanged) {
351 numberOfUnchanged++;
352 }
353 }
354
355 double goldenValue = issueWeightsConstant
356 * (1 - (Math.pow(timeline.getTime(),
357 learningTimeController
358 + utilitySpace.getDiscountFactor())))
359 / numberOfIssues;
360 double totalSum = 1D + goldenValue * numberOfUnchanged;
361 double maximumWeight = 1D - (numberOfIssues) * goldenValue / totalSum;
362
363 for (Integer issueNumber : changed.keySet()) {
364 if (!changed.get(issueNumber) && opponentUtilitySpace
365 .getWeight(issueNumber) < maximumWeight) {
366 opponentUtilitySpace.setWeight(
367 opponentUtilitySpace.getDomain().getObjectivesRoot()
368 .getObjective(issueNumber),
369 (opponentUtilitySpace.getWeight(issueNumber)
370 + goldenValue) / totalSum);
371 } else {
372 opponentUtilitySpace.setWeight(
373 opponentUtilitySpace.getDomain().getObjectivesRoot()
374 .getObjective(issueNumber),
375 opponentUtilitySpace.getWeight(issueNumber) / totalSum);
376 }
377 }
378
379 try {
380 for (Entry<Objective, Evaluator> issueEvaluatorEntry : opponentUtilitySpace
381 .getEvaluators()) {
382 if (issueEvaluatorEntry.getKey() instanceof IssueDiscrete) {
383 ((EvaluatorDiscrete) issueEvaluatorEntry.getValue())
384 .setEvaluation(
385 opponentsLatestBid.getBid().getValue(
386 ((IssueDiscrete) issueEvaluatorEntry
387 .getKey()).getNumber()),
388 (int) (issueValuesConstant
389 * (1 - Math.pow(timeline.getTime(),
390 learningTimeController
391 + utilitySpace
392 .getDiscountFactor()))
393 + ((EvaluatorDiscrete) issueEvaluatorEntry
394 .getValue())
395 .getEvaluationNotNormalized(
396 (ValueDiscrete) opponentsLatestBid
397 .getBid()
398 .getValue(
399 ((IssueDiscrete) issueEvaluatorEntry
400 .getKey())
401 .getNumber()))));
402 } else if (issueEvaluatorEntry
403 .getKey() instanceof IssueInteger) {
404 int issueNumber = ((IssueInteger) issueEvaluatorEntry
405 .getKey()).getNumber();
406 Value opponentsLatestValueForIssue = opponentsLatestBid
407 .getBid().getValue(issueNumber);
408 int opponentsLatestValueForIssueAsInteger = ((ValueInteger) opponentsLatestValueForIssue)
409 .getValue();
410
411 int upperBound = ((IssueInteger) issueEvaluatorEntry
412 .getKey()).getUpperBound();
413 int lowerBound = ((IssueInteger) issueEvaluatorEntry
414 .getKey()).getLowerBound();
415 double midPoint = Math.ceil(
416 lowerBound + (upperBound - lowerBound) / 2) + 1;
417
418 if (midPoint > opponentsLatestValueForIssueAsInteger) {
419 double distanceFromMidPoint = midPoint
420 - opponentsLatestValueForIssueAsInteger;
421 double normalizedDistanceFromMidPoint = distanceFromMidPoint
422 / (midPoint - lowerBound);
423
424 double total = 1;
425 double newLowEndEvaluation = ((EvaluatorInteger) issueEvaluatorEntry
426 .getValue()).getEvaluation(lowerBound)
427 + (issueValuesConstant / 10000)
428 * normalizedDistanceFromMidPoint
429 * (1 - Math.pow(timeline.getTime(),
430 learningTimeController
431 + utilitySpace
432 .getDiscountFactor()));
433 double highEndEvaluation = ((EvaluatorInteger) issueEvaluatorEntry
434 .getValue()).getEvaluation(upperBound);
435
436 if (newLowEndEvaluation > 1) {
437 total = newLowEndEvaluation + highEndEvaluation;
438 }
439
440 ((EvaluatorInteger) issueEvaluatorEntry.getValue())
441 .setLinearFunction(newLowEndEvaluation / total,
442 highEndEvaluation / total);
443 } else {
444 double distanceFromMidPoint = opponentsLatestValueForIssueAsInteger
445 - midPoint + 1; // because
446 // midPoint
447 // is
448 // included
449 // and
450 // I
451 // don't
452 // want
453 // a
454 // 0
455 // value.
456 double normalizedDistanceFromMidPoint = distanceFromMidPoint
457 / (upperBound - midPoint + 1);
458
459 double total = 1;
460 double newHighEndEvaluation = ((EvaluatorInteger) issueEvaluatorEntry
461 .getValue()).getEvaluation(upperBound)
462 + (issueValuesConstant / 10000)
463 * normalizedDistanceFromMidPoint
464 * (1 - Math.pow(timeline.getTime(),
465 learningTimeController
466 + utilitySpace
467 .getDiscountFactor()));
468 double lowEndEvaluation = ((EvaluatorInteger) issueEvaluatorEntry
469 .getValue()).getEvaluation(lowerBound);
470
471 if (newHighEndEvaluation > 1) {
472 total = newHighEndEvaluation + lowEndEvaluation;
473 }
474
475 ((EvaluatorInteger) issueEvaluatorEntry.getValue())
476 .setLinearFunction(lowEndEvaluation / total,
477 newHighEndEvaluation / total);
478 }
479 }
480 }
481 } catch (Exception e) {
482 e.printStackTrace();
483 }
484
485 try {
486
487 BidSpace bidSpace = new BidSpace(this.utilitySpace,
488 opponentUtilitySpace, true);
489 double kalaiPoint = bidSpace.getKalaiSmorodinsky().getUtilityA();
490
491 // UNCOMMENT THE FOLLOWING LINES IF THE ESTIMATED KALAI POINT IS A
492 // BIT TOO CONSERVATIVE
493
494 if (kalaiPoint <= 0.4) {
495 kalaiPoint = kalaiPoint + kalaiPointCorrection;
496 } else if (kalaiPoint <= 0.7) {
497 kalaiPoint = kalaiPoint + (kalaiPointCorrection / 2);
498 }
499
500 if (kalaiPoint > senderInfo.getBestBids().getBestBidDetails()
501 .getMyUndiscountedUtil()) {
502 senderInfo.setDomainCompetitiveness(kalaiPoint);
503 } else {
504 senderInfo.setDomainCompetitiveness(senderInfo.getBestBids()
505 .getBestBidDetails().getMyUndiscountedUtil());
506 }
507
508 if (senderInfo.getAgentBidHistory().size() >= minimumHistorySize) {
509 // TODO Changeable formulas
510 double domainWeight = (1 - Math.pow(senderInfo.getLeniency(),
511 domainWeightController));
512 double agentDifficulty = (1 - domainWeight)
513 * senderInfo.getLeniency()
514 + domainWeight * senderInfo.getDomainCompetitiveness();
515 senderInfo.setAgentDifficulty(agentDifficulty);
516 } else {
517 double agentDifficulty = senderInfo.getDomainCompetitiveness();
518 senderInfo.setAgentDifficulty(agentDifficulty);
519 }
520 } catch (Exception e) {
521
522 e.printStackTrace();
523 }
524
525 }
526
527 private HashMap<Integer, Boolean> determineDifference(
528 OpponentInfo senderInfo, BidDetails first, BidDetails second) {
529 HashMap<Integer, Boolean> changed = new HashMap<Integer, Boolean>();
530 try {
531 for (Issue i : senderInfo.getOpponentUtilitySpace().getDomain()
532 .getIssues()) {
533 if (i instanceof IssueDiscrete) {
534 changed.put(i.getNumber(),
535 (((ValueDiscrete) first.getBid()
536 .getValue(i.getNumber()))
537 .equals(second.getBid()
538 .getValue(i.getNumber())))
539 ? false : true);
540 } else if (i instanceof IssueInteger) {
541 changed.put(i.getNumber(),
542 (((ValueInteger) first.getBid()
543 .getValue(i.getNumber()))
544 .equals(second.getBid()
545 .getValue(i.getNumber())))
546 ? false : true);
547 }
548 }
549 } catch (Exception ex) {
550 ex.printStackTrace();
551 }
552
553 return changed;
554 }
555
556 private OpponentInfo getOpponentInfoObjectOfSender(Object sender) {
557 if (infoA != null && infoA.getAgentID().equals(sender.toString())) {
558 return infoA;
559 } else if (infoB != null
560 && infoB.getAgentID().equals(sender.toString())) {
561 return infoB;
562 }
563
564 return null;
565 }
566
567 private void initializeOpponentInfo(Object sender) {
568 if (infoA == null) {
569 infoA = new OpponentInfo(sender.toString(),
570 (AdditiveUtilitySpace) utilitySpace);
571 } else if (infoB == null) {
572 infoB = new OpponentInfo(sender.toString(),
573 (AdditiveUtilitySpace) utilitySpace);
574 }
575
576 if (infoA != null && infoB != null) {
577 initialized = true;
578 }
579 }
580
581 private void updateOpponentBidHistory(OpponentInfo opponent, Bid bid) {
582
583 if (opponent == null || bid == null) {
584 return;
585 }
586
587 try {
588 opponent.getAgentBidHistory().add(new BidDetails(bid,
589 utilitySpace.getUtility(bid), timeline.getTime()));
590
591 for (Integer i : opponent.getBidPointWeights()) {
592 if (i > 1) {
593 i--;
594 }
595 }
596 opponent.getBidPointWeights().add(maxWeightForBidPoint);
597
598 if (opponent.getBestBid() == null
599 || utilitySpace.getUtility(bid) >= utilitySpace
600 .getUtility(opponent.getBestBid())) {
601 opponent.setBestBid(bid);
602 opponent.getBestBids().add(new BidDetails(bid,
603 utilitySpace.getUtility(bid), timeline.getTime()));
604 } else {
605 opponent.getBestBids()
606 .add(new BidDetails(opponent.getBestBid(),
607 utilitySpace.getUtility(opponent.getBestBid()),
608 timeline.getTime()));
609
610 }
611 } catch (Exception e) {
612 e.printStackTrace();
613 }
614
615 }
616
617 @Override
618 public String getDescription() {
619 return "ANAC2015";
620 }
621
622}
Note: See TracBrowser for help on using the repository browser.