[200] | 1 | package agents.anac.y2019.podagent;
|
---|
| 2 |
|
---|
| 3 | import java.util.Comparator;
|
---|
| 4 | import java.util.List;
|
---|
| 5 | import java.util.Map;
|
---|
| 6 | import java.util.Random;
|
---|
| 7 |
|
---|
| 8 | import genius.core.Bid;
|
---|
| 9 | import genius.core.bidding.BidDetails;
|
---|
| 10 | import genius.core.boaframework.NegotiationSession;
|
---|
| 11 | import genius.core.boaframework.OMStrategy;
|
---|
| 12 | import genius.core.boaframework.OfferingStrategy;
|
---|
| 13 | import genius.core.boaframework.OpponentModel;
|
---|
| 14 | import genius.core.boaframework.SortedOutcomeSpace;
|
---|
| 15 | import genius.core.misc.Range;
|
---|
| 16 | import genius.core.uncertainty.UserModel;
|
---|
| 17 |
|
---|
| 18 | public class Group1_BS extends OfferingStrategy {
|
---|
| 19 |
|
---|
| 20 | private final int HOW_MANY_BIDS_TO_START_WITH = 5;
|
---|
| 21 | private boolean panicMode = false;
|
---|
| 22 | private boolean extremePanicMode = false;
|
---|
| 23 | private double targetUtility = 1;
|
---|
| 24 | private double undiscountedTargetUtil = 1;
|
---|
| 25 | private double timeLimitForStep = 0.1;
|
---|
| 26 | private List<BidDetails> possibleBids = null;
|
---|
| 27 | private double lastStepTime = 0;
|
---|
| 28 | private NegotiationSession negoSession;
|
---|
| 29 | public OpponentModel opponentModel;
|
---|
| 30 | private SortedOutcomeSpace outcomespace;
|
---|
| 31 | private boolean hardHeaded = false;
|
---|
| 32 | private boolean omHardHeaded = false;
|
---|
| 33 | private Random rand = new Random();
|
---|
| 34 | private Double reservation;
|
---|
| 35 |
|
---|
| 36 |
|
---|
| 37 | @Override
|
---|
| 38 | public void init(NegotiationSession negoSession, OpponentModel model, OMStrategy oms,
|
---|
| 39 | Map<String, Double> parameters) throws Exception {
|
---|
| 40 | super.init(negoSession, parameters);
|
---|
| 41 | this.negoSession = negoSession;
|
---|
| 42 | this.reservation = negoSession.getUtilitySpace().getReservationValue();
|
---|
| 43 | if(this.reservation == null) {
|
---|
| 44 | System.out.println("No reservation");
|
---|
| 45 | }
|
---|
| 46 | this.opponentModel = model;
|
---|
| 47 | outcomespace = new SortedOutcomeSpace(negotiationSession.getUtilitySpace());
|
---|
| 48 | negotiationSession.setOutcomeSpace(outcomespace);
|
---|
| 49 | setNewStep();
|
---|
| 50 | }
|
---|
| 51 |
|
---|
| 52 | @Override
|
---|
| 53 | public BidDetails determineOpeningBid() {
|
---|
| 54 | int bidI = rand.nextInt(HOW_MANY_BIDS_TO_START_WITH);
|
---|
| 55 | bidI = Math.min(bidI, possibleBids.size() - 1);
|
---|
| 56 | return possibleBids.remove(bidI);
|
---|
| 57 | }
|
---|
| 58 |
|
---|
| 59 | @Override
|
---|
| 60 | public BidDetails determineNextBid() {
|
---|
| 61 | setPanicModeIfNeccesary();
|
---|
| 62 |
|
---|
| 63 | if (extremePanicMode) {
|
---|
| 64 | return negoSession.getOpponentBidHistory().getBestBidDetails();
|
---|
| 65 | }
|
---|
| 66 |
|
---|
| 67 | if (possibleBids.isEmpty() || negoSession.getTime() >= timeLimitForStep + lastStepTime || panicMode) {
|
---|
| 68 | setNewStep();
|
---|
| 69 | }
|
---|
| 70 | BidDetails bestBid = null;
|
---|
| 71 | double bestOpponentUtility = 0;
|
---|
| 72 | for (BidDetails bid : possibleBids) {
|
---|
| 73 | double opponentUtil = opponentModel.getBidEvaluation(bid.getBid());
|
---|
| 74 | if (opponentUtil > bestOpponentUtility) {
|
---|
| 75 | bestBid = bid;
|
---|
| 76 | bestOpponentUtility = opponentUtil;
|
---|
| 77 | }
|
---|
| 78 | }
|
---|
| 79 |
|
---|
| 80 | possibleBids.remove(bestBid);
|
---|
| 81 | return bestBid;
|
---|
| 82 | }
|
---|
| 83 |
|
---|
| 84 | @Override
|
---|
| 85 | public String getName() {
|
---|
| 86 | return "Group1_BS";
|
---|
| 87 | }
|
---|
| 88 |
|
---|
| 89 | /**
|
---|
| 90 | * Calculate concession rate depending on time and friendliness factor
|
---|
| 91 | *
|
---|
| 92 | * @return concession rate between 0 and 1
|
---|
| 93 | */
|
---|
| 94 | public double getCurrentConcessionRate() {
|
---|
| 95 | double time = negoSession.getTime(); // Between 0 and 1
|
---|
| 96 | double friendlinessFactor = getFriendlinessFactor();
|
---|
| 97 | // Concession function 1 - t^3
|
---|
| 98 | double timeDiscount = (this.undiscountedTargetUtil - (1 - Math.pow(time, 3)));
|
---|
| 99 | // Concession amount is scaled by friendliness factor
|
---|
| 100 | double discount = timeDiscount * friendlinessFactor;
|
---|
| 101 | this.undiscountedTargetUtil = (1 - Math.pow(time, 3));
|
---|
| 102 | double newUtility = this.targetUtility - discount;
|
---|
| 103 | if (newUtility < this.reservation) {
|
---|
| 104 | return this.reservation;
|
---|
| 105 | }
|
---|
| 106 | if (newUtility > 1) {
|
---|
| 107 | return 1;
|
---|
| 108 | } else if (newUtility < 0) {
|
---|
| 109 | return 0;
|
---|
| 110 | }
|
---|
| 111 | return newUtility;
|
---|
| 112 | }
|
---|
| 113 |
|
---|
| 114 | /**
|
---|
| 115 | * Reads the friendliness factor from the opponent model
|
---|
| 116 | *
|
---|
| 117 | * @return value between 0 and 1 that indicates the willingness of our opponent
|
---|
| 118 | * to cooperate
|
---|
| 119 | */
|
---|
| 120 | private double getFriendlinessFactor() {
|
---|
| 121 | // If the panic mode is on, ignore the friendliness factor
|
---|
| 122 | if (panicMode) {
|
---|
| 123 | return 1;
|
---|
| 124 | } else if (opponentModel instanceof Group1_OM) {
|
---|
| 125 | omHardHeaded = ((Group1_OM) opponentModel).isHardHeaded();
|
---|
| 126 | return ((Group1_OM) opponentModel).getOpponentSentiment(lastStepTime);
|
---|
| 127 | }
|
---|
| 128 | // Fallback
|
---|
| 129 | else {
|
---|
| 130 | return 0.5;
|
---|
| 131 | }
|
---|
| 132 | }
|
---|
| 133 |
|
---|
| 134 | /**
|
---|
| 135 | * Panic mode depending on passed time
|
---|
| 136 | */
|
---|
| 137 | private void setPanicModeIfNeccesary() {
|
---|
| 138 | // Extreme panic in the last 33% of panic mode
|
---|
| 139 | if (!extremePanicMode && 1 - negoSession.getTime() < 0.05 / 3) {
|
---|
| 140 | extremePanicMode = true;
|
---|
| 141 | }
|
---|
| 142 | // Panic in the last 5% of negotiation time
|
---|
| 143 | if (!panicMode && 1 - negoSession.getTime() < 0.05) {
|
---|
| 144 | panicMode = true;
|
---|
| 145 | hardHeaded = omHardHeaded;
|
---|
| 146 | }
|
---|
| 147 | }
|
---|
| 148 |
|
---|
| 149 | /**
|
---|
| 150 | * New step - recalculate concession and range of good bids
|
---|
| 151 | */
|
---|
| 152 | private void setNewStep() {
|
---|
| 153 | // Make sure the steps don't get too small
|
---|
| 154 | timeLimitForStep = timeLimitForStep > 0.01 ? timeLimitForStep * 0.9 : timeLimitForStep;
|
---|
| 155 | if (!hardHeaded) {
|
---|
| 156 | targetUtility = getCurrentConcessionRate();
|
---|
| 157 | } else {
|
---|
| 158 | // Go back to 1 against hard headed opponents
|
---|
| 159 | targetUtility = 1;
|
---|
| 160 | }
|
---|
| 161 | // Set range of possible bids
|
---|
| 162 | Range range = new Range(targetUtility, 1);
|
---|
| 163 | possibleBids = negoSession.getOutcomeSpace().getBidsinRange(range);
|
---|
| 164 | lastStepTime = this.negotiationSession.getTime();
|
---|
| 165 | }
|
---|
| 166 |
|
---|
| 167 | /**
|
---|
| 168 | * Getter for panic mode
|
---|
| 169 | *
|
---|
| 170 | * @return panic mode status
|
---|
| 171 | */
|
---|
| 172 | public Boolean getPanicMode() {
|
---|
| 173 | return (panicMode);
|
---|
| 174 | }
|
---|
| 175 | }
|
---|