source: src/main/java/agents/anac/y2017/madagent/MadAgent.java@ 1

Last change on this file since 1 was 1, checked in by Wouter Pasman, 6 years ago

Initial import : Genius 9.0.0

File size: 9.8 KB
Line 
1package agents.anac.y2017.madagent;
2
3import java.util.ArrayList;
4import java.util.Comparator;
5import java.util.HashMap;
6import java.util.List;
7import java.util.Random;
8
9import genius.core.AgentID;
10import genius.core.Bid;
11import genius.core.actions.Accept;
12import genius.core.actions.Action;
13import genius.core.actions.Offer;
14import genius.core.boaframework.SortedOutcomeSpace;
15import genius.core.parties.AbstractNegotiationParty;
16import genius.core.parties.NegotiationInfo;
17import genius.core.persistent.PersistentDataType;
18
19public class MadAgent extends AbstractNegotiationParty {
20
21 private static final Random RANDOM = new Random();
22 private static final int MAXIMUM_NUMBER_OF_TRIALS = 2000;
23
24 /*
25 * -------------------------------- RISK FUNCTION
26 * -------------------------------- f <- Round number to fake (Agent will
27 * fake in every f rounds) c <- Risk constant p <- Risk parameter Formula ->
28 * f = c / 2 ^ p We choose 5 as our parameter because we want our agent to
29 * be both aggressive and defensive
30 */
31 private static final double RISK_CONSTANT = 100000;
32 private static final double RISK_PARAMETER = 5; // Risk Parameter: 0, 1, 2,
33 // ..., 8, 9, 10
34 private static final int ROUND_NUMBER_TO_FAKE = (int) (RISK_CONSTANT
35 / Math.pow(2, RISK_PARAMETER));
36
37 private SortedOutcomeSpace sortedOutcomeSpace = null;
38 private Bid lastReceivedBid = null;
39 private Bid bestReceivedBid = null;
40 private Bid secondBestBid = null;
41 private String negotiationType = null;
42 private double negotiationLimit = 0;
43 private double numberOfRoundsPassed = 0;
44 private double timeToGetAlmostMad = 0;
45 private double timeToGetMad = 0;
46 private double threshold = 0.8;
47 private double currentThreshold = 0.8;
48 /* Variables for Opponent Modeling */
49 private int opponentTurn = 0; // Value to keep track opponents
50 private int myTurn = 0; // Random value to choose one of the opponents and
51 // use its preferences while generating bid
52 private int shiftBids[] = null; // Index for bidsPreferredByOpponents for
53 // each opponent
54 private OpponentModel[] opponentModels = null; // Opponent Model for each
55 // opponent.
56 private List<List<Bid>> bidsPreferredByOpponents = null; // bidsPrefferredByOpponents
57 // for each
58 // opponent
59
60 @Override
61 public void init(NegotiationInfo info) {
62 super.init(info);
63
64 System.out.println("Discount Factor is "
65 + info.getUtilitySpace().getDiscountFactor());
66 System.out.println("Reservation Value is "
67 + info.getUtilitySpace().getReservationValueUndiscounted());
68
69 sortedOutcomeSpace = new SortedOutcomeSpace(utilitySpace);
70 threshold *= 1.125;
71
72 shiftBids = new int[3];
73 opponentModels = new OpponentModel[3];
74 bidsPreferredByOpponents = new ArrayList<List<Bid>>();
75
76 // Filling the array with empty values to avoid 'Null Pointer Exception'
77 for (int i = 0; i < 3; i++) {
78 opponentModels[i] = new OpponentModel(utilitySpace, threshold);
79 bidsPreferredByOpponents.add(null);
80 }
81
82 try {
83 bestReceivedBid = utilitySpace.getMinUtilityBid();
84 } catch (Exception e) {
85 System.err.println("An exception thrown at init..");
86 }
87
88 negotiationType = info.getDeadline().getType().toString();
89 negotiationLimit = info.getDeadline().getValue();
90
91 /* This values will be used for adapting threshold */
92 timeToGetMad = negotiationLimit * 0.8; // Agent gets mad in the last 20%
93 // of the negotiation
94 timeToGetAlmostMad = negotiationLimit * 0.5; // Agent gets almost mad in
95 // the last 50% of the
96 // negotiation
97
98 if (getData().getPersistentDataType() != PersistentDataType.STANDARD)
99 throw new IllegalStateException("need standard persistent data");
100
101 /* Agent calculates the second best bid */
102 try {
103 calculateSecondBestBid();
104 } catch (Exception e) {
105 System.err.println(
106 "An exception thrown while calculating the second best bid..");
107 }
108 }
109
110 private void calculateSecondBestBid() throws Exception {
111 for (double u = utilitySpace
112 .getUtility(utilitySpace.getMaxUtilityBid()); true; u -= 0.01) {
113 secondBestBid = sortedOutcomeSpace.getBidNearUtility(u).getBid();
114
115 if (utilitySpace.getUtility(secondBestBid) != utilitySpace
116 .getUtility(utilitySpace.getMaxUtilityBid()))
117 break;
118 }
119 }
120
121 @Override
122 public void receiveMessage(AgentID sender, Action action) { // ...
123 // Opponent's
124 // turn ...
125 super.receiveMessage(sender, action);
126
127 /*
128 * If the action is an Offer, get the last received bid and use it to
129 * form Opponent Model
130 */
131 if (action instanceof Offer) {
132 lastReceivedBid = ((Offer) action).getBid();
133
134 opponentModels[2].offer(lastReceivedBid, numberOfRoundsPassed);
135 opponentModels[opponentTurn++ % 2].offer(lastReceivedBid,
136 numberOfRoundsPassed);
137 }
138 }
139
140 @Override
141 public Action chooseAction(List<Class<? extends Action>> validActions) { // ...
142 // Your
143 // agent's
144 // turn
145 // ...
146 numberOfRoundsPassed++;
147
148 if (lastReceivedBid == null) { // You are the starter party, offer the
149 // best possible bid
150 return new Offer(getPartyId(), getBestBidPossible());
151 } else { // You are not the starter party
152 /* Determine the best received bid */
153 if (utilitySpace.getUtility(lastReceivedBid) > utilitySpace
154 .getUtility(bestReceivedBid))
155 bestReceivedBid = lastReceivedBid;
156
157 /*
158 * If utility of the last received bid is higher than the threshold,
159 * accept the offer.
160 */
161 /* Else, offer a new bid. */
162 if (utilitySpace.getUtility(lastReceivedBid) > currentThreshold)
163 return new Accept(getPartyId(), lastReceivedBid);
164 else
165 return new Offer(getPartyId(), getBestBidPossible());
166 }
167 }
168
169 private Bid getBestBidPossible() {
170 try {
171 double currentStatus = getCurrentStatus();
172
173 if (currentStatus <= negotiationLimit * 0.05) { // First 5% of the
174 // negotiation
175 return secondBestBid;
176 } else if ((int) numberOfRoundsPassed % ROUND_NUMBER_TO_FAKE <= 10
177 && currentStatus <= negotiationLimit * 0.9) {
178 return getFakeBid();
179 } else {
180 myTurn = RANDOM.nextInt(3); // Generate random value among {0,
181 // 1, 2}
182 calculateCurrentThreshold(currentStatus);
183
184 if (currentStatus > negotiationLimit * 0.99 && utilitySpace
185 .getUtility(bestReceivedBid) >= currentThreshold)
186 return bestReceivedBid;
187 else
188 return getNiceBid(currentStatus);
189 }
190 } catch (Exception e) {
191 System.err.println("An exception thrown while generating bid..");
192 }
193
194 return generateRandomBid(); // This line will never be executed!!
195 }
196
197 /* Current status is the time/number of rounds passed */
198 private double getCurrentStatus() {
199 /* If the negotiation is time limited, use time as current status */
200 if (negotiationType.equals("TIME"))
201 return timeline.getTime() * timeline.getTotalTime();
202
203 /*
204 * If the negotiation is round limited, use number of rounds as current
205 * status
206 */
207 return numberOfRoundsPassed;
208 }
209
210 /*
211 * At first 90% of negotiation, agent generates a random bid to fake his
212 * opponent with certain frequency
213 */
214 private Bid getFakeBid() {
215 for (int trial = 1; trial <= MAXIMUM_NUMBER_OF_TRIALS; trial++) {
216 Bid bid = generateRandomBid();
217
218 /*
219 * The utility of the bid should be greater than 80% of the
220 * threshold
221 */
222 if (utilitySpace.getUtility(bid) >= threshold * 0.8)
223 return bid;
224 }
225
226 return generateRandomBid();
227 }
228
229 private void calculateCurrentThreshold(double currentStatus) {
230 /* Threshold value is updated according to the agent's boulware level */
231 threshold = opponentModels[myTurn].getNewThreshold();
232
233 if (numberOfRoundsPassed % 10 == 0) {
234 currentThreshold = threshold;
235 } else if (currentStatus > timeToGetAlmostMad) {
236 currentThreshold = threshold * 0.95;
237
238 if (currentStatus > timeToGetMad)
239 currentThreshold = threshold * 0.9;
240 }
241 }
242
243 /* Get a nice bid using Opponent Model */
244 private Bid getNiceBid(double currentStatus) throws Exception {
245 Bid bid = generateRandomBid();
246
247 /*
248 * Shift Bids is for shifting the index if the bid at the current index
249 * is not accepted by opponent
250 */
251 if (currentStatus > timeToGetAlmostMad) {
252 getBidsPreferredByOpponent();
253 bid = (bidsPreferredByOpponents.get(myTurn) != null)
254 ? bidsPreferredByOpponents.get(myTurn)
255 .get(shiftBids[myTurn]++ % bidsPreferredByOpponents
256 .get(myTurn).size())
257 : utilitySpace.getMaxUtilityBid();
258
259 if (utilitySpace.getUtility(bid) >= currentThreshold)
260 return bid;
261 else
262 shiftBids[myTurn] = 0;
263 }
264
265 for (int trial = 1; trial <= MAXIMUM_NUMBER_OF_TRIALS; trial++) {
266 bid = generateRandomBid();
267
268 if (utilitySpace.getUtility(bid) >= currentThreshold)
269 return bid;
270 }
271
272 /*
273 * If it cannot generate a random bid higher than current threshold in
274 * the maximum number of trials, it returns max utility bid
275 */
276 return utilitySpace.getMaxUtilityBid();
277 }
278
279 private void getBidsPreferredByOpponent() throws Exception {
280 opponentModels[myTurn].computeMostPreferredBid();
281
282 bidsPreferredByOpponents.set(myTurn, null);
283 bidsPreferredByOpponents.set(myTurn,
284 opponentModels[myTurn].getAcceptableBids());
285
286 sortBids(bidsPreferredByOpponents.get(myTurn));
287
288 /* If there is no element in the list, just add one */
289 if (bidsPreferredByOpponents.get(myTurn).size() == 0)
290 bidsPreferredByOpponents.get(myTurn)
291 .add(utilitySpace.getMaxUtilityBid());
292 }
293
294 private void sortBids(List<Bid> bids) {
295 bids.sort(new Comparator<Bid>() {
296 @Override
297 public int compare(Bid a, Bid b) {
298 if (utilitySpace.getUtility(a) < utilitySpace.getUtility(b))
299 return 1;
300 if (utilitySpace.getUtility(a) > utilitySpace.getUtility(b))
301 return -1;
302
303 return 0;
304 }
305 });
306 }
307
308 @Override
309 public String getDescription() {
310 return "ANAC2017";
311 }
312
313 @Override
314 public HashMap<String, String> negotiationEnded(Bid acceptedBid) {
315 System.out.println("Negotiation has ended..");
316 return null;
317 }
318}
Note: See TracBrowser for help on using the repository browser.