1 | package agents.anac.y2016.agentlight;
|
---|
2 |
|
---|
3 | import java.util.ArrayList;
|
---|
4 | import java.util.Collections;
|
---|
5 | import java.util.HashMap;
|
---|
6 | import java.util.List;
|
---|
7 |
|
---|
8 | import genius.core.AgentID;
|
---|
9 | import genius.core.Bid;
|
---|
10 | import genius.core.actions.Accept;
|
---|
11 | import genius.core.actions.Action;
|
---|
12 | import genius.core.actions.EndNegotiation;
|
---|
13 | import genius.core.actions.Inform;
|
---|
14 | import genius.core.actions.Offer;
|
---|
15 | import genius.core.issue.Issue;
|
---|
16 | import genius.core.issue.IssueDiscrete;
|
---|
17 | import genius.core.issue.IssueInteger;
|
---|
18 | import genius.core.issue.Value;
|
---|
19 | import genius.core.issue.ValueInteger;
|
---|
20 | import genius.core.parties.AbstractNegotiationParty;
|
---|
21 | import genius.core.parties.NegotiationInfo;
|
---|
22 |
|
---|
23 | public class AgentLight extends AbstractNegotiationParty {
|
---|
24 |
|
---|
25 | // PARAMETER LIST. THIS IS WHAT YOU'RE SUPPOSED TO PLAY AROUND WITH.
|
---|
26 |
|
---|
27 | // newly create variables
|
---|
28 | private double discountFactor = 0;
|
---|
29 | private double reservationValue = 0;
|
---|
30 | private static boolean isPrinting = true;
|
---|
31 | private boolean nextOpponentIndicator;
|
---|
32 | private int opponentNum;
|
---|
33 | private HashMap<Bid, Integer> bidSupport = new HashMap<Bid, Integer>();
|
---|
34 | private ArrayList<Bid> bidPotential = new ArrayList<Bid>();
|
---|
35 | private HashMap<AgentID, OpponentInfo> opponentInfo = new HashMap<AgentID, OpponentInfo>();
|
---|
36 | private ArrayList<Bid> totalBidHistory = new ArrayList<Bid>();
|
---|
37 | private OpponentInfo worthyOpponent = null;
|
---|
38 | private OpponentInfo nextOpponent = null;
|
---|
39 | private Bid lastBidInHistory = null;
|
---|
40 | private Bid bestBidInPotential = null;
|
---|
41 | private ArrayList<AgentID> agentOrder = new ArrayList<AgentID>();
|
---|
42 |
|
---|
43 | // variable in init()
|
---|
44 | private double maxUtility, minUtility;
|
---|
45 | private List<Issue> issueList;
|
---|
46 | private HashMap<Integer, ArrayList<Value>> issue2Value = new HashMap<Integer, ArrayList<Value>>();
|
---|
47 | private long possibleBidNum;
|
---|
48 | private ArrayList<ComparableBid> bidList = new ArrayList<ComparableBid>();
|
---|
49 |
|
---|
50 | // new variable find here
|
---|
51 | // private Bid opponentPreBid;
|
---|
52 | private int frequencyReward;
|
---|
53 | private int unchangeReward;
|
---|
54 | private ArrayList<Bid> myBidRecord = new ArrayList<Bid>();
|
---|
55 | private ArrayList<Bid> myAcceptBidRecord = new ArrayList<Bid>();
|
---|
56 |
|
---|
57 | // variable in receive()
|
---|
58 | private Bid opponentCurBid;
|
---|
59 | private int recordTimes = 0;
|
---|
60 | // variable in chooseAction()
|
---|
61 | private double learningTimes = 10, learningExp = 0.1;
|
---|
62 | private double discount = 0.7;
|
---|
63 |
|
---|
64 | @Override
|
---|
65 | public void init(NegotiationInfo info) {
|
---|
66 | super.init(info);
|
---|
67 | // initialize variables
|
---|
68 | this.discountFactor = utilitySpace.getDiscountFactor();
|
---|
69 | this.reservationValue = utilitySpace.getReservationValueUndiscounted();
|
---|
70 |
|
---|
71 | if (isPrinting) {
|
---|
72 | System.out.println("Discount Factor is " + discountFactor);
|
---|
73 | System.out.println("Reservation Value is " + reservationValue);
|
---|
74 | }
|
---|
75 |
|
---|
76 | this.maxUtility = 1;
|
---|
77 | this.frequencyReward = 1;
|
---|
78 | this.unchangeReward = 1;
|
---|
79 | this.nextOpponentIndicator = false;
|
---|
80 |
|
---|
81 | issueList = utilitySpace.getDomain().getIssues();
|
---|
82 |
|
---|
83 | for (Issue issue : issueList) {
|
---|
84 | int issueNum = issue.getNumber();
|
---|
85 | switch (issue.getType()) {
|
---|
86 | case DISCRETE:
|
---|
87 | IssueDiscrete discreteIssue = (IssueDiscrete) issue;
|
---|
88 | ArrayList<Value> discreteValue = new ArrayList<Value>();
|
---|
89 | for (int i = 0; i < discreteIssue.getNumberOfValues(); i++) {
|
---|
90 | discreteValue.add(discreteIssue.getValue(i));
|
---|
91 | }
|
---|
92 | issue2Value.put(issueNum, discreteValue);
|
---|
93 | break;
|
---|
94 | case INTEGER:
|
---|
95 | IssueInteger integerIssue = (IssueInteger) issue;
|
---|
96 | ArrayList<Value> integerValue = new ArrayList<Value>();
|
---|
97 | for (int i = integerIssue.getLowerBound(); i <= integerIssue
|
---|
98 | .getUpperBound(); i++) {
|
---|
99 | integerValue.add(new ValueInteger(i));
|
---|
100 | }
|
---|
101 | issue2Value.put(issueNum, integerValue);
|
---|
102 | break;
|
---|
103 | default:
|
---|
104 | try {
|
---|
105 | throw new Exception(
|
---|
106 | "issue type " + issue.getType() + " not supported");
|
---|
107 | } catch (Exception e) {
|
---|
108 | // TODO Auto-generated catch block
|
---|
109 | e.printStackTrace();
|
---|
110 | }
|
---|
111 | }
|
---|
112 | }
|
---|
113 |
|
---|
114 | possibleBidNum = utilitySpace.getDomain().getNumberOfPossibleBids();
|
---|
115 | try {
|
---|
116 | for (int i = 0; i < possibleBidNum; i++) {
|
---|
117 | HashMap<Integer, Value> issueInst;
|
---|
118 | issueInst = Int2Bid(i);
|
---|
119 | ComparableBid bid = new ComparableBid(
|
---|
120 | new Bid(utilitySpace.getDomain(), issueInst));
|
---|
121 | bidList.add(bid);
|
---|
122 | }
|
---|
123 |
|
---|
124 | Collections.sort(bidList);
|
---|
125 | } catch (Exception e) {
|
---|
126 | // TODO Auto-generated catch block
|
---|
127 | e.printStackTrace();
|
---|
128 | }
|
---|
129 | }
|
---|
130 |
|
---|
131 | @Override
|
---|
132 | public Action chooseAction(List<Class<? extends Action>> Actions) {
|
---|
133 |
|
---|
134 | if (!agentOrder.contains(getPartyId())) {
|
---|
135 | agentOrder.add(getPartyId());
|
---|
136 | } else {
|
---|
137 | for (AgentID agentId : agentOrder) {
|
---|
138 | System.out.println("agentID: " + agentId);
|
---|
139 | }
|
---|
140 | if (agentOrder.indexOf(getPartyId()) == (opponentNum - 1))
|
---|
141 | nextOpponent = opponentInfo.get(agentOrder.get(0));
|
---|
142 | else {
|
---|
143 | nextOpponent = opponentInfo.get(
|
---|
144 | agentOrder.get(agentOrder.indexOf(getPartyId()) + 1));
|
---|
145 | }
|
---|
146 | }
|
---|
147 | recordTimes++;
|
---|
148 |
|
---|
149 | double remainingRounds = (timeline.getTotalTime()
|
---|
150 | - timeline.getCurrentTime())
|
---|
151 | / (timeline.getCurrentTime() / recordTimes);
|
---|
152 | if (recordTimes >= learningTimes) {
|
---|
153 | worthyOpponent = findOpponent(opponentInfo);
|
---|
154 | if (worthyOpponent == null) {
|
---|
155 | worthyOpponent = nextOpponent;
|
---|
156 | nextOpponentIndicator = true;
|
---|
157 | }
|
---|
158 | if (isPrinting) {
|
---|
159 | System.out.println("worthyOpponent: "
|
---|
160 | + worthyOpponent.getAgentID().toString());
|
---|
161 | }
|
---|
162 | int worthyOpponentBidSize = worthyOpponent.getAgentBidHistory()
|
---|
163 | .size();
|
---|
164 | opponentCurBid = worthyOpponent.getAgentBidHistory()
|
---|
165 | .get(worthyOpponentBidSize - 1);
|
---|
166 | // opponentPreBid =
|
---|
167 | // worthyOpponent.getAgentBidHistory().get(worthyOpponentBidSize-2);
|
---|
168 | }
|
---|
169 | if (!totalBidHistory.isEmpty()) {
|
---|
170 | int totalBidHistorySize = totalBidHistory.size();
|
---|
171 | lastBidInHistory = totalBidHistory.get(totalBidHistorySize - 1);
|
---|
172 | }
|
---|
173 | if (!bidPotential.isEmpty()) {
|
---|
174 | bestBidInPotential = findBestBid(bidPotential);
|
---|
175 | }
|
---|
176 |
|
---|
177 | if (isPrinting) {
|
---|
178 | System.out.println("Threshold calculating!");
|
---|
179 | System.out.println("remaining Rounds: " + remainingRounds);
|
---|
180 | System.out.println("timeline.getType " + timeline.getType());
|
---|
181 | System.out.println("getTotalTime: " + timeline.getTotalTime());
|
---|
182 | System.out.println("getTime(): " + timeline.getTime());
|
---|
183 | System.out.println("currentTime: " + timeline.getCurrentTime());
|
---|
184 | // System.out.println("getTimeUtility:
|
---|
185 | // "+utilitySpace.getUtilityWithDiscount(lastBidInHistory,
|
---|
186 | // timeline.getTime()));
|
---|
187 | // System.out.println("currentTimeUtility:
|
---|
188 | // "+utilitySpace.getUtilityWithDiscount(lastBidInHistory,
|
---|
189 | // timeline.getCurrentTime()));
|
---|
190 | }
|
---|
191 |
|
---|
192 | double base = ((timeline.getTotalTime() - timeline.getCurrentTime())
|
---|
193 | / timeline.getTotalTime()) > 0.7
|
---|
194 | ? ((timeline.getTotalTime() - timeline.getCurrentTime())
|
---|
195 | / timeline.getTotalTime())
|
---|
196 | : 0.7;
|
---|
197 | if (recordTimes >= learningTimes && worthyOpponent != null) {
|
---|
198 | learningExp = ((worthyOpponent.getOpponentStandardDeviation())[1]
|
---|
199 | + (worthyOpponent.getOpponentAverage())[1]);
|
---|
200 | }
|
---|
201 | minUtility = (reservationValue
|
---|
202 | + (maxUtility - reservationValue) * Math.pow(base, learningExp))
|
---|
203 | * discountFactor;
|
---|
204 | if (remainingRounds <= 3) {
|
---|
205 | minUtility = minUtility * (discount);
|
---|
206 | }
|
---|
207 | if (isPrinting) {
|
---|
208 | System.out.println("learningExp: " + learningExp);
|
---|
209 | System.out.println("base: " + base);
|
---|
210 | System.out.println("discountFactor: " + discountFactor);
|
---|
211 | System.out.println("minUtility: " + minUtility);
|
---|
212 | }
|
---|
213 |
|
---|
214 | if (remainingRounds <= 3 && lastBidInHistory != null
|
---|
215 | && utilitySpace.getUtilityWithDiscount(lastBidInHistory,
|
---|
216 | timeline.getTime()) >= minUtility
|
---|
217 | && bidPotential.contains(lastBidInHistory)) {
|
---|
218 | if (isPrinting) {
|
---|
219 | System.out.println("Accept condition 1!");
|
---|
220 | }
|
---|
221 | return (new Accept(getPartyId(), opponentCurBid));
|
---|
222 | }
|
---|
223 | if (lastBidInHistory != null
|
---|
224 | && utilitySpace.getUtilityWithDiscount(lastBidInHistory,
|
---|
225 | timeline.getTime()) >= minUtility
|
---|
226 | && !myAcceptBidRecord.contains(lastBidInHistory)
|
---|
227 | && !bidPotential.contains(lastBidInHistory)
|
---|
228 | || (bestBidInPotential != null
|
---|
229 | && !myAcceptBidRecord.contains(lastBidInHistory)
|
---|
230 | && !bidPotential.contains(lastBidInHistory)
|
---|
231 | && utilitySpace.getUtilityWithDiscount(lastBidInHistory,
|
---|
232 | timeline.getTime()) >= utilitySpace
|
---|
233 | .getUtilityWithDiscount(
|
---|
234 | bestBidInPotential,
|
---|
235 | timeline.getTime()))) {
|
---|
236 | if (isPrinting) {
|
---|
237 | System.out.println(bidPotential);
|
---|
238 | System.out.println(lastBidInHistory);
|
---|
239 | System.out.println(bidPotential.contains(lastBidInHistory));
|
---|
240 | System.out.println("Accept condition 2!");
|
---|
241 | }
|
---|
242 | myAcceptBidRecord.add(lastBidInHistory);
|
---|
243 | return new Accept(getPartyId(), opponentCurBid);
|
---|
244 | }
|
---|
245 |
|
---|
246 | if (bestBidInPotential != null && remainingRounds <= 3
|
---|
247 | && utilitySpace.getUtilityWithDiscount(bestBidInPotential,
|
---|
248 | timeline.getTime()) >= minUtility) {
|
---|
249 | if (isPrinting) {
|
---|
250 | System.out.println("Offer condition 1!");
|
---|
251 | }
|
---|
252 | return (new Offer(getPartyId(), bestBidInPotential));
|
---|
253 | }
|
---|
254 |
|
---|
255 | if (remainingRounds > 3 && recordTimes >= learningTimes) {
|
---|
256 | if (isPrinting) {
|
---|
257 | System.out.println("choose Negotiation Action");
|
---|
258 | }
|
---|
259 | return NegotiationAction(minUtility);
|
---|
260 | }
|
---|
261 | if (remainingRounds <= 3) {
|
---|
262 | if (isPrinting) {
|
---|
263 | System.out.println("choose Concession Action");
|
---|
264 | }
|
---|
265 | return NegotiationAction(minUtility);
|
---|
266 | }
|
---|
267 | if (isPrinting) {
|
---|
268 | System.out.println("choose Learning Action");
|
---|
269 | }
|
---|
270 | return LearningAction();
|
---|
271 |
|
---|
272 | }
|
---|
273 |
|
---|
274 | public OpponentInfo findOpponent(
|
---|
275 | HashMap<AgentID, OpponentInfo> opponentInfo) {
|
---|
276 | double minValue = 999;
|
---|
277 | OpponentInfo minInfo = null;
|
---|
278 | for (AgentID agentId : opponentInfo.keySet()) {
|
---|
279 | int opponentBidSize = opponentInfo.get(agentId).getAgentBidHistory()
|
---|
280 | .size();
|
---|
281 | if (opponentBidSize >= 2) {
|
---|
282 | Bid opponentCurBid = opponentInfo.get(agentId)
|
---|
283 | .getAgentBidHistory().get(opponentBidSize - 1);
|
---|
284 | Bid opponentPreBid = opponentInfo.get(agentId)
|
---|
285 | .getAgentBidHistory().get(opponentBidSize - 2);
|
---|
286 | double value = opponentInfo.get(agentId)
|
---|
287 | .getOpponentStandardDeviation()[1]
|
---|
288 | + opponentInfo.get(agentId).getOpponentAverage()[1];
|
---|
289 | if (value < minValue
|
---|
290 | && (opponentInfo.get(agentId)
|
---|
291 | .getOpponentLastAction() instanceof Offer)
|
---|
292 | && opponentCurBid != opponentPreBid) {
|
---|
293 | minValue = value;
|
---|
294 | minInfo = opponentInfo.get(agentId);
|
---|
295 | }
|
---|
296 | }
|
---|
297 | }
|
---|
298 | return minInfo;
|
---|
299 | }
|
---|
300 |
|
---|
301 | public Bid findBestBid(ArrayList<Bid> bidList) {
|
---|
302 | double maxValue = 0;
|
---|
303 | Bid maxBid = null;
|
---|
304 | for (Bid bid : bidList) {
|
---|
305 | double utility = utilitySpace.getUtility(bid);
|
---|
306 | if (utility > maxValue) {
|
---|
307 | maxValue = utility;
|
---|
308 | maxBid = bid;
|
---|
309 | }
|
---|
310 | }
|
---|
311 | return maxBid;
|
---|
312 | }
|
---|
313 |
|
---|
314 | public Action LearningAction() {
|
---|
315 | Bid bid = null;
|
---|
316 | try {
|
---|
317 | bid = utilitySpace.getMaxUtilityBid();
|
---|
318 | } catch (Exception e) {
|
---|
319 | // TODO Auto-generated catch block
|
---|
320 | e.printStackTrace();
|
---|
321 | }
|
---|
322 |
|
---|
323 | if (bid != null) {
|
---|
324 | myBidRecord.add(bid);
|
---|
325 | totalBidHistory.add(bid);
|
---|
326 | bidSupport.put(bid, 0);
|
---|
327 | myAcceptBidRecord.add(bid);
|
---|
328 | return (new Offer(getPartyId(), bid));
|
---|
329 | } else {
|
---|
330 | myBidRecord.add(bidList.get(bidList.size() - 1).bid);
|
---|
331 | totalBidHistory.add(bid);
|
---|
332 | bidSupport.put(bid, 0);
|
---|
333 | myAcceptBidRecord.add(bid);
|
---|
334 | return (new Offer(getPartyId(),
|
---|
335 | bidList.get(bidList.size() - 1).bid));
|
---|
336 | }
|
---|
337 | }
|
---|
338 |
|
---|
339 | public Action NegotiationAction(double minUtility) {
|
---|
340 | // allowedBidList
|
---|
341 | // Tit for Tat
|
---|
342 | double time = timeline.getTime();
|
---|
343 | double tftUtility = minUtility;
|
---|
344 | double curUtility = minUtility;
|
---|
345 | double offerUtility;
|
---|
346 | if (recordTimes > 1) {
|
---|
347 | // tftUtility = utilitySpace.getUtility(opponentCurBid)-
|
---|
348 | // utilitySpace.getUtility(opponentPreBid);
|
---|
349 | // curUtility =
|
---|
350 | // utilitySpace.getUtilityWithDiscount(myBidRecord.get(myBidRecord.size()-1),
|
---|
351 | // time)-tftUtility*discount;
|
---|
352 | tftUtility = (utilitySpace.getUtility(opponentCurBid) - utilitySpace
|
---|
353 | .getUtility(worthyOpponent.getAgentBidHistory().get(0)))
|
---|
354 | * (worthyOpponent.getOpponentStandardDeviation()[1]
|
---|
355 | + worthyOpponent.getOpponentAverage()[1]);
|
---|
356 | curUtility = maxUtility - tftUtility;
|
---|
357 | }
|
---|
358 | // if(worthyOpponent.getOpponentStandardDeviation()[0]<worthyOpponent.getOpponentStandardDeviation()[1]
|
---|
359 | // &&
|
---|
360 | // worthyOpponent.getOpponentAverage()[0]<worthyOpponent.getOpponentAverage()[1])
|
---|
361 | // offerUtility = (minUtility>curUtility?minUtility:curUtility);
|
---|
362 | // else
|
---|
363 | offerUtility = curUtility;
|
---|
364 | if (isPrinting) {
|
---|
365 | System.out.println("OpponentStandardDeviation()[0]: "
|
---|
366 | + worthyOpponent.getOpponentStandardDeviation()[0]);
|
---|
367 | System.out.println("OpponentStandardDeviation()[1]: "
|
---|
368 | + worthyOpponent.getOpponentStandardDeviation()[1]);
|
---|
369 | System.out.println("OpponentAverage()[0]: "
|
---|
370 | + worthyOpponent.getOpponentAverage()[0]);
|
---|
371 | System.out.println("OpponentAverage()[1]: "
|
---|
372 | + worthyOpponent.getOpponentAverage()[1]);
|
---|
373 | }
|
---|
374 | if (offerUtility < reservationValue)
|
---|
375 | offerUtility = reservationValue;
|
---|
376 |
|
---|
377 | if (offerUtility < maxUtility
|
---|
378 | - (utilitySpace.getUtility(worthyOpponent.getBestBid())
|
---|
379 | - utilitySpace.getUtility(
|
---|
380 | worthyOpponent.getAgentBidHistory().get(0))))
|
---|
381 | offerUtility = maxUtility - (utilitySpace
|
---|
382 | .getUtility(worthyOpponent.getBestBid())
|
---|
383 | - utilitySpace.getUtility(
|
---|
384 | worthyOpponent.getAgentBidHistory().get(0)));
|
---|
385 | if (nextOpponentIndicator) {
|
---|
386 | offerUtility = minUtility;
|
---|
387 | nextOpponentIndicator = false;
|
---|
388 | }
|
---|
389 | if (isPrinting) {
|
---|
390 | // System.out.println("bestBidUtility:
|
---|
391 | // "+utilitySpace.getUtility(worthyOpponent.getBestBid()));
|
---|
392 | // System.out.println("lastBidInHistor:
|
---|
393 | // "+utilitySpace.getUtility(lastBidInHistory));
|
---|
394 | // System.out.println("bestBidInPotential:
|
---|
395 | // "+utilitySpace.getUtility(bestBidInPotential));
|
---|
396 | System.out.println("offerUtility: " + offerUtility);
|
---|
397 | }
|
---|
398 |
|
---|
399 | Bid bid = chooseBestBid(offerUtility);
|
---|
400 |
|
---|
401 | if (utilitySpace.getUtility(lastBidInHistory) > minUtility
|
---|
402 | && utilitySpace.getUtilityWithDiscount(bid, time) < utilitySpace
|
---|
403 | .getUtilityWithDiscount(lastBidInHistory, time)
|
---|
404 | && !myAcceptBidRecord.contains(lastBidInHistory)
|
---|
405 | || (bestBidInPotential != null
|
---|
406 | && !myAcceptBidRecord.contains(lastBidInHistory)
|
---|
407 | && utilitySpace.getUtilityWithDiscount(lastBidInHistory,
|
---|
408 | time) > utilitySpace.getUtilityWithDiscount(
|
---|
409 | bestBidInPotential, time))) {
|
---|
410 | if (isPrinting) {
|
---|
411 | System.out.println("Accept in Negotiation!");
|
---|
412 | }
|
---|
413 | myAcceptBidRecord.add(lastBidInHistory);
|
---|
414 | return (new Accept(getPartyId(), opponentCurBid));
|
---|
415 | }
|
---|
416 | if (isPrinting) {
|
---|
417 | System.out.println("Offer in Negotiation");
|
---|
418 | }
|
---|
419 | myBidRecord.add(bid);
|
---|
420 | totalBidHistory.add(bid);
|
---|
421 | bidSupport.put(bid, 0);
|
---|
422 | myAcceptBidRecord.add(bid);
|
---|
423 | return (new Offer(getPartyId(), bid));
|
---|
424 | }
|
---|
425 |
|
---|
426 | public Bid chooseBestBid(double minUtility) {
|
---|
427 | double time = timeline.getTime();
|
---|
428 | int ceil = (int) Math.ceil(0.5 * bidList.size());
|
---|
429 | int exp = 2;
|
---|
430 | // int inc;
|
---|
431 | // find allowed bid list
|
---|
432 | while (((ceil > 0) && (ceil < bidList.size() - 1))
|
---|
433 | && ((utilitySpace.getUtilityWithDiscount(bidList.get(ceil).bid,
|
---|
434 | time) > minUtility
|
---|
435 | && utilitySpace.getUtilityWithDiscount(
|
---|
436 | bidList.get(ceil + 1).bid, time) > minUtility)
|
---|
437 | || (utilitySpace.getUtilityWithDiscount(
|
---|
438 | bidList.get(ceil).bid, time) <= minUtility
|
---|
439 | && utilitySpace.getUtilityWithDiscount(
|
---|
440 | bidList.get(ceil + 1).bid,
|
---|
441 | time) <= minUtility))) {
|
---|
442 | if (utilitySpace.getUtilityWithDiscount(bidList.get(ceil).bid,
|
---|
443 | time) > minUtility) {
|
---|
444 | if ((int) Math.ceil(bidList.size() * Math.pow(0.5, exp)) == 0) {
|
---|
445 | ceil -= 1;
|
---|
446 | } else {
|
---|
447 | ceil -= (int) Math
|
---|
448 | .ceil(bidList.size() * Math.pow(0.5, exp));
|
---|
449 | }
|
---|
450 | } else {
|
---|
451 | if ((int) Math
|
---|
452 | .floor(bidList.size() * Math.pow(0.5, exp)) == 0) {
|
---|
453 | ceil += 1;
|
---|
454 | } else {
|
---|
455 | ceil += (int) Math
|
---|
456 | .floor(bidList.size() * Math.pow(0.5, exp));
|
---|
457 | }
|
---|
458 | }
|
---|
459 | exp++;
|
---|
460 | }
|
---|
461 | if (ceil <= 0) {
|
---|
462 | ceil = 0;
|
---|
463 | } else if (ceil >= bidList.size() - 1) {
|
---|
464 | ceil = bidList.size() - 1;
|
---|
465 | }
|
---|
466 | List<ComparableBid> tempBidList;
|
---|
467 | tempBidList = bidList.subList(ceil, bidList.size());
|
---|
468 |
|
---|
469 | // find opponent most favorable bids
|
---|
470 | ComparableBid bestBid = tempBidList.get(0);
|
---|
471 | for (ComparableBid bid : tempBidList) {
|
---|
472 | if (getOppUtility(bid.bid) > getOppUtility(bestBid.bid))
|
---|
473 | bestBid = bid;
|
---|
474 | }
|
---|
475 | return bestBid.bid;
|
---|
476 | }
|
---|
477 |
|
---|
478 | public double getOppUtility(Bid bid) {
|
---|
479 | HashMap<Integer, Value> bidTemp = bid.getValues();
|
---|
480 | double utility = 0;
|
---|
481 | for (Issue issue : bid.getIssues()) {
|
---|
482 | switch (issue.getType()) {
|
---|
483 | case DISCRETE:
|
---|
484 | utility += worthyOpponent.getValueWeights().get(issue)
|
---|
485 | .get(bidTemp.get(issue.getNumber()));
|
---|
486 | break;
|
---|
487 | case INTEGER:
|
---|
488 | IssueInteger integerIssue = (IssueInteger) issue;
|
---|
489 | double lowerBound = integerIssue.getLowerBound();
|
---|
490 | double upperBound = integerIssue.getUpperBound();
|
---|
491 | double lowerWeight = utility += worthyOpponent.getIssueWeights()
|
---|
492 | .get(issue)[0];
|
---|
493 | double upperWeight = utility += worthyOpponent.getIssueWeights()
|
---|
494 | .get(issue)[1];
|
---|
495 | utility = lowerWeight + (upperWeight - lowerWeight)
|
---|
496 | * (((ValueInteger) bidTemp.get(issue.getNumber()))
|
---|
497 | .getValue() - lowerBound)
|
---|
498 | / (upperBound - lowerBound);
|
---|
499 | break;
|
---|
500 | default:
|
---|
501 | try {
|
---|
502 | throw new Exception(
|
---|
503 | "issue type " + issue.getType() + " not supported");
|
---|
504 | } catch (Exception e) {
|
---|
505 | // TODO Auto-generated catch block
|
---|
506 | e.printStackTrace();
|
---|
507 | }
|
---|
508 | }
|
---|
509 | }
|
---|
510 | return utility;
|
---|
511 | }
|
---|
512 |
|
---|
513 | @Override
|
---|
514 | public void receiveMessage(AgentID sender, Action action) {
|
---|
515 |
|
---|
516 | super.receiveMessage(sender, action);
|
---|
517 | if (!(action instanceof Inform) && !agentOrder.contains(sender)) {
|
---|
518 | agentOrder.add(sender);
|
---|
519 | }
|
---|
520 |
|
---|
521 | Bid bid = null;
|
---|
522 |
|
---|
523 | if (isPrinting) {
|
---|
524 | System.out.println("Sender:" + sender + ", Action:" + action);
|
---|
525 | }
|
---|
526 |
|
---|
527 | if (action != null) {
|
---|
528 | if (action instanceof Inform
|
---|
529 | && ((Inform) action).getName() == "NumberOfAgents"
|
---|
530 | && ((Inform) action).getValue() instanceof Integer) {
|
---|
531 | opponentNum = ((Integer) ((Inform) action).getValue())
|
---|
532 | .intValue();
|
---|
533 | if (isPrinting) {
|
---|
534 | System.out.println("OpponentNum: " + opponentNum);
|
---|
535 | }
|
---|
536 | } else if (action instanceof Accept) {
|
---|
537 | bid = totalBidHistory.get(totalBidHistory.size() - 1);
|
---|
538 | int supportNum = bidSupport.get(bid);
|
---|
539 | bidSupport.put(bid, supportNum + 1);
|
---|
540 | if (bidSupport.get(bid) == (opponentNum - 1)) {
|
---|
541 | bidPotential.add(bid);
|
---|
542 | }
|
---|
543 | if (!opponentInfo.keySet().contains(sender)) {
|
---|
544 | opponentInfo.put(sender, new OpponentInfo(sender));
|
---|
545 | }
|
---|
546 | opponentInfo.get(sender).setOpponentLastAction(action);
|
---|
547 | } else if (action instanceof Offer) {
|
---|
548 | bid = ((Offer) action).getBid();
|
---|
549 | if (!opponentInfo.keySet().contains(sender)) {
|
---|
550 | opponentInfo.put(sender, new OpponentInfo(sender));
|
---|
551 | opponentInfo.get(sender).setBestBid(bid);
|
---|
552 | }
|
---|
553 | totalBidHistory.add(bid);
|
---|
554 | bidSupport.put(bid, 1);
|
---|
555 | opponentInfo.get(sender).updateBid(bid);
|
---|
556 | if (utilitySpace.getUtility(
|
---|
557 | opponentInfo.get(sender).getBestBid()) < utilitySpace
|
---|
558 | .getUtility(bid)) {
|
---|
559 | opponentInfo.get(sender).setBestBid(bid);
|
---|
560 | }
|
---|
561 | opponentInfo.get(sender).setOpponentLastAction(action);
|
---|
562 | } else if (action instanceof EndNegotiation) {
|
---|
563 | opponentInfo.get(sender).setOpponentLastAction(action);
|
---|
564 | }
|
---|
565 | }
|
---|
566 | }
|
---|
567 |
|
---|
568 | public HashMap<Integer, Value> Int2Bid(int number) {
|
---|
569 | HashMap<Integer, Value> issueInst = new HashMap<Integer, Value>();
|
---|
570 | int numberTemp = number;
|
---|
571 | int temp = 0;
|
---|
572 | for (int i = issueList.size() - 1; i >= 0; i--) {
|
---|
573 | temp = numberTemp
|
---|
574 | % (issue2Value.get(issueList.get(i).getNumber()).size());
|
---|
575 | issueInst.put(issueList.get(i).getNumber(),
|
---|
576 | issue2Value.get(issueList.get(i).getNumber()).get(temp));
|
---|
577 | numberTemp = (numberTemp - temp)
|
---|
578 | / (issue2Value.get(issueList.get(i).getNumber()).size());
|
---|
579 | }
|
---|
580 | return issueInst;
|
---|
581 | }
|
---|
582 |
|
---|
583 | private class ComparableBid implements Comparable<ComparableBid> {
|
---|
584 | public Bid bid;
|
---|
585 |
|
---|
586 | public ComparableBid(Bid bid) {
|
---|
587 | this.bid = bid;
|
---|
588 | }
|
---|
589 |
|
---|
590 | @Override
|
---|
591 | public int compareTo(ComparableBid cBid) {
|
---|
592 | double time = timeline.getTime();
|
---|
593 | return (int) (utilitySpace.getUtilityWithDiscount(this.bid, time)
|
---|
594 | * 1000)
|
---|
595 | - (int) (utilitySpace.getUtilityWithDiscount(cBid.bid, time)
|
---|
596 | * 1000);
|
---|
597 | }
|
---|
598 |
|
---|
599 | }
|
---|
600 |
|
---|
601 | private class OpponentInfo {
|
---|
602 |
|
---|
603 | private AgentID agentID;
|
---|
604 | private ArrayList<Bid> bidHistory, bestBids;
|
---|
605 | private double opponentSum, opponentPowerSum, opponentVariance;
|
---|
606 | private double[] opponentAverage, opponentStandardDeviation;
|
---|
607 | private Bid bestBid;
|
---|
608 | private HashMap<Issue, HashMap<Value, Integer>> valueWeights;
|
---|
609 | private HashMap<Issue, double[]> issueWeights;
|
---|
610 | private Action opponentLastAction;
|
---|
611 |
|
---|
612 | public OpponentInfo(AgentID sender) {
|
---|
613 | this.agentID = sender;
|
---|
614 | this.bidHistory = new ArrayList<Bid>();
|
---|
615 | this.bestBids = new ArrayList<Bid>();
|
---|
616 | this.opponentSum = 0;
|
---|
617 | this.opponentPowerSum = 0;
|
---|
618 | this.opponentVariance = 0;
|
---|
619 | this.opponentAverage = new double[2];
|
---|
620 | this.opponentStandardDeviation = new double[2];
|
---|
621 | this.valueWeights = new HashMap<Issue, HashMap<Value, Integer>>();
|
---|
622 | initializeOpponentUtilitySpace();
|
---|
623 |
|
---|
624 | }
|
---|
625 |
|
---|
626 | private void initializeOpponentUtilitySpace() {
|
---|
627 | for (Issue issue : utilitySpace.getDomain().getIssues()) {
|
---|
628 | switch (issue.getType()) {
|
---|
629 | case DISCRETE:
|
---|
630 | IssueDiscrete discreteIssue = (IssueDiscrete) issue;
|
---|
631 | HashMap<Value, Integer> value = new HashMap<Value, Integer>();
|
---|
632 | for (int i = 0; i < discreteIssue
|
---|
633 | .getNumberOfValues(); i++) {
|
---|
634 | value.put(discreteIssue.getValue(i), 0);
|
---|
635 | }
|
---|
636 | valueWeights.put(issue, value);
|
---|
637 | break;
|
---|
638 | case INTEGER:
|
---|
639 | double[] boundWeight = new double[2];
|
---|
640 | boundWeight[0] = 0.5;
|
---|
641 | boundWeight[1] = 0.5;
|
---|
642 | issueWeights.put(issue, boundWeight);
|
---|
643 | break;
|
---|
644 | default:
|
---|
645 | try {
|
---|
646 | throw new Exception("issue type " + issue.getType()
|
---|
647 | + " not supported");
|
---|
648 | } catch (Exception e) {
|
---|
649 | // TODO Auto-generated catch block
|
---|
650 | e.printStackTrace();
|
---|
651 | }
|
---|
652 | }
|
---|
653 | }
|
---|
654 |
|
---|
655 | }
|
---|
656 |
|
---|
657 | public AgentID getAgentID() {
|
---|
658 | return agentID;
|
---|
659 | }
|
---|
660 |
|
---|
661 | public void setAgentID(AgentID agentID) {
|
---|
662 | this.agentID = agentID;
|
---|
663 | }
|
---|
664 |
|
---|
665 | public ArrayList<Bid> getAgentBidHistory() {
|
---|
666 | return bidHistory;
|
---|
667 | }
|
---|
668 |
|
---|
669 | public void setAgentBidHistory(ArrayList<Bid> bidHistory) {
|
---|
670 | this.bidHistory = bidHistory;
|
---|
671 | }
|
---|
672 |
|
---|
673 | public ArrayList<Bid> getBestBids() {
|
---|
674 | return bestBids;
|
---|
675 | }
|
---|
676 |
|
---|
677 | public void setBestBids(ArrayList<Bid> bestBids) {
|
---|
678 | this.bestBids = bestBids;
|
---|
679 | }
|
---|
680 |
|
---|
681 | public double getOpponentSum() {
|
---|
682 | return opponentSum;
|
---|
683 | }
|
---|
684 |
|
---|
685 | public void setOpponentSum(double opponentSum) {
|
---|
686 | this.opponentSum = opponentSum;
|
---|
687 | }
|
---|
688 |
|
---|
689 | public double getOpponentPowerSum() {
|
---|
690 | return opponentPowerSum;
|
---|
691 | }
|
---|
692 |
|
---|
693 | public void setOpponentPowerSum(double opponentPowerSum) {
|
---|
694 | this.opponentPowerSum = opponentPowerSum;
|
---|
695 | }
|
---|
696 |
|
---|
697 | public double getOpponentVariance() {
|
---|
698 | return opponentVariance;
|
---|
699 | }
|
---|
700 |
|
---|
701 | public void setOpponentVariance(double opponentVariance) {
|
---|
702 | this.opponentVariance = opponentVariance;
|
---|
703 | }
|
---|
704 |
|
---|
705 | public double[] getOpponentAverage() {
|
---|
706 | return opponentAverage;
|
---|
707 | }
|
---|
708 |
|
---|
709 | public void setOpponent(double[] opponentAverage) {
|
---|
710 | this.opponentAverage = opponentAverage;
|
---|
711 | }
|
---|
712 |
|
---|
713 | public double[] getOpponentStandardDeviation() {
|
---|
714 | return opponentStandardDeviation;
|
---|
715 | }
|
---|
716 |
|
---|
717 | public void setOpponentStandardDeviation(
|
---|
718 | double[] opponentStandardDeviation) {
|
---|
719 | this.opponentStandardDeviation = opponentStandardDeviation;
|
---|
720 | }
|
---|
721 |
|
---|
722 | public Bid getBestBid() {
|
---|
723 | return bestBid;
|
---|
724 | }
|
---|
725 |
|
---|
726 | public void setBestBid(Bid bestBid) {
|
---|
727 | this.bestBid = bestBid;
|
---|
728 | }
|
---|
729 |
|
---|
730 | public HashMap<Issue, HashMap<Value, Integer>> getValueWeights() {
|
---|
731 | return valueWeights;
|
---|
732 | }
|
---|
733 |
|
---|
734 | public void setValueWeights(
|
---|
735 | HashMap<Issue, HashMap<Value, Integer>> valueWeights) {
|
---|
736 | this.valueWeights = valueWeights;
|
---|
737 | }
|
---|
738 |
|
---|
739 | public HashMap<Issue, double[]> getIssueWeights() {
|
---|
740 | return issueWeights;
|
---|
741 | }
|
---|
742 |
|
---|
743 | public void setIssueWeights(HashMap<Issue, double[]> issueWeights) {
|
---|
744 | this.issueWeights = issueWeights;
|
---|
745 | }
|
---|
746 |
|
---|
747 | public Action getOpponentLastAction() {
|
---|
748 | return opponentLastAction;
|
---|
749 | }
|
---|
750 |
|
---|
751 | public void setOpponentLastAction(Action opponentLastAction) {
|
---|
752 | this.opponentLastAction = opponentLastAction;
|
---|
753 | }
|
---|
754 |
|
---|
755 | public void updateBid(Bid bid) {
|
---|
756 | this.bidHistory.add(bid);
|
---|
757 | // modeling opponent preference
|
---|
758 | for (Issue issue : bid.getIssues()) {
|
---|
759 | switch (issue.getType()) {
|
---|
760 | case DISCRETE:
|
---|
761 | HashMap<Value, Integer> value = valueWeights.get(issue);
|
---|
762 | int times = value.get(bid.getValue(issue.getNumber()));
|
---|
763 | if (recordTimes > 1
|
---|
764 | && bid.getValue(issue.getNumber()) == bidHistory
|
---|
765 | .get(bidHistory.size() - 2)
|
---|
766 | .getValue(issue.getNumber())) {
|
---|
767 | value.put(bid.getValue(issue.getNumber()),
|
---|
768 | times + frequencyReward + unchangeReward);
|
---|
769 | valueWeights.put(issue, value);
|
---|
770 | }
|
---|
771 | value.put(bid.getValue(issue.getNumber()),
|
---|
772 | times + frequencyReward);
|
---|
773 | valueWeights.put(issue, value);
|
---|
774 | break;
|
---|
775 | case INTEGER:
|
---|
776 | int issueNum = ((IssueInteger) issue).getNumber();
|
---|
777 | Value opponentValue = bid.getValue(issueNum);
|
---|
778 | int opponentValueInteger = ((ValueInteger) opponentValue)
|
---|
779 | .getValue();
|
---|
780 |
|
---|
781 | int upperBound = ((IssueInteger) issue).getUpperBound();
|
---|
782 | int lowerBound = ((IssueInteger) issue).getLowerBound();
|
---|
783 | double midPoint = Math.ceil(
|
---|
784 | lowerBound + (upperBound - lowerBound) / 2) + 1;
|
---|
785 |
|
---|
786 | if (midPoint > opponentValueInteger) {
|
---|
787 | double distanceFromMidPoint = midPoint
|
---|
788 | - opponentValueInteger;
|
---|
789 | double normalizedDistanceFromMidPoint = distanceFromMidPoint
|
---|
790 | / (midPoint - lowerBound);
|
---|
791 |
|
---|
792 | double total = 1;
|
---|
793 | double lowerBoundWeight = issueWeights.get(issue)[0];
|
---|
794 | double upperBoundWeight = issueWeights.get(issue)[1];
|
---|
795 |
|
---|
796 | double newLowEndEvaluation = lowerBoundWeight
|
---|
797 | + lowerBoundWeight
|
---|
798 | * normalizedDistanceFromMidPoint
|
---|
799 | * Math.pow(1 - timeline.getCurrentTime()
|
---|
800 | / timeline.getTotalTime(),
|
---|
801 | learningExp);
|
---|
802 | double highEndEvaluation = upperBoundWeight;
|
---|
803 |
|
---|
804 | if (newLowEndEvaluation > 1) {
|
---|
805 | total = newLowEndEvaluation + highEndEvaluation;
|
---|
806 | }
|
---|
807 |
|
---|
808 | double[] boundWeight = new double[2];
|
---|
809 | boundWeight[0] = newLowEndEvaluation / total;
|
---|
810 | boundWeight[1] = highEndEvaluation / total;
|
---|
811 |
|
---|
812 | issueWeights.put(issue, boundWeight);
|
---|
813 | } else {
|
---|
814 | double distanceFromMidPoint = opponentValueInteger
|
---|
815 | - midPoint + 1;
|
---|
816 | double normalizedDistanceFromMidPoint = distanceFromMidPoint
|
---|
817 | / (upperBound - midPoint + 1);
|
---|
818 | double total = 1;
|
---|
819 | double lowerBoundWeight = issueWeights.get(issue)[0];
|
---|
820 | double upperBoundWeight = issueWeights.get(issue)[1];
|
---|
821 |
|
---|
822 | double newHighEndEvaluation = upperBoundWeight
|
---|
823 | + upperBoundWeight
|
---|
824 | * normalizedDistanceFromMidPoint
|
---|
825 | * Math.pow(1 - timeline.getCurrentTime()
|
---|
826 | / timeline.getTotalTime(),
|
---|
827 | learningExp);
|
---|
828 | double lowEndEvaluation = lowerBoundWeight;
|
---|
829 |
|
---|
830 | if (newHighEndEvaluation > 1) {
|
---|
831 | total = newHighEndEvaluation + lowEndEvaluation;
|
---|
832 | }
|
---|
833 |
|
---|
834 | double[] boundWeight = new double[2];
|
---|
835 | boundWeight[0] = lowEndEvaluation / total;
|
---|
836 | boundWeight[1] = newHighEndEvaluation / total;
|
---|
837 |
|
---|
838 | issueWeights.put(issue, boundWeight);
|
---|
839 | }
|
---|
840 | break;
|
---|
841 | default:
|
---|
842 | try {
|
---|
843 | throw new Exception("issue type " + issue.getType()
|
---|
844 | + " not supported");
|
---|
845 | } catch (Exception e) {
|
---|
846 | // TODO Auto-generated catch block
|
---|
847 | e.printStackTrace();
|
---|
848 | }
|
---|
849 | }
|
---|
850 |
|
---|
851 | }
|
---|
852 | // learning opponent behavior
|
---|
853 | if (opponentAverage != null && opponentStandardDeviation != null) {
|
---|
854 | opponentAverage[0] = opponentAverage[1];
|
---|
855 | opponentStandardDeviation[0] = opponentStandardDeviation[1];
|
---|
856 | } else {
|
---|
857 | opponentAverage[0] = 0;
|
---|
858 | opponentStandardDeviation[0] = 0;
|
---|
859 | }
|
---|
860 | opponentSum += utilitySpace.getUtility(bid);
|
---|
861 | opponentAverage[1] = opponentSum / recordTimes;
|
---|
862 | opponentPowerSum += Math.pow(utilitySpace.getUtility(bid), 2);
|
---|
863 | opponentVariance = (opponentPowerSum / recordTimes)
|
---|
864 | - Math.pow(opponentAverage[1], 2);
|
---|
865 | opponentStandardDeviation[1] = Math
|
---|
866 | .sqrt((opponentVariance >= 0 ? opponentVariance : 0));
|
---|
867 | }
|
---|
868 |
|
---|
869 | public boolean containsBid(Bid bid) {
|
---|
870 | return bidHistory.contains(bid);
|
---|
871 | }
|
---|
872 | }
|
---|
873 |
|
---|
874 | @Override
|
---|
875 | public String getDescription() {
|
---|
876 | return "ANAC2016";
|
---|
877 | }
|
---|
878 | } |
---|