1 | package agents;
|
---|
2 |
|
---|
3 | import java.util.List;
|
---|
4 |
|
---|
5 | import agents.anac.y2011.Nice_Tit_for_Tat.BilateralAgent;
|
---|
6 | import genius.core.Bid;
|
---|
7 | import genius.core.bidding.BidDetails;
|
---|
8 | import genius.core.boaframework.SortedOutcomeSpace;
|
---|
9 |
|
---|
10 | /**
|
---|
11 | * Boulware/Conceder tactics, by Tim Baarslag, adapted from [1]. Adapted by Mark
|
---|
12 | * Hendrikx to use the SortedOutcomeSpace instead of BidHistory.
|
---|
13 | *
|
---|
14 | * [1] S. Shaheen Fatima Michael Wooldridge Nicholas R. Jennings Optimal
|
---|
15 | * Negotiation Strategies for Agents with Incomplete Information
|
---|
16 | * http://eprints.ecs.soton.ac.uk/6151/1/atal01.pdf
|
---|
17 | *
|
---|
18 | * @author Tim Baarslag, Mark Hendrikx
|
---|
19 | */
|
---|
20 | public abstract class TimeDependentAgent extends BilateralAgent {
|
---|
21 | /** k \in [0, 1]. For k = 0 the agent starts with a bid of maximum utility */
|
---|
22 | private static final double k = 0;
|
---|
23 |
|
---|
24 | private SortedOutcomeSpace outcomeSpace;
|
---|
25 | private double Pmax;
|
---|
26 | private double Pmin;
|
---|
27 |
|
---|
28 | /**
|
---|
29 | * Depending on the value of e, extreme sets show clearly different patterns
|
---|
30 | * of behaviour [1]:
|
---|
31 | *
|
---|
32 | * 1. Boulware: For this strategy e < 1 and the initial offer is maintained
|
---|
33 | * till time is almost exhausted, when the agent concedes up to its
|
---|
34 | * reservation value.
|
---|
35 | *
|
---|
36 | * 2. Conceder: For this strategy e > 1 and the agent goes to its
|
---|
37 | * reservation value very quickly.
|
---|
38 | *
|
---|
39 | * 3. When e = 1, the price is increased linearly.
|
---|
40 | *
|
---|
41 | * 4. When e = 0, the agent plays hardball.
|
---|
42 | */
|
---|
43 | public abstract double getE();
|
---|
44 |
|
---|
45 | @Override
|
---|
46 | public String getName() {
|
---|
47 | return "Time Dependent Agent";
|
---|
48 | }
|
---|
49 |
|
---|
50 | @Override
|
---|
51 | public String getVersion() {
|
---|
52 | return "1.1";
|
---|
53 | }
|
---|
54 |
|
---|
55 | /**
|
---|
56 | * Sets Pmax to the highest obtainable utility, en Pmin to the lowest
|
---|
57 | * obtainable utility above the reservation value.
|
---|
58 | */
|
---|
59 | @Override
|
---|
60 | public void init() {
|
---|
61 | super.init();
|
---|
62 | initFields();
|
---|
63 | }
|
---|
64 |
|
---|
65 | /**
|
---|
66 | * Initialize our fields.
|
---|
67 | */
|
---|
68 | protected void initFields() {
|
---|
69 | outcomeSpace = new SortedOutcomeSpace(utilitySpace);
|
---|
70 | List<BidDetails> allOutcomes = outcomeSpace.getAllOutcomes();
|
---|
71 | double maximumUtilityInScenario = allOutcomes.get(0)
|
---|
72 | .getMyUndiscountedUtil();
|
---|
73 | double mininimumUtilityInScenario = allOutcomes.get(
|
---|
74 | allOutcomes.size() - 1).getMyUndiscountedUtil();
|
---|
75 | double rv = utilitySpace.getReservationValueUndiscounted();
|
---|
76 | Pmax = maximumUtilityInScenario;
|
---|
77 | Pmin = Math.max(mininimumUtilityInScenario, rv);
|
---|
78 | // log("Pmin = " + Pmin);
|
---|
79 | // log("Pmax = " + Pmax);
|
---|
80 |
|
---|
81 | }
|
---|
82 |
|
---|
83 | /**
|
---|
84 | * From [1]:
|
---|
85 | *
|
---|
86 | * A wide range of time dependent functions can be defined by varying the
|
---|
87 | * way in which f(t) is computed. However, functions must ensure that 0 <=
|
---|
88 | * f(t) <= 1, f(0) = k, and f(1) = 1.
|
---|
89 | *
|
---|
90 | * That is, the offer will always be between the value range, at the
|
---|
91 | * beginning it will give the initial constant and when the deadline is
|
---|
92 | * reached, it will offer the reservation value.
|
---|
93 | *
|
---|
94 | * For e = 0 (special case), it will behave as a Hardliner.
|
---|
95 | */
|
---|
96 | public double f(double t) {
|
---|
97 | if (getE() == 0)
|
---|
98 | return k;
|
---|
99 | double ft = k + (1 - k) * Math.pow(t, 1 / getE());
|
---|
100 | // log("f(t) = " + ft);
|
---|
101 | return ft;
|
---|
102 | }
|
---|
103 |
|
---|
104 | public double p(double t) {
|
---|
105 | return Pmin + (Pmax - Pmin) * (1 - f(t));
|
---|
106 | }
|
---|
107 |
|
---|
108 | /**
|
---|
109 | * Does not care about opponent's utility!
|
---|
110 | */
|
---|
111 | public Bid pickBidOfUtility(double utility) {
|
---|
112 | return outcomeSpace.getBidNearUtility(utility).getBid();
|
---|
113 | }
|
---|
114 |
|
---|
115 | public Bid makeBid() {
|
---|
116 | double time = timeline.getTime();
|
---|
117 | double utilityGoal = p(time);
|
---|
118 | Bid b = pickBidOfUtility(utilityGoal);
|
---|
119 |
|
---|
120 | // double foundUtility = getUtility(b);
|
---|
121 | // if (getE() != 0)
|
---|
122 | // log("[e=" + getE() + "] t = " + round2(time) + ". Aiming for " +
|
---|
123 | // round2(utilityGoal) + ". Found bid of utility " +
|
---|
124 | // round2(foundUtility));
|
---|
125 | return b;
|
---|
126 | }
|
---|
127 |
|
---|
128 | @Override
|
---|
129 | public Bid chooseCounterBid() {
|
---|
130 | return makeBid();
|
---|
131 | }
|
---|
132 |
|
---|
133 | @Override
|
---|
134 | public Bid chooseFirstCounterBid() {
|
---|
135 | return makeBid();
|
---|
136 | }
|
---|
137 |
|
---|
138 | @Override
|
---|
139 | public Bid chooseOpeningBid() {
|
---|
140 | return makeBid();
|
---|
141 | }
|
---|
142 |
|
---|
143 | @Override
|
---|
144 | public boolean isAcceptable(Bid plannedBid) {
|
---|
145 | Bid opponentLastBid = getOpponentLastBid();
|
---|
146 | // is acnext(1, 0);
|
---|
147 | if (getUndiscountedUtility(opponentLastBid) >= getUndiscountedUtility(plannedBid))
|
---|
148 | return true;
|
---|
149 | return false;
|
---|
150 | }
|
---|
151 | }
|
---|