source: src/main/java/agents/anac/y2016/farma/etc/negotiationInfo.java@ 93

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

Initial import : Genius 9.0.0

File size: 15.3 KB
Line 
1package agents.anac.y2016.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.utility.AbstractUtilitySpace;
14
15public class negotiationInfo {
16 private AbstractUtilitySpace utilitySpace; // 効用空間
17 private List<Issue> issues; // 論点
18 private ArrayList<Object> opponents; // 自身以外の交渉参加者のsender
19 private ArrayList<Bid> MyBidHistory = null; // 提案履歴
20 private HashMap<Object, ArrayList<Bid>> opponentsBidHistory = null; // 提案履歴
21 private HashMap<Object, Double> opponentsAverage; // 平均
22 private HashMap<Object, Double> opponentsVariance; // 分散
23 private HashMap<Object, Double> opponentsSum; // 和
24 private HashMap<Object, Double> opponentsPowSum; // 二乗和
25 private HashMap<Object, Double> opponentsStandardDeviation; // 標準偏差
26 // 自身の効用空間における各論点値の相対効用値行列(線形効用空間用)
27 private HashMap<Issue, HashMap<Value, Double>> valueRelativeUtility = null;
28 private int round = 0;
29 private int negotiatorNum = 0; // 交渉者数
30 private boolean isLinerUtilitySpace = true; // 線形効用空間であるかどうか
31
32 private boolean isPrinting = false; // デバッグ用
33
34 // new parameter
35 private double myAverage;
36 private double myVariance;
37 private double mySum;
38 private double myPowSum;
39 private double myStandardDeviation;
40
41 private int valueNum;
42 private boolean isWorth; // これ以上交渉する余地があるか
43
44 public HashMap<Bid, CntBySender> bidAcceptNum; // Bid別のAccept数(OfferもAcceptと加算)
45 public HashMap<Value, CntBySender> offeredValueNum; // Value別のOffer数
46 public CntBySender opponentsAcceptNum; // Sender別のAccept数(Offerは含まない)
47 public HashMap<Bid, Integer> neighborhoodBid; // 近傍・頻度探索した結果
48 public HashMap<Bid, Integer> myOfferedBids; // 自身がOfferしたビットの回数
49 public ArrayList<Pair<Double, Bid>> myUtilityAllBits; // bid集合が少ない場合、
50
51 public negotiationInfo(AbstractUtilitySpace utilitySpace, boolean isPrinting) {
52 // 初期化
53 this.utilitySpace = utilitySpace;
54 this.isPrinting = isPrinting;
55
56 issues = utilitySpace.getDomain().getIssues();
57 opponents = new ArrayList<Object>();
58 MyBidHistory = new ArrayList<>();
59 opponentsBidHistory = new HashMap<Object, ArrayList<Bid>>();
60 opponentsAverage = new HashMap<Object, Double>();
61 opponentsVariance = new HashMap<Object, Double>();
62 opponentsSum = new HashMap<Object, Double>();
63 opponentsPowSum = new HashMap<Object, Double>();
64 opponentsStandardDeviation = new HashMap<Object, Double>();
65 valueRelativeUtility = new HashMap<Issue, HashMap<Value, Double>>();
66
67 isWorth = true;
68 bidAcceptNum = new HashMap<Bid, CntBySender>();
69 offeredValueNum = new HashMap<Value, CntBySender>();
70 opponentsAcceptNum = new CntBySender(0);
71 neighborhoodBid = new HashMap<Bid, Integer>();
72 myOfferedBids = new HashMap<Bid, Integer>();
73 myUtilityAllBits = new ArrayList<Pair<Double, Bid>>();
74
75 try {
76 initValueRelativeUtility();
77 } catch (Exception e) {
78 System.out.println("相対効用行列の初期化に失敗しました");
79 e.printStackTrace();
80 }
81 }
82
83 public void initOpponent(Object sender) {
84 initNegotiatingInfo(sender); // 交渉情報を初期化
85 opponents.add(sender); // 交渉参加者にsenderを追加
86 }
87
88 public void updateInfo(Object sender, Bid offeredBid) {
89 // 交渉情報の更新
90 try {
91 updateNegotiatingInfo(sender, offeredBid);
92 } catch (Exception e1) {
93 System.out.println("交渉情報の更新に失敗しました");
94 e1.printStackTrace();
95 }
96 }
97
98 private void initNegotiatingInfo(Object sender) {
99 opponentsBidHistory.put(sender, new ArrayList<Bid>());
100 opponentsAverage.put(sender, 0.0);
101 opponentsVariance.put(sender, 0.0);
102 opponentsSum.put(sender, 0.0);
103 opponentsPowSum.put(sender, 0.0);
104 opponentsStandardDeviation.put(sender, 0.0);
105 }
106
107 /**
108 * 相対効用行列の初期化
109 *
110 * @throws Exception
111 */
112 private void initValueRelativeUtility() throws Exception {
113 ArrayList<Value> values = null;
114 for (Issue issue : issues) {
115 // 論点行の初期化
116 valueRelativeUtility.put(issue, new HashMap<Value, Double>());
117 values = getValues(issue);
118
119 // 論点行の要素の初期化
120 for (Value value : values) {
121 valueRelativeUtility.get(issue).put(value, 0.0);
122 }
123 }
124 }
125
126 /**
127 * 相対効用行列の導出
128 *
129 * @param maxBid
130 * @throws Exception
131 */
132 public void setValueRelativeUtility(Bid maxBid) throws Exception {
133 ArrayList<Value> values = null;
134 Bid currentBid = null;
135 valueNum = issues.size();
136 for (Issue issue : issues) {
137 currentBid = new Bid(maxBid);
138 values = getValues(issue);
139 valueNum += values.size();
140 for (Value value : values) {
141 currentBid = currentBid.putValue(issue.getNumber(), value);
142 valueRelativeUtility.get(issue).put(
143 value,
144 utilitySpace.getUtility(currentBid)
145 - utilitySpace.getUtility(maxBid));
146 }
147 }
148 }
149
150 public void updateNegotiatingInfo(Object sender, Bid offeredBid)
151 throws Exception {
152 opponentsBidHistory.get(sender).add(offeredBid); // 提案履歴
153
154 double util = utilitySpace.getUtility(offeredBid);
155 opponentsSum.put(sender, opponentsSum.get(sender) + util); // 和
156 opponentsPowSum.put(sender,
157 opponentsPowSum.get(sender) + Math.pow(util, 2)); // 二乗和
158
159 int round_num = opponentsBidHistory.get(sender).size();
160 opponentsAverage.put(sender, opponentsSum.get(sender) / round_num); // 平均
161 // 分散
162 opponentsVariance.put(sender, (opponentsPowSum.get(sender) / round_num)
163 - Math.pow(opponentsAverage.get(sender), 2));
164
165 if (opponentsVariance.get(sender) < 0) {
166 opponentsVariance.put(sender, 0.0);
167 }
168 // 標準偏差
169 opponentsStandardDeviation.put(sender,
170 Math.sqrt(opponentsVariance.get(sender)));
171 }
172
173 public void updateRound() {
174 round += 1;
175 }
176
177 public void updateMyNegotiatingInfo(Bid offeredBid) throws Exception {
178 double util = utilitySpace.getUtility(offeredBid);
179 mySum += util; // 和
180 myPowSum += Math.pow(util, 2); // 二乗和
181
182 int round_num = MyBidHistory.size();
183 myAverage = mySum / round_num; // 平均
184
185 myVariance = Math.max(0,
186 (myPowSum / round_num) - Math.pow(myAverage, 2)); // 分散
187 myStandardDeviation = Math.sqrt(myVariance); // 標準偏差
188 }
189
190 /**
191 * 交渉者数を返す
192 *
193 * @param num
194 */
195 public void updateOpponentsNum(int num) {
196 negotiatorNum = num;
197 }
198
199 /**
200 * 線形効用空間でない場合
201 */
202 public void utilitySpaceTypeisNonLiner() {
203 isLinerUtilitySpace = false;
204 }
205
206 /**
207 * 自身の提案情報の更新
208 *
209 * @param offerBid
210 */
211 public void updateMyBidHistory(Bid offerBid) {
212 MyBidHistory.add(offerBid);
213 }
214
215 /**
216 * 平均
217 *
218 * @param sender
219 * @return
220 */
221 public double getAverage(Object sender) {
222 return opponentsAverage.get(sender);
223 }
224
225 /**
226 * 分散
227 *
228 * @param sender
229 * @return
230 */
231 public double getVariancer(Object sender) {
232 return opponentsVariance.get(sender);
233 }
234
235 /**
236 * 標準偏差
237 *
238 * @param sender
239 * @return
240 */
241 public double getStandardDeviation(Object sender) {
242 return opponentsStandardDeviation.get(sender);
243 }
244
245 /**
246 * 相手の提案履歴の要素数を返す
247 *
248 * @param sender
249 * @return
250 */
251 public int getPartnerBidNum(Object sender) {
252 return opponentsBidHistory.get(sender).size();
253 }
254
255 /**
256 * 自身のラウンド数を返す
257 *
258 * @return
259 */
260 public int getRound() {
261 return round;
262 }
263
264 /**
265 * 交渉者数を返す
266 *
267 * @return
268 */
269 public int getNegotiatorNum() {
270 return negotiatorNum;
271 }
272
273 /**
274 * 相対効用行列を返す
275 *
276 * @return
277 */
278 public HashMap<Issue, HashMap<Value, Double>> getValueRelativeUtility() {
279 return valueRelativeUtility;
280 }
281
282 /**
283 * 線形効用空間であるかどうかを返す
284 *
285 * @return
286 */
287 public boolean isLinerUtilitySpace() {
288 return isLinerUtilitySpace;
289 }
290
291 /**
292 * 論点一覧を返す
293 *
294 * @return
295 */
296 public List<Issue> getIssues() {
297 return issues;
298 }
299
300 /**
301 * 論点における取り得る値の一覧を返す
302 *
303 * @param issue
304 * @return
305 */
306 public ArrayList<Value> getValues(Issue issue) {
307 ArrayList<Value> values = new ArrayList<Value>();
308 switch (issue.getType()) {
309 case DISCRETE:
310 List<ValueDiscrete> valuesDis = ((IssueDiscrete) issue).getValues();
311 for (Value value : valuesDis) {
312 values.add(value);
313 }
314 break;
315
316 case INTEGER:
317 int min_value = ((IssueInteger) issue).getUpperBound();
318 int max_value = ((IssueInteger) issue).getUpperBound();
319
320 for (int j = min_value; j <= max_value; j++) {
321 Object valueObject = new Integer(j);
322 values.add((Value) valueObject);
323 }
324 break;
325
326 default:
327 try {
328 throw new Exception("issue type " + issue.getType()
329 + " not supported by Atlas3");
330 } catch (Exception e) {
331 System.out.println("論点の取り得る値の取得に失敗しました");
332 e.printStackTrace();
333 }
334 }
335 return values;
336 }
337
338 /**
339 * 交渉相手の一覧を返す
340 *
341 * @return
342 */
343 public ArrayList<Object> getOpponents() {
344 return opponents;
345 }
346
347 // new functions
348
349 // EndNegotiation関連
350 public int getValueNum() {
351 return valueNum;
352 }
353
354 public void updateMyOfferedBids(Bid bid) {
355 if (myOfferedBids.containsKey(bid)) {
356 myOfferedBids.put(bid, myOfferedBids.get(bid) + 1);
357 } else {
358 myOfferedBids.put(bid, 1);
359 }
360 }
361
362 public HashMap<Bid, Integer> getMyOfferedBids() {
363 return myOfferedBids;
364 }
365
366 public void updateIsWorth(boolean isworth) {
367 isWorth = isworth;
368 }
369
370 public boolean getIsWorth() {
371 return isWorth;
372 }
373
374 /**
375 * エージェントsenderのidx番目の提案履歴を返す
376 *
377 * @param sender
378 * @param idx
379 * @return
380 */
381 public Bid getOpponentsBidHistory(Object sender, int idx) {
382 return opponentsBidHistory.get(sender).get(idx);
383 }
384
385 /**
386 * Bid1とBid2について、cos類似度を計算. TODO 各valueについて重みを設定する。(でないと、単にvalueの一致度と一緒).
387 *
388 * @param b1
389 * @param b2
390 * @return
391 */
392 public Double cosSimilarity(Bid b1, Bid b2) {
393 Double sim = 0.0;
394
395 for (Issue issue : issues) {
396 int issueIdx = issue.getNumber();
397 Value v1 = b1.getValue(issueIdx);
398 Value v2 = b2.getValue(issueIdx);
399
400 if (v1.equals(v2)) {
401 sim += 1.0 - valueRelativeUtility.get(issue).get(v1);
402 }
403 }
404 sim /= issues.size();
405 return sim;
406 }
407
408 // 相手の性格の把握
409
410 /**
411 * 相手の自己主張性を求める
412 *
413 * @param sender
414 * @return
415 */
416 public double calAssertiveness(Object sender) {
417 double assertiveValue = myVariance - opponentsVariance.get(sender);
418 return assertiveValue;
419 }
420
421 /**
422 * 相手の協調性を求める
423 *
424 * @param sender
425 * @return
426 */
427 public double calCooperativeness(Object sender) {
428 double cooperativeValue = myAverage - opponentsAverage.get(sender);
429 return cooperativeValue;
430 }
431
432 // 頻度情報の更新
433
434 /**
435 *
436 * @param sender
437 * @param bid
438 * @param time
439 */
440 public void updateOfferedValueNum(Object sender, Bid bid, double time) {
441 for (Issue issue : issues) {
442 Value value = bid.getValue(issue.getNumber());
443 if (!offeredValueNum.containsKey(value)) {
444 offeredValueNum.put(value, new CntBySender(0));
445 }
446 offeredValueNum.get(value).incrementCnt(sender, time);
447 }
448 }
449
450 public void updateBidAcceptNum(Object sender, Bid bid, double time) {
451 if (!bidAcceptNum.containsKey(bid)) {
452 bidAcceptNum.put(bid, new CntBySender(0));
453 }
454 bidAcceptNum.get(bid).incrementCnt(sender, time);
455 }
456
457 public void updateOpponentsAcceptNum(Object sender, double time) {
458 opponentsAcceptNum.incrementCnt(sender, time);
459 }
460
461 // 頻度情報を用いた値を返す
462
463 /**
464 * エージェントSenderの全体に対するAccept率を返す[0.0, 1.0]
465 *
466 * @param sender
467 * @return
468 */
469 public double calAcceptRate(Object sender) {
470 return (opponentsAcceptNum.getSimpleCnt(sender) + 1)
471 / (opponentsAcceptNum.getSimpleSum() + opponents.size());
472 }
473
474 /**
475 * 相手の効用空間との差とAccept率から、どのエージェントを優先的にするか決める
476 *
477 * @param sender
478 * @return
479 */
480 public double calImportanceRate(Object sender) {
481 // TODO:どっちか選ぶ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
482
483 // log_4 Accept率が低くて、効用空間の差が大きい人優先
484 return 1 - calAcceptRate(sender) + calSpaceDistByInitOffer(sender);
485 // log_5 Accept率が低くて、効用空間の差が小さい人優先
486 // return 2 - calAcceptRate(sender) - calSpaceDistByInitOffer(sender);
487 }
488
489 /**
490 * BidのAccept数を返す
491 *
492 * @param bid
493 * @param isWeighted
494 * Accept率を考慮するかどうか
495 * @return
496 */
497 public double getAcceptNumByBid(Bid bid, boolean isWeighted) {
498 double acceptNum = 0.0;
499
500 // Accept率を考慮したBidに置けるAccept数を返す
501 if (isWeighted) {
502 for (Object sender : opponents) {
503 if (bidAcceptNum.containsKey(bid)
504 && bidAcceptNum.get(bid).isContainOpponents(sender)) {
505 acceptNum += calImportanceRate(sender)
506 * bidAcceptNum.get(bid).getSimpleCnt(sender);
507 }
508 }
509 } else {
510 if (bidAcceptNum.containsKey(bid)) {
511 acceptNum = bidAcceptNum.get(bid).getSimpleSum();
512 }
513 }
514 return acceptNum;
515 }
516
517 /**
518 * BidのAccept率を返す[0.0, 1.0]
519 *
520 * @param bid
521 * @param isWeighted
522 * @return
523 */
524 public double getAcceptRateByBid(Bid bid, boolean isWeighted) {
525 return getAcceptNumByBid(bid, isWeighted)
526 / opponentsAcceptNum.getSimpleSum();
527 }
528
529 /**
530 * エージェントSenderの最高頻度Bidを返す
531 *
532 * @param sender
533 * @param baseBid
534 * @return
535 */
536 public Bid getHighFrequencyBid(Object sender, Bid baseBid) {
537 Bid ansBid = new Bid(baseBid);
538 for (Issue issue : issues) {
539 Value ansValue = getHighFrequencyValue(sender, issue);
540 ansBid = ansBid.putValue(issue.getNumber(), ansValue);
541 }
542 return ansBid;
543 }
544
545 /**
546 * エージェントSenderの論点issueの最高頻度のValueを返す
547 *
548 * @param sender
549 * @param issue
550 * @return
551 */
552 public Value getHighFrequencyValue(Object sender, Issue issue) {
553 ArrayList<Value> values = getValues(issue);
554
555 double tempMax = 0.0;
556 Value tempValue = values.get(0);
557 for (Value value : values) {
558 // 最大頻度のValueを求める
559 if (offeredValueNum.containsKey(value)) {
560 double nowCnt = offeredValueNum.get(value).getSimpleCnt(sender);
561 if (tempMax < nowCnt) {
562 tempMax = nowCnt;
563 tempValue = value;
564 }
565 }
566 }
567 return tempValue;
568 }
569
570 // 効用空間の違い
571 /**
572 * エージェントsenderと自分の効用空間との差を、自身の効用空間の値で数値化[0.0, 1.0]
573 *
574 * @param sender
575 * @return
576 */
577 public double calSpaceDistByInitOffer(Object sender) {
578 if (opponentsBidHistory.get(sender).isEmpty()) {
579 return 0.0;
580 }
581 return 1.0 - utilitySpace.getUtility(opponentsBidHistory.get(sender)
582 .get(0));
583 }
584
585 // 近傍・頻度探索
586 public void updateNeighborhoodBid(Bid bid) {
587 if (neighborhoodBid.containsKey(bid)) {
588 neighborhoodBid.put(bid, neighborhoodBid.get(bid) + 1);
589 } else {
590 neighborhoodBid.put(bid, 1);
591 }
592 }
593
594 public boolean isNeighborhoodBidContain(Bid bid) {
595 return neighborhoodBid.containsKey(bid);
596 }
597
598 public HashMap<Bid, Integer> getNeighborhoodBid() {
599 return neighborhoodBid;
600 }
601
602 public int getNeighborhoodBidSize() {
603 return neighborhoodBid.size();
604 }
605
606}
Note: See TracBrowser for help on using the repository browser.