source: anac2020/AzarAgent/src/main/java/geniusweb/exampleparties/simpleshaop/ShaopParty.java@ 14

Last change on this file since 14 was 1, checked in by wouter, 4 years ago

#1910 added anac2020 parties

File size: 20.7 KB
Line 
1package geniusweb.exampleparties.simpleshaop;
2
3import java.io.IOException;
4import java.math.BigInteger;
5import java.util.ArrayList;
6import java.util.Arrays;
7import java.util.HashSet;
8import java.util.List;
9import java.util.Map;
10import java.util.Random;
11import java.util.logging.Level;
12import javax.websocket.DeploymentException;
13import geniusweb.actions.Accept;
14import geniusweb.actions.Action;
15import geniusweb.actions.Comparison;
16import geniusweb.actions.ElicitComparison;
17import geniusweb.actions.EndNegotiation;
18import geniusweb.actions.Offer;
19import geniusweb.actions.PartyId;
20import geniusweb.bidspace.AllBidsList;
21import geniusweb.issuevalue.Bid;
22import geniusweb.issuevalue.Domain;
23import geniusweb.party.Capabilities;
24import geniusweb.party.DefaultParty;
25import geniusweb.party.inform.ActionDone;
26import geniusweb.party.inform.Finished;
27import geniusweb.party.inform.Inform;
28import geniusweb.party.inform.Settings;
29import geniusweb.party.inform.YourTurn;
30import geniusweb.profile.PartialOrdering;
31import geniusweb.profile.Profile;
32import geniusweb.profileconnection.ProfileConnectionFactory;
33import geniusweb.profileconnection.ProfileInterface;
34import geniusweb.progress.Progress;
35import geniusweb.progress.ProgressRounds;
36import tudelft.utilities.logging.Reporter;
37
38/**
39 * This Agent work on partial preference and use
40 * the GravityAgent ( ANAC 2019 competition ) user model
41 * to model user and use Frequency method to model our opponent.
42 *
43 * @author Arash Ebrahinezhad
44 *
45 * Arash.ebrah@gmail.com
46 * arash.ebrah@nit.ac.ir
47 */
48public class ShaopParty extends DefaultParty {
49
50 private Random rand = new Random();
51
52 private int numberOfSameConsecutiveBidInMyBids = 0;
53 private double eCost; // Elicitation Cost
54 private double rValue; // Reservation Value
55 private FrequencyModel opModel; // Opponent Model
56 private boolean myConcessionEnough = false;
57 private GravityEs myModel2; // User Model
58 private Bid receivedBid = null; // Last Received bid
59 ArrayList<Bid> oppBids = new ArrayList<Bid>(); // All Bids that received from Opponent
60 ArrayList<Bid> myBids = new ArrayList<Bid>(); // All Bids that we sent to opponent
61 private List<Bid> bidOrder;
62 private int allBidSize;
63 private List<Double> expectedValue; // توزیع احتمالاتی بیدهای در بین بیدهای مرتب شده
64
65 // Time depending bidding strategy : boulware or conceder
66 private double e = 0.8;
67 private static final double k = 0;
68 private int afterRank = 2; // How many rank after our estimation bid rank must be checked
69 private int beforeRank = 1; // How many rank before our estimation bid rank must be checked
70 private double agreementSimilarityThreshold; // threshold of similarity for acceptance Strategy
71 private double opponentConcesionRate = 0.08; // our expected opponent concession rate
72 private int howManyRankMustBeChecked = 5; // threshold of bid rank which we mast to check if Estimation rank satisfy the condition
73
74 double Pagreement; // the threshold of bid agreement by opponent we must to select ( control our concession strategy )
75
76 ////////////////////////////////////////////////////////////////////////////////////////////
77 private Bid reservationBid;
78 private PartyId me;
79 protected ProfileInterface profileint;
80 private Progress progress;
81
82 private USpace utilitySpace;
83 private Profile profile;
84 private Domain domain;
85 private AllBidsList allBids;
86 private double totalBother = 0;
87 private SimpleLinearOrdering estimatedProfile = null;
88 ////////////////////////////////////////////////////////////////////////////////////////////
89
90
91 public ShaopParty() {
92 }
93
94 public ShaopParty(Reporter reporter) {
95 super(reporter); // for debugging
96 }
97
98
99 private void init(Settings info) throws IOException, DeploymentException {
100
101 Settings settings = (Settings) info;
102 this.profileint = ProfileConnectionFactory
103 .create(settings.getProfile().getURI(), getReporter());
104 this.me = settings.getID();
105 this.progress = settings.getProgress();
106
107 this.profile = profileint.getProfile();
108 this.domain = this.profile.getDomain();
109 utilitySpace = new USpace(this.domain);
110 allBids = new AllBidsList(profileint.getProfile().getDomain());
111
112
113 if ( reservationBid != null ) // if the reservation bid does not exist so we accept opponent bid with more probability
114 agreementSimilarityThreshold = 0.85;
115 else
116 agreementSimilarityThreshold = 0.7;
117
118
119 estimatedProfile = new SimpleLinearOrdering( profile );
120 List<Bid> bOr = new ArrayList<Bid>();
121 if ( estimatedProfile.getBids().size() == 2 ) { // if ordered bids size equal 2, add reservation value or random Bid
122
123 bOr.add( estimatedProfile.getBids().get(0) );
124
125 if(reservationBid != null &&
126 !reservationBid.equals(estimatedProfile.getBids().get(0)) &&
127 !reservationBid.equals(estimatedProfile.getBids().get(1)) )
128 bOr.add( reservationBid );
129 else
130 while ( true ) {
131 long i = rand.nextInt(allBids.size().intValue());
132 Bid randBid = allBids.get(BigInteger.valueOf(i));
133 if ( !randBid.equals(estimatedProfile.getBids().get(0)) &&
134 !randBid.equals(estimatedProfile.getBids().get(1)) ) {
135 bOr.add( randBid );
136 break;
137 }
138 }
139
140 bOr.add( estimatedProfile.getBids().get(1) );
141
142 estimatedProfile = new SimpleLinearOrdering(domain, bOr);
143
144 }
145
146
147 bidOrder = estimatedProfile.getBids();
148
149
150 try { // if elicitation cost is set, catch it, else set it 0.1
151 eCost = (double) settings.getParameters().get("elicitationcost");
152 } catch (Exception e) {
153 eCost = 0.1; // if elicitation cost is not set, we set it to 0.1
154 }
155
156 try { // if reservation Bid is set, catch it, else set it null
157 reservationBid = profile.getReservationBid();
158 }catch (Exception e) {
159 reservationBid = null;
160 }
161
162 opModel = new FrequencyModel(utilitySpace);
163
164
165
166
167 allBidSize = allBids.size().intValue();
168 expectedValue = new ArrayList<Double>();
169 initExpectedValue();
170
171 myModel2 = new GravityEs(domain, bidOrder);
172
173 //myModel = new WinkyA2(domain, bidOrder, profileint);
174
175 if ( reservationBid != null ) // if reservation bid is set, set the reservation value to utility of it
176 rValue = myModel2.getUtilityForBid(reservationBid); // این قسمت شاید تغییر کند
177 else
178 rValue = 0;
179
180
181 }
182
183 public void initExpectedValue() {
184 for ( int i = 0; i < bidOrder.size()-1; i++ )
185 expectedValue.add((double)1.0/(bidOrder.size()-1));
186
187 }
188
189 private void updateExpectedUtility() {
190 expectedValue.clear();
191 for ( int i = 0; i < bidOrder.size()-1; i++ )
192 expectedValue.add((double)1.0/(bidOrder.size()-1));
193 }
194
195 @Override
196 public void notifyChange(Inform info) {
197 try {
198 if (info instanceof Settings) {
199 init( (Settings) info);
200 } else if (info instanceof ActionDone) {
201 Action otheract = ((ActionDone) info).getAction();
202 if (otheract instanceof Offer) {
203 receivedBid = ((Offer) otheract).getBid();
204 opModel.updateLearner(receivedBid);
205 } else if (otheract instanceof Comparison) {
206 totalBother += eCost; // شاید این قسمت تغییر کند
207 estimatedProfile = estimatedProfile.with(
208 ((Comparison) otheract).getBid(),
209 ((Comparison) otheract).getWorse());
210 bidOrder = estimatedProfile.getBids(); // After each elicitation update bidOrder
211 updateExpectedUtility();
212 myModel2 = myModel2.updateGravityModel(bidOrder); // After each elicitation update User Model
213 if ( reservationBid != null )
214 rValue = myModel2.getUtilityForBid(reservationBid); // After each elicitation update reservation value
215 myTurn(true);
216 }
217 } else if (info instanceof YourTurn) {
218 myTurn(false);
219 } else if (info instanceof Finished) {
220 getReporter().log(Level.INFO, "Final ourcome:" + info);
221 }
222 } catch (Exception e) {
223 throw new RuntimeException("Failed to handle info", e);
224 }
225 }
226
227 @Override
228 public Capabilities getCapabilities() {
229 return new Capabilities(new HashSet<>(Arrays.asList("SHAOP")));
230 }
231
232 @Override
233 public String getDescription() {
234 return "Azar Agent ANAC 2020";
235 }
236
237 /**
238 * Called when it's (still) our turn and we should take some action. Also
239 * Updates the progress if necessary.
240 */
241 void myTurn(boolean elicitation) throws IOException {
242
243 Action action = null;
244
245 if ( !elicitation && !myConcessionEnough ) {
246 double t = progress.get(System.currentTimeMillis());
247 Pagreement = getPagreement(t);
248 }
249
250
251 // Elicitation Strategy and Bidding Strategy
252 //log2("--------------------------------<Elicitation start>------------------------------------"+Pagreement);
253 MyBidDetails bidDetail = null;
254
255 if ( totalBother < 0.6 /*1-rValue*/ ) { // تا زمانی که به مقدار رزرویشن نرسیدیم، الیسیتیشن رو ادامه بده
256 bidDetail = getBestBidInKnownSet( Pagreement, elicitation );
257
258 MyBidDetails bidDetailPrim = getBestBidInUnKnownSet( Pagreement );
259
260 // Only for log!!!
261 //String s = " Is this ("+bidDetailPrim.getEu()+" - "+eCost+" > "+bidDetail.getEu() + ") True?";
262 //s +=( (bidDetailPrim.getEu() - eCost > bidDetail.getEu()) ) ? " True => Elicit" : " False => not Elicit";
263 //log2( s );
264
265 if ( bidDetailPrim.getEu() - eCost > bidDetail.getEu() )
266 action = new ElicitComparison(me, bidDetailPrim.getBid(), estimatedProfile.getBids());
267
268 } else {
269 //log2("Elicitation total bother is more than 0.6 !!!");
270 }
271 //log2("---------------------------------<Elicitation End>-------------------------------------\n\n");
272
273
274 if(bidDetail == null) {
275 if(reservationBid != null)
276 bidDetail = new MyBidDetails(reservationBid, 0.5);
277 else
278 if ( bidOrder.size() > 10 )
279 bidDetail = new MyBidDetails(bidOrder.get(bidOrder.size()/2), 1.0);
280 else
281 bidDetail = new MyBidDetails(bidOrder.get(bidOrder.size()-1), 1.0);
282 }
283
284
285 if ( action == null && receivedBid != null ) {
286 if ( isGood(receivedBid,bidDetail.getBid()) )
287 action = new Accept(me, receivedBid);
288
289 if (progress instanceof ProgressRounds)
290 progress = ((ProgressRounds) progress).advance();
291
292 }
293
294
295 if ( action == null ) {
296 Bid myBid = bidDetail.getBid();
297
298 if ( myModel2.getUtilityForBid(myBid) > rValue ) {
299
300 if ( myBids.isEmpty() )
301 myBids.add(myBid);
302 if (!myBids.contains(myBid) )
303 myBids.add(myBid);
304
305
306
307
308 if ( myBids.size() > 1 )
309 if ( myBids.get( myBids.size()-1 ).equals( myBids.get( myBids.size()-2 ) ) )
310 numberOfSameConsecutiveBidInMyBids++;
311 else
312 numberOfSameConsecutiveBidInMyBids = 0;
313
314
315
316
317
318
319 action = new Offer(me, myBid );
320 } else
321 action = new EndNegotiation(me);
322
323 }
324
325 getConnection().send(action);
326
327 }
328
329
330
331
332 //***************************************************************************************
333
334 /**
335 * Acceptance Strategy
336 *
337 * @param reBid the last received bid from opponent
338 *
339 * @param nextBid the next bid that we prepare to send to opponent
340 *
341 * @return true if we must accept opponent offer and false vice versa
342 */
343 private boolean isGood( Bid reBid, Bid nextBid ) {
344
345 if ( oppBids.isEmpty() || !oppBids.contains(reBid) ) // اگر این بید را قبلا دریافت نکرده باشیم اضافه کن
346 oppBids.add(reBid);
347
348
349
350 if ( myModel2.getUtilityForBid(reBid) < rValue )
351 return false;
352
353 if ( reBid.equals(nextBid) )
354 return true;
355
356 if ( myBids.contains(reBid) )
357 return true;
358
359 if ( myModel2.getUtilityForBid(reBid) >= myModel2.getUtilityForBid(nextBid) )
360 return true;
361
362 for ( Bid b : myBids )
363 if ( myModel2.getUtilityForBid(reBid) >= myModel2.getUtilityForBid(b)+ 0.07 )
364 return true;
365
366
367 double currentAgreementSimilarityThreshold = ((1 - Pagreement) > agreementSimilarityThreshold) ?
368 (1 - Pagreement) :
369 agreementSimilarityThreshold;
370
371 return (getAcceptanceProbability(reBid, nextBid) > currentAgreementSimilarityThreshold ? true : false) &&
372 myModel2.getUtilityForBid(reBid) > rValue;
373
374
375 }
376
377 /**
378 *
379 * @param reBid Last Received Bid From Opponent
380 * @param nextBid the next bid that we prepare send to opponent
381 *
382 * @return double value that determine maximum
383 * similarity (1-distance) value of received
384 * bid from opponent to our sent bids
385 */
386 private double getAcceptanceProbability( Bid reBid,Bid nextBid) {
387
388 double t = Double.MAX_VALUE;
389
390 double reBidU = myModel2.getUtilityForBid(reBid);
391
392 //for ( Bid b : oppBids ) {
393 for ( Bid b : myBids ) {
394 double temp = 1 - Math.abs( myModel2.getUtilityForBid(b) - reBidU );
395 if( temp < t ) {
396 t = temp;
397 }
398 }
399
400 double nextBidU = myModel2.getUtilityForBid( nextBid );
401 if ( ( 1 - Math.abs( nextBidU - reBidU ) ) < t )
402 return ( 1 - Math.abs( nextBidU - reBidU ) );
403
404 return t;
405
406 }
407
408
409
410 /**
411 *
412 * @param the Agreement probability of the bid that we
413 * want decide about its elicitation must be more than it.
414 *
415 * @return the best bid and its utility (MyBidDetails object) in the
416 * set of bids which we know about its order.
417 */
418 private MyBidDetails getBestBidInKnownSet( double Pagreement1, boolean elicitation ) {
419
420
421 for ( int i = bidOrder.size()-1; i > 0; i-- ) {
422 double Pat = getAgreementProbability( bidOrder.get(i) );
423 if ( Pat >= Pagreement1 && myModel2.getUtilityForBid( bidOrder.get(i) ) > myModel2.getUtilityForBid( bidOrder.get(i) )/2 ) {
424 if ( myBids.size() > 1 )
425 if ( myModel2.getUtilityForBid( myBids.get(myBids.size()-1) ) - myModel2.getUtilityForBid(bidOrder.get(i)) > 0.3 )
426 if ( myModel2.getUtilityForBid(bidOrder.get(i))-0.3 > 0 )
427 return new MyBidDetails(bidOrder.get(i), myModel2.getUtilityForBid(bidOrder.get(i))-0.3);
428 else
429 return new MyBidDetails(null, 0.0);
430
431 return new MyBidDetails(bidOrder.get(i), myModel2.getUtilityForBid(bidOrder.get(i)) );
432 }
433 }
434
435
436
437 return new MyBidDetails(null, 0.0);
438
439 /*
440 if ( myBids.size() > 0 ) {
441
442 if( myModel2.getUtilityForBid( myBids.get( myBids.size()-1 ))-(numberOfSameConsecutiveBidInMyBids*0.1) > 0 )
443 return new MyBidDetails(myBids.get( myBids.size()-1 ), myModel2.getUtilityForBid( myBids.get( myBids.size()-1 ))-(numberOfSameConsecutiveBidInMyBids*0.1) );
444 else
445 return new MyBidDetails(myBids.get( myBids.size()-1 ), 0.0 );
446
447 }
448 else
449 return new MyBidDetails(bidOrder.get( bidOrder.size()-1 ), myModel2.getUtilityForBid( bidOrder.get( bidOrder.size()-1 )) );
450 */
451
452 }
453
454 /**
455 *
456 * @param Pagreement2 the Agreement probability of the bid that we
457 * want decide about its elicitation must be more than it.
458 *
459 * @return the best bid in the bids set that we don't know about
460 * their orders respect to if we would elicit it.
461 */
462 private MyBidDetails getBestBidInUnKnownSet( double Pagreement2 ) {
463
464 /*
465 * for decrease the size of variety Check the probabilities
466 * we check only bids with high estimation rank and high utility
467 */
468
469
470
471 int estimateBidRank = 0;
472
473 double EEu = 0;
474 Bid bestBid = null;
475
476
477 for ( Bid bid : allBids) {
478
479 if ( !bidOrder.contains(bid) ) {
480
481 double Pat = getAgreementProbability(bid);
482
483
484
485
486 if( Pat > Pagreement2 /*&& myModel2.getUtilityForBid(bid) > bidThreshold*/ ) {
487
488 estimateBidRank = getEstimateBidRank(bid);
489
490 if ( estimateBidRank >= (bidOrder.size()-1)-howManyRankMustBeChecked ) {
491
492 double tempEu = getNewEu(estimateBidRank, bid);
493
494 double tempEEu = tempEu/*Pat*/;
495
496 if ( tempEEu > EEu ) {
497 EEu = tempEEu;
498 bestBid = bid;
499 }
500
501 }
502 }
503 }
504
505 }
506 if ( bestBid != null )
507 return new MyBidDetails(bestBid, EEu);
508
509 else
510 return new MyBidDetails(null, 0.0);
511
512
513
514 }
515
516
517
518 /**
519 *
520 * @param bid the bid we want estimate about its bid rank
521 * with our current knowledge
522 * @return estimated bid rank
523 */
524 private int getEstimateBidRank( Bid bid ) {
525
526
527 double tempU = myModel2.getUtilityForBid(bid);
528
529 int rank = 0;
530 for ( Bid b : bidOrder ) {
531
532 double bU = myModel2.getUtilityForBid(b);
533
534 if ( tempU <= bU ) {
535 break;
536 }
537 else
538 rank++;
539
540 }
541 if ( rank == 0 )
542 rank = 1;
543
544 return rank;
545
546
547 }
548
549 /**
550 *
551 * @param rank the rank of the bid that we estimate with current knowledge
552 * @param bid the bid which we want estimate its utility if it is elicited
553 * @return the our expected utility of bid that if we would elicite it
554 */
555 private double getNewEu(int rank, Bid bid) {
556
557 expectedValue.clear();
558 expectedValue = getNewExpectedValue(rank);
559
560 double newEU = 0;
561 int bidOrderSize2 = bidOrder.size();
562
563 if ( rank == bidOrderSize2-1 )
564 return myModel2.getUtilityForBid(bid);
565
566 int aJ = 0;
567 for (int j = rank; j <= Integer.min(rank+afterRank, bidOrderSize2-1); j++) { // ما بعد
568
569 List<Bid> bidOrderProbability2 = new ArrayList<Bid>();
570
571 for ( Bid b : bidOrder )
572 bidOrderProbability2.add(b);
573
574 double probabilityBelong = expectedValue.get(j-1);//*bidOrderSize2;
575
576 bidOrderProbability2.add(j, bid);
577
578 GravityEs modelProbability2 = new GravityEs(domain, bidOrderProbability2);
579
580 newEU += probabilityBelong*( modelProbability2.getUtilityForBid(bid) );
581 aJ++;
582 }
583 if ( rank > 1 ) {
584 for (int j = rank-1; j > Integer.min( Integer.max(0,aJ-1), Integer.max(0, rank-beforeRank)); j--) { // ما قبل
585
586 List<Bid> bidOrderProbability1 = new ArrayList<Bid>();
587
588 for ( Bid b : bidOrder )
589 bidOrderProbability1.add(b);
590
591 double probabilityBelong = expectedValue.get(j-1);//*bidOrderSize2;
592 bidOrderProbability1.add(j, bid);
593
594 GravityEs modelProbability1 = new GravityEs(domain, bidOrderProbability1);
595
596 newEU += probabilityBelong*( modelProbability1.getUtilityForBid(bid) );
597
598 }
599 }
600
601
602
603 return newEU;
604
605 }
606
607 /**
608 *
609 * @param rank the rank of the bid that we estimate with current knowledge
610 * @return probability distribution of bid in variety ranks,
611 * that we want decide about its elicitation
612 */
613 private List<Double> getNewExpectedValue(int rank)
614 {
615
616 double certainty = (double)bidOrder.size()/allBidSize;
617
618 List<Double> expectedValue = new ArrayList<Double>();
619 for ( int i = 0; i < bidOrder.size(); i++ )
620 expectedValue.add((double)1.0/(bidOrder.size()-1));
621
622
623 double temp1 = expectedValue.size();
624 for (int i = rank; i > 0; i--) {
625 double ttemp = expectedValue.get(i-1);
626 expectedValue.remove( i-1);
627 expectedValue.add( i-1, (temp1*certainty)+ttemp);
628 temp1--;
629 }
630
631 double temp2 = expectedValue.size()-1;
632 for ( int i = rank+1; i<= expectedValue.size(); i++) {
633 double ttemp = expectedValue.get(i-1);
634 expectedValue.remove( i-1);
635 expectedValue.add( i-1, (temp2*certainty)+ttemp );
636 temp2--;
637 }
638
639
640
641 double n = 0;
642 for ( double t : expectedValue )
643 n += t;
644
645 for (int i = 0; i < expectedValue.size(); i++) {
646 double tTemp = expectedValue.get(i);
647 expectedValue.remove(i);
648 expectedValue.add(i, (double)tTemp/n );
649 }
650
651 return expectedValue;
652
653 }
654
655
656 private double f(double t) {
657 if (e == 0)
658 return k;
659 double ft = k + (1 - k) * Math.pow(t, 1 / e);
660
661 return ft;
662 }
663
664 /**
665 *
666 * @param t Time (if we want use time for compute concession rate)
667 * @return double value that the agent must be found
668 * a bid that has Agreement Probability more than it.
669 */
670 private double getPagreement(double t) {
671
672 //if ( reservationBid != null || t <= 0.7 )
673 return Pagreement+0.01;
674 //else
675 //return Pagreement+0.01; // 0.02
676 //return 1 - ( myEstimateMin + (myEstimateMax - myEstimateMin) * (1 - f(t)) );
677 }
678
679
680 /**
681 *
682 * Opponent Model
683 *
684 * @param bid the bid want to know its agreement probability
685 * with opponent
686 *
687 * @return double value which determine opponent agreement
688 * probability of the bid
689 *
690 */
691 private double getAgreementProbability(Bid bid) {
692
693
694 if ( oppBids.isEmpty() ) { // if we don't got any bid from opponent
695 return 1.0;
696 }
697 if ( myBids.contains(bid) ) { // if we sent this bid before
698 return opponentConcesionRate*progress.get(System.currentTimeMillis());
699 }
700 if ( oppBids.contains(bid) ) { // if this bid is one of previous bids that we got from opponent
701 return 1.0;
702 }
703
704
705 double t = Double.MAX_VALUE;
706
707 for ( Bid b : oppBids ) {
708
709 double temp = 1 - Math.abs( opModel.getOpponentUtilitySpace().getUtility(b) - opModel.getOpponentUtilitySpace().getUtility(bid) );
710
711 if( temp < t ) {
712 t = temp;
713 }
714
715 }
716
717
718 return t;
719
720
721 }
722
723
724
725
726 //**********************************************************
727 //**********************************************************
728 //**********************************************************
729 //*********************** Test *************************
730 //**********************************************************
731 //**********************************************************
732 //**********************************************************
733
734
735 private void log(Object o) {
736
737 System.err.println(o);
738
739 }
740
741 private void log2(Object o) {
742
743 System.out.println(o);
744
745 }
746
747
748
749
750
751}
Note: See TracBrowser for help on using the repository browser.