source: src/main/java/negotiator/boaframework/offeringstrategy/anac2012/IAMHaggler2012_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: 21.6 KB
Line 
1package negotiator.boaframework.offeringstrategy.anac2012;
2
3import java.util.ArrayList;
4import java.util.Map;
5import java.util.Random;
6
7import agents.Jama.Matrix;
8import agents.anac.y2012.IAMhaggler2012.agents2011.southampton.utils.RandomBidCreator;
9import agents.anac.y2012.IAMhaggler2012.utility.SouthamptonUtilitySpace;
10import agents.org.apache.commons.math.MathException;
11import agents.org.apache.commons.math.MaxIterationsExceededException;
12import agents.org.apache.commons.math.special.Erf;
13import agents.uk.ac.soton.ecs.gp4j.bmc.BasicPrior;
14import agents.uk.ac.soton.ecs.gp4j.bmc.GaussianProcessMixture;
15import agents.uk.ac.soton.ecs.gp4j.bmc.GaussianProcessMixturePrediction;
16import agents.uk.ac.soton.ecs.gp4j.bmc.GaussianProcessRegressionBMC;
17import agents.uk.ac.soton.ecs.gp4j.gp.covariancefunctions.CovarianceFunction;
18import agents.uk.ac.soton.ecs.gp4j.gp.covariancefunctions.Matern3CovarianceFunction;
19import agents.uk.ac.soton.ecs.gp4j.gp.covariancefunctions.NoiseCovarianceFunction;
20import agents.uk.ac.soton.ecs.gp4j.gp.covariancefunctions.SumCovarianceFunction;
21import genius.core.Bid;
22import genius.core.BidIterator;
23import genius.core.bidding.BidDetails;
24import genius.core.boaframework.NegotiationSession;
25import genius.core.boaframework.NoModel;
26import genius.core.boaframework.OMStrategy;
27import genius.core.boaframework.OfferingStrategy;
28import genius.core.boaframework.OpponentModel;
29import genius.core.boaframework.SortedOutcomeSpace;
30import genius.core.misc.Pair;
31import genius.core.utility.AdditiveUtilitySpace;
32import negotiator.boaframework.opponentmodel.DefaultModel;
33
34/**
35 * @author Colin Williams
36 *
37 * The IAMhaggler Agent, created for ANAC 2012. Designed by C. R.
38 * Williams, V. Robu, E. H. Gerding and N. R. Jennings.
39 *
40 */
41public class IAMHaggler2012_Offering extends OfferingStrategy {
42
43 protected double RISK_PARAMETER = 1;
44
45 private Matrix utilitySamples;
46 private Matrix timeSamples;
47 private Matrix utility;
48 private GaussianProcessRegressionBMC regression;
49 private double lastRegressionTime = 0;
50 private double lastRegressionUtility = 1;
51 private ArrayList<Double> opponentTimes = new ArrayList<Double>();
52 private ArrayList<Double> opponentUtilities = new ArrayList<Double>();
53
54 private double maxUtilityInTimeSlot;
55 private int lastTimeSlot = -1;
56 private Matrix means;
57 private Matrix variances;
58
59 private double maxUtility;
60 private Bid bestReceivedBid;
61 private double previousTargetUtility;
62 private double intercept;
63 private Matrix matrixTimeSamplesAdjust;
64 private double maxOfferedUtility = Double.MIN_VALUE;
65 private double minOfferedUtility = Double.MAX_VALUE;
66 private SortedOutcomeSpace outcomespace;
67 private RandomBidCreator bidCreator;
68 private AdditiveUtilitySpace utilitySpace;
69 private SouthamptonUtilitySpace sus;
70
71 /**
72 * Empty constructor for the BOA framework.
73 */
74 public IAMHaggler2012_Offering() {
75 }
76
77 public IAMHaggler2012_Offering(NegotiationSession negoSession, OpponentModel model, OMStrategy oms)
78 throws Exception {
79 init(negoSession, model, oms, null);
80 }
81
82 /**
83 * Init required for the Decoupled Framework.
84 */
85 @Override
86 public void init(NegotiationSession negoSession, OpponentModel model, OMStrategy oms,
87 Map<String, Double> parameters) throws Exception {
88 if (model instanceof DefaultModel) {
89 model = new NoModel();
90 }
91 super.init(negoSession, model, oms, parameters);
92 if (!(opponentModel instanceof NoModel)) {
93 outcomespace = new SortedOutcomeSpace(negotiationSession.getUtilitySpace());
94 }
95
96 utilitySpace = (AdditiveUtilitySpace) negoSession.getUtilitySpace();
97 double discountingFactor = 0.5;
98 try {
99 discountingFactor = adjustDiscountFactor(utilitySpace.getDiscountFactor());
100 } catch (Exception ex) {
101 ex.printStackTrace();
102 }
103 if (discountingFactor == 0)
104 discountingFactor = 1;
105 makeUtilitySamples(100);
106 makeTimeSamples(100);
107 Matrix discounting = generateDiscountingFunction(discountingFactor);
108 Matrix risk = generateRiskFunction(RISK_PARAMETER);
109 utility = risk.arrayTimes(discounting);
110
111 BasicPrior[] bps = { new BasicPrior(11, 0.252, 0.5), new BasicPrior(11, 0.166, 0.5),
112 new BasicPrior(1, .01, 1.0) };
113 CovarianceFunction cf = new SumCovarianceFunction(Matern3CovarianceFunction.getInstance(),
114 NoiseCovarianceFunction.getInstance());
115
116 regression = new GaussianProcessRegressionBMC();
117 regression.setCovarianceFunction(cf);
118 regression.setPriors(bps);
119
120 // regression.calculateRegression(new Matrix(new double[] {}, 0), new
121 // Matrix(new double[] {}, 0));
122
123 maxUtility = 0;
124 previousTargetUtility = 1;
125 bidCreator = new RandomBidCreator();
126
127 sus = new SouthamptonUtilitySpace(utilitySpace);
128 }
129
130 @Override
131 public BidDetails determineOpeningBid() {
132 return determineNextBid();
133 }
134
135 @Override
136 public BidDetails determineNextBid() {
137 Bid opponentBid = negotiationSession.getOpponentBidHistory().getLastBid();
138 Bid b;
139 try {
140 b = handleOffer(opponentBid);
141 nextBid = new BidDetails(b, negotiationSession.getUtilitySpace().getUtility(b));
142 } catch (Exception e) {
143 e.printStackTrace();
144 }
145
146 return nextBid;
147 }
148
149 /**
150 * Handle an opponent's offer.
151 *
152 * @param opponentBid
153 * The bid made by the opponent.
154 * @return the action that we should take in response to the opponent's
155 * offer.
156 * @throws Exception
157 */
158 private Bid handleOffer(Bid opponentBid) throws Exception {
159 Bid bidToOffer;
160 if (negotiationSession.getOwnBidHistory().getHistory().isEmpty()) {
161 // Special case to handle first action
162 bidToOffer = proposeInitialBid();
163 if (bidToOffer == null) {
164 endNegotiation = true;
165 }
166 } else {
167 bidToOffer = proposeNextBid(opponentBid);
168 if (bidToOffer == null)
169 endNegotiation = true;
170 }
171
172 return bidToOffer;
173 }
174
175 /*
176 *
177 * (non-Javadoc)
178 *
179 * @see agents2011.southampton.IAMhaggler2011#proposeInitialBid()
180 */
181 private Bid proposeInitialBid() throws Exception {
182 Bid b = sus.getMaxUtilityBid();
183 if (utilitySpace.getUtilityWithDiscount(b, negotiationSession.getTimeline()) < utilitySpace
184 .getReservationValueWithDiscount(negotiationSession.getTimeline())) {
185 return null;
186 }
187 return b;
188 }
189
190 /*
191 * (non-Javadoc)
192 *
193 * @see agents.southampton.SouthamptonAgent#proposeNextBid(negotiator.Bid)
194 */
195 protected Bid proposeNextBid(Bid opponentBid) throws Exception {
196
197 double opponentUtility = utilitySpace.getUtility(opponentBid);
198
199 if (opponentUtility > maxUtility) {
200 bestReceivedBid = opponentBid;
201 maxUtility = opponentUtility;
202 }
203
204 double targetUtility = getTarget(opponentUtility, negotiationSession.getTime());
205
206 if (targetUtility <= maxUtility && previousTargetUtility > maxUtility)
207 return bestReceivedBid;
208 previousTargetUtility = targetUtility;
209
210 Bid b = null;
211 if (opponentModel instanceof NoModel) {
212 // Now get a random bid in the range targetUtility � 0.025
213 b = bidCreator.getBid(utilitySpace, targetUtility - 0.025, targetUtility + 0.025);
214 } else {
215 b = omStrategy.getBid(outcomespace, targetUtility).getBid();
216 }
217
218 if (utilitySpace.getUtilityWithDiscount(b, negotiationSession.getTimeline()) < utilitySpace
219 .getReservationValueWithDiscount(negotiationSession.getTimeline())) {
220 return utilitySpace.getMaxUtilityBid();
221 }
222 // System.out.println("Decoupled Bid: " + b);
223
224 return b;
225 }
226
227 /*
228 * (non-Javadoc)
229 *
230 * @see agents2011.southampton.IAMhaggler2011#getTarget(double, double)
231 */
232 protected double getTarget(double opponentUtility, double time) {
233
234 maxOfferedUtility = Math.max(maxOfferedUtility, opponentUtility);
235 minOfferedUtility = Math.min(minOfferedUtility, opponentUtility);
236
237 // Calculate the current time slot
238 int timeSlot = (int) Math.floor(time * 36);
239
240 boolean regressionUpdateRequired = false;
241 if (lastTimeSlot == -1) {
242 regressionUpdateRequired = true;
243 }
244
245 // If the time slot has changed
246 if (timeSlot != lastTimeSlot) {
247 if (lastTimeSlot != -1) {
248 // Store the data from the time slot
249 opponentTimes.add((lastTimeSlot + 0.5) / 36.0);
250 if (opponentUtilities.size() == 0) {
251 intercept = Math.max(0.5, maxUtilityInTimeSlot);
252 double[] timeSamplesAdjust = new double[timeSamples.getColumnDimension()];
253 int i = 0;
254 double gradient = 0.9 - intercept;
255 for (double d : timeSamples.getRowPackedCopy()) {
256 timeSamplesAdjust[i++] = intercept + (gradient * d);
257 }
258 matrixTimeSamplesAdjust = new Matrix(timeSamplesAdjust, timeSamplesAdjust.length);
259 }
260 opponentUtilities.add(maxUtilityInTimeSlot);
261 // Flag regression receiveMessage required
262 regressionUpdateRequired = true;
263 }
264 // Update the time slot
265 lastTimeSlot = timeSlot;
266 // Reset the max utility
267 maxUtilityInTimeSlot = 0;
268 }
269
270 // Calculate the maximum utility observed in the current time slot
271 maxUtilityInTimeSlot = Math.max(maxUtilityInTimeSlot, opponentUtility);
272
273 if (timeSlot == 0) {
274 return 1.0 - time / 2.0;
275 }
276
277 if (regressionUpdateRequired) {
278 double gradient = 0.9 - intercept;
279 /*
280 * double[] x = new double[opponentTimes.size()]; double[] yAdjust =
281 * new double[opponentTimes.size()]; double[] y = new
282 * double[opponentUtilities.size()];
283 *
284 * int i; i = 0; for (double d : opponentTimes) { x[i++] = d; } i =
285 * 0; for (double d : opponentTimes) { yAdjust[i++] = intercept +
286 * (gradient * d); } i = 0; for (double d : opponentUtilities) {
287 * y[i++] = d; }
288 *
289 * Matrix matrixX = new Matrix(x, x.length); Matrix matrixYAdjust =
290 * new Matrix(yAdjust, yAdjust.length); Matrix matrixY = new
291 * Matrix(y, y.length);
292 *
293 * matrixY.minusEquals(matrixYAdjust);
294 *
295 * //GaussianProcessMixture predictor =
296 * regression.calculateRegression(matrixX, matrixY);
297 */
298
299 GaussianProcessMixture predictor;
300
301 if (lastTimeSlot == -1) {
302 predictor = regression.calculateRegression(new double[] {}, new double[] {});
303 } else {
304 double x;
305 double y;
306 try {
307 x = opponentTimes.get(opponentTimes.size() - 1);
308 y = opponentUtilities.get(opponentUtilities.size() - 1);
309 } catch (Exception ex) {
310 System.out.println("Error getting x or y");
311 throw new Error(ex);
312 }
313
314 predictor = regression.updateRegression(new Matrix(new double[] { x }, 1),
315 new Matrix(new double[] { y - intercept - (gradient * x) }, 1));
316 }
317
318 GaussianProcessMixturePrediction prediction = predictor.calculatePrediction(timeSamples.transpose());
319
320 // Store the means and variances
321 means = prediction.getMean().plus(matrixTimeSamplesAdjust);
322 variances = prediction.getVariance();
323
324 }
325
326 Pair<Matrix, Matrix> acceptMatrices = generateProbabilityAccept(means, variances, time);
327 Matrix probabilityAccept = acceptMatrices.getFirst();
328 Matrix cumulativeAccept = acceptMatrices.getSecond();
329
330 Matrix probabilityExpectedUtility = probabilityAccept.arrayTimes(utility);
331 Matrix cumulativeExpectedUtility = cumulativeAccept.arrayTimes(utility);
332
333 Pair<Double, Double> bestAgreement = getExpectedBestAgreement(probabilityExpectedUtility,
334 cumulativeExpectedUtility, time);
335 double bestTime = bestAgreement.getFirst();
336 double bestUtility = bestAgreement.getSecond();
337
338 double targetUtility = lastRegressionUtility + ((time - lastRegressionTime)
339 * (bestUtility - lastRegressionUtility) / (bestTime - lastRegressionTime));
340
341 // Store the target utility and time
342 lastRegressionUtility = targetUtility;
343 lastRegressionTime = time;
344
345 double d = limitConcession(targetUtility);
346
347 return Math.max(utilitySpace.getReservationValueWithDiscount(time), d);
348 }
349
350 /**
351 * Create an m-by-1 matrix of utility samples.
352 *
353 * @param m
354 * The sample size.
355 */
356 private void makeUtilitySamples(int m) {
357 double[] utilitySamplesArray = new double[m];
358 {
359 for (int i = 0; i < utilitySamplesArray.length; i++) {
360 utilitySamplesArray[i] = 1.0 - ((double) i + 0.5) / ((double) m + 1.0);
361 }
362 }
363 utilitySamples = new Matrix(utilitySamplesArray, utilitySamplesArray.length);
364 }
365
366 /**
367 * Create a 1-by-n matrix of time samples.
368 *
369 * @param n
370 * The sample size.
371 */
372 private void makeTimeSamples(int n) {
373 double[] timeSamplesArray = new double[n + 1];
374 {
375 for (int i = 0; i < timeSamplesArray.length; i++) {
376 timeSamplesArray[i] = ((double) i) / ((double) n);
377 }
378 }
379 timeSamples = new Matrix(timeSamplesArray, 1);
380 }
381
382 private double limitConcession(double targetUtility) {
383 double limit = 1.0 - ((maxOfferedUtility - minOfferedUtility) + 0.1);
384 if (limit > targetUtility) {
385 return limit;
386 }
387 return targetUtility;
388 }
389
390 /**
391 * Generate an n-by-m matrix representing the effect of the discounting
392 * factor for a given utility-time combination. The combinations are given
393 * by the time and utility samples stored in timeSamples and utilitySamples
394 * respectively.
395 *
396 * @param discountingFactor
397 * The discounting factor, in the range (0, 1].
398 * @return An n-by-m matrix representing the discounted utilities.
399 */
400 private Matrix generateDiscountingFunction(double discountingFactor) {
401 double[] discountingSamples = timeSamples.getRowPackedCopy();
402 double[][] m = new double[utilitySamples.getRowDimension()][timeSamples.getColumnDimension()];
403 for (int i = 0; i < m.length; i++) {
404 for (int j = 0; j < m[i].length; j++) {
405 m[i][j] = Math.pow(discountingFactor, discountingSamples[j]);
406 }
407 }
408 return new Matrix(m);
409 }
410
411 /**
412 * Generate an (n-1)-by-m matrix representing the probability of acceptance
413 * for a given utility-time combination. The combinations are given by the
414 * time and utility samples stored in timeSamples and utilitySamples
415 * respectively.
416 *
417 * @param mean
418 * The means, at each of the sample time points.
419 * @param variance
420 * The variances, at each of the sample time points.
421 * @param time
422 * The current time, in the range [0, 1].
423 * @return An (n-1)-by-m matrix representing the probability of acceptance.
424 */
425 private Pair<Matrix, Matrix> generateProbabilityAccept(Matrix mean, Matrix variance, double time) {
426 int i = 0;
427 for (; i < timeSamples.getColumnDimension(); i++) {
428 if (timeSamples.get(0, i) > time)
429 break;
430 }
431 Matrix cumulativeAccept = new Matrix(utilitySamples.getRowDimension(), timeSamples.getColumnDimension(), 0);
432 Matrix probabilityAccept = new Matrix(utilitySamples.getRowDimension(), timeSamples.getColumnDimension(), 0);
433
434 double interval = 1.0 / utilitySamples.getRowDimension();
435
436 for (; i < timeSamples.getColumnDimension(); i++) {
437 double s = Math.sqrt(2 * variance.get(i, 0));
438 double m = mean.get(i, 0);
439
440 double minp = (1.0 - (0.5 * (1 + erf((utilitySamples.get(0, 0) + (interval / 2.0) - m) / s))));
441 double maxp = (1.0 - (0.5 * (1
442 + erf((utilitySamples.get(utilitySamples.getRowDimension() - 1, 0) - (interval / 2.0) - m) / s))));
443
444 for (int j = 0; j < utilitySamples.getRowDimension(); j++) {
445 double utility = utilitySamples.get(j, 0);
446 double p = (1.0 - (0.5 * (1 + erf((utility - m) / s))));
447 double p1 = (1.0 - (0.5 * (1 + erf((utility - (interval / 2.0) - m) / s))));
448 double p2 = (1.0 - (0.5 * (1 + erf((utility + (interval / 2.0) - m) / s))));
449
450 cumulativeAccept.set(j, i, (p - minp) / (maxp - minp));
451 probabilityAccept.set(j, i, (p1 - p2) / (maxp - minp));
452 }
453 }
454 return new Pair<Matrix, Matrix>(probabilityAccept, cumulativeAccept);
455 }
456
457 /**
458 * Wrapper for the erf function.
459 *
460 * @param x
461 * @return
462 */
463 private double erf(double x) {
464 if (x > 6)
465 return 1;
466 if (x < -6)
467 return -1;
468 try {
469 double d = Erf.erf(x);
470 if (d > 1)
471 return 1;
472 if (d < -1)
473 return -1;
474 return d;
475 } catch (MaxIterationsExceededException e) {
476 if (x > 0)
477 return 1;
478 else
479 return -1;
480 } catch (MathException e) {
481 e.printStackTrace();
482 return 0;
483 }
484 }
485
486 /**
487 * Generate an n-by-m matrix representing the risk based utility for a given
488 * utility-time combination. The combinations are given by the time and
489 * utility samples stored in timeSamples and utilitySamples
490 *
491 * @param riskParameter
492 * The risk parameter.
493 * @return an n-by-m matrix representing the risk based utility.
494 */
495 protected Matrix generateRiskFunction(double riskParameter) {
496 double mmin = generateRiskFunction(riskParameter, 0.0);
497 double mmax = generateRiskFunction(riskParameter, 1.0);
498 double range = mmax - mmin;
499
500 double[] riskSamples = utilitySamples.getColumnPackedCopy();
501 double[][] m = new double[utilitySamples.getRowDimension()][timeSamples.getColumnDimension()];
502 for (int i = 0; i < m.length; i++) {
503 double val;
504 if (range == 0) {
505 val = riskSamples[i];
506 } else {
507 val = (generateRiskFunction(riskParameter, riskSamples[i]) - mmin) / range;
508 }
509 for (int j = 0; j < m[i].length; j++) {
510 m[i][j] = val;
511 }
512 }
513 return new Matrix(m);
514 }
515
516 /**
517 * Generate the risk based utility for a given actual utility.
518 *
519 * @param riskParameter
520 * The risk parameter.
521 * @param utility
522 * The actual utility to calculate the risk based utility from.
523 * @return the risk based utility.
524 */
525 protected double generateRiskFunction(double riskParameter, double utility) {
526 return Math.pow(utility, riskParameter);
527 }
528
529 /**
530 * Get a pair representing the time and utility value of the expected best
531 * agreement.
532 *
533 * @param expectedValues
534 * A matrix of expected utility values at the sampled time and
535 * utilities given by timeSamples and utilitySamples
536 * respectively.
537 * @param time
538 * The current time.
539 * @return a pair representing the time and utility value of the expected
540 * best agreement.
541 */
542 private Pair<Double, Double> getExpectedBestAgreement(Matrix probabilityExpectedValues,
543 Matrix cumulativeExpectedValues, double time) {
544 Matrix probabilityFutureExpectedValues = getFutureExpectedValues(probabilityExpectedValues, time);
545 Matrix cumulativeFutureExpectedValues = getFutureExpectedValues(cumulativeExpectedValues, time);
546
547 double[][] probabilityFutureExpectedValuesArray = probabilityFutureExpectedValues.getArray();
548 double[][] cumulativeFutureExpectedValuesArray = cumulativeFutureExpectedValues.getArray();
549
550 Double bestX = null;
551 Double bestY = null;
552
553 double[] colSums = new double[probabilityFutureExpectedValuesArray[0].length];
554 double bestColSum = 0;
555 int bestCol = 0;
556
557 for (int x = 0; x < probabilityFutureExpectedValuesArray[0].length; x++) {
558 colSums[x] = 0;
559 for (int y = 0; y < probabilityFutureExpectedValuesArray.length; y++) {
560 colSums[x] += probabilityFutureExpectedValuesArray[y][x];
561 }
562
563 if (colSums[x] >= bestColSum) {
564 bestColSum = colSums[x];
565 bestCol = x;
566 }
567 }
568
569 int bestRow = 0;
570 double bestRowValue = 0;
571
572 for (int y = 0; y < cumulativeFutureExpectedValuesArray.length; y++) {
573 double expectedValue = cumulativeFutureExpectedValuesArray[y][bestCol];
574 if (expectedValue > bestRowValue) {
575 bestRowValue = expectedValue;
576 bestRow = y;
577 }
578 }
579
580 bestX = timeSamples.get(0, bestCol + probabilityExpectedValues.getColumnDimension()
581 - probabilityFutureExpectedValues.getColumnDimension());
582 bestY = utilitySamples.get(bestRow, 0);
583
584 return new Pair<Double, Double>(bestX, bestY);
585 }
586
587 /**
588 * Get a matrix of expected utility values at the sampled time and utilities
589 * given by timeSamples and utilitySamples, for times in the future.
590 *
591 * @param expectedValues
592 * A matrix of expected utility values at the sampled time and
593 * utilities given by timeSamples and utilitySamples
594 * respectively.
595 * @param time
596 * The current time.
597 * @return a matrix of expected utility values for future time.
598 */
599 private Matrix getFutureExpectedValues(Matrix expectedValues, double time) {
600 int i = 0;
601 for (; i < timeSamples.getColumnDimension(); i++) {
602 if (timeSamples.get(0, i) > time)
603 break;
604 }
605 return expectedValues.getMatrix(0, expectedValues.getRowDimension() - 1, i,
606 expectedValues.getColumnDimension() - 1);
607 }
608
609 /**
610 * Get all of the bids in a utility range.
611 *
612 * @param lowerBound
613 * The minimum utility level of the bids.
614 * @param upperBound
615 * The maximum utility level of the bids.
616 * @return all of the bids in a utility range.
617 * @throws Exception
618 */
619 private ArrayList<Bid> getBidsInRange(double lowerBound, double upperBound) throws Exception {
620 ArrayList<Bid> bidsInRange = new ArrayList<Bid>();
621 BidIterator iter = new BidIterator(utilitySpace.getDomain());
622 while (iter.hasNext()) {
623 Bid tmpBid = iter.next();
624 double util = 0;
625 try {
626 util = utilitySpace.getUtility(tmpBid);
627 if (util >= lowerBound && util <= upperBound)
628 bidsInRange.add(tmpBid);
629 } catch (Exception e) {
630 e.printStackTrace();
631 }
632 }
633
634 return bidsInRange;
635 }
636
637 /**
638 * Get a random bid in a given utility range.
639 *
640 * @param lowerBound
641 * The lower bound on utility.
642 * @param upperBound
643 * The upper bound on utility.
644 * @return a random bid in a given utility range.
645 * @throws Exception
646 */
647 protected Bid getRandomBidInRange(double lowerBound, double upperBound) throws Exception {
648 ArrayList<Bid> bidsInRange = getBidsInRange(lowerBound, upperBound);
649
650 int index = (new Random()).nextInt(bidsInRange.size() - 1);
651
652 return bidsInRange.get(index);
653 }
654
655 public double adjustDiscountFactor(double discountFactor) {
656 return discountFactor;
657 }
658
659 @Override
660 public String getName() {
661 return "2012 - IAMHaggler";
662 }
663}
Note: See TracBrowser for help on using the repository browser.