source: src/main/java/onetomany/bargainingchipsgame/players/AbstractTimeDependentNegotiationParty.java@ 300

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

AbstractTimeDependentNegotiationParty works

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