source: src/main/java/agents/anac/y2015/SENGOKU/etc/strategy.java@ 1

Last change on this file since 1 was 1, checked in by Wouter Pasman, 6 years ago

Initial import : Genius 9.0.0

File size: 14.4 KB
Line 
1package agents.anac.y2015.SENGOKU.etc;
2
3import java.util.ArrayList;
4
5import genius.core.Bid;
6import genius.core.utility.AdditiveUtilitySpace;
7
8public class strategy {
9 private AdditiveUtilitySpace utilitySpace;
10 private negotiatingInfo negotiatingInfo;
11 private bidSearch bidSearch;
12
13 private double df = 1.0; // 割引係数
14 private double rv = 0.0; // 留保価格
15 public double myThreshold = 1.0; // 閾値
16 public int firstState = 0;
17 public boolean endNegotieitionFlag = false; // エンドネゴシエーションするときtrue
18 private double startTime = 0.0;
19 public int myState = 0; // 協力的は1 非協力的は0
20 private double eBase = 1.0; // hardheadを使うときの係数の基本
21 private double e = eBase; // hardheadを使うときの係数
22 private double cThreshold = 1.0; // 以前自分が協力的な時は
23 private int cooperationNum = 0; // 非協力的な人の数
24
25 // デバッグ用
26 public static boolean isPrinting = false; // メッセージを表示する
27
28 public strategy(AdditiveUtilitySpace utilitySpace, negotiatingInfo negotiatingInfo,
29 bidSearch bidSeach) {
30 this.utilitySpace = utilitySpace;
31 this.negotiatingInfo = negotiatingInfo;
32 df = utilitySpace.getDiscountFactor();
33 rv = utilitySpace.getReservationValue();
34 }
35
36 public void updateThreshold(double num) {
37 myThreshold = num;
38 }
39
40 // 自身のラウンド数を返す
41 public double getThreshold() {
42 return myThreshold;
43 }
44
45 // 受容判定
46 // 閾値より上なら真を返す!
47 public boolean selectAccept(Bid offeredBid, double time) {
48 try {
49 double offeredBidUtil = utilitySpace.getUtility(offeredBid);
50 if (offeredBidUtil >= getThreshold(time)) {
51 return true;
52 } else {
53 return false;
54 }
55 } catch (Exception e) {
56 System.out.println("受容判定に失敗しました");
57 e.printStackTrace();
58 return false;
59 }
60 }
61
62 // 交渉終了判定
63 public boolean selectEndNegotiation(double time) {
64 return false;
65 }
66
67 // 閾値を決めるときに最初に呼ばれるメソッド
68 public double getThreshold(double time) {
69
70 if (negotiatingInfo.getMyBidHistory().size() < 50) { // 最初はデータ収集で強気でいく
71 if (negotiatingInfo.getMyBidHistory().size() > 10) {
72 cooperationCheck();
73 }
74 return strongThreshold();
75 }
76
77 switch (negotiatingInfo.getActionFlag()) {
78 case 0:// オファーするとき
79 return getOfferThreshold(time);
80 case 1:// アクセプトする時
81 return getAcceptThreshold(time);
82 }
83 return myThreshold;
84 }
85
86 // これが閾値! オファーするときの閾値決め
87 public double getOfferThreshold(double time) {
88 double threshold = maxthreshold(0); // 閾値の最大を取得
89 switch (myState) {
90 case 0: // 裏切る 
91 startTime = time;
92 return bThreshold();
93
94 case 1: // 協力する //おふぁーで相手に戦略を公開するから偽の裏切っているようにみせる!少数はに入るようにする 1 1
95 return cooperateThreshold(time);
96 // threshold = maxthreshold(1); //閾値の最小でいい
97 // return hardThreshold(threshold, time);
98 // return hardThresholdDf(time);
99 case 2: // 協力する
100 return cooperateThreshold(time);
101 // threshold = maxthreshold(1); //閾値の最小でいい
102 // return hardThreshold(threshold, time);
103 // return hardThresholdDf(time);
104 default:
105 return strongThreshold();
106 }
107 }
108
109 // これが閾値! accept用
110 public double getAcceptThreshold(double time) {
111
112 double threshold = maxthreshold(0); // 閾値の最大を取得
113 // System.out.println("最大閾値:"+threshold);
114 int num = cooperationCheck(); // 非協力的な人数
115 myState = num;
116
117 switch (num) {
118 case 0: // 裏切る 
119 return bThreshold();
120 case 1: // 協力する
121 return cooperateThreshold(time);
122 // threshold = maxthreshold(1); //閾値の最小でいい
123 // return hardThreshold(threshold, time);
124 // return hardThresholdDf(time);
125 case 2: // 協力する
126 return cooperateThreshold(time);
127 // threshold = maxthreshold(1); //閾値の最小でいい
128 // return hardThreshold(threshold, time);
129 // return hardThresholdDf(time);
130 default:
131 // System.out.println("警告-----------------------------");
132 return 1.0;
133 }
134 }
135
136 // 非協力的な人の人数を返す
137 private int cooperationCheck() {
138 ArrayList<Object> opponents = negotiatingInfo.getOpponents();
139 int count = 0;
140
141 for (Object sender : opponents) {
142 // アクセプトがあるかないか
143 double a = negotiatingInfo.getNewAccept(sender);
144 if (a > 0) {
145 // System.out.println("アクセプトで協力"+sender);
146 negotiatingInfo.updateopponentsCooperateHistory(sender, true);
147 continue;
148 }
149
150 // 効用値が上昇傾向にある時
151 if (thresholdUpRate(sender, 7) > 0.0) {
152 // System.out.println("効用値の上昇で協力"+sender);
153 negotiatingInfo.updateopponentsCooperateHistory(sender, true);
154 continue;
155 }
156
157 // 同じ提案数 半分以上同じ提案のとき
158 double s = negotiatingInfo.getNewSumNum(sender);
159 // System.out.println("NewSumNum"+s);
160 if (s > 2) {
161 // System.out.println("同じ提案で非協力"+sender);
162 negotiatingInfo.updateopponentsCooperateHistory(sender, false);
163 count++;
164 continue;
165 }
166
167 // 標準偏差
168 double sd = negotiatingInfo.getNewStandardDeviation(sender);
169 double aveSd = negotiatingInfo.getStandardDeviation(sender);
170 // System.out.println("最新の標準偏差"+sd);
171 if (sd < aveSd) {
172 // System.out.println("偏差が平均より小さくて非協力"+sender);
173 negotiatingInfo.updateopponentsCooperateHistory(sender, false);
174 count++;
175 continue;
176 }
177
178 // 10回の平均が期待値以下の時 その人の!
179 double ave = negotiatingInfo.getNewAverage(sender);
180 if (ave < negotiatingInfo.getAverage(sender)) {
181 // System.out.println("平均以下で非協力"+sender +"平均:" + ave);
182 negotiatingInfo.updateopponentsCooperateHistory(sender, false);
183 count++;
184 continue;
185 }
186 negotiatingInfo.updateopponentsCooperateHistory(sender, true);
187
188 }
189 // System.out.println("非協力的人数:" + count);
190 return count;
191 }
192
193 // 相手の協力する確率をこれまでの情報より計算して出す。 すべての相手の合計で計算する。
194 public ArrayList<Double> getCooperateRate() {
195 ArrayList<Double> rateList = new ArrayList<Double>();
196 ArrayList<Object> opponents = negotiatingInfo.getOpponents();
197 for (Object sender : opponents) {
198 double allCount = 0;
199 double copperateCount = 0;
200 ArrayList<Boolean> states = negotiatingInfo
201 .getopponentsCooperateHistory(sender);
202 for (Boolean state : states) {
203 allCount++;
204 if (state) {
205 copperateCount++;
206 }
207 }
208 if (copperateCount == 0) {
209 rateList.add(0.0);
210 } else {
211 rateList.add(copperateCount / allCount);
212 }
213 }
214 return rateList;
215 }
216
217 // 協力状態するときの閾値
218 public double cooperateThreshold(double time) {
219
220 // 相手の協力度の計算
221 ArrayList<Double> rateList = getCooperateRate();
222 double cooperateRate = 0.0; // 他2人の合計の協力レートを算出する
223 for (int i = 0; i < rateList.size(); i++) {
224 if (i == 0) {
225 cooperateRate = rateList.get(i);
226 } else {
227 cooperateRate = cooperateRate * rateList.get(i);
228 }
229 }
230
231 double minThreshold = maxthreshold(1); // 相手の平均と分散から得られる最低
232 double maxThreshold = bThreshold(); // 非協力のときの裏切りの閾値
233 double fThreshold = cooperateRate * maxThreshold + (1 - cooperateRate)
234 * minThreshold; // 最終的な効用値を協力レートから算出
235 double dffThreshold = fThreshold * df; // 最終の結果に割引効用を適用する。
236 double rvUtil = rv * Math.pow(df, time); // 現在もらうことができる留保価格を算出する。
237
238 double hardThreshold = fThreshold + (1 - fThreshold)
239 * (1 - Math.pow(time, 1 / e)); // 実際の使用する閾値 ファティマの式を線形でいれる
240
241 if (dffThreshold < rvUtil) { // エンドネゴシエーション
242 if (isPrinting) {
243 System.out.println("最後の閾値にリザ:" + dffThreshold + "リザベーションバリュー:"
244 + rvUtil);
245 }
246 double harddffThreshold = dffThreshold + (1 - dffThreshold)
247 * (1 - Math.pow(time, 0.5)); // 最後の予想値にファティマで落としていく
248 if (isPrinting) {
249 System.out.println("線形で最後のリザにおとしていくときの閾値:" + harddffThreshold);
250 }
251 if (harddffThreshold < rvUtil) { // エンドネゴシエーション
252 endNegotieitionFlag = true;
253 return 1.0;
254 } else { // 割引効用に応じてもっと早めに落としていく
255 return harddffThreshold;
256 }
257 }
258
259 /*
260 * if (df == 0.0){ //割引効用がないとき //期待予想値にファティマの式を代入する。 hardThreshold =
261 * fThreshold + (1 -fThreshold) * (1 - Math.pow(time,1/e));
262 * //System.out.println("協力閾値"+hardThreshold); }else { //割引効用があるとき
263 * hardThreshold = fThreshold / Math.pow(df,time); double
264 * firstHardthreshold = dffThreshold + (1 - dffThreshold) * (1 -
265 * Math.pow(time,1/e)); if (hardThreshold < firstHardthreshold) {
266 * hardThreshold = firstHardthreshold; } }
267 */
268
269 if (isPrinting) {
270 System.out.println("今の協力値" + hardThreshold + "最後の予想値" + fThreshold);
271 }
272 cThreshold = hardThreshold;
273 return hardThreshold;
274 }
275
276 // 期待できる一番高い閾値を返す
277 public double maxthreshold(int flag) {
278 // opponents 交渉相手の一覧を返す
279 ArrayList<Object> opponents = negotiatingInfo.getOpponents();
280 double threshold = 1.0;
281 double mAll = 0.0;
282 double sdAll = 0.0;
283
284 for (Object sender : opponents) {
285 // 平均
286 double m = negotiatingInfo.getAverage(sender);
287 mAll = mAll + m;
288 // 分散
289 // double v = negotiatingInfo.getVariancer(sender);
290 // 標準偏差
291 double sd = negotiatingInfo.getStandardDeviation(sender);
292 sdAll = sdAll + sd;
293 }
294
295 mAll = mAll / opponents.size();
296 // System.out.println("平均all"+mAll);
297 sdAll = sdAll / opponents.size();
298 // System.out.println("偏差all"+sdAll);
299
300 if (flag == 0) { // このメソッドの引数によって変えれる
301 threshold = mAll + sdAll;
302 } else if (flag == 1) {
303 threshold = mAll - sdAll;
304 }
305 // System.out.println("相手から今の状況でとれる最大閾値"+threshold);
306
307 return threshold;
308
309 }
310
311 // ある区間で相手ごとに閾値が何パーセント上昇するか調べる numはどれふぁけのを観察するか>
312 private double thresholdUpRate(Object sender, int num) {
313 ArrayList<Double> List = negotiatingInfo.getBidValue(sender);
314 double rateSum = 0;
315 if (List.size() < num) {
316 return 0;
317 } // 閾値の配列に要素がないとき
318 for (int i = num; i < num; i++) {
319 double now = List.get(List.size() - 1 - i);
320 double old = List.get(List.size() - 2 - i);
321 double rate = (now - old) / now;
322 rateSum = rateSum + rate;
323 }
324 return rateSum;
325 }
326
327 // 閾値に対して 引数に対して収束していく関数
328 private double hardThreshold(double threshold, double time) {
329 double rateTime = 1 / (1 - startTime);
330 double useTime = (time - startTime) * rateTime;
331 double hardthreshold = threshold + (1 - threshold)
332 * (1 - Math.pow(useTime, 1 / e));
333 return hardthreshold;
334 }
335
336 // 非協力のときの閾値を返す
337 private double hardThresholdDf(double time) {
338 double hThreshold = maxthreshold(1) * Math.pow(df, time); // 割引効用を考えたあたい
339 if (myThreshold * df > hThreshold) {
340 firstState = 0;
341 startTime = time;
342 return myThreshold;
343 } else {
344 firstState = 1;
345 return hardThreshold(hThreshold, time);
346 }
347 }
348
349 // 裏切りの閾値を返す 相手提案のなかの最大の閾値に分散を適用させて使用
350 private double bThreshold() {
351 ArrayList<Object> opponents = negotiatingInfo.getOpponents();
352 double util = 0.0; // 最大有効値
353 double sdAll = 0.0; // 標準偏差
354
355 for (Object sender : opponents) {
356 double sd = negotiatingInfo.getStandardDeviation(sender);
357 sdAll = sdAll + sd;
358
359 double senderUtil = negotiatingInfo.getmaxUtil(sender);
360 if (util == 0.0) {
361 util = senderUtil;
362 } else if (util > senderUtil) {
363 util = senderUtil;
364 }
365 }
366 sdAll = sdAll / opponents.size();
367
368 double threshold = util + sdAll * Math.random();
369
370 if (maxthreshold(1) > threshold) { // 裏切り閾値が最低期待値を下回っているときは平均の分散の最大と交換
371 threshold = maxthreshold(0);
372 }
373
374 if (cThreshold != 1.0 && cThreshold > threshold) {
375 threshold = cThreshold;
376 }
377
378 if (threshold > 1.0) { // 裏切りの閾値が1を超えてしまった時
379 return 1.0 - (sdAll * Math.random());
380 }
381
382 return threshold;
383 }
384
385 // 強気の閾値は自分のいい効用情報を公開していく
386 private double strongThreshold() {
387 return 1.0 - (Math.random() * 0.1);
388
389 /*
390 * ArrayList<Object> opponents = negotiatingInfo.getOpponents(); if
391 * (negotiatingInfo.getRound() < 3){ //相手の情報がないとき return 1.0 -
392 * (Math.random() * 0.1); }else{ double sdAll=0.0; //標準偏差
393 *
394 * for(Object sender:opponents){ double sd =
395 * negotiatingInfo.getStandardDeviation(sender); sdAll = sdAll + sd; }
396 * sdAll = sdAll/opponents.size();
397 *
398 * return 1.0 - (Math.random() * sdAll); }
399 */
400 }
401
402 // 係数調節システム
403 private void eSet(double threshold, double time) {
404 System.out.println("--------set------------" + time + "------"
405 + (double) 20 / 180);
406 if (time < (double) 20 / 180) {
407 return;
408 }// 最初はデータがないからできない
409
410 ArrayList<Object> opponents = negotiatingInfo.getOpponents();
411 double rateMax = 0.0;
412 for (Object sender : opponents) {
413 double rate = thresholdUpRate(sender, 7);
414 if (rate > rateMax) {
415 rateMax = rate; // 上がる予定
416 }
417 }
418
419 int flag = 0;
420 double myRate = (hardThreshold(threshold, time) - hardThreshold(
421 threshold, time + (double) 1 / 180))
422 / hardThreshold(threshold, time);
423 if (myRate > rateMax) { // 自分の方が下げている
424 flag = 0;
425 } else { // 相手の方が下げている
426 e = e + 0.1;
427 flag = 1;
428 }
429
430 while (true) {
431 // 1つ後の閾値とのレート 自分レート プラスに出るようにする
432 myRate = (hardThreshold(threshold, time) - hardThreshold(threshold,
433 time + 1 / 180)) / hardThreshold(threshold, time);
434 if (myRate > rateMax) { // 自分の方が下げている
435 if (flag == 1) {
436 return;
437 }
438 e = e - 0.1;
439 } else { // 相手の方が下げている
440 if (flag == 0) {
441 return;
442 }
443 e = e + 0.1;
444 }
445 }
446 }
447
448}
Note: See TracBrowser for help on using the repository browser.