source: src/main/java/agents/anac/y2018/shiboy/etc/NegoStats.java

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

Fixed all errors in all 2018 agents

File size: 20.5 KB
Line 
1package agents.anac.y2018.shiboy.etc;
2
3import java.util.List;
4
5import java.util.ArrayList;
6import java.util.HashMap;
7
8import genius.core.Bid;
9import genius.core.issue.Issue;
10import genius.core.issue.IssueDiscrete;
11import genius.core.issue.IssueInteger;
12import genius.core.issue.Value;
13import genius.core.issue.ValueDiscrete;
14import genius.core.parties.NegotiationInfo;
15
16/**
17 * Created by shota_suzuki on 2018/05/16.
18 */
19public class NegoStats {
20 private NegotiationInfo info;
21 private boolean isPrinting = false; // デバッグ用
22 private boolean isPrinting_Stats = false;
23
24 // 交渉における基本情報
25 private List<Issue> issues;
26 private ArrayList<Object> rivals;
27 private int negotiatorNum = 0; // 交渉者数
28 private boolean isLinerUtilitySpace = true; // 線形効用空間であるかどうか
29 private HashMap<Issue, HashMap<Value, Double>> valueRelativeUtility = null; // 自身の効用空間における各論点値の相対効用値行列(線形効用空間用)
30
31 // current session の提案履歴
32 private ArrayList<Bid> myBidHist = null;
33 private HashMap<Object, ArrayList<Bid>> rivalsBidHist = null;
34 private HashMap<Object, HashMap<Issue, HashMap<Value, Integer>>> agreedValueFrequency = null;
35 private HashMap<Object, HashMap<Issue, HashMap<Value, Integer>>> rejectedValueFrequency = null;
36
37
38 // 交渉相手の統計情報
39 private HashMap<Object, Double> rivalsMean = null;
40 private HashMap<Object, Double> rivalsVar = null;
41 private HashMap<Object, Double> rivalsSum = null;
42 private HashMap<Object, Double> rivalsPowSum = null;
43 private HashMap<Object, Double> rivalsSD = null;
44
45 private HashMap<Object, Double> rivalsMax = null; // 今sessionにおける相手の提案に対する自身の最大効用値
46 private HashMap<Object, Double> rivalsMin = null; // 今sessionにおける相手の提案に対する自身の最低効用値
47
48
49 public NegoStats(NegotiationInfo info, boolean isPrinting) {
50 this.info = info;
51 this.isPrinting = isPrinting;
52
53 // 交渉における基本情報
54 issues = info.getUtilitySpace().getDomain().getIssues();
55 rivals = new ArrayList<Object>();
56 valueRelativeUtility = new HashMap<Issue, HashMap<Value, Double>>();
57
58 // current session の提案履歴
59 myBidHist = new ArrayList<Bid>();
60 rivalsBidHist = new HashMap<Object, ArrayList<Bid>>();
61 agreedValueFrequency = new HashMap<Object, HashMap<Issue, HashMap<Value, Integer>>>(); // Value毎のAccept数
62 rejectedValueFrequency = new HashMap<Object, HashMap<Issue, HashMap<Value, Integer>>>(); // Value毎のReject数
63
64 try {
65 initValueRelativeUtility();
66 } catch (Exception e) {
67 System.out.println("[Exception_Stats] 相対効用行列の初期化に失敗しました");
68 e.printStackTrace();
69 }
70
71 // 交渉相手の統計情報
72 rivalsMean = new HashMap<Object, Double>();
73 rivalsVar = new HashMap<Object, Double>();
74 rivalsSum = new HashMap<Object, Double>();
75 rivalsPowSum = new HashMap<Object, Double>();
76 rivalsSD = new HashMap<Object, Double>();
77
78 rivalsMax = new HashMap<Object, Double>();
79 rivalsMin = new HashMap<Object, Double>();
80
81 if (this.isPrinting) {
82 System.out.println("[isPrinting] NegoStats: success");
83 }
84
85 }
86
87 public void initRivals(Object sender) {
88 initNegotiatingInfo(sender); // 交渉情報を初期化
89 rivals.add(sender); // 交渉参加者にsenderを追加
90 }
91
92 public void updateInfo(Object sender, Bid offeredBid) {
93 try {
94 updateNegoStats(sender, offeredBid); // 交渉情報の更新
95 } catch (Exception e1) {
96 System.out.println("[Exception_Stats] 交渉情報の更新に失敗しました");
97 e1.printStackTrace();
98 }
99 }
100
101 private void initNegotiatingInfo(Object sender) {
102 rivalsBidHist.put(sender, new ArrayList<Bid>());
103 rivalsMean.put(sender, 0.0);
104 rivalsVar.put(sender, 0.0);
105 rivalsSum.put(sender, 0.0);
106 rivalsPowSum.put(sender, 0.0);
107 rivalsSD.put(sender, 0.0);
108
109 rivalsMax.put(sender, 0.0);
110 rivalsMin.put(sender, 1.0);
111 }
112
113 /**
114 * 交渉者数を更新する
115 *
116 * @param num
117 */
118 public void updateNegotiatorsNum(int num) {
119 negotiatorNum = num;
120 }
121
122
123 /**
124 * 線形効用空間でない場合
125 */
126 public void utilSpaceTypeisNonLiner() {
127 isLinerUtilitySpace = false;
128 }
129
130 /**
131 * 相対効用行列の初期化
132 *
133 * @throws Exception
134 */
135 private void initValueRelativeUtility() throws Exception {
136 //ArrayList<Value> values = null;
137 ArrayList<Object> rivals = getRivals();
138
139 for (Issue issue : issues) {
140 valueRelativeUtility.put(issue, new HashMap<Value, Double>()); // 論点行の初期化
141
142 // 論点行の要素の初期化
143 ArrayList<Value> values = getValues(issue);
144 for (Value value : values) {
145 valueRelativeUtility.get(issue).put(value, 0.0);
146 }
147 }
148 }
149
150 // 相対効用行列の導出
151 public void setValueRelativeUtility(Bid maxBid) throws Exception {
152 ArrayList<Value> values = null;
153 Bid currentBid = null;
154 for (Issue issue : issues) {
155 currentBid = new Bid(maxBid);
156 values = getValues(issue);
157 for (Value value : values) {
158 currentBid = currentBid.putValue(issue.getNumber(), value);
159 valueRelativeUtility.get(issue).put(value,
160 info.getUtilitySpace().getUtility(currentBid) - info.getUtilitySpace().getUtility(maxBid));
161 }
162 }
163 }
164
165 /**
166 * Agent senderが受け入れたValueの頻度を更新
167 *
168 * @param sender
169 * @param bid
170 */
171 public void updateAgreedValues(Object sender, Bid bid) {
172 // senderが過去に登場していない場合は初期化
173 if (!agreedValueFrequency.containsKey(sender)) {
174 agreedValueFrequency.put(sender, new HashMap<Issue, HashMap<Value, Integer>>());
175
176 for (Issue issue : issues) {
177 agreedValueFrequency.get(sender).put(issue, new HashMap<Value, Integer>());
178
179 ArrayList<Value> values = getValues(issue);
180 for (Value value : values) {
181 agreedValueFrequency.get(sender).get(issue).put(value, 0);
182 }
183 }
184 }
185
186 // 各issue毎に個数をカウント
187 for (Issue issue : issues) {
188 Value value = bid.getValue(issue.getNumber());
189 agreedValueFrequency.get(sender).get(issue).put(value, agreedValueFrequency.get(sender).get(issue).get(value) + 1);
190 }
191
192 if (isPrinting_Stats) {
193 System.out.println("[isPrint_Stats] (ACCEPT) " + sender.toString() + ":");
194 for (Issue issue : issues) {
195 ArrayList<Value> values = getValues(issue);
196 for (Value value : values) {
197 System.out.print(agreedValueFrequency.get(sender).get(issue).get(value) + " ");
198 }
199 System.out.println();
200 }
201
202 getMostAgreedValues(sender);
203 }
204 }
205
206 /**
207 * senderが拒絶したValueの頻度を更新
208 *
209 * @param sender
210 * @param bid
211 */
212 public void updateRejectedValues(Object sender, Bid bid) {
213 // senderが過去に登場していない場合は初期化
214 if (!rejectedValueFrequency.containsKey(sender)) {
215 rejectedValueFrequency.put(sender, new HashMap<Issue, HashMap<Value, Integer>>());
216
217 for (Issue issue : issues) {
218 rejectedValueFrequency.get(sender).put(issue, new HashMap<Value, Integer>());
219
220 ArrayList<Value> values = getValues(issue);
221 for (Value value : values) {
222 rejectedValueFrequency.get(sender).get(issue).put(value, 0);
223 }
224 }
225 }
226
227 // 各issue毎に個数をカウント
228 for (Issue issue : issues) {
229 Value value = bid.getValue(issue.getNumber());
230 rejectedValueFrequency.get(sender).get(issue).put(value, rejectedValueFrequency.get(sender).get(issue).get(value) + 1);
231 }
232
233 if (isPrinting_Stats) {
234 System.out.println("[isPrint_Stats] (REJECT) " + sender.toString() + ":");
235 for (Issue issue : issues) {
236 ArrayList<Value> values = getValues(issue);
237 for (Value value : values) {
238 System.out.print(rejectedValueFrequency.get(sender).get(issue).get(value) + " ");
239 }
240 System.out.println();
241 }
242
243 getMostRejectedValues(sender);
244 }
245 }
246
247
248 public void updateNegoStats(Object sender, Bid offeredBid) throws Exception {
249 // current session の提案履歴 への追加
250 rivalsBidHist.get(sender).add(offeredBid);
251 updateAgreedValues(sender, offeredBid);
252
253 // 交渉相手の統計情報 の更新
254 double util = info.getUtilitySpace().getUtility(offeredBid);
255 rivalsSum.put(sender, rivalsSum.get(sender) + util); // 和
256 rivalsPowSum.put(sender, rivalsPowSum.get(sender) + Math.pow(util, 2)); // 二乗和
257
258 int round_num = rivalsBidHist.get(sender).size();
259 rivalsMean.put(sender, rivalsSum.get(sender) / round_num); // 平均
260 rivalsVar.put(sender, (rivalsPowSum.get(sender) / round_num) - Math.pow(rivalsMean.get(sender), 2)); // 分散
261
262 if (rivalsVar.get(sender) < 0) {
263 rivalsVar.put(sender, 0.0);
264 }
265 rivalsSD.put(sender, Math.sqrt(rivalsVar.get(sender))); // 標準偏差
266
267 // 最大最小の更新
268 if (util > rivalsMax.get(sender)) {
269 rivalsMax.put(sender, util);
270 } else if (util < rivalsMin.get(sender)) {
271 rivalsMin.put(sender, util);
272 }
273
274 if (isPrinting_Stats) {
275 System.out.println("[isPrint_Stats] Mean: " + getRivalMean(sender) + " (Agent: " + sender.toString() + ")");
276 }
277 }
278
279 /**
280 * 自身の提案情報の更新
281 *
282 * @param offerBid
283 */
284 public void updateMyBidHist(Bid offerBid) {
285 myBidHist.add(offerBid);
286 }
287
288
289 // 交渉における基本情報 の取得
290
291 /**
292 * 論点一覧を返す
293 *
294 * @return
295 */
296 public List<Issue> getIssues() {
297 return issues;
298 }
299
300 /**
301 * 交渉相手の一覧を返す
302 *
303 * @return
304 */
305 public ArrayList<Object> getRivals() {
306 return rivals;
307 }
308
309 /**
310 * 交渉者数(自身を含む)を返す
311 *
312 * @return
313 */
314 public int getNegotiatorNum() {
315 // + 1: 自分
316 return rivals.size() + 1;
317 }
318
319 /**
320 * 論点における取り得る値の一覧を返す
321 *
322 * @param issue
323 * @return
324 */
325 public ArrayList<Value> getValues(Issue issue) {
326 ArrayList<Value> values = new ArrayList<Value>();
327
328 // 効用情報のtype毎に処理が異なる
329 switch (issue.getType()) {
330 case DISCRETE:
331 List<ValueDiscrete> valuesDis = ((IssueDiscrete) issue).getValues();
332 for (Value value : valuesDis) {
333 values.add(value);
334 }
335 break;
336 case INTEGER:
337 int min_value = ((IssueInteger) issue).getUpperBound();
338 int max_value = ((IssueInteger) issue).getUpperBound();
339 for (int j = min_value; j <= max_value; j++) {
340 Object valueObject = new Integer(j);
341 values.add((Value) valueObject);
342 }
343 break;
344 default:
345 try {
346 throw new Exception("issue type \"" + issue.getType() + "\" not supported by" + info.getAgentID().getName());
347 } catch (Exception e) {
348 System.out.println("[Exception] 論点の取り得る値の取得に失敗しました");
349 e.printStackTrace();
350 }
351 }
352
353 return values;
354 }
355
356 /**
357 * 線形効用空間であるかどうかを返す
358 *
359 * @return
360 */
361 public boolean isLinerUtilitySpace() {
362 return isLinerUtilitySpace;
363 }
364
365 /**
366 * 相対効用行列を返す
367 *
368 * @return
369 */
370 public HashMap<Issue, HashMap<Value, Double>> getValueRelativeUtility() {
371 return valueRelativeUtility;
372 }
373
374
375 // current session の提案履歴 の取得
376
377 /**
378 * エージェントsenderの論点issueにおける最大Agree数となる選択肢valueを取得
379 *
380 * @param sender
381 * @param issue
382 * @return
383 */
384 public Value getMostAgreedValue(Object sender, Issue issue) {
385 ArrayList<Value> values = getValues(issue);
386
387 int maxN = 0;
388 Value mostAgreedValue = values.get(0);
389 for (Value value : values) {
390 int tempN = agreedValueFrequency.get(sender).get(issue).get(value);
391 // もし最大数が更新されたら
392 if (maxN < tempN) {
393 maxN = tempN;
394 mostAgreedValue = value;
395 }
396 }
397
398 return mostAgreedValue;
399 }
400
401 /**
402 * エージェントsenderの論点issueにおける選択肢valueのAgree率を返す
403 *
404 * @param sender
405 * @param issue
406 * @param value
407 * @return
408 */
409 public double getProbAgreedValue(Object sender, Issue issue, Value value) {
410 ArrayList<Value> values = getValues(issue);
411
412 int sum = 0;
413 for (Value v : values) {
414 sum += agreedValueFrequency.get(sender).get(issue).get(v);
415 }
416
417 double prob = agreedValueFrequency.get(sender).get(issue).get(value) * 1.0 / sum;
418 return prob;
419 }
420
421
422 /**
423 * エージェントSenderにおける各論点における累積確率(CP)を取得
424 *
425 * @param sender
426 * @param issue
427 * @return
428 */
429 public HashMap<Value, ArrayList<Double>> getCPAgreedValue(Object sender, Issue issue) {
430 HashMap<Value, ArrayList<Double>> CPMap = new HashMap<Value, ArrayList<Double>>();
431
432 ArrayList<Value> values = getValues(issue);
433 int sum = 0;
434 for (Value value : values) {
435 sum += agreedValueFrequency.get(sender).get(issue).get(value);
436 }
437
438 double tempCP = 0.0;
439 for (Value value : values) {
440 ArrayList<Double> tempArray = new ArrayList<Double>();
441 // 範囲のStartを格納
442 tempArray.add(tempCP);
443
444 // 範囲のEndを格納
445 tempCP += agreedValueFrequency.get(sender).get(issue).get(value) * 1.0 / sum;
446 tempArray.add(tempCP);
447
448 CPMap.put(value, tempArray);
449 }
450
451 return CPMap;
452 }
453
454
455 /**
456 * エージェントSenderにおける各論点における最大Agree数となる選択肢valueをArrayListで取得
457 *
458 * @param sender
459 * @return
460 */
461 public ArrayList<Value> getMostAgreedValues(Object sender) {
462 ArrayList<Value> values = new ArrayList<Value>();
463
464 // issueの内部的な順番はa-b-c-d-...じゃないので注意
465 for (Issue issue : issues) {
466 values.add(getMostAgreedValue(sender, issue));
467 }
468
469
470 if (isPrinting_Stats) {
471 System.out.print("[isPrint_Stats] ");
472 for (int i = 0; i < issues.size(); i++) {
473 //System.out.print(issues.get(i).toString() + ":" + values.get(issues.get(i).getNumber()-1) + " ");
474 //System.out.print(issues.get(i).toString() + ":" + values.get(i) + "(" + getProbAgreedValue(sender,issues.get(i),values.get(i)) + ") ");
475
476 HashMap<Value, ArrayList<Double>> cp = getCPAgreedValue(sender, issues.get(i));
477
478 System.out.print(issues.get(i).toString() + ":"
479 + values.get(i) + "(" + cp.get(values.get(i)).get(0) + " - " + cp.get(values.get(i)).get(1) + ") ");
480 }
481 System.out.println();
482 }
483
484 return values;
485 }
486
487
488 /**
489 * エージェントsenderの論点issueにおける最大Reject数となる選択肢valueを取得
490 *
491 * @param sender
492 * @param issue
493 * @return
494 */
495 public Value getMostRejectedValue(Object sender, Issue issue) {
496 ArrayList<Value> values = getValues(issue);
497
498 int maxN = 0;
499 Value mostRejectedValue = values.get(0);
500 for (Value value : values) {
501 int tempN = rejectedValueFrequency.get(sender).get(issue).get(value);
502 // もし最大数が更新されたら
503 if (maxN < tempN) {
504 maxN = tempN;
505 mostRejectedValue = value;
506 }
507 }
508
509 return mostRejectedValue;
510 }
511
512 /**
513 * エージェントsenderの論点issueにおける選択肢valueのReject率を返す
514 *
515 * @param sender
516 * @param issue
517 * @param value
518 * @return
519 */
520 public double getProbRejectedValue(Object sender, Issue issue, Value value) {
521 ArrayList<Value> values = getValues(issue);
522
523 int sum = 0;
524 for (Value v : values) {
525 sum += rejectedValueFrequency.get(sender).get(issue).get(v);
526 }
527
528 double prob = rejectedValueFrequency.get(sender).get(issue).get(value) * 1.0 / sum;
529 return prob;
530 }
531
532 /**
533 * エージェントSenderにおける各論点における累積確率(CP)を取得
534 *
535 * @param sender
536 * @param issue
537 * @return
538 */
539 public HashMap<Value, ArrayList<Double>> getCPRejectedValue(Object sender, Issue issue) {
540 HashMap<Value, ArrayList<Double>> CPMap = new HashMap<Value, ArrayList<Double>>();
541
542 ArrayList<Value> values = getValues(issue);
543 int sum = 0;
544 for (Value value : values) {
545 sum += rejectedValueFrequency.get(sender).get(issue).get(value);
546 }
547
548 double tempCP = 0.0;
549 for (Value value : values) {
550 ArrayList<Double> tempArray = new ArrayList<Double>();
551 // 範囲のStartを格納
552 tempArray.add(tempCP);
553
554 // 範囲のEndを格納
555 tempCP += rejectedValueFrequency.get(sender).get(issue).get(value) * 1.0 / sum;
556 tempArray.add(tempCP);
557
558 CPMap.put(value, tempArray);
559 }
560
561 return CPMap;
562 }
563
564 /**
565 * エージェントSenderにおける各論点における最大Reject数となる選択肢valueをArrayListで取得
566 *
567 * @param sender
568 * @return
569 */
570 public ArrayList<Value> getMostRejectedValues(Object sender) {
571 ArrayList<Value> values = new ArrayList<Value>();
572
573 // issueの内部的な順番はa-b-c-d-...じゃないので注意
574 for (Issue issue : issues) {
575 values.add(getMostRejectedValue(sender, issue));
576 }
577
578
579 if (isPrinting_Stats) {
580 System.out.print("[isPrint_Stats] ");
581 for (int i = 0; i < issues.size(); i++) {
582 //System.out.print(issues.get(i).toString() + ":" + values.get(issues.get(i).getNumber()-1) + " ");
583 //System.out.print(issues.get(i).toString() + ":" + values.get(i) + "(" + getProbRejectedValue(sender,issues.get(i),values.get(i)) + ") ");
584
585 HashMap<Value, ArrayList<Double>> cp = getCPRejectedValue(sender, issues.get(i));
586
587 System.out.print(issues.get(i).toString() + ":"
588 + values.get(i) + "(" + cp.get(values.get(i)).get(0) + " - " + cp.get(values.get(i)).get(1) + ") ");
589 }
590 System.out.println();
591 }
592
593 return values;
594 }
595
596
597 // 交渉相手の統計情報 の取得
598
599 /**
600 * 平均
601 *
602 * @param sender
603 * @return
604 */
605 public double getRivalMean(Object sender) {
606 return rivalsMean.get(sender);
607 }
608
609 /**
610 * 分散
611 *
612 * @param sender
613 * @return
614 */
615 public double getRivalVar(Object sender) {
616 return rivalsVar.get(sender);
617 }
618
619 /**
620 * 標準偏差
621 *
622 * @param sender
623 * @return
624 */
625 public double getRivalSD(Object sender) {
626 return rivalsSD.get(sender);
627 }
628
629
630 /**
631 * エージェントSenderにおける今sessionにおける提案の自身の最大効用値
632 *
633 * @param sender
634 * @return
635 */
636 public double getRivalMax(Object sender) {
637 return rivalsMax.get(sender);
638 }
639
640 /**
641 * エージェントSenderにおける今sessionにおける提案の自身の最小効用値
642 *
643 * @param sender
644 * @return
645 */
646 public double getRivalMin(Object sender) {
647 return rivalsMin.get(sender);
648 }
649
650
651}
Note: See TracBrowser for help on using the repository browser.