source: src/main/java/negotiator/boaframework/offeringstrategy/anac2013/Fawkes_Offering.java

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

#41 ROLL BACK of rev.126 . So this version is equal to rev. 125

File size: 11.4 KB
Line 
1package negotiator.boaframework.offeringstrategy.anac2013;
2
3import java.io.BufferedReader;
4import java.io.File;
5import java.io.FileReader;
6import java.io.IOException;
7import java.util.List;
8import java.util.Map;
9
10import genius.core.bidding.BidDetails;
11import genius.core.boaframework.NegotiationSession;
12import genius.core.boaframework.OMStrategy;
13import genius.core.boaframework.OfferingStrategy;
14import genius.core.boaframework.OpponentModel;
15import genius.core.boaframework.SortedOutcomeSpace;
16import genius.core.misc.Range;
17import negotiator.boaframework.offeringstrategy.anac2013.TheFawkes.Fawkews_Math;
18import negotiator.boaframework.omstrategy.TheFawkes_OMS;
19import negotiator.boaframework.opponentmodel.TheFawkes_OM;
20
21/**
22 * Bidding Strategy
23 */
24public final class Fawkes_Offering extends OfferingStrategy {
25 // Three very important variables -> beta: concession rate formula 7, rho:
26 // tolerance threshold formula 1, nu: risk factor formula 7
27 private double beta, rho, nu, discountFactor;
28 private TheFawkes_OM OM;
29 private TheFawkes_OMS OMS;
30
31 @Override
32 public void init(NegotiationSession nSession, OpponentModel oppModel, OMStrategy omStrategy,
33 Map<String, Double> params) throws Exception {
34 super.init(nSession, oppModel, omStrategy, params);
35 this.OM = (TheFawkes_OM) oppModel;
36 this.OMS = (TheFawkes_OMS) omStrategy;
37 this.negotiationSession.setOutcomeSpace(new SortedOutcomeSpace(this.negotiationSession.getUtilitySpace()));
38
39 // The final parameters resulting from tests:
40 this.beta = 0.002;
41 this.rho = 0.8;
42 this.nu = 0.2;
43
44 File biddingParams = new File("g3_biddingparams.txt");
45 if (biddingParams.exists() && biddingParams.canRead()) {
46 try {
47 BufferedReader reader = new BufferedReader(new FileReader(biddingParams));
48 this.beta = Double.parseDouble(reader.readLine());
49 this.rho = Double.parseDouble(reader.readLine());
50 this.nu = Double.parseDouble(reader.readLine());
51 reader.close();
52 } catch (IOException io) {
53 io.printStackTrace();
54 }
55 }
56
57 this.discountFactor = this.negotiationSession.getDiscountFactor();
58 this.discountFactor = (this.discountFactor == 0) ? 1 : this.discountFactor; // FIX:
59 // use
60 // discount
61 // factor
62 // 1
63 // when
64 // it
65 // is
66 // given
67 // as
68 // 0
69 }
70
71 @Override
72 public BidDetails determineOpeningBid() { // Our opening bid is just the
73 // maximum possible bid for us
74 BidDetails returned = this.negotiationSession.getMaxBidinDomain();
75 returned.setTime(this.negotiationSession.getTime());
76 return returned;
77 }
78
79 @Override
80 public BidDetails determineNextBid() {
81 BidDetails returned;
82 if (this.negotiationSession.getOpponentBidHistory().getHistory().size() > 1) { // If
83 // we
84 // have
85 // anything
86 // to
87 // base
88 // our
89 // OM
90 // on,
91 // use
92 // it
93 returned = this.responseMechanism(this.getTargetUtility());
94 } else { // Otherwise, just do our opening bid
95 returned = this.determineOpeningBid();
96 }
97 returned.setTime(this.negotiationSession.getTime());
98 return returned;
99 }
100
101 private BidDetails responseMechanism(double targetUtility) {
102 double timeCorrection = 1 - (this.negotiationSession.getTime() / 10.0); // TODO:
103 // do
104 // something
105 // with
106 // discountfactor
107 // here
108 // too?!
109 double inertiaCorrection = this.OMS.getSecondBestCount()
110 / (this.negotiationSession.getOwnBidHistory().size() * 10.0); // TODO:
111 // this
112 // is
113 // still
114 // not
115 // ideal...
116 double lowerBound = (timeCorrection - inertiaCorrection) * targetUtility;
117 // Group3_Agent.debug( "tCor: " + timeCorrection + ", -iCor: " +
118 // inertiaCorrection + ", *targetU: " + targetUtility + ", =lB: " +
119 // lowerBound );
120 List<BidDetails> possibleBids = this.negotiationSession.getOutcomeSpace()
121 .getBidsinRange(new Range(lowerBound, Double.MAX_VALUE));
122 if (possibleBids.isEmpty()) { // if no solution is found, the latest
123 // offer made by the agent is used again
124 // in the subsequent round
125 // Group3_Agent.debug( "No solution
126 // found, using our own last bid again"
127 // );
128 return this.negotiationSession.getOwnBidHistory().getLastBidDetails();
129 } else {
130 // Group3_Agent.debug( "Selecting a bid out of " +
131 // possibleBids.size() + " bids (" +
132 // this.OM.getMaxOpponentBidTimeDiff() + ")" );
133 return this.omStrategy.getBid(possibleBids); // selecting a bid in
134 // this range is
135 // done in the OMS
136 }
137 }
138
139 /**
140 * Obtain the utility of the next bid we are willing to make, based on our
141 * concession rate and the OM.
142 *
143 * @return Target utility
144 */
145 private double getTargetUtility() {
146 // Paper step 4 (formulas 7 and 8) is to calculate the reserved utility
147 // function and the estimated received utility
148 double currentTime = this.negotiationSession.getTime();
149 double maxDiff = Double.MIN_VALUE, minDiff = Double.MAX_VALUE, optimisticEstimatedTime = 0,
150 optimisticEstimatedUtility = 0, pessimisticEstimatedTime = 0, pessimisticEstimatedUtility = 0;
151 for (double time = currentTime; time < Math.min(currentTime + (this.OM.getMaxOpponentBidTimeDiff() * 10),
152 1); time += this.OM.getMaxOpponentBidTimeDiff()) { // formulas
153 // 9, 10,
154 // 11, and
155 // 13 are
156 // all
157 // applied
158 // in this
159 // loop:
160 // finding
161 // the
162 // estimated
163 // u and t
164 // (Uhat/That).
165 // Note that
166 // the
167 // time-window
168 // here is
169 // the same
170 // as used
171 // in the AS
172 double reservedUtility = this.reservedUtility(time);
173 double discountedReservedUtility = this.discountedUtility(reservedUtility, time);
174 double estimatedReceivedUtility = this.estimatedReceivedUtility(time);
175 double discountedEstimatedReceivedUtility = this.discountedUtility(estimatedReceivedUtility, time);
176 double diff = discountedEstimatedReceivedUtility - discountedReservedUtility;
177 // Group3_Agent.debug( "(reservedU,estReceivedU)=(" +
178 // reservedUtility + "," + estimatedReceivedUtility + ")" + " @" +
179 // time );
180 if (discountedEstimatedReceivedUtility >= discountedReservedUtility && diff > maxDiff) { // optimistic
181 // result!
182 maxDiff = diff; // argmax
183 optimisticEstimatedTime = time;
184 optimisticEstimatedUtility = estimatedReceivedUtility;
185 }
186 if (maxDiff == Double.MIN_VALUE) { // once we became optimistic,
187 // we'll never be pessimistic
188 // this round
189 double absoluteDiff = Math.abs(diff);
190 if (absoluteDiff < minDiff) {
191 minDiff = absoluteDiff; // argmin
192 pessimisticEstimatedTime = time;
193 pessimisticEstimatedUtility = estimatedReceivedUtility;
194 }
195 }
196 }
197
198 double estimatedTime, estimatedUtility;
199 if (maxDiff == Double.MIN_VALUE) { // pessimistic result! use formula 12
200 double xsi = (Math.pow(this.rho, -1)
201 * this.discountedUtility(pessimisticEstimatedUtility, pessimisticEstimatedTime))
202 / this.discountedUtility(this.reservedUtility(pessimisticEstimatedTime), pessimisticEstimatedTime);
203 if (xsi > 1) { // good pessimist :) use the pessimistic values found
204 estimatedTime = pessimisticEstimatedTime;
205 estimatedUtility = pessimisticEstimatedUtility;
206 } else { // panic... no usuable result even when pessimistic (14-1)
207 estimatedTime = -1;
208 estimatedUtility = -1;
209 }
210 // Group3_Agent.debug( "[PESSIMIST] X:" + xsi + "(" + ( Math.pow(
211 // this.rho, -1 ) * this.discountedUtility(
212 // pessimisticEstimatedUtility, pessimisticEstimatedTime ) )
213 // + "/" + this.discountedUtility( this.reservedUtility(
214 // pessimisticEstimatedTime ), pessimisticEstimatedTime ) + ")" );
215 } else { // optimistic result; use the optimistic values found
216 estimatedTime = optimisticEstimatedTime;
217 estimatedUtility = optimisticEstimatedUtility;
218
219 }
220 // Group3_Agent.debug( "T: " + estimatedTime + ", U:" + estimatedUtility
221 // );
222
223 double targetUtility;
224 if (estimatedUtility == -1) { // still no result (formula 14-1)
225 targetUtility = this.reservedUtility(currentTime);
226 // Group3_Agent.debug( "[RESERVERDU]=" + targetUtility );
227 } else { // formula 14-2
228 BidDetails myPreviousBid = this.negotiationSession.getOwnBidHistory().getLastBidDetails();
229 double myPreviousUtil = myPreviousBid.getMyUndiscountedUtil(); // targetUtility
230 // is
231 // undiscounted
232 // too
233 double factor = (currentTime - estimatedTime) / (myPreviousBid.getTime() - estimatedTime);
234 targetUtility = estimatedUtility + (myPreviousUtil - estimatedUtility) * factor;
235 // Group3_Agent.debug( "[factor,U]=" + factor + "," + targetUtility
236 // );
237 }
238 return targetUtility;
239 }
240
241 /**
242 * Reserved utility function. This function guarantees the minimum utility
243 * at each time step. The calculated utility is dependent on the concession
244 * rate beta.
245 *
246 * @param t
247 * Normalized time stamp
248 * @return Utility value that is at least the lowest discounted utility
249 * value at time t. Range: (reservationValue,maxUtility)
250 */
251 private double reservedUtility(double time) { // formula 7
252 double reservationValue = this.negotiationSession.getUtilitySpace().getReservationValueUndiscounted();
253 double myBestBidUtility = this.negotiationSession.getMaxBidinDomain().getMyUndiscountedUtil();
254 return reservationValue + (1 - Math.pow(time, 1 / this.beta))
255 * ((myBestBidUtility * Math.pow(this.discountFactor, this.nu)) - reservationValue);
256 }
257
258 /**
259 * Estimated Received Utility. Expectation of the opponents future
260 * concession. Uses the OM to estimate what the opponent will offer at a
261 * certain time.
262 *
263 * @param time
264 * Normalized time stamp
265 * @return Utility value that the OM has calculated the opponent will offer
266 * at time t.
267 */
268 private double estimatedReceivedUtility(double time) { // formula 8
269 int timeIndex = (int) Math.floor(time * this.OM.timeIndexFactor);
270 return this.OM.alpha.evaluate(timeIndex) * (1 + Fawkews_Math.getStandardDeviation(this.OM.ratio));
271 }
272
273 /**
274 * The Discounted Utility given a specific time. This is the current utility
275 * multiplied by the discount factor to the power of the time.
276 *
277 * @param utility
278 * The undiscounted utility.
279 * @param time
280 * The time you want the discount for.
281 * @return The discounted utility.
282 */
283 private double discountedUtility(double utility, double time) {
284 return utility * Math.pow(this.discountFactor, time);
285 }
286
287 @Override
288 public String getName() {
289 return "2013 - Fawkes";
290 }
291}
Note: See TracBrowser for help on using the repository browser.