source: src/main/java/agents/anac/y2013/TMFAgent/TMFAgent.java@ 316

Last change on this file since 316 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: 18.1 KB
Line 
1package agents.anac.y2013.TMFAgent;
2
3import java.io.Serializable;
4import java.util.ArrayList;
5import java.util.Collections;
6import java.util.HashMap;
7import java.util.List;
8
9import genius.core.Agent;
10import genius.core.Bid;
11import genius.core.NegotiationResult;
12import genius.core.SupportedNegotiationSetting;
13import genius.core.actions.Accept;
14import genius.core.actions.Action;
15import genius.core.actions.DefaultAction;
16import genius.core.actions.EndNegotiation;
17import genius.core.actions.Offer;
18import genius.core.issue.ISSUETYPE;
19import genius.core.issue.Issue;
20import genius.core.issue.IssueDiscrete;
21import genius.core.issue.IssueInteger;
22import genius.core.issue.IssueReal;
23import genius.core.issue.Value;
24import genius.core.issue.ValueDiscrete;
25import genius.core.issue.ValueInteger;
26import genius.core.issue.ValueReal;
27import genius.core.utility.EvaluatorInteger;
28import genius.core.utility.EvaluatorReal;
29
30public class TMFAgent extends Agent {
31
32 private ArrayList<ComparableBid> relevantBids;
33 private ArrayList<HashMap<Object, Double>> opponentUtilityEstimator;
34 private HashMap<Bid, Integer> previousOpponentBids;
35 private Bid lastBid;
36 private ArrayList<Double> maxValue;
37 private int lastPropose = 0;
38 private Bid BestOpponentBid;
39 private double firstOpponentBidUtility = 0;
40 private double EstimatedRTT = 0;
41 private double devRTT = 0;
42 private double prevTime = 0;
43
44 private boolean isFirstBid;
45
46 @Override
47 public void init() {
48 isFirstBid = true;
49
50 // init opponentUtilityEstimator
51 Serializable s = loadSessionData();
52 maxValue = new ArrayList<Double>();
53 if (s != null) {
54 opponentUtilityEstimator = (ArrayList<HashMap<Object, Double>>) s;
55 int i = 0;
56 for (HashMap<Object, Double> issue : opponentUtilityEstimator) {
57 maxValue.add(0.0);
58 for (double curr : issue.values()) {
59 if (maxValue.get(i) < curr)
60 maxValue.set(i, curr);
61 }
62 i++;
63 }
64 }
65
66 else {
67 opponentUtilityEstimator = new ArrayList<HashMap<Object, Double>>();
68
69 List<Issue> issues = this.utilitySpace.getDomain().getIssues();
70 for (Issue issue : issues) {
71 int max_i = opponentUtilityEstimator.size();
72 opponentUtilityEstimator.add(new HashMap<Object, Double>());
73 if (issue.getType() == ISSUETYPE.DISCRETE) {
74 for (ValueDiscrete vd : ((IssueDiscrete) issue)
75 .getValues()) {
76 opponentUtilityEstimator.get(max_i).put(vd, 0.0);
77 }
78 } else if (issue.getType() == ISSUETYPE.INTEGER) {
79 int k = Math.min(10, ((IssueInteger) issue).getUpperBound()
80 - ((IssueInteger) issue).getLowerBound());
81 for (int i = 0; i <= k; i++) {
82 opponentUtilityEstimator.get(max_i).put(i, 0.0);
83 }
84 /*
85 *
86 *
87 *
88 * opponentUtilityEstimator.add(new HashMap<Value,
89 * Double>()); EvaluatorInteger ei = new EvaluatorInteger();
90 *
91 * //putting the opponent best offer if
92 * (ei.getEvaluation(((IssueInteger)issue).getLowerBound())
93 * <
94 * ei.getEvaluation(((IssueInteger)issue).getUpperBound()))
95 * opponentUtilityEstimator.get(max_i).put(new
96 * ValueInteger(((IssueInteger)issue).getLowerBound()),
97 * 0.0); else opponentUtilityEstimator.get(max_i).put(new
98 * ValueInteger(((IssueInteger)issue).getUpperBound()),
99 * 0.0);
100 */
101 } else if (issue.getType() == ISSUETYPE.REAL) {
102 int k = 10;
103 for (int i = 0; i < k; i++) {
104 opponentUtilityEstimator.get(max_i).put(i + 0.0, 0.0);
105 }
106
107 /*
108 * opponentUtilityEstimator.add(new HashMap<Value,
109 * Double>()); opponentUtilityEstimator.get(max_i).put(new
110 * ValueReal(((IssueReal)issue).getLowerBound()), 0.0);
111 * opponentUtilityEstimator.get(max_i).put(new
112 * ValueReal(((IssueReal)issue).getUpperBound()), 0.0);
113 */
114 }
115 maxValue.add(0.0);
116 }
117 }
118 // init relevantBids - sorted from highest utility bid to lowest.
119 ArrayList<Bid> allBids = GetDiscreteBids();
120 relevantBids = new ArrayList<ComparableBid>();
121 for (Bid b : allBids) {
122 try {
123 relevantBids
124 .add(new ComparableBid(b, utilitySpace.getUtility(b)));
125 } catch (Exception e) {
126 e.printStackTrace();
127 }
128 }
129 Collections.sort(relevantBids);
130
131 // init previousOpponentBids
132 previousOpponentBids = new HashMap<Bid, Integer>();
133
134 BestOpponentBid = null;
135 lastBid = null;
136 lastPropose = 0;
137 }
138
139 public void BeginSession(int sessionNumber) {
140 isFirstBid = true;
141
142 }
143
144 @Override
145 public void endSession(NegotiationResult res) {
146 if (res.getLastAction() instanceof Accept)
147 AddOpponentBidToModel(res.getLastBid(), true);
148
149 saveSessionData(opponentUtilityEstimator);
150 }
151
152 @Override
153 public String getVersion() {
154 return "1.2";
155 }
156
157 @Override
158 public String getName() {
159 return "TMF-Agent";
160 }
161
162 @Override
163 public void ReceiveMessage(Action opponentAction) {
164 // estimating time of one bid-response time (like Round Trip Time in
165 // communication)
166 double currRTT = timeline.getTime() - prevTime;
167 prevTime = timeline.getTime();
168 EstimatedRTT = 0.6 * EstimatedRTT + 0.4 * currRTT;
169 devRTT = 0.75 * devRTT + 0.25 * Math.abs(currRTT - EstimatedRTT);
170
171 Bid b = DefaultAction.getBidFromAction(opponentAction);
172 if (b == null)
173 return;
174 isFirstBid = false;
175 Integer i = previousOpponentBids.get(b);
176 if (i == null) {
177 i = 0;
178 AddOpponentBidToModel(b, false);
179 }
180 previousOpponentBids.put(b, i + 1);
181
182 if (lastBid == null) {
183 // remove all unrelevance bids = all bids below the first opponent
184 // bid or all bids below the reservation value.
185 try {
186 double minimumRelevant = Math.max(utilitySpace.getUtility(b),
187 utilitySpace.getReservationValueUndiscounted());
188 while (relevantBids.size() > 0 && (utilitySpace
189 .getUtility(relevantBids.get(relevantBids.size()
190 - 1).bid) < minimumRelevant))
191 relevantBids.remove(relevantBids.size() - 1);
192 BestOpponentBid = b;
193
194 firstOpponentBidUtility = utilitySpace.getUtility(b);
195 } catch (Exception e) {
196 e.printStackTrace();
197 }
198 }
199
200 lastBid = b;
201 try {
202 if (utilitySpace.getUtility(BestOpponentBid) < utilitySpace
203 .getUtility(b))
204 BestOpponentBid = b;
205 } catch (Exception e) {
206 }
207 }
208
209 private void AddOpponentBidToModel(Bid b, boolean isAgreed) {
210 // go over every issue of the bid
211 for (int i = 0; i < utilitySpace.getDomain().getIssues().size(); i++) {
212 // extract the value of that issue
213 Object v = null;
214 Issue issue = utilitySpace.getDomain().getIssues().get(i);
215 Value v1 = null;
216 try {
217 v1 = b.getValue(issue.getNumber());
218 } catch (Exception e) {
219 e.printStackTrace();
220 return;
221 }
222
223 if (issue.getType() == ISSUETYPE.DISCRETE) {
224 v = v1;
225 } else if (issue.getType() == ISSUETYPE.INTEGER) {
226 // throw the value to the closest bucket
227 int currValue = ((ValueInteger) v1).getValue();
228 int k = Math.min(10, ((IssueInteger) issue).getUpperBound()
229 - ((IssueInteger) issue).getLowerBound());
230 int bucket = (int) Math.round((double) (currValue
231 - ((IssueInteger) issue).getLowerBound())
232 / (((IssueInteger) issue).getUpperBound()
233 - ((IssueInteger) issue).getLowerBound())
234 * k);
235 v = bucket; // not a real value - it just the "bucket name"
236 } else if (issue.getType() == ISSUETYPE.REAL) {
237 // throw the value to the closest bucket
238 double currValue = ((ValueReal) v1).getValue();
239 int k = 10;
240 int bucket = (int) Math.round((currValue
241 - ((IssueInteger) issue).getLowerBound())
242 / (((IssueInteger) issue).getUpperBound()
243 - ((IssueInteger) issue).getLowerBound())
244 * k);
245 v = bucket + 0.0; // not a real value - it just the
246 // "bucket name"
247 } else
248 return;
249
250 // get the previous data and enter the new one (add 1-t)
251 HashMap<Object, Double> hm = opponentUtilityEstimator.get(i);
252 Double d = null;
253 if (hm.containsKey(v))
254 d = hm.get(v);
255 else
256 d = 0.0;
257 double currData;
258 if (isAgreed)
259 currData = d + (maxValue.get(i) - d) / 2;
260 else
261 currData = d + 1.0 - timeline.getTime();
262 opponentUtilityEstimator.get(i).put(v, currData);
263
264 // set max value (for later normalization)
265 if (currData > maxValue.get(i))
266 maxValue.set(i, currData);
267
268 }
269 }
270
271 @Override
272 public Action chooseAction() {
273 // a plan so timeout won't occur
274 if (!HaveMoreTimeToBid(true)) { // if have time for one last bid, offer
275 // the opponent Best possible bid for us
276 // (or accept it, if the opponent just
277 // offer it)
278 try {
279 if (utilitySpace.getUtility(BestOpponentBid) <= utilitySpace
280 .getUtility(lastBid)) {
281 if (utilitySpace.getUtility(lastBid) > utilitySpace
282 .getReservationValueUndiscounted())
283 return new Accept(getAgentID(), lastBid);
284 } else if (utilitySpace
285 .getUtility(BestOpponentBid) > utilitySpace
286 .getReservationValueUndiscounted())
287 return new Offer(getAgentID(), BestOpponentBid);
288 } catch (Exception e) {
289 e.printStackTrace();
290 }
291 return new EndNegotiation(getAgentID()); // if the opponent's best
292 // offer is
293 // worse than the reservation value,
294 // end the negotiation.
295 }
296 if (!HaveMoreTimeToBid(false)) { // if have no more time for bidding (it
297 // about to have time-out), accept
298 // the opponent's offer, if it's
299 // high than the reservation value
300 try {
301 if (utilitySpace.getUtility(lastBid) > utilitySpace
302 .getReservationValueUndiscounted())
303 return new Accept(getAgentID(), lastBid);
304 } catch (Exception e) {
305 e.printStackTrace();
306 }
307 return new EndNegotiation(getAgentID()); // else, take the
308 // reservation value.
309
310 }
311
312 // if have time to negotiate properly..
313 Action a = null;
314
315 if (isFirstBid) {
316 isFirstBid = false;
317 try {
318 return new Offer(getAgentID(), utilitySpace.getMaxUtilityBid());
319 } catch (Exception e) {
320 // TODO Auto-generated catch block
321 e.printStackTrace();
322 }
323 }
324
325 double alpha = getHardness();
326 ComparableBid cb = relevantBids.get(0); // get <best bid , it's
327 // utility>;
328 double best; // best bid's utility
329 try {
330 best = alpha * cb.utility
331 + (1 - alpha) * GetEstimatedOpponentUtility(cb.bid);
332 } catch (Exception e1) {
333 e1.printStackTrace();
334 best = 0.0;
335 }
336 int j = Math.max(1, lastPropose - 3000); // for efficient reasons, don't
337 // go over all possible bids
338 // - only on 10,000 bids at
339 // most (around our last
340 // proposal)
341 for (int i = j; i < relevantBids.size()
342 && i < lastPropose + 7000; i++) {
343 double curr;
344 ComparableBid currBid = relevantBids.get(i);
345
346 try {
347 curr = alpha * currBid.utility + (1 - alpha)
348 * GetEstimatedOpponentUtility(currBid.bid);
349 } catch (Exception e) {
350 e.printStackTrace();
351 curr = 0.0;
352 }
353
354 if (curr > best) {
355 cb = currBid;
356 best = curr;
357 }
358
359 }
360
361 try {
362 if (lastBid != null
363 && utilitySpace.getUtility(lastBid) > cb.utility)
364 /*
365 * if the opponent offered better offer (to us) than what we
366 * decided to offer, we accept this offer.
367 */
368 a = new Accept(getAgentID(), lastBid);
369 else if (cb.utility < utilitySpace
370 .getReservationValueUndiscounted())
371 /*
372 * if our offer is worse than the reservation value we can
373 * achieve, we'll end the negotiation.
374 */
375 a = new EndNegotiation(getAgentID());
376 else
377 a = new Offer(getAgentID(), cb.bid);
378 } catch (Exception e) {
379 e.printStackTrace();
380 }
381
382 return a;
383 }
384
385 private ArrayList<Bid> GetDiscreteBids() {
386 ArrayList<Bid> bids = new ArrayList<Bid>();
387 HashMap<Integer, Value> issusesFirstValue = new HashMap<Integer, Value>();
388
389 // initial bids list - contains only one bid.
390 for (Issue issue : utilitySpace.getDomain().getIssues()) {
391 Value v = null;
392 if (issue.getType() == ISSUETYPE.INTEGER)
393 v = new ValueInteger(((IssueInteger) issue).getLowerBound());
394 else if (issue.getType() == ISSUETYPE.REAL)
395 v = new ValueReal(((IssueReal) issue).getLowerBound());
396 else if (issue.getType() == ISSUETYPE.DISCRETE)
397 v = ((IssueDiscrete) issue).getValue(0);
398 issusesFirstValue.put(issue.getNumber(), v);
399 }
400 try {
401 bids.add(new Bid(utilitySpace.getDomain(), issusesFirstValue));
402 } catch (Exception e) {
403 return null;
404 }
405
406 for (Issue issue : utilitySpace.getDomain().getIssues()) { // for every
407 // issue
408 ArrayList<Bid> tempBids = new ArrayList<Bid>(); // createFrom a list
409 // of
410 // bids
411 ArrayList<Value> issueValues = new ArrayList<Value>();
412 if (issue.getType() == ISSUETYPE.DISCRETE) {
413 ArrayList<ValueDiscrete> valuesD = (ArrayList<ValueDiscrete>) ((IssueDiscrete) issue)
414 .getValues(); // get
415 // list
416 // of
417 // options/values
418 // for
419 // this
420 // issue
421 for (Value v : valuesD) {
422 issueValues.add(v);
423 }
424 } else if (issue.getType() == ISSUETYPE.INTEGER) {
425 int k = Math.min(10, ((IssueInteger) issue).getUpperBound()
426 - ((IssueInteger) issue).getLowerBound());
427 for (int i = 0; i <= k; i++) {
428 ValueInteger vi = (ValueInteger) GetRepresentorOfBucket(i,
429 issue, k, true);
430 issueValues.add(vi);
431 }
432 } else if (issue.getType() == ISSUETYPE.REAL) {
433 int k = 10;
434 for (int i = 0; i <= k; i++) {
435 ValueReal vr = (ValueReal) GetRepresentorOfBucket(i, issue,
436 k, false);
437 issueValues.add(vr);
438 }
439 }
440
441 for (Bid bid : bids) { // for each bid seen so far (init bids list)
442 for (Value value : issueValues) { // for every value
443 HashMap<Integer, Value> bidValues = new HashMap<Integer, Value>(); // make
444 // new
445 // ("empty")
446 // bid
447 // -
448 // only
449 // values.
450 for (Issue issue1 : utilitySpace.getDomain().getIssues())
451 // go over all issues
452 try {
453 bidValues.put(issue1.getNumber(),
454 bid.getValue(issue1.getNumber())); // each
455 // issue
456 // is
457 // entered
458 } catch (Exception e) {
459 e.printStackTrace();
460 }
461 bidValues.put(issue.getNumber(), value);
462 try {
463 Bid newBid = new Bid(utilitySpace.getDomain(),
464 bidValues);
465 tempBids.add(newBid);
466 } catch (Exception e) {
467 e.printStackTrace();
468 }
469 }
470 }
471 bids = tempBids;
472 }
473 return bids;
474 }
475
476 private double GetEstimatedOpponentUtility(Bid b) {
477 double d = 0.0;
478 int count = 0;
479 // go over all issues
480 for (HashMap<Object, Double> h : opponentUtilityEstimator) {
481 try {
482 // add the normalize utility of that bid's value
483 Issue issue = utilitySpace.getDomain().getIssues().get(count);
484 int i = issue.getNumber(); // issue id
485 if (issue.getType() == ISSUETYPE.DISCRETE)
486 d += h.get(b.getValue(i)) / maxValue.get(count);
487 else if (issue.getType() == ISSUETYPE.INTEGER) {
488 Value v = b.getValue(i);
489 ValueInteger vi = (ValueInteger) v;
490 d += h.get(vi.getValue()) / maxValue.get(count);
491 }
492
493 else if (issue.getType() == ISSUETYPE.REAL) {
494 Value v = b.getValue(i);
495 ValueReal vr = (ValueReal) v;
496 d += h.get(vr.getValue()) / maxValue.get(count);
497 }
498 } catch (Exception e) {
499 return count == 0 ? d : d / count;
500 }
501 count++;
502 }
503 // make an average of all utilities (assuming weight is equal).
504 return d / count;
505 }
506
507 private double getHardness() {
508 double alpha = 0, x = timeline.getTime(),
509 y = utilitySpace.getDiscountFactor() <= 0.0 ? 0.0
510 : 1 - utilitySpace.getDiscountFactor();
511 double weight = (1 - firstOpponentBidUtility) * 2 / 3;
512 alpha = 1 - weight * Math.pow(x, 65) - (1 - weight) * Math.pow(y, 3);
513 alpha = alpha / (x * y + 1);
514
515 return alpha;
516 }
517
518 private boolean HaveMoreTimeToBid(boolean wantToMakeTwoProposals) {
519 if (wantToMakeTwoProposals
520 && 1 - timeline.getTime() > 2 * EstimatedRTT + devRTT) {
521 return true;
522 }
523 if (!wantToMakeTwoProposals
524 && 1 - timeline.getTime() > EstimatedRTT + devRTT) {
525 return true;
526 }
527 return false;
528 }
529
530 private Value GetRepresentorOfBucket(int bucket, Issue issue, int k,
531 boolean isInteger) {
532 double ans = 0;
533
534 if (isInteger) {
535 EvaluatorInteger ei = new EvaluatorInteger();
536 boolean upperIsTheBest = ei.getEvaluation(
537 ((IssueInteger) issue).getUpperBound()) > ei.getEvaluation(
538 ((IssueInteger) issue).getLowerBound());
539 if (upperIsTheBest) {
540 if (bucket < k) {
541 ans = ((double) (bucket + 1)) / k;
542 ans = ans
543 * (((IssueInteger) issue).getUpperBound()
544 - ((IssueInteger) issue).getLowerBound())
545 + ((IssueInteger) issue).getLowerBound() - 1;
546 } else
547 ans = ((IssueInteger) issue).getUpperBound();
548 } else {
549 ans = ((double) (bucket)) / k;
550 ans = ans
551 * (((IssueInteger) issue).getUpperBound()
552 - ((IssueInteger) issue).getLowerBound())
553 + ((IssueInteger) issue).getLowerBound();
554 }
555 return new ValueInteger((int) Math.round(ans));
556 }
557
558 EvaluatorReal ei = new EvaluatorReal();
559 boolean upperIsTheBest = ei
560 .getEvaluation(((IssueReal) issue).getUpperBound()) > ei
561 .getEvaluation(((IssueReal) issue).getLowerBound());
562 if (upperIsTheBest) {
563 if (bucket < k) {
564 ans = ((double) (bucket + 1)) / k;
565 ans = ans
566 * (((IssueReal) issue).getUpperBound()
567 - ((IssueReal) issue).getLowerBound())
568 + ((IssueReal) issue).getLowerBound();
569 } else
570 ans = ((IssueReal) issue).getUpperBound();
571 } else {
572 ans = ((double) (bucket)) / k;
573 ans = ans
574 * (((IssueReal) issue).getUpperBound()
575 - ((IssueReal) issue).getLowerBound())
576 + ((IssueReal) issue).getLowerBound();
577 }
578 return new ValueReal(ans);
579
580 }
581
582 @Override
583 public SupportedNegotiationSetting getSupportedNegotiationSetting() {
584 return SupportedNegotiationSetting.getLinearUtilitySpaceInstance();
585 }
586
587 @Override
588 public String getDescription() {
589 return "ANAC2012";
590 }
591
592}
Note: See TracBrowser for help on using the repository browser.