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

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

Agents receive a message that an outcome was reached

File size: 4.8 KB
RevLine 
[316]1package bargainingchips.players;
[315]2
3import static java.lang.Math.pow;
4
5import java.util.concurrent.BlockingQueue;
6
[316]7import bargainingchips.Bundle;
8import bargainingchips.NegotiationContext;
9import bargainingchips.OutcomeSpace;
10import bargainingchips.actions.Accept;
[319]11import bargainingchips.actions.Bid;
[316]12import bargainingchips.actions.Offer;
[323]13import bargainingchips.actions.OfferBy;
[328]14import bargainingchips.outcomes.Outcome;
[316]15import bargainingchips.utilityfunctions.UtilityFunction;
[315]16import genius.core.protocol.MultilateralProtocol;
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,
[316]30 BlockingQueue<Offer> in,
[323]31 BlockingQueue<OfferBy> out,
[315]32 BlockingQueue<CoordinationMessage> cin,
33 BlockingQueue<StatusMessage> cout) {
34 super(name, u, nc, in, out, cin, cout);
35 }
36
37 /**
38 * When this class is called, it is expected that the Party chooses one of
39 * the actions from the possible action list and returns an instance of the
40 * chosen action. This class is only called if this
41 * {@link genius.core.parties.NegotiationParty} is in the
42 * {@link MultilateralProtocol#getRoundStructure(java.util.List, negotiator.session.Session)}
43 * .
44 *
45 * @param possibleActions
46 * List of all actions possible.
47 * @return The chosen action
48 */
49 @Override
50 protected Offer sendOffer()
51 {
52 // Nothing received yet
53 if (lastReceivedOffer == null)
[319]54 return new Bid(getNextBid());
[315]55
56 // Our last bid got accepted. We are also accepting (and we should notify the coordinator).
57 if (lastReceivedOffer.isAccept())
58 return new Accept(lastReceivedOffer);
59
60 Bundle lastReceivedBid = lastReceivedOffer.getBundle();
61 Bundle nextBid = getNextBid();
62
63 double lastUtil = lastReceivedBid != null ? u.getUtility(lastReceivedBid) : 0;
64 double nextUtil = nextBid != null ? u.getUtility(nextBid) : 0;
65
66 // Accept
67 if (nextUtil <= lastUtil)
68 return new Accept(lastReceivedOffer);
69 // Counter offer based actions
70 else
[319]71 return new Bid(nextBid);
[315]72 }
73
74 /**
75 * Get the next bid we should do
76 */
77 protected Bundle getNextBid()
78 {
79 OutcomeSpace outcomeSpace = negotiationContext.getOutcomeSpace();
80 return outcomeSpace.getBidNearUtility(getTargetUtility(), u, this);
81 }
82
83 @Override
84 protected void receiveOffer(Offer o)
85 {
86 lastReceivedOffer = o;
87 }
[328]88
89 @Override
90 protected void receiveOutcome(Outcome outcome)
91 {
92 System.out.println(this + " is done with outcome " + outcome + ". Should clean up now.");
93 }
[315]94
95 /**
96 * Gets the target utility for the next bid
97 *
98 * @return The target utility for the given time
99 */
100 private double getTargetUtility()
101 {
102 // timeline runs from 0.0 to 1.0
103 int totalrounds = NegotiationContext.DEADLINE;
104 double time = (double) k / totalrounds;
105 double target = 1d - f(time);
106// System.out.println(this + ": t = " + time + ". Target util: " + target);
107 return target;
108 }
109
110 /**
111 * From [1]:
112 *
113 * A wide range of time dependent functions can be defined by varying the
114 * way in which f(t) is computed. However, functions must ensure that 0 <=
115 * f(t) <= 1, f(0) = k, and f(1) = 1.
116 *
117 * That is, the offer will always be between the value range, at the
118 * beginning it will give the initial constant and when the deadline is
119 * reached, it will offer the reservation value.
120 *
121 * For e = 0 (special case), it will behave as a Hardliner.
122 */
123 private double f(double t) {
124 if (getE() == 0) {
125 return 0;
126 }
127 return pow(t, 1 / getE());
128 }
129
130 /**
131 * Depending on the value of e, extreme sets show clearly different patterns
132 * of behaviour [1]:
133 *
134 * 1. Boulware: For this strategy e < 1 and the initial offer is maintained
135 * till time is almost exhausted, when the agent concedes up to its
136 * reservation value.
137 *
138 * 2. Conceder: For this strategy e > 1 and the agent goes to its
139 * reservation value very quickly.
140 *
141 * 3. When e = 1, the price is increased linearly.
142 *
143 * 4. When e = 0, the agent plays hardball.
144 */
145 public abstract double getE();
146
147 @Override
148 protected Offer sendOpeningOffer()
149 {
150 return sendOffer();
151 }
152
153 /**
154 * Messaging with the coordinator can happen below
155 */
156
157 @Override
158 protected void receiveCoordinationMessage(CoordinationMessage cpoll)
159 {
160 // Update the utility function
161 u = cpoll.getUtilityFunction();
162 }
163
164 @Override
165 protected StatusMessage sendStatusMessage()
166 {
167 return null;
168 }
169}
Note: See TracBrowser for help on using the repository browser.