source: boa/src/main/java/geniusweb/boa/biddingstrategy/TimeDependentBiddingStrategy.java

Last change on this file was 52, checked in by ruud, 14 months ago

Fixed small issues in domaineditor.

File size: 7.6 KB
Line 
1package geniusweb.boa.biddingstrategy;
2
3import java.math.BigDecimal;
4import java.util.concurrent.ThreadLocalRandom;
5import java.util.logging.Level;
6
7import geniusweb.actions.Accept;
8import geniusweb.actions.Action;
9import geniusweb.actions.EndNegotiation;
10import geniusweb.actions.Offer;
11import geniusweb.actions.PartyId;
12import geniusweb.boa.BoaState;
13import geniusweb.inform.Settings;
14import geniusweb.issuevalue.Bid;
15import geniusweb.profile.Profile;
16import geniusweb.profile.utilityspace.LinearAdditive;
17import tudelft.utilities.immutablelist.ImmutableList;
18
19/**
20 * This places offers in a time-dependent-only way, monotonically decreasing the
21 * utility of the offers according to the given parameters. Implements a
22 * TimeDependentAgent Strategy adapted from S. Shaheen Fatima Michael Wooldridge
23 * Nicholas R. Jennings Optimal Negotiation Strategies for Agents with
24 * Incomplete Information http://eprints.ecs.soton.ac.uk/6151/1/atal01.pdf
25 * <p>
26 * Required: the profile is {@link LinearAdditive}. Does not currently handle
27 * profile changes.
28 * <p>
29 * As basis, the original Genius'
30 * negotiator.boaframework.offeringstrategy.other.GeniusTimeDependent_Offering
31 * was used. However that seems to ignore the reservation value. This was fixed
32 * here.
33 * <p>
34 * The default strategy was extended to enable the usage of opponent models.
35 * <p>
36 * The time-dependent utility target function is f(t) = k + (1.0 - k) *
37 * Math.pow((t - startTime) / (1.0 - startTime), 1.0 / e). The utility target is
38 * then set at min+(max-min)*f(t) where the default values for min = either the
39 * utility of the reservation bid or the absolute minimum utility of the
40 * profile, and default for max the maximum attainable utility.
41 * <p>
42 *
43 * Parameters:
44 * <ul>
45 * <li>e: see {@link #getE(BoaState)}
46 * <li>k: see {@link #getK(BoaState)}
47 * <li>min: see {@link #getMin(BoaState)}.
48 * <li>max: see {@link #getMax(BoaState)}
49 * </ul>
50 */
51public class TimeDependentBiddingStrategy implements BiddingStrategy {
52 // bidSpace=null means we're not yet initialized.
53 private ExtendedUtilSpace bidSpace = null;
54 private Double e, k, min, max; // min, max attainable utility
55 private PartyId me;
56
57 @Override
58 public Action getAction(BoaState state) {
59 if (bidSpace == null) {
60 init(state);
61 }
62
63 double utilityGoal = p(
64 state.getProgress().get(System.currentTimeMillis()));
65
66 // if there is no opponent model available
67 ImmutableList<Bid> bidOptions = bidSpace
68 .getBids((BigDecimal.valueOf(utilityGoal)));
69
70 if (bidOptions.size().intValue() == 0) {
71 // should not happen unless profile is broken, emergency exit
72 state.getReporter().log(Level.WARNING,
73 "No viable bids found around current utility target");
74 Offer lastOffer = state.getLastReceivedOffer();
75 if (lastOffer == null)
76 return new EndNegotiation(me);
77 return new Accept(me, lastOffer.getBid());
78 }
79 Bid pickedBid = bidOptions.get(ThreadLocalRandom.current()
80 .nextInt(bidOptions.size().intValue()));
81 return new Offer(me, pickedBid);
82
83 }
84
85 /**
86 * Overrideable for hard configuring this component.
87 *
88 * @param state the {@link BoaState}
89 * @return the parameter e for the time depemdency function
90 * {@link #f(double)}. The parameter is 1 by default, or the value
91 * for the "e" parameter in the {@link Settings} if available.
92 */
93 protected Double getE(BoaState state) {
94 return state.getSettings().getParameters().getDouble("e", 1d, 0d, 1d);
95 }
96
97 /**
98 * Overrideable for hard configuring this component.
99 *
100 * @param state the {@link BoaState}
101 * @return the parameter k for the time depemdency function
102 * {@link #f(double)}. The parameter is 0 by default, or the value
103 * for the "k" parameter in the {@link Settings} if available.
104 */
105 protected Double getK(BoaState state) {
106 return state.getSettings().getParameters().getDouble("k", 0d, 0d, 1d);
107 }
108
109 /**
110 * Assumes {@link #bidSpace} has been initialized.
111 * <p>
112 * Overrideable for hard configuring this component.
113 *
114 * @param state the {@link BoaState}
115 * @return the min value for {@link #p(double)}. We use the "min" parameter
116 * in the {@link Settings} if available. If not available, the
117 * parameter is computed as the utility of the reservation bid. If
118 * there is no reservation bid, we use the minimum utility of the
119 * available profile.
120 */
121 protected Double getMin(BoaState state) {
122 Double val = state.getSettings().getParameters().getDouble("min", null,
123 0d, 1d);
124 if (val != null)
125 return val;
126 // val=null, try the reservation bid
127 LinearAdditive profile = (LinearAdditive) state.getProfile();
128 if (profile.getReservationBid() != null) {
129 return profile.getUtility(profile.getReservationBid())
130 .doubleValue();
131 }
132
133 return bidSpace.getMin().doubleValue();
134 }
135
136 /**
137 * Assumes {@link #bidSpace} has been initialized.
138 * <p>
139 * Overrideable for hard configuring this component.
140 *
141 * @param state the {@link BoaState}
142 * @return the max value for {@link #p(double)}. We use the "max" parameter
143 * in the {@link Settings} if available. If not available, we use
144 * the maximum utility of the available profile.
145 */
146 protected Double getMax(BoaState state) {
147 Double val = state.getSettings().getParameters().getDouble("max", null,
148 0d, 1d);
149 if (val != null)
150 return val;
151 return bidSpace.getMax().doubleValue();
152 }
153
154// /**
155// * @return the most recent bid that was offered, or null if no offer has
156// * been done yet.
157// */
158// private Bid getLastBid(List<Action> history) {
159// for (int n = history.size() - 1; n >= 0; n--) {
160// Action action = history.get(n);
161// if (action instanceof Offer) {
162// return ((Offer) action).getBid();
163// }
164// }
165// return null;
166// }
167
168 /**
169 * initializes bidSpace
170 *
171 * @param state
172 */
173 private void init(BoaState state) {
174 this.me = state.getSettings().getID();
175 Profile prof = state.getProfile();
176 if (!(prof instanceof LinearAdditive))
177 throw new IllegalArgumentException(
178 "Requires a LinearAdditive space but got " + prof);
179 LinearAdditive profile = (LinearAdditive) prof;
180
181 this.bidSpace = getBidSpace(profile);
182 this.e = getE(state);
183 this.k = getK(state);
184 this.min = getMin(state);
185 this.max = getMax(state);
186
187 state.getReporter().log(Level.INFO,
188 "BOA biddingstrategy min util = " + this.min);
189 }
190
191 /**
192 * Makes sure the target utility with in the acceptable range according to
193 * the domain
194 *
195 * @param t the normalized current time in the negotiation, where t=9 at
196 * start of negotiation and t=1 at end of negotiation.
197 * @return double
198 */
199 private double p(double t) {
200 return this.min + (this.max - this.min) * (1.0 - f(t));
201 }
202
203 /**
204 * From the paper:
205 *
206 * A wide range of time dependent functions can be defined by varying the
207 * way in which f(t) is computed. However, functions must ensure that 0 <=
208 * f(t) <= 1, f(0) = k, and f(1) = 1.
209 *
210 * That is, the offer will always be between the value range, at the
211 * beginning it will give the initial constant and when the deadline is
212 * reached, it will offer the reservation value.
213 *
214 * @param t the normalized current time in the negotiation, where t=9 at
215 * start of negotiation and t=1 at end of negotiation.
216 * @return
217 */
218 private double f(double t) {
219 double ft = k + (1.0 - k) * Math.pow(t, 1.0 / e);
220 return ft;
221 }
222
223 /**
224 * Factory method to get the {@link ExtendedUtilSpace} helper class.
225 * Overridable eg for tests
226 *
227 * @param profile a {@link LinearAdditive} profile
228 *
229 * @return {@link ExtendedUtilSpace}
230 */
231 protected ExtendedUtilSpace getBidSpace(LinearAdditive profile) {
232 return new ExtendedUtilSpace(profile);
233 }
234}
Note: See TracBrowser for help on using the repository browser.