source: src/main/java/onetomany/bargainingchipsgame/players/TimeDependentNegotiationAgent.java@ 314

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

Ready for v0

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