source: src/main/java/bargainingchips/players/TimeDependentNegotiationAgent.java@ 337

Last change on this file since 337 was 337, checked in by Tim Baarslag, 5 years ago

Added support for PreAccept and FinalAccept

File size: 4.2 KB
Line 
1package bargainingchips.players;
2
3import static java.lang.Math.pow;
4
5import java.util.concurrent.BlockingQueue;
6
7import bargainingchips.Bundle;
8import bargainingchips.NegotiationContext;
9import bargainingchips.OutcomeSpace;
10import bargainingchips.actions.Bid;
11import bargainingchips.actions.FinalAccept;
12import bargainingchips.actions.Offer;
13import bargainingchips.actions.OfferBy;
14import bargainingchips.actions.PreAccept;
15import bargainingchips.outcomes.Outcome;
16import bargainingchips.utilityfunctions.UtilityFunction;
17
18/**
19 * Boulware/Conceder tactics, by Tim Baarslag, adapted from [1].
20 *
21 * [1] S. Shaheen Fatima Michael Wooldridge Nicholas R. Jennings Optimal
22 * Negotiation Strategies for Agents with Incomplete Information
23 * http://eprints.ecs.soton.ac.uk/6151/1/atal01.pdf
24 */
25public abstract class TimeDependentNegotiationAgent extends Agent
26{
27 private Offer lastReceivedOffer = null;
28
29 public TimeDependentNegotiationAgent(String name, UtilityFunction u, NegotiationContext nc,
30 BlockingQueue<Offer> in,
31 BlockingQueue<OfferBy> out,
32 BlockingQueue<CoordinationMessage> cin,
33 BlockingQueue<StatusMessage> cout) {
34 super(name, u, nc, in, out, cin, cout);
35 }
36
37 @Override
38 protected Offer sendOffer()
39 {
40 // Nothing received yet
41 if (lastReceivedOffer == null)
42 return new Bid(getNextBid());
43
44 // Our last bid got accepted. We are also accepting (and we should notify the coordinator).
45 if (lastReceivedOffer.isPreAccept())
46 return new FinalAccept(lastReceivedOffer);
47
48 Bundle lastReceivedBid = lastReceivedOffer.getBundle();
49 Bundle nextBid = getNextBid();
50
51 double lastUtil = lastReceivedBid != null ? u.getUtility(lastReceivedBid) : 0;
52 double nextUtil = nextBid != null ? u.getUtility(nextBid) : 0;
53
54 // Accept
55 if (nextUtil <= lastUtil)
56 return new PreAccept(lastReceivedOffer);
57 // Counter offer based actions
58 else
59 return new Bid(nextBid);
60 }
61
62 /**
63 * Get the next bid we should do
64 */
65 protected Bundle getNextBid()
66 {
67 OutcomeSpace outcomeSpace = negotiationContext.getOutcomeSpace();
68 return outcomeSpace.getBidNearUtility(getTargetUtility(), u, this);
69 }
70
71 @Override
72 protected void receiveOffer(Offer o)
73 {
74 lastReceivedOffer = o;
75 }
76
77 @Override
78 protected void receiveOutcome(Outcome outcome)
79 {
80 System.out.println(this + " is done with outcome " + outcome + ". Should clean up now.");
81 }
82
83 /**
84 * Gets the target utility for the next bid
85 *
86 * @return The target utility for the given time
87 */
88 private double getTargetUtility()
89 {
90 // timeline runs from 0.0 to 1.0
91 int totalrounds = NegotiationContext.DEADLINE;
92 double time = (double) k / totalrounds;
93 double target = 1d - f(time);
94 return target;
95 }
96
97 /**
98 * From [1]:
99 *
100 * A wide range of time dependent functions can be defined by varying the
101 * way in which f(t) is computed. However, functions must ensure that 0 <=
102 * f(t) <= 1, f(0) = k, and f(1) = 1.
103 *
104 * That is, the offer will always be between the value range, at the
105 * beginning it will give the initial constant and when the deadline is
106 * reached, it will offer the reservation value.
107 *
108 * For e = 0 (special case), it will behave as a Hardliner.
109 */
110 private double f(double t) {
111 if (getE() == 0) {
112 return 0;
113 }
114 return pow(t, 1 / getE());
115 }
116
117 /**
118 * Depending on the value of e, extreme sets show clearly different patterns
119 * of behaviour [1]:
120 *
121 * 1. Boulware: For this strategy e < 1 and the initial offer is maintained
122 * till time is almost exhausted, when the agent concedes up to its
123 * reservation value.
124 *
125 * 2. Conceder: For this strategy e > 1 and the agent goes to its
126 * reservation value very quickly.
127 *
128 * 3. When e = 1, the price is increased linearly.
129 *
130 * 4. When e = 0, the agent plays hardball.
131 */
132 public abstract double getE();
133
134 @Override
135 protected Offer sendOpeningOffer()
136 {
137 return sendOffer();
138 }
139
140 /**
141 * Messaging with the coordinator can happen below
142 */
143
144 @Override
145 protected void receiveCoordinationMessage(CoordinationMessage cpoll)
146 {
147 // Update the utility function
148 u = cpoll.getUtilityFunction();
149 }
150
151 @Override
152 protected StatusMessage sendStatusMessage()
153 {
154 return null;
155 }
156}
157
Note: See TracBrowser for help on using the repository browser.