source: src/main/java/agents/anac/y2017/farma/etc/NegoStats.java@ 346

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

Initial import : Genius 9.0.0

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