1 | package agents.anac.y2018.smac_agent;
|
---|
2 |
|
---|
3 | import java.util.List;
|
---|
4 |
|
---|
5 | import java.util.HashMap;
|
---|
6 | import java.util.LinkedHashMap;
|
---|
7 | import java.util.Map;
|
---|
8 |
|
---|
9 | import genius.core.AgentID;
|
---|
10 | import genius.core.Bid;
|
---|
11 | import genius.core.actions.Accept;
|
---|
12 | import genius.core.actions.Action;
|
---|
13 | import genius.core.actions.Inform;
|
---|
14 | import genius.core.actions.Offer;
|
---|
15 | import genius.core.bidding.BidDetails;
|
---|
16 | import genius.core.boaframework.SortedOutcomeSpace;
|
---|
17 | import genius.core.issue.Issue;
|
---|
18 | import genius.core.issue.IssueDiscrete;
|
---|
19 | import genius.core.issue.Value;
|
---|
20 | import genius.core.misc.Range;
|
---|
21 | import genius.core.parties.AbstractNegotiationParty;
|
---|
22 | import genius.core.parties.NegotiationInfo;
|
---|
23 | import genius.core.utility.AbstractUtilitySpace;
|
---|
24 |
|
---|
25 | public 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 | }
|
---|