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