source: src/main/java/agents/anac/y2018/seto/etc/NegoStats.java@ 341

Last change on this file since 341 was 341, checked in by Katsuhide Fujita, 5 years ago

Katsuhide Fujita added ANAC2018 agents.

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