source: src/main/java/agents/anac/y2018/smac_agent/SMAC_Agent.java

Last change on this file was 345, checked in by Tim Baarslag, 4 years ago

Fixed agent 2018 descriptions

File size: 22.6 KB
Line 
1package agents.anac.y2018.smac_agent;
2
3import java.util.List;
4
5import java.util.HashMap;
6import java.util.LinkedHashMap;
7import java.util.Map;
8
9import genius.core.AgentID;
10import genius.core.Bid;
11import genius.core.actions.Accept;
12import genius.core.actions.Action;
13import genius.core.actions.Inform;
14import genius.core.actions.Offer;
15import genius.core.bidding.BidDetails;
16import genius.core.boaframework.SortedOutcomeSpace;
17import genius.core.issue.Issue;
18import genius.core.issue.IssueDiscrete;
19import genius.core.issue.Value;
20import genius.core.misc.Range;
21import genius.core.parties.AbstractNegotiationParty;
22import genius.core.parties.NegotiationInfo;
23import genius.core.utility.AbstractUtilitySpace;
24
25public class SMAC_Agent extends AbstractNegotiationParty {
26
27 // Parameter initialisation
28 private Bid lastReceivedBid = null;
29 private Bid myLastBid = null;
30 private SortedOutcomeSpace sortedOutcomeSpace = null;
31 private UtilCurve BS_curve = null;
32 private UtilCurve AS_curve = null;
33 private UtilCurve OMS_curve = null;
34
35 private double resValue = 0;
36 private double discountFactor = 0;
37 private double domainSize = 0;
38 private double potLoss = 0;
39
40 private int domainSmallThres = 100;
41 private int domainMediumThres = 1000;
42 private double resThres = 0.5;
43 private double discountThres = 0.5;
44 private int partiesToReveal = -1;
45 private int round = 0;
46
47 private Map<String, AgentProfile> agentProfiles = new HashMap<>();
48
49 private double BS_utilInit;
50 private double BS_utilEnd;
51 private double BS_shapeLeft;
52 private double BS_shapeRight;
53 private double BS_stdDev;
54 private double BS_utilRange;
55 private int BS_useUtilRange;
56 private int BS_scaleMinMax;
57
58 private double AS_timethreshold1;
59 private double AS_timethreshold2;
60 private double AS_timethreshold3;
61 private double AS_rate1;
62 private double AS_rate2;
63 private double AS_rate3;
64 private double AS_discount_rate1;
65 private double AS_discount_rate2;
66 private double AS_discount_rate3;
67 private double AS_threshold1;
68
69 private double OMS_utilInit;
70 private double OMS_utilEnd;
71 private double OMS_shapeLeft;
72 private double OMS_shapeRight;
73 private int OMS_useScaling;
74 private int OMS_useOM;
75 private int OMS_limitScaling;
76 private int OMS_euclidean;
77
78 private int useResValue;
79 private int RM_updateUtilCurve;
80
81 // Arrays of optimised parameters to select config from
82 private double[] BS_utilInit_Array = { 0.8726814917149487, 0.777828754759162, 0.794611415535526, 0.8338477204370194,
83 0.794611415535526, 0.9902714777558712, 0.8177264028188669, 0.9369503033177021, 0.8752031270267119,
84 0.9130860700146172, 0.8985462879619349, 0.968496462717577, 0.9475036977013452, 0.6358476408988469,
85 0.8187434422624748 };
86 private double[] BS_utilEnd_Array = { 0.7234378711390601, 0.5039748507682985, 0.28288734275992156,
87 0.5043866091578793, 0.28288734275992156, 0.4003485368855013, 0.5775989724689408, 0.8449151525540153,
88 0.6439901974110889, 0.5128376365334515, 0.8815381590699309, 0.7512965956758736, 0.7732741878711409,
89 0.6890153697768392, 0.4575950773478153 };
90 private double[] BS_shapeLeft_Array = { -3.3591096890191987, -1.701604675744841, -1.477010357010462,
91 -3.8655124599356254, -1.477010357010462, -4.578937298449693, -0.6220720689296879, -0.33672176040647983,
92 -1.028771048186937, -2.0559509070865096, -2.8918016435189267, -0.7799716189241472, -1.3695282977990084,
93 -5.218031753259722, -2.751303202136022 };
94 private double[] BS_shapeRight_Array = { 1.6257316909626451, 5.743207917861144, 0.5042105201178133,
95 1.2177749917981506, 0.5042105201178133, 0.23509522311374287, 4.091234186082431, 4.1350076547071914,
96 2.4754885878922317, 2.164288746994306, 2.7254163735351717, 4.6865277838004795, 3.2756425247103667,
97 4.954211560087625, 0.9268696757205295 };
98 private double[] BS_stdDev_Array = { 0.011291090432680746, 0.00806602340055852, 0.03993171716605801,
99 0.04541686791307292, 0.03993171716605801, 0.016756394004539998, 0.02050154318077101, 0.029271019497824725,
100 0.043415206320189886, 0.0070856192273503205, 0.039755330055406116, 0.016399241309376957,
101 0.025102281569543264, 0.04820460835411705, 0.02050857459278594 };
102 private double[] BS_utilRange_Array = { 0.12747022094357666, 0, 0, 0, 0, 0.13272162785215005, 0, 0.0983190266452012,
103 0.05856974543348425, 0, 0.07746667826547407, 0.07280579445258521, 0.18730438418792866, 0.14765559656825974,
104 0.1 };
105 private int[] BS_useUtilRange_Array = { 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1 };
106 private int[] BS_scaleMinMax_Array = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
107
108 private double[] AS_timethreshold1_Array = { 0.04674955360732539, 0.21892573208596458, 0.16179316499336657,
109 0.017950789417510913, 0.16179316499336657, 0.24113343505148666, 0.07195359710638492, 0.24062799038166227,
110 0.06459440421448916, 0.05992314378385267, 0.0404833611227041, 0.016365548306668937, 0.03720304384144093,
111 0.03478252915311665, 0.09717022719016756 };
112 private double[] AS_timethreshold2_Array = { 0.43303206747881884, 0.43815743675678354, 0.661647912300392,
113 0.6641557212474182, 0.661647912300392, 0.6343062109766446, 0.31691596321099397, 0.6193435123380937,
114 0.5101124045982374, 0.6439117927197825, 0.3097759359131537, 0.6779137891044901, 0.3191532652234305,
115 0.36151362475862164, 0.49570228758309676 };
116 private double[] AS_timethreshold3_Array = { 0.7245716275829817, 0.9673408842892797, 0.9430960906851461,
117 0.8068138909742011, 0.9430960906851461, 0.9259546534020413, 0.7785900567996049, 0.7315861505357254,
118 0.9861492577603947, 0.8404594822840576, 0.8996360620044062, 0.8866203037044917, 0.7572372266466516,
119 0.9713328720627714, 0.7682567113937757 };
120 private double[] AS_rate1_Array = { 0.11219220522147239, 0.08003925149326611, 0.33051281601825294,
121 0.5168640464469102, 0.33051281601825294, 0.13512460983555102, 0.3688780153278271, 0.29676619243083197,
122 0.6646699560793469, 0.08650858607226897, 0.5000849837001996, 0.6245922813980603, 0.40987041296162613,
123 0.5267683830657954, 0.42081900454556703 };
124 private double[] AS_rate2_Array = { 0.004898877513807327, 0.5634389184435432, 0.5882550637609057,
125 0.1736660799531687, 0.5882550637609057, 0.3052688029644835, 0.2634165350102941, 0.1128289859613561,
126 0.09148496643943949, 0.594472202286485, 0.003764210630213882, 0.3267176154876564, 0.16025942852106756,
127 0.33889339364499194, 0.29231207452138 };
128 private double[] AS_rate3_Array = { 0.548875357115968, 0.4749109394742966, 0.14967914649484768, 0.12365288690420985,
129 0.14967914649484768, 0.46068703380168724, 0.008086833565920028, 0.4505848794497385, 0.5688130910774031,
130 0.009397472597385702, 0.3072190282216138, 0.013929751760161762, 0.22948249946166988, 0.24981417826220348,
131 0.02859766493418777 };
132 private double[] AS_discount_rate1_Array = { 0.60078421520277, 0.041443536726597396, 0.062408258801741855,
133 0.09097496706566402, 0.062408258801741855, 0.2201074114341298, 0.6400322557728236, 0.5788620610232695,
134 0.11081606927344186, 0.5229841600644036, 0.24433177863341993, 0.4661668394745566, 0.35628521577122196,
135 0.33720834099081726, 0.049371938906709045 };
136 private double[] AS_discount_rate2_Array = { 0.60078421520277, 0.041443536726597396, 0.062408258801741855,
137 0.09097496706566402, 0.062408258801741855, 0.2201074114341298, 0.6400322557728236, 0.5788620610232695,
138 0.11081606927344186, 0.5229841600644036, 0.3208622393478284, 0.4661668394745566, 0.35628521577122196,
139 0.33720834099081726, 0.049371938906709045 };
140 private double[] AS_discount_rate3_Array = { 0.7657680975742767, 0.39061103724559, 0.2228029756845122,
141 0.23097016208565402, 0.2228029756845122, 0.6512371835270208, 0.6855684205205383, 0.051066815285715085,
142 0.3292575463583758, 0.5720037378648264, 0.40017902857747045, 0.2710384577710453, 0.25373107722701543,
143 0.36883611624486773, 0.10017027025202459 };
144 private double[] AS_threshold1_Array = { 0.8219843158180532, 0.923099025516942, 0.7932091636158838,
145 0.9580958735836536, 0.7932091636158838, 0.9685239192034572, 0.7859975846053607, 0.7499410639013572,
146 0.7020301444423871, 0.7739229197734587, 0.9240012133461064, 0.7794051769942631, 0.8620257399086155,
147 0.7607469411657954, 0.8870099642076714 };
148
149 private double[] OMS_utilInit_Array = { 0, 0, 0, 0, 0, 0, 0, 0.815223752226039, 0, 0, 0, 0, 0, 0,
150 0.5163591000775694 };
151 private double[] OMS_utilEnd_Array = { 0, 0, 0, 0, 0, 0, 0, 0.6473775354471122, 0, 0, 0, 0, 0, 0,
152 0.7778975091828539 };
153 private double[] OMS_shapeLeft_Array = { 0, 0, 0, 0, 0, 0, 0, -1.7202463296555042, 0, 0, 0, 0, 0, 0,
154 -0.5137389957405025 };
155 private double[] OMS_shapeRight_Array = { 0, 0, 0, 0, 0, 0, 0, 2.317670771610482, 0, 0, 0, 0, 0, 0,
156 5.911300168932384 };
157 private int[] OMS_useScaling_Array = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };
158 private int[] OMS_useOM_Array = { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 };
159 private int[] OMS_limitScaling_Array = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
160 private int[] OMS_euclidean_Array = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
161
162 private int[] useResValue_Array = { 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1 };
163 private int[] RM_updateUtilCurve_Array = { 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0 };
164 // ----------
165
166 @Override
167 public void init(NegotiationInfo info) {
168 super.init(info);
169
170 sortedOutcomeSpace = new SortedOutcomeSpace(utilitySpace);
171
172 // Sets max and min utility in domain
173 double utilMin = sortedOutcomeSpace.getMinBidPossible().getMyUndiscountedUtil();
174 double utilMax = sortedOutcomeSpace.getMaxBidPossible().getMyUndiscountedUtil();
175
176 // Obtain res' value, discounted value and domain size
177 resValue = utilitySpace.getReservationValue();
178 discountFactor = utilitySpace.getDiscountFactor();
179 domainSize = utilitySpace.getDomain().getNumberOfPossibleBids();
180
181 // Set agent parameters accordingly
182 initparameter(resValue, discountFactor, domainSize);
183
184 // Set minimum utility to reservation value if higher
185 if (resValue > utilMin && useResValue == 1) {
186 utilMin = resValue;
187 }
188
189 // Initialise ulitity curves
190 BS_curve = new UtilCurve(BS_shapeLeft, BS_shapeRight, BS_utilInit, BS_utilEnd);
191 OMS_curve = new UtilCurve(OMS_shapeLeft, OMS_shapeRight, OMS_utilInit, OMS_utilEnd);
192
193 // Change bidding utility parameters
194 if (BS_scaleMinMax == 1) {
195 BS_curve.setMinMax(utilMin, utilMax);
196 }
197 BS_curve.setStdDev(BS_stdDev);
198
199 }
200
201 @Override
202 public Action chooseAction(List<Class<? extends Action>> validActions) {
203 round++;
204
205 if (round > 1 && AS() == 1) {
206 return new Accept(getPartyId(), lastReceivedBid);
207 } else {
208 myLastBid = determineNextBid();
209 return new Offer(getPartyId(), myLastBid);
210 }
211 }
212
213 public int AS() {
214 // get some values
215 double time = timeline.getTime();
216 double nextMyBidUtil = getUtilityWithDiscount(myLastBid);
217 double lastOpponentBidUtil = getUtilityWithDiscount(lastReceivedBid);
218
219 // Check first threshold
220 if (lastOpponentBidUtil >= AS_threshold1) {
221 return 1;
222 }
223
224 if (lastOpponentBidUtil < resValue * discountFactor) {
225 return 0;
226 }
227 // time=(0, time_threshold1]
228 if (time <= AS_timethreshold1) {
229 return 0;
230 } else if (time <= AS_timethreshold2) { // time=(time_threshold1, time_threshold2]
231 if (lastOpponentBidUtil > AS_threshold1 - (time - AS_timethreshold1) * AS_rate1
232 - (1 - discountFactor) * (time - AS_timethreshold1) * AS_discount_rate1) {
233 return 1;
234 } else
235 return 0;
236 } else if (time <= AS_timethreshold3) { // time=(time_threshold2, time_threshold3]
237 if (lastOpponentBidUtil > AS_threshold1 - (AS_timethreshold2 - AS_timethreshold1) * AS_rate1 / 2
238 - Math.pow(10 * (time - AS_timethreshold2), 2) / 10 * AS_rate2
239 - (1 - discountFactor) * (time - AS_timethreshold2) * AS_discount_rate2) {
240 return 1;
241 } else
242 return 0;
243 }
244 // time=(time_threshold3,1]
245 else {
246 if (lastOpponentBidUtil > nextMyBidUtil - (time - AS_timethreshold3) * AS_rate3
247 - (1 - discountFactor) * (time - AS_timethreshold3) * AS_discount_rate3) {
248 return 1;
249 }
250 }
251
252 return 0;
253 }
254
255 public Bid determineNextBid() {
256 // Initialise values
257 double time = timeline.getTime();
258 Range range = null;
259 double util = BS_curve.getUtil(time);
260
261 // Max util = 1
262 if (util > 1)
263 util = 1;
264
265 // Sets utility range to go for
266 if (BS_useUtilRange == 1) {
267 range = new Range(util, util + BS_utilRange);
268 } else {
269 range = new Range(util, 1);
270 }
271
272 // Selects bid based on utility thresholds, expands threshold if no bids are
273 // found
274 BidDetails bidDetails = null;
275 while (bidDetails == null) {
276 List<BidDetails> lBids = sortedOutcomeSpace.getBidsinRange(range);
277 bidDetails = OMS(lBids);
278 if (bidDetails == null) {
279 range.setLowerbound(range.getLowerbound() - 0.001);
280 range.setUpperbound(range.getUpperbound() + 0.001);
281 }
282 }
283 return bidDetails.getBid();
284 }
285
286 public BidDetails OMS(List<BidDetails> allBids) {
287 // Initialise values
288 double time = timeline.getTime();
289 double utilGoal = OMS_curve.getUtil(time);
290
291 // 1. If there is only a single bid, return this bid
292 if (allBids.size() == 1) {
293 System.out.println("OMS_ found only 1 bid");
294 return null;
295 }
296
297 // If no OM is used, return random bid
298 if (OMS_useOM == 0) {
299 return allBids.get(rand.nextInt(allBids.size()));
300 }
301
302 // Initialise individual opponent util
303 Map<String, Double> agentUtilGoals = new HashMap<>();
304
305
306 if (OMS_useScaling == 1 && partiesToReveal == 0) {
307 // Set individual opponent util according to their thoughness
308 double sum = 0.0;
309 double count = 0.0;
310 for (String key : agentProfiles.keySet()) {
311 agentUtilGoals.put(key, agentProfiles.get(key).getLastBidOppUtil());
312 sum += agentUtilGoals.get(key);
313 count++;
314 }
315 double average = sum / count;
316 for (String key : agentUtilGoals.keySet()) {
317 double util = agentUtilGoals.get(key) - average + utilGoal;
318 if (util > 1 && OMS_limitScaling == 1) {
319 agentUtilGoals.put(key, 1.0);
320 } else {
321 agentUtilGoals.put(key, util);
322 }
323 }
324 } else {
325 // Set individual opponent util to the same value
326 for (String key : agentProfiles.keySet()) {
327 agentUtilGoals.put(key, utilGoal);
328 }
329 }
330
331 double diff = 2;
332 BidDetails nearestBid = allBids.get(allBids.size() - 1);
333
334 // Select bid from list based on distance to individual opponent util
335 for (BidDetails bidDetails : allBids) {
336 double minDistance = 0.0;
337 double distance = 0.0;
338 boolean validBid = true;
339 for (String key : agentUtilGoals.keySet()) {
340 double oppUtilGoal = agentUtilGoals.get(key);
341 double oppUtil = agentProfiles.get(key).evaluateBid(bidDetails.getBid());
342 if (oppUtil > oppUtilGoal) {
343 validBid = false;
344 break;
345 } else {
346 if (OMS_euclidean == 1) {
347 //euclidean
348 distance += Math.pow(oppUtilGoal - oppUtil, 2);
349 } else {
350 //chebyshev
351 distance = Math.abs(oppUtilGoal - oppUtil);
352 if (distance > minDistance) {
353 minDistance = distance;
354 }
355 }
356 }
357 }
358 if (OMS_euclidean == 1) {
359 minDistance = Math.sqrt(distance);
360 }
361
362 // Save minimum distance
363 if (minDistance < diff && validBid) {
364 nearestBid = bidDetails;
365 diff = minDistance;
366 }
367 }
368 return nearestBid;
369 }
370
371 @Override
372 public void receiveMessage(AgentID sender, Action action) {
373
374 if (action instanceof Offer) {
375 lastReceivedBid = ((Offer) action).getBid();
376 String agentName = getPartyName(action.getAgent().toString());
377
378 // initialise opponent model
379 if (agentProfiles.get(agentName) == null) {
380 partiesToReveal--;
381 agentProfiles.put(agentName, new AgentProfile(utilitySpace));
382 }
383 agentProfiles.get(agentName).registerOffer(lastReceivedBid);
384 } else if (action instanceof Accept) {
385 if (RM_updateUtilCurve == 1 && partiesToReveal == 0) {
386 // Update utility curve based on accepting util
387 Bid bid = ((Accept) action).getBid();
388 String agentName = getPartyName(action.getAgent().toString());
389
390 agentProfiles.get(agentName).registerAccept(bid);
391 updateUtilCurve();
392 }
393 } else if (action instanceof Inform) {
394 partiesToReveal = (int) ((Inform) action).getValue() - 1;
395 }
396 }
397
398 private void updateUtilCurve() {
399 double minAcceptedUtil = 1.0;
400 for (String key : agentProfiles.keySet()) {
401 double acceptedUtil = getUtility(agentProfiles.get(key).getBestAccepted());
402 if (acceptedUtil < minAcceptedUtil) {
403 minAcceptedUtil = acceptedUtil;
404 }
405 }
406 BS_curve.setMinAccepted(minAcceptedUtil);
407 }
408
409 private String getPartyName(String partyID) {
410 return partyID.substring(0, partyID.indexOf("@"));
411 }
412
413 @Override
414 public String getDescription() {
415 return "ANAC2018";
416 }
417
418 // This function selects the parameter set based on the domain
419 void initparameter(double resValue, double discountFactor, double domainSize) {
420 int resdisIndex = 0;
421 int domainIndex = 0;
422 int parameterIndex = 0;
423
424 // Parameter selection
425 // ##################
426 // ##################
427 if (resValue == 0 || discountFactor == 1) {
428 resdisIndex = 0;
429 } else if (resValue <= resThres && discountFactor <= discountThres) {
430 resdisIndex = 1;
431 } else if (resValue <= resThres && discountFactor > discountThres) {
432 resdisIndex = 2;
433 } else if (resValue > resThres && discountFactor <= discountThres) {
434 resdisIndex = 3;
435 } else if (resValue > resThres && discountFactor > discountThres) {
436 resdisIndex = 4;
437 }
438
439 if (domainSize <= domainSmallThres) {
440 domainIndex = 0;
441 } else if (domainSize <= domainMediumThres) {
442 domainIndex = 1;
443 } else {
444 domainIndex = 2;
445 }
446
447 parameterIndex = 5 * domainIndex + resdisIndex;
448 System.out.println("parameterIndex:" + parameterIndex);
449
450 // Assign parameter value
451 // #############################
452 // #############################
453
454 BS_utilInit = BS_utilInit_Array[parameterIndex];
455 BS_utilEnd = BS_utilEnd_Array[parameterIndex];
456 BS_shapeLeft = BS_shapeLeft_Array[parameterIndex];
457 BS_shapeRight = BS_shapeRight_Array[parameterIndex];
458 BS_stdDev = BS_stdDev_Array[parameterIndex];
459 BS_utilRange = BS_utilRange_Array[parameterIndex];
460 BS_useUtilRange = BS_useUtilRange_Array[parameterIndex];
461 BS_scaleMinMax = BS_scaleMinMax_Array[parameterIndex];
462
463 AS_timethreshold1 = AS_timethreshold1_Array[parameterIndex];
464 AS_timethreshold2 = AS_timethreshold2_Array[parameterIndex];
465 AS_timethreshold3 = AS_timethreshold3_Array[parameterIndex];
466 AS_rate1 = AS_rate1_Array[parameterIndex];
467 AS_rate2 = AS_rate2_Array[parameterIndex];
468 AS_rate3 = AS_rate3_Array[parameterIndex];
469 AS_discount_rate1 = AS_discount_rate1_Array[parameterIndex];
470 AS_discount_rate2 = AS_discount_rate2_Array[parameterIndex];
471 AS_discount_rate3 = AS_discount_rate3_Array[parameterIndex];
472 AS_threshold1 = AS_threshold1_Array[parameterIndex];
473
474 OMS_utilInit = OMS_utilInit_Array[parameterIndex];
475 OMS_utilEnd = OMS_utilEnd_Array[parameterIndex];
476 OMS_shapeLeft = OMS_shapeLeft_Array[parameterIndex];
477 OMS_shapeRight = OMS_shapeRight_Array[parameterIndex];
478 OMS_useScaling = OMS_useScaling_Array[parameterIndex];
479 OMS_useOM = OMS_useOM_Array[parameterIndex];
480 OMS_limitScaling = OMS_limitScaling_Array[parameterIndex];
481 OMS_euclidean = OMS_euclidean_Array[parameterIndex];
482
483 useResValue = useResValue_Array[parameterIndex];
484 RM_updateUtilCurve = RM_updateUtilCurve_Array[parameterIndex];
485
486 }
487
488 // Utility curve class
489 private class UtilCurve {
490 double shapeLeft;
491 double shapeRight;
492 double utilInit;
493 double utilEnd;
494
495 double correction;
496 double correctionFactor;
497
498 double utilMin = 0.0;
499 double utilMax = 1.0;
500 double stdDev = 0.0;
501
502 public UtilCurve(double shapeLeft, double shapeRight, double utilInit, double utilEnd) {
503 this.shapeLeft = shapeLeft;
504 this.shapeRight = shapeRight;
505 this.utilInit = utilInit;
506 this.utilEnd = utilEnd;
507
508 correction = 1.0 / (1.0 + Math.exp(-shapeLeft));
509 correctionFactor = (utilEnd - utilInit) / (1.0 / (1.0 + Math.exp(-shapeRight)) - correction);
510 }
511
512 public void setMinMax(double utilMin, double utilMax) {
513 this.utilMin = utilMin;
514 this.utilMax = utilMax;
515 }
516
517 public void setStdDev(double stdDev) {
518 this.stdDev = stdDev;
519 }
520
521 public void setMinAccepted(double minAccepted) {
522 double finalUtil = utilMin + (utilMax - utilMin) * utilEnd;
523 if (minAccepted > finalUtil) {
524 utilEnd = (minAccepted - utilMin) / (utilMax - utilMin);
525 }
526 correctionFactor = (utilEnd - utilInit) / (1.0 / (1.0 + Math.exp(-shapeRight)) - correction);
527 }
528
529 public double getUtil(double time) {
530 double x = (shapeRight - shapeLeft) * time + shapeLeft;
531 double S = (1.0 / (1.0 + Math.exp(-x)) - correction) * correctionFactor + utilInit;
532
533 return utilMin + (utilMax - utilMin) * S + rand.nextGaussian() * stdDev;
534 }
535 }
536
537 // Opponent model class
538 private class AgentProfile {
539 private LinkedHashMap<Integer, HashMap<Value, Incremental>> valueFrequency = new LinkedHashMap<>();
540 private LinkedHashMap<Integer, Incremental> issueFrequency = new LinkedHashMap<>();
541
542 private Bid lastBid = null;
543 private Bid bestAccepted = null;
544
545 private double bidsReceived = 0;
546 private double issuesChanged = 0;
547 private double issues = 0;
548
549 public AgentProfile(AbstractUtilitySpace utilitySpace) {
550 for (Issue issue : utilitySpace.getDomain().getIssues()) {
551 issues++;
552 Integer issuenr = issue.getNumber();
553 issueFrequency.put(issuenr, new Incremental());
554
555 valueFrequency.put(issuenr, new HashMap<>());
556 IssueDiscrete issued = (IssueDiscrete) issue;
557
558 for (Value value : issued.getValues()) {
559 valueFrequency.get(issuenr).put(value, new Incremental());
560 }
561 }
562 }
563
564 public void registerOffer(Bid bid) {
565 bidsReceived++;
566
567 if (lastBid == null)
568 lastBid = bid;
569
570 for (Issue issue : bid.getIssues()) {
571 Integer issuenr = issue.getNumber();
572 Value value = bid.getValue(issuenr);
573 valueFrequency.get(issuenr).get(value).increment();
574
575 if (value != lastBid.getValue(issuenr)) {
576 issuesChanged++;
577 issueFrequency.get(issuenr).increment();
578 }
579 }
580 }
581
582 public void registerAccept(Bid bid) {
583 double utility = getUtility(bid);
584
585 if (bestAccepted == null) {
586 bestAccepted = bid;
587 } else if (utility > getUtility(bestAccepted)) {
588 bestAccepted = bid;
589 }
590 }
591
592 public double evaluateBid(Bid bid) {
593 double predict = 0.0;
594
595 if (bidsReceived == 0)
596 return 0.0;
597
598 for (Issue issue : bid.getIssues()) {
599 Integer issuenr = issue.getNumber();
600 Value value = bid.getValue(issuenr);
601
602 double fValue = valueFrequency.get(issuenr).get(value).get();
603 double fIssue = issueFrequency.get(issuenr).get();
604
605 if (issuesChanged == 0) {
606 predict += (fValue / bidsReceived) * (1.0 / issues);
607 } else {
608 predict += (fValue / bidsReceived) * (1.0 - fIssue / issuesChanged) / (issues - 1.0);
609 }
610 }
611 return predict;
612 }
613
614 public Bid getBestAccepted() {
615 return bestAccepted;
616 }
617
618 public double getLastBidOppUtil() {
619 return evaluateBid(lastBid);
620 }
621
622 public String toString() {
623 return valueFrequency.toString() + "\n" + issueFrequency.toString();
624 }
625 }
626
627 private class Incremental {
628 int value = 0;
629
630 public void increment() {
631 value++;
632 }
633
634 public int get() {
635 return value;
636 }
637
638 public String toString() {
639 return String.valueOf(value);
640 }
641 }
642}
Note: See TracBrowser for help on using the repository browser.