1 | package parties.in4010.q12015.group14;
|
---|
2 |
|
---|
3 | import java.util.ArrayList;
|
---|
4 | import java.util.Collections;
|
---|
5 | import java.util.HashMap;
|
---|
6 | import java.util.List;
|
---|
7 | import java.util.Map;
|
---|
8 | import java.util.Random;
|
---|
9 |
|
---|
10 | import genius.core.AgentID;
|
---|
11 | import genius.core.Bid;
|
---|
12 | import genius.core.BidHistory;
|
---|
13 | import genius.core.actions.Accept;
|
---|
14 | import genius.core.actions.Action;
|
---|
15 | import genius.core.actions.DefaultAction;
|
---|
16 | import genius.core.actions.Offer;
|
---|
17 | import genius.core.bidding.BidDetails;
|
---|
18 | import genius.core.boaframework.OutcomeSpace;
|
---|
19 | import genius.core.parties.AbstractNegotiationParty;
|
---|
20 | import genius.core.parties.NegotiationInfo;
|
---|
21 | import genius.core.timeline.TimeLineInfo;
|
---|
22 | import genius.core.utility.AdditiveUtilitySpace;
|
---|
23 |
|
---|
24 | /**
|
---|
25 | * This is your negotiation party.
|
---|
26 | */
|
---|
27 | public class Group14 extends AbstractNegotiationParty {
|
---|
28 |
|
---|
29 | private Random randomGen = new Random();
|
---|
30 | private Action lastAction = null;
|
---|
31 | private AdditiveUtilitySpace myUtilSpace;
|
---|
32 | private TimeLineInfo myTimeLine;
|
---|
33 | private OutcomeSpace outSpace;
|
---|
34 | private List<BidDetails> allbids, allbidsByNash; // eventually a sorted list
|
---|
35 | // of all bids
|
---|
36 | private List<BidDetails> firstSetBids, secondSetBids, thirdSetBids, fourthSetBids, fifthSetBids, lastSetBids;
|
---|
37 | // a hash map from the opponent agents to the opponentmodelling objects
|
---|
38 | private HashMap<String, OpponentModelling> oppModelHashMap = new HashMap<String, OpponentModelling>();
|
---|
39 | private BidHistory oppBidHistory;
|
---|
40 |
|
---|
41 | private int count = 0;
|
---|
42 | // private int count2 = 0;
|
---|
43 | private int roundNr = 0;
|
---|
44 |
|
---|
45 | /**
|
---|
46 | * This method is called to initialize our agent
|
---|
47 | */
|
---|
48 | @Override
|
---|
49 | public void init(NegotiationInfo info) {
|
---|
50 | super.init(info);
|
---|
51 | firstSetBids = new ArrayList<BidDetails>();
|
---|
52 | secondSetBids = new ArrayList<BidDetails>();
|
---|
53 | thirdSetBids = new ArrayList<BidDetails>();
|
---|
54 | fourthSetBids = new ArrayList<BidDetails>();
|
---|
55 | fifthSetBids = new ArrayList<BidDetails>();
|
---|
56 | lastSetBids = new ArrayList<BidDetails>();
|
---|
57 | oppBidHistory = new BidHistory();
|
---|
58 | myUtilSpace = (AdditiveUtilitySpace) info.getUtilitySpace();
|
---|
59 | myTimeLine = info.getTimeline();
|
---|
60 | outSpace = new OutcomeSpace(info.getUtilitySpace());
|
---|
61 | allbids = outSpace.getAllOutcomes(); // get all possible outcomes
|
---|
62 | Collections.sort(allbids); // sort the in descending order
|
---|
63 | // allbids.remove(0); //remove the best bid in the list
|
---|
64 | makeLists(allbids);
|
---|
65 | };
|
---|
66 |
|
---|
67 | /**
|
---|
68 | * Each round this method gets called and ask you to accept or offer. The
|
---|
69 | * first party in the first round is a bit different, it can only propose an
|
---|
70 | * offer.
|
---|
71 | *
|
---|
72 | * @param validActions
|
---|
73 | * Either a list containing both accept and offer or only offer.
|
---|
74 | * @return The chosen action.
|
---|
75 | */
|
---|
76 | public Action chooseAction(List<Class<? extends Action>> validActions) {
|
---|
77 | // No offer to consider so we propose the one with max utility for us
|
---|
78 | roundNr++;
|
---|
79 |
|
---|
80 | if (!validActions.contains(Accept.class))
|
---|
81 | return maxUtilBid(myUtilSpace);
|
---|
82 | /*
|
---|
83 | * if (lastAction instanceof Offer){ //Bid bidOfOffer=((Offer)
|
---|
84 | * lastAction).getBid();
|
---|
85 | *
|
---|
86 | * //Analysis on Opponent Modeling if ((myTimeLine.getTime()>0.1 &&
|
---|
87 | * count2==0) || (myTimeLine.getTime()>0.2 && count==1) ||
|
---|
88 | * (myTimeLine.getTime()>0.3 && count==2) || (myTimeLine.getTime()>0.4
|
---|
89 | * && count==3) || (myTimeLine.getTime()>0.5 && count==4) ||
|
---|
90 | * (myTimeLine.getTime()>0.6 && count==5) || (myTimeLine.getTime()>0.7
|
---|
91 | * && count==6) || (myTimeLine.getTime()>0.8 && count==7) ||
|
---|
92 | * (myTimeLine.getTime()>0.9 && count==8)){ System.out.println("TIME: "
|
---|
93 | * + Double.toString(myTimeLine.getTime())); for(Map.Entry<String,
|
---|
94 | * OpponentModelling> entry: oppModelHashMap.entrySet()){
|
---|
95 | * System.out.println("The name of the agent is :"+entry.getKey());
|
---|
96 | * entry.getValue().printOppModel(); } count2++; } }
|
---|
97 | */
|
---|
98 |
|
---|
99 | // At certain times, we want to evaluate our bids using the latest
|
---|
100 | // oppModel
|
---|
101 | if ((myTimeLine.getTime() > 0.4 && count == 0) || (myTimeLine.getTime() > 0.55 && count == 1)
|
---|
102 | || (myTimeLine.getTime() > 0.65 && count == 2) || (myTimeLine.getTime() > 0.75 && count == 3)
|
---|
103 | || (myTimeLine.getTime() > 0.85 && count == 4) || (myTimeLine.getTime() > 0.95 && count == 5)) {
|
---|
104 | int phase = count + 1;
|
---|
105 | System.out.println("Starting phase " + phase + " at t=" + myTimeLine.getTime() + " and round=" + roundNr);
|
---|
106 | allbidsByNash = orderListByNash(allbids);
|
---|
107 | makeLists(allbidsByNash);
|
---|
108 |
|
---|
109 | count++;
|
---|
110 | }
|
---|
111 |
|
---|
112 | return myOffer();
|
---|
113 | // return new EndNegotiation();
|
---|
114 |
|
---|
115 | }
|
---|
116 |
|
---|
117 | /**
|
---|
118 | * All offers proposed by the other parties will be received as a message.
|
---|
119 | * You can use this information to your advantage, for example to predict
|
---|
120 | * their utility.
|
---|
121 | *
|
---|
122 | * @param sender
|
---|
123 | * The party that did the action.
|
---|
124 | * @param action
|
---|
125 | * The action that party did.
|
---|
126 | */
|
---|
127 | public void receiveMessage(AgentID sender, Action action) {
|
---|
128 | super.receiveMessage(sender, action);
|
---|
129 | /*
|
---|
130 | * if(action instanceof Offer){ lastAction=action; }
|
---|
131 | */
|
---|
132 | if (action instanceof Offer) {
|
---|
133 | lastAction = action;
|
---|
134 | Bid curBid = DefaultAction.getBidFromAction(lastAction);
|
---|
135 | if (!(sender == null)) { // if don't have ourselves as a
|
---|
136 | // bid offerer
|
---|
137 | // update the opponent modelling for this agent given its offer
|
---|
138 | if (!oppModelHashMap.containsKey(sender.toString())) {
|
---|
139 | oppModelHashMap.put(sender.toString(), new OpponentModelling(sender.toString(),
|
---|
140 | myUtilSpace.getDomain().getIssues(), curBid, getPartyId()));
|
---|
141 | // here we get the very first offer of the current agent
|
---|
142 | } else {
|
---|
143 | oppModelHashMap.get(sender.toString()).updateModel(curBid);
|
---|
144 | }
|
---|
145 |
|
---|
146 | // add the offer to the bid history
|
---|
147 | Bid bidOfLastOffer = ((Offer) lastAction).getBid();
|
---|
148 | BidDetails lastbd = new BidDetails(bidOfLastOffer, getUtility(bidOfLastOffer), myTimeLine.getTime());
|
---|
149 | oppBidHistory.add(lastbd);
|
---|
150 | }
|
---|
151 |
|
---|
152 | }
|
---|
153 |
|
---|
154 | // System.out.println("The sender of this action is
|
---|
155 | // "+sender.toString());
|
---|
156 | }
|
---|
157 |
|
---|
158 | /**
|
---|
159 | * We have to respond with an Action after we consult our acceptance
|
---|
160 | * strategy
|
---|
161 | *
|
---|
162 | * @return An Action which is either Accept or a new Offer by us
|
---|
163 | */
|
---|
164 | public Action myOffer() {
|
---|
165 | Offer oppOffer = (Offer) lastAction;
|
---|
166 | BidDetails ourNextBid;
|
---|
167 | if (myTimeLine.getTime() < 0.4) { // timeslot 1
|
---|
168 | ourNextBid = new BidDetails(maxUtilBid(myUtilSpace).getBid(), getUtility(maxUtilBid(myUtilSpace).getBid()));
|
---|
169 | } else if (myTimeLine.getTime() < 0.55) { // timeslot 2.1
|
---|
170 | int index = randomGen.nextInt(firstSetBids.size());
|
---|
171 | ourNextBid = firstSetBids.get(index);
|
---|
172 | } else if (myTimeLine.getTime() < 0.65) { // timeslot 2.2
|
---|
173 | int index = randomGen.nextInt(secondSetBids.size());
|
---|
174 | ourNextBid = secondSetBids.get(index);
|
---|
175 | } else if (myTimeLine.getTime() < 0.75) { // timeslot 2.3
|
---|
176 | int index = randomGen.nextInt(thirdSetBids.size());
|
---|
177 | ourNextBid = thirdSetBids.get(index);
|
---|
178 | } else if (myTimeLine.getTime() < 0.85) { // timeslot 2.4
|
---|
179 | int index = randomGen.nextInt(fourthSetBids.size());
|
---|
180 | ourNextBid = fourthSetBids.get(index);
|
---|
181 | } else if (myTimeLine.getTime() < 0.95) { // timeslot 2.5
|
---|
182 | int index = randomGen.nextInt(fifthSetBids.size());
|
---|
183 | ourNextBid = fifthSetBids.get(index);
|
---|
184 | } else { // timeslot 3
|
---|
185 | int index = randomGen.nextInt(lastSetBids.size());
|
---|
186 | ourNextBid = lastSetBids.get(index);
|
---|
187 | }
|
---|
188 |
|
---|
189 | // if our utility from this offer is bigger than that we are going to
|
---|
190 | // propose we have to accept
|
---|
191 | if (getUtility(oppOffer.getBid()) >= getUtility(ourNextBid.getBid())) {
|
---|
192 | return new Accept(getPartyId(), oppOffer.getBid());
|
---|
193 | } else {
|
---|
194 | // System.out.println("Time is:"+myTimeLine.getTime()+" and the
|
---|
195 | // offer's utility is :"+getUtility(ourNextBid.getBid()));
|
---|
196 | return new Offer(getPartyId(), ourNextBid.getBid());
|
---|
197 | }
|
---|
198 | }
|
---|
199 |
|
---|
200 | /**
|
---|
201 | * Divides the bidList into separate lists filtered for certain Utility
|
---|
202 | * intervals
|
---|
203 | *
|
---|
204 | * @param bidList
|
---|
205 | */
|
---|
206 | public void makeLists(List<BidDetails> bidList) {
|
---|
207 | firstSetBids.clear();
|
---|
208 | secondSetBids.clear();
|
---|
209 | thirdSetBids.clear();
|
---|
210 | fourthSetBids.clear();
|
---|
211 | fifthSetBids.clear();
|
---|
212 | lastSetBids.clear();
|
---|
213 |
|
---|
214 | // 1st range: [1.0,0.9], 2nd range: [0.95,0.8], 3rd range: [0.85,0.75]
|
---|
215 | for (BidDetails bd : bidList) {
|
---|
216 | double util = getUtility(bd.getBid());
|
---|
217 | if (util > 0.95) {
|
---|
218 | firstSetBids.add(bd);
|
---|
219 | }
|
---|
220 | if (util > 0.9) {
|
---|
221 | secondSetBids.add(bd);
|
---|
222 | }
|
---|
223 | if (util > 0.85) {
|
---|
224 | thirdSetBids.add(bd);
|
---|
225 | }
|
---|
226 | if (util > 0.8) {
|
---|
227 | fourthSetBids.add(bd);
|
---|
228 | }
|
---|
229 | if (util > 0.75) {
|
---|
230 | fifthSetBids.add(bd);
|
---|
231 | }
|
---|
232 | }
|
---|
233 |
|
---|
234 | BidDetails maxUtilbd = new BidDetails(maxUtilBid(myUtilSpace).getBid(),
|
---|
235 | getUtility(maxUtilBid(myUtilSpace).getBid()));
|
---|
236 |
|
---|
237 | // System.out.println("list sizes are 2.1:"+firstSetBids.size()+" -
|
---|
238 | // 2.2:"+secondSetBids.size()+" - 2.3:"+thirdSetBids.size()+" -
|
---|
239 | // 2.4:"+fourthSetBids.size()+" - 2.5:"+fifthSetBids.size());
|
---|
240 |
|
---|
241 | // 1
|
---|
242 | if (firstSetBids.isEmpty())
|
---|
243 | System.err.println("firstSetBids is empty at t=" + myTimeLine.getTime());
|
---|
244 | else if (firstSetBids.size() > 10)
|
---|
245 | firstSetBids = firstSetBids.subList(0, 10);
|
---|
246 | firstSetBids.add(maxUtilbd);
|
---|
247 |
|
---|
248 | // 2
|
---|
249 | if (secondSetBids.isEmpty())
|
---|
250 | System.err.println("secondSetBids is empty at t=" + myTimeLine.getTime());
|
---|
251 | else if (secondSetBids.size() > 12)
|
---|
252 | secondSetBids = secondSetBids.subList(0, 12);
|
---|
253 | secondSetBids.add(maxUtilbd);
|
---|
254 |
|
---|
255 | // 3
|
---|
256 | if (thirdSetBids.isEmpty())
|
---|
257 | System.err.println("thirdSetBids is empty at t=" + myTimeLine.getTime());
|
---|
258 | else if (thirdSetBids.size() > 15)
|
---|
259 | thirdSetBids = thirdSetBids.subList(0, 15);
|
---|
260 | thirdSetBids.add(maxUtilbd);
|
---|
261 |
|
---|
262 | // 4
|
---|
263 | if (fourthSetBids.isEmpty())
|
---|
264 | System.err.println("fourthSetBids is empty at t=" + myTimeLine.getTime());
|
---|
265 | else if (fourthSetBids.size() > 18)
|
---|
266 | fourthSetBids = fourthSetBids.subList(0, 18);
|
---|
267 | fourthSetBids.add(maxUtilbd);
|
---|
268 |
|
---|
269 | // 5
|
---|
270 | if (fifthSetBids.isEmpty())
|
---|
271 | System.err.println("fifthSetBids is empty at t=" + myTimeLine.getTime());
|
---|
272 | else if (fifthSetBids.size() > 20)
|
---|
273 | fifthSetBids = fifthSetBids.subList(0, 20);
|
---|
274 | fifthSetBids.add(maxUtilbd);
|
---|
275 |
|
---|
276 | // Lastly the list using BidHistory
|
---|
277 | // if(oppBidHistory.size()>10)
|
---|
278 | lastSetBids = oppBidHistory.getNBestBids(10);
|
---|
279 | // else
|
---|
280 | // lastSetBids = oppBidHistory.getHistory();
|
---|
281 |
|
---|
282 | }
|
---|
283 |
|
---|
284 | /**
|
---|
285 | * Order the list of bids by descending estimated Nash product
|
---|
286 | *
|
---|
287 | * @param bidList
|
---|
288 | * @return The newly ordered List of bids
|
---|
289 | */
|
---|
290 | public List<BidDetails> orderListByNash(List<BidDetails> bidList) {
|
---|
291 | // System.out.println("1 size = "+bidList.size());
|
---|
292 |
|
---|
293 | List<BidDetails> orderedList = new ArrayList<BidDetails>();
|
---|
294 | orderedList.add(bidList.get(1));
|
---|
295 |
|
---|
296 | List<Double> nashProdList = new ArrayList<Double>();
|
---|
297 | double nashProd = bidList.get(0).getMyUndiscountedUtil();
|
---|
298 | for (Map.Entry<String, OpponentModelling> entry : oppModelHashMap.entrySet()) {
|
---|
299 | nashProd = nashProd * entry.getValue().getOppUtil(bidList.get(1).getBid());
|
---|
300 | }
|
---|
301 | nashProdList.add(nashProd);
|
---|
302 |
|
---|
303 | BidDetails bd;
|
---|
304 | for (int j = 2; j < bidList.size(); j++) {
|
---|
305 | bd = bidList.get(j);
|
---|
306 | nashProd = bd.getMyUndiscountedUtil();
|
---|
307 | for (Map.Entry<String, OpponentModelling> entry : oppModelHashMap.entrySet()) {
|
---|
308 | nashProd = nashProd * entry.getValue().getOppUtil(bd.getBid());
|
---|
309 | }
|
---|
310 | for (int i = 0; i < nashProdList.size(); i++) {
|
---|
311 | if (nashProd > nashProdList.get(i)) {
|
---|
312 | orderedList.add(i, bd);
|
---|
313 | nashProdList.add(i, nashProd);
|
---|
314 | i = nashProdList.size();
|
---|
315 | }
|
---|
316 | if (i == nashProdList.size() - 1) {
|
---|
317 | orderedList.add(i, bd);
|
---|
318 | nashProdList.add(i, nashProd);
|
---|
319 | i = nashProdList.size();
|
---|
320 | }
|
---|
321 | }
|
---|
322 | }
|
---|
323 | // System.out.println("1 size = "+orderedList.size());
|
---|
324 | return orderedList;
|
---|
325 | }
|
---|
326 |
|
---|
327 | /**
|
---|
328 | * Returns the bid with the highest Utility for us out of the whole
|
---|
329 | * UtilitySpace
|
---|
330 | *
|
---|
331 | * @param us
|
---|
332 | * The UtilitySpace object
|
---|
333 | * @return The Offer with maximum utility, in case of exception an offer
|
---|
334 | * with a random bid
|
---|
335 | */
|
---|
336 | public Offer maxUtilBid(AdditiveUtilitySpace us) {
|
---|
337 | try {
|
---|
338 | return new Offer(getPartyId(), us.getMaxUtilityBid());
|
---|
339 | } catch (Exception e) {
|
---|
340 | System.err.println("Error generating maximum utility!");
|
---|
341 | e.printStackTrace();
|
---|
342 | return new Offer(getPartyId(), generateRandomBid());
|
---|
343 | }
|
---|
344 | }
|
---|
345 |
|
---|
346 | /**
|
---|
347 | * Just a string describing Group14 Agent
|
---|
348 | */
|
---|
349 | @Override
|
---|
350 | public String getDescription() {
|
---|
351 | return "Party Group 14";
|
---|
352 | }
|
---|
353 |
|
---|
354 | }
|
---|