1 | package agents.anac.y2014.Aster;
|
---|
2 |
|
---|
3 | import java.util.ArrayList;
|
---|
4 |
|
---|
5 | import genius.core.Bid;
|
---|
6 | import genius.core.utility.AbstractUtilitySpace;
|
---|
7 |
|
---|
8 | public class GetAcceptProb {
|
---|
9 | private AbstractUtilitySpace utilitySpace;
|
---|
10 | private double target;
|
---|
11 | private double bidTarget;
|
---|
12 | private double sum;
|
---|
13 | private double sum2;
|
---|
14 | private double prob;
|
---|
15 | private double deviation;
|
---|
16 | private double estimateMax;
|
---|
17 | private int rounds;
|
---|
18 | private double tremor;
|
---|
19 | private double minimumConcessionUtility;
|
---|
20 | private double minimum;
|
---|
21 | private double maximumConcessionUtility;
|
---|
22 | private double maximum;
|
---|
23 | private double alpha;
|
---|
24 | private double diff;
|
---|
25 | private double alphaInit;
|
---|
26 | private double estrangement;
|
---|
27 | private boolean firstFlag;
|
---|
28 | private ArrayList<Double> oppUtilHistory;
|
---|
29 | private ArrayList<Double> oppShort_EMA;
|
---|
30 | private ArrayList<Double> oppLong_EMA;
|
---|
31 | private static final int EMA_SHORT = 26;
|
---|
32 | private static final int EMA_LONG = 52;
|
---|
33 |
|
---|
34 | public GetAcceptProb(AbstractUtilitySpace utilitySpace) {
|
---|
35 | this.utilitySpace = utilitySpace;
|
---|
36 | this.target = 1.0D;
|
---|
37 | this.bidTarget = 1.0D;
|
---|
38 | this.sum = 0.0D;
|
---|
39 | this.sum2 = 0.0D;
|
---|
40 | this.prob = 0.0D;
|
---|
41 | this.rounds = 0;
|
---|
42 | this.tremor = 3.0D;
|
---|
43 | this.minimumConcessionUtility = 0.1D;
|
---|
44 | this.maximumConcessionUtility = 1.0D;
|
---|
45 | this.maximum = 1.0D;
|
---|
46 | this.deviation = 0.0D;
|
---|
47 | this.estimateMax = 0.0D;
|
---|
48 | this.alphaInit = 1.0D;
|
---|
49 | this.estrangement = 1.0D;
|
---|
50 | this.firstFlag = false;
|
---|
51 | this.oppUtilHistory = new ArrayList<Double>();
|
---|
52 | this.oppShort_EMA = new ArrayList<Double>();
|
---|
53 | this.oppLong_EMA = new ArrayList<Double>();
|
---|
54 | this.checkDiscountFactor();
|
---|
55 | }
|
---|
56 |
|
---|
57 | /**
|
---|
58 | * Calculate Accept Probability
|
---|
59 | *
|
---|
60 | */
|
---|
61 | public double getAcceptProbability(Bid offeredBid, double oppMaxUtil,
|
---|
62 | double time) throws Exception {
|
---|
63 | double unDiscountedOfferedUtil = utilitySpace.getUtility(offeredBid);
|
---|
64 | double offeredUtility = utilitySpace.getUtilityWithDiscount(offeredBid,
|
---|
65 | time);
|
---|
66 | double weight, mean, variance, rand, alpha, beta, preTarget, preTarget2, ratio, ratio2;
|
---|
67 | double utilityEval, satisfy;
|
---|
68 |
|
---|
69 | checkException(offeredUtility, time); // checkException
|
---|
70 |
|
---|
71 | if (offeredUtility > 1.0D) {
|
---|
72 | offeredUtility = 1.0D;
|
---|
73 | }
|
---|
74 |
|
---|
75 | // Historyã�«è¿½åŠ
|
---|
76 | oppUtilHistory.add(unDiscountedOfferedUtil);
|
---|
77 |
|
---|
78 | if (oppUtilHistory.size() > EMA_SHORT) {
|
---|
79 | double emaUtility;
|
---|
80 | if (oppShort_EMA.isEmpty()) {
|
---|
81 | oppShort_EMA.add(calcN_EMA_init(oppUtilHistory, EMA_SHORT));
|
---|
82 | } else {
|
---|
83 | emaUtility = oppShort_EMA.get(oppShort_EMA.size() - 1);
|
---|
84 | oppShort_EMA.add(calcN_EMA(emaUtility, unDiscountedOfferedUtil,
|
---|
85 | EMA_SHORT));
|
---|
86 | }
|
---|
87 | if (oppUtilHistory.size() > EMA_LONG) {
|
---|
88 | if (oppLong_EMA.isEmpty()) {
|
---|
89 | oppLong_EMA.add(calcN_EMA_init(oppUtilHistory, EMA_LONG));
|
---|
90 | } else {
|
---|
91 | emaUtility = oppLong_EMA.get(oppLong_EMA.size() - 1);
|
---|
92 | oppLong_EMA.add(calcN_EMA(emaUtility,
|
---|
93 | unDiscountedOfferedUtil, EMA_LONG));
|
---|
94 | estrangement = calcEMAEstrangement();
|
---|
95 | }
|
---|
96 | }
|
---|
97 | }
|
---|
98 |
|
---|
99 | // ��付�
|
---|
100 | if ((this.estimateMax != 0.0) && (offeredUtility > this.estimateMax)) {
|
---|
101 | weight = offeredUtility / estimateMax;
|
---|
102 | offeredUtility *= weight;
|
---|
103 | } else {
|
---|
104 | weight = 1.0;
|
---|
105 | }
|
---|
106 |
|
---|
107 | // �計値
|
---|
108 | sum += offeredUtility;
|
---|
109 | // 効用値�二乗��計
|
---|
110 | sum2 += offeredUtility * offeredUtility;
|
---|
111 | // ラウンド数
|
---|
112 | rounds += weight;
|
---|
113 |
|
---|
114 | // ï¼ˆåŠ é‡�)平å�‡å€¤
|
---|
115 | mean = sum / rounds;
|
---|
116 |
|
---|
117 | // 分散
|
---|
118 | variance = sum2 / rounds - mean * mean;
|
---|
119 | // 相手�推定行動幅
|
---|
120 | deviation = Math.sqrt(variance * 12.0D);
|
---|
121 |
|
---|
122 | if (Double.isNaN(deviation)) {
|
---|
123 | deviation = 0.0;
|
---|
124 | }
|
---|
125 |
|
---|
126 | // �在推定�れる�相手�ら引�出�る最大効用値
|
---|
127 | estimateMax = mean + (1.0D - mean) * deviation;
|
---|
128 | double diffest = oppMaxUtil - estimateMax;
|
---|
129 | if (diffest > 0) {
|
---|
130 | estimateMax *= 1.0D + diffest;
|
---|
131 | }
|
---|
132 |
|
---|
133 | if (firstFlag) {
|
---|
134 | estimateMax = .990 * estrangement;
|
---|
135 | }
|
---|
136 |
|
---|
137 | // 接近関数
|
---|
138 | alpha = alphaInit + tremor + (10.0D * mean) - (2.0D * tremor * mean);
|
---|
139 | rand = minimum + (maximum - minimum) * Math.random();
|
---|
140 | beta = alpha + rand * tremor - tremor / 2.0D;
|
---|
141 |
|
---|
142 | // 接近関数を基�計算
|
---|
143 | preTarget = calcPreTarget(alpha, time);
|
---|
144 | preTarget2 = calcPreTarget(beta, time);
|
---|
145 |
|
---|
146 | // 相手ã�¨ã�®è²æ©æ¯”率
|
---|
147 | ratio = calcRatio(preTarget);
|
---|
148 | ratio2 = calcRatio(preTarget2);
|
---|
149 |
|
---|
150 | // 補æ£
|
---|
151 | target = calcTarget(ratio, preTarget, time, oppMaxUtil, false);
|
---|
152 | bidTarget = calcTarget(ratio2, preTarget2, time, oppMaxUtil, true)
|
---|
153 | * estrangement;
|
---|
154 | if (bidTarget > 1.0D) {
|
---|
155 | bidTarget = 0.99D;
|
---|
156 | }
|
---|
157 |
|
---|
158 | utilityEval = offeredUtility - oppMaxUtil;
|
---|
159 | satisfy = offeredUtility - target;
|
---|
160 | prob = Math.pow(time, alpha) / alpha + utilityEval + satisfy;
|
---|
161 |
|
---|
162 | if ((prob < 0.1D) || (Double.isNaN(prob))) {
|
---|
163 | prob = 0.0D;
|
---|
164 | }
|
---|
165 |
|
---|
166 | return prob;
|
---|
167 | }
|
---|
168 |
|
---|
169 | /**
|
---|
170 | * getCurrentBidTarget
|
---|
171 | *
|
---|
172 | */
|
---|
173 | public double getCurrentBidTarget() {
|
---|
174 | return this.bidTarget;
|
---|
175 | }
|
---|
176 |
|
---|
177 | public double getEstimateMax() {
|
---|
178 | return this.estimateMax;
|
---|
179 | }
|
---|
180 |
|
---|
181 | /**
|
---|
182 | * åˆ�回è¨å®š
|
---|
183 | *
|
---|
184 | * @param sessionNr
|
---|
185 | * @param maxConcessionUtility
|
---|
186 | * @param opponentMinUtility
|
---|
187 | */
|
---|
188 | public void setTargetParam(int sessionNr, double maxConcessionUtility,
|
---|
189 | double opponentMinUtility) {
|
---|
190 | // �回�強気
|
---|
191 | if (sessionNr == 0) {
|
---|
192 | this.firstFlag = true;
|
---|
193 | this.alpha = 15;
|
---|
194 | this.diff = 1.0;
|
---|
195 | } else {
|
---|
196 | this.alpha = 15;
|
---|
197 | this.diff = 0.5 * (0.5 + utilitySpace.getDiscountFactor());
|
---|
198 | this.maximumConcessionUtility = 1.0D;
|
---|
199 | this.minimumConcessionUtility = opponentMinUtility;
|
---|
200 | }
|
---|
201 | }
|
---|
202 |
|
---|
203 | public void updateMinConcessionUtil(double minConcessionUtil) {
|
---|
204 | this.minimumConcessionUtility = minConcessionUtil;
|
---|
205 | }
|
---|
206 |
|
---|
207 | private double calcPreTarget(double x, double t) {
|
---|
208 | return 1.0D - Math.pow(t, x) * (1.0D - this.estimateMax);
|
---|
209 | }
|
---|
210 |
|
---|
211 | private double calcRatio(double preTarget) {
|
---|
212 | double preRatio = (this.deviation + this.minimumConcessionUtility)
|
---|
213 | / (1.0D - preTarget);
|
---|
214 |
|
---|
215 | if ((Double.isNaN(preRatio)) || (preRatio > 2.0D)) {
|
---|
216 | return 2.0D;
|
---|
217 | } else {
|
---|
218 | return preRatio;
|
---|
219 | }
|
---|
220 | }
|
---|
221 |
|
---|
222 | private double calcTarget(double ratio, double preTarget, double t,
|
---|
223 | double oppMax, boolean checkdf) {
|
---|
224 | double target = (ratio * preTarget + maximumConcessionUtility - ratio);
|
---|
225 | double pt;
|
---|
226 | if ((checkdf) && (utilitySpace.getDiscountFactor() < 1.0)) {
|
---|
227 | pt = 1.0 / (1.0 + Math.exp(-alpha * (t - diff)));
|
---|
228 | } else {
|
---|
229 | pt = Math.pow(t, 3);
|
---|
230 | }
|
---|
231 | double m = pt * -300.0D + 400.0D;
|
---|
232 | if (target > this.estimateMax) {
|
---|
233 | double r = target - this.estimateMax;
|
---|
234 | double f = 1.0D / (r * r);
|
---|
235 | double app;
|
---|
236 |
|
---|
237 | if ((f > m) || (Double.isNaN(f))) {
|
---|
238 | f = m;
|
---|
239 | }
|
---|
240 | app = r * f / m;
|
---|
241 | target -= app;
|
---|
242 | } else {
|
---|
243 | target = this.estimateMax;
|
---|
244 | }
|
---|
245 |
|
---|
246 | if (Double.isNaN(target)) {
|
---|
247 | target = 1.0D;
|
---|
248 | }
|
---|
249 |
|
---|
250 | target = checkReservationValue(target, t);
|
---|
251 |
|
---|
252 | return target;
|
---|
253 | }
|
---|
254 |
|
---|
255 | // EMA�計算(�回)
|
---|
256 | private double calcN_EMA_init(ArrayList<Double> oppUtilHist, int n) {
|
---|
257 | double ave = 0.0D;
|
---|
258 | for (int i = 0; i < n; i++) {
|
---|
259 | ave += oppUtilHist.get(i);
|
---|
260 | }
|
---|
261 | return ave / n;
|
---|
262 | }
|
---|
263 |
|
---|
264 | // EMA�計算
|
---|
265 | private double calcN_EMA(double prevutil, double util, int n) {
|
---|
266 | return prevutil + (2.0D / (1.0D + (double) n)) * (util - prevutil);
|
---|
267 | }
|
---|
268 |
|
---|
269 | // EMA2線カイリ率
|
---|
270 | private double calcEMAEstrangement() {
|
---|
271 | int size = oppLong_EMA.size() - 1;
|
---|
272 | double emaShort = oppShort_EMA.get(size + EMA_SHORT);
|
---|
273 | double emaLong = oppLong_EMA.get(size);
|
---|
274 | double estrangement = 1.0 + ((emaShort - emaLong) / emaLong);
|
---|
275 | if (estrangement > 1.0) {
|
---|
276 | estrangement = 1.0;
|
---|
277 | }
|
---|
278 | return estrangement;
|
---|
279 | }
|
---|
280 |
|
---|
281 | private double checkReservationValue(double target, double t) {
|
---|
282 | double reservationValue = utilitySpace
|
---|
283 | .getReservationValueWithDiscount(t);
|
---|
284 |
|
---|
285 | if (!Double.isNaN(reservationValue)) {
|
---|
286 | if (target < reservationValue) {
|
---|
287 | return reservationValue;
|
---|
288 | }
|
---|
289 | }
|
---|
290 | return target;
|
---|
291 | }
|
---|
292 |
|
---|
293 | private void checkException(double oUtility, double t) throws Exception {
|
---|
294 | if ((oUtility < 0.0D) || (oUtility > 1.05D)) {
|
---|
295 | throw new Exception("utility " + oUtility + " outside [0,1]");
|
---|
296 | }
|
---|
297 | if ((t < 0.0D) || (t > 1.0D)) {
|
---|
298 | throw new Exception("time " + t + " outside [0,1]");
|
---|
299 | }
|
---|
300 | }
|
---|
301 |
|
---|
302 | private void checkDiscountFactor() {
|
---|
303 | double discountfactor = utilitySpace.getDiscountFactor();
|
---|
304 |
|
---|
305 | if (discountfactor < 1.0) {
|
---|
306 | this.minimum = 0.5;
|
---|
307 | } else {
|
---|
308 | this.minimum = 0.7;
|
---|
309 | }
|
---|
310 | }
|
---|
311 | }
|
---|