source: src/main/java/agents/anac/y2016/myagent/etc/negotiationInfo.java@ 316

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

Initial import : Genius 9.0.0

File size: 15.2 KB
Line 
1package agents.anac.y2016.myagent.etc;
2
3import java.util.ArrayList;
4import java.util.HashMap;
5import java.util.List;
6import java.util.Map;
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.utility.UtilitySpace;
15
16public class negotiationInfo {
17 private UtilitySpace utilitySpace; // 効用空間
18 private List<Issue> issues; // 論点
19 private ArrayList<Object> opponents; // 自身以外の交渉参加者のsender
20 private ArrayList<Bid> MyBidHistory = null; // 提案履歴
21 private HashMap<Object, ArrayList<Bid>> opponentsBidHistory = null; // 提案履歴
22 private HashMap<Object, Double> opponentsAverage; // 平均
23 private HashMap<Object, Double> opponentsVariance; // 分散
24 private HashMap<Object, Double> opponentsSum; // 和
25 private HashMap<Object, Double> opponentsPowSum; // 二乗和
26 private HashMap<Object, Double> opponentsStandardDeviation; // 標準偏差
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 // original
33 private boolean isLast = false; // 受けると終わり
34 private HashMap<Object, ArrayList<Bid>> opponentsAccept; // 受け入れた提案
35 private HashMap<Object, HashMap<Issue, HashMap<Value, Integer>>> opponentsIssueWeight; // 敵の論点の重み
36
37 private Bid insurance; // 保険ビッド
38
39 private boolean isPrinting = false; // デバッグ用
40
41 public negotiationInfo(UtilitySpace utilitySpace, boolean isPrinting) {
42 // 初期化
43 this.utilitySpace = utilitySpace;
44 this.isPrinting = isPrinting;
45
46 issues = utilitySpace.getDomain().getIssues();
47 opponents = new ArrayList<Object>();
48 MyBidHistory = new ArrayList<>();
49 opponentsBidHistory = new HashMap<Object, ArrayList<Bid>>();
50 opponentsAverage = new HashMap<Object, Double>();
51 opponentsVariance = new HashMap<Object, Double>();
52 opponentsSum = new HashMap<Object, Double>();
53 opponentsPowSum = new HashMap<Object, Double>();
54 opponentsStandardDeviation = new HashMap<Object, Double>();
55 valueRelativeUtility = new HashMap<Issue, HashMap<Value, Double>>();
56
57 opponentsAccept = new HashMap<>();
58 opponentsIssueWeight = new HashMap<>();
59
60 try {
61 initValueRelativeUtility();
62 } catch (Exception e) {
63 System.out.println("相対効用行列の初期化に失敗しました");
64 e.printStackTrace();
65 }
66 }
67
68 public void initOpponent(Object sender) {
69 initNegotiatingInfo(sender); // 交渉情報を初期化
70 opponents.add(sender); // 交渉参加者にsenderを追加
71 }
72
73 public void updateInfo(Object sender, Bid offeredBid) {
74 try {
75 updateNegotiatingInfo(sender, offeredBid);
76 } // 交渉情報の更新
77 catch (Exception e1) {
78 System.out.println("交渉情報の更新に失敗しました");
79 e1.printStackTrace();
80 }
81 }
82
83 private void initNegotiatingInfo(Object sender) {
84 opponentsBidHistory.put(sender, new ArrayList<Bid>());
85 opponentsAverage.put(sender, 0.0);
86 opponentsVariance.put(sender, 0.0);
87 opponentsSum.put(sender, 0.0);
88 opponentsPowSum.put(sender, 0.0);
89 opponentsStandardDeviation.put(sender, 0.0);
90 }
91
92 // 相対効用行列の初期化
93 private void initValueRelativeUtility() throws Exception {
94 ArrayList<Value> values = null;
95 for (Issue issue : issues) {
96 valueRelativeUtility.put(issue, new HashMap<Value, Double>()); // 論点行の初期化
97 values = getValues(issue);
98 for (Value value : values) {
99 valueRelativeUtility.get(issue).put(value, 0.0);
100 } // 論点行の要素の初期化
101 }
102 }
103
104 // 相対効用行列の導出
105 public void setValueRelativeUtility(Bid maxBid) throws Exception {
106 ArrayList<Value> values = null;
107 Bid currentBid = null;
108 for (Issue issue : issues) {
109 currentBid = new Bid(maxBid);
110 values = getValues(issue);
111 for (Value value : values) {
112 currentBid = currentBid.putValue(issue.getNumber(), value);
113 valueRelativeUtility.get(issue).put(
114 value,
115 utilitySpace.getUtility(currentBid)
116 - utilitySpace.getUtility(maxBid));
117 }
118 }
119 }
120
121 public void updateNegotiatingInfo(Object sender, Bid offeredBid)
122 throws Exception {
123 opponentsBidHistory.get(sender).add(offeredBid); // 提案履歴
124
125 double util = utilitySpace.getUtility(offeredBid);
126 opponentsSum.put(sender, opponentsSum.get(sender) + util); // 和
127 opponentsPowSum.put(sender,
128 opponentsPowSum.get(sender) + Math.pow(util, 2)); // 二乗和
129
130 int round_num = opponentsBidHistory.get(sender).size();
131 opponentsAverage.put(sender, opponentsSum.get(sender) / round_num); // 平均
132 opponentsVariance.put(sender, (opponentsPowSum.get(sender) / round_num)
133 - Math.pow(opponentsAverage.get(sender), 2)); // 分散
134
135 if (opponentsVariance.get(sender) < 0) {
136 opponentsVariance.put(sender, 0.0);
137 }
138 opponentsStandardDeviation.put(sender,
139 Math.sqrt(opponentsVariance.get(sender))); // 標準偏差
140 }
141
142 // 交渉者数を返す
143 public void updateOpponentsNum(int num) {
144 negotiatorNum = num;
145 }
146
147 // 線形効用空間でない場合
148 public void utilitySpaceTypeisNonLiner() {
149 isLinerUtilitySpace = false;
150 }
151
152 // 自身の提案情報の更新
153 public void updateMyBidHistory(Bid offerBid) {
154 MyBidHistory.add(offerBid);
155 }
156
157 // 平均
158 public double getAverage(Object sender) {
159 return opponentsAverage.get(sender);
160 }
161
162 // 分散
163 public double getVariancer(Object sender) {
164 return opponentsVariance.get(sender);
165 }
166
167 // 標準偏差
168 public double getStandardDeviation(Object sender) {
169 return opponentsStandardDeviation.get(sender);
170 }
171
172 // 相手の提案履歴の要素数を返す
173 public int getPartnerBidNum(Object sender) {
174 return opponentsBidHistory.get(sender).size();
175 }
176
177 // 自身のラウンド数を返す
178 public int getRound() {
179 return round;
180 }
181
182 // 交渉者数を返す
183 public int getNegotiatorNum() {
184 return negotiatorNum;
185 }
186
187 // 相対効用行列を返す
188 public HashMap<Issue, HashMap<Value, Double>> getValueRelativeUtility() {
189 return valueRelativeUtility;
190 }
191
192 // 線形効用空間であるかどうかを返す
193 public boolean isLinerUtilitySpace() {
194 return isLinerUtilitySpace;
195 }
196
197 // 論点一覧を返す
198 public List<Issue> getIssues() {
199 return issues;
200 }
201
202 // 論点における取り得る値の一覧を返す
203 public ArrayList<Value> getValues(Issue issue) {
204 ArrayList<Value> values = new ArrayList<Value>();
205 switch (issue.getType()) {
206 case DISCRETE:
207 List<ValueDiscrete> valuesDis = ((IssueDiscrete) issue).getValues();
208 for (Value value : valuesDis) {
209 values.add(value);
210 }
211 break;
212 case INTEGER:
213 int min_value = ((IssueInteger) issue).getUpperBound();
214 int max_value = ((IssueInteger) issue).getUpperBound();
215 for (int j = min_value; j <= max_value; j++) {
216 Object valueObject = new Integer(j);
217 values.add((Value) valueObject);
218 }
219 break;
220 default:
221 try {
222 throw new Exception("issue type " + issue.getType()
223 + " not supported by Atlas3");
224 } catch (Exception e) {
225 System.out.println("論点の取り得る値の取得に失敗しました");
226 e.printStackTrace();
227 }
228 }
229 return values;
230 }
231
232 // 交渉相手の一覧を返す
233 public ArrayList<Object> getOpponents() {
234 return opponents;
235 }
236
237 // 最後のフェーズかを確認
238 public boolean isLast() {
239 return isLast;
240 }
241
242 // 最後のフェーズかを更新
243 public void updateLast(boolean b) {
244 isLast = b;
245 }
246
247 // Accept履歴を更新
248 public void updateAcceptList(Object sender, Bid acceptedBid) {
249 // 初期化
250 if (!opponentsAccept.containsKey(sender)) {
251 ArrayList<Bid> temp = new ArrayList<>();
252 opponentsAccept.put(sender, temp);
253 }
254
255 // 追加
256 opponentsAccept.get(sender).add(acceptedBid);
257 }
258
259 public ArrayList<Bid> getAcceptList(Object sender) {
260 if (!opponentsAccept.containsKey(sender)) {
261 return new ArrayList<Bid>();
262 }
263 return opponentsAccept.get(sender);
264 }
265
266 // 今までにAcceptした回数を返す
267 public int getAcceptedNum(Object opponent) {
268 // 初期化されていない:1回もAcceptされていない
269 if (!opponentsAccept.containsKey(opponent)) {
270 return 0;
271 }
272 return opponentsAccept.get(opponent).size();
273 }
274
275 // 弱気の連中を返す
276 public ArrayList<Object> getCowards() {
277 ArrayList<Object> cowards = new ArrayList<>();
278
279 for (Object opponent : opponents) {
280 if (getAcceptedNum(opponent) > 3) {
281 cowards.add(opponent);
282 }
283 }
284
285 return cowards;
286 }
287
288 // 強気の連中を返す
289 public ArrayList<Object> getArrogants() {
290 ArrayList<Object> arrogants = new ArrayList<>();
291
292 for (Object opponent : opponents) {
293 if (getAcceptedNum(opponent) <= 2) {
294 arrogants.add(opponent);
295 }
296 }
297
298 return arrogants;
299 }
300
301 // 最低ラインを求める
302 public double getLeastValue(ArrayList<Object> arrogants) {
303 double least = 0.0;
304 for (Object opponent : arrogants) {
305 double ave = getAverage(opponent);
306 double var = getVariancer(opponent);
307 double temp = ave + var * 0.1;
308 if (temp > least) {
309 least = temp;
310 }
311 }
312
313 return least;
314 }
315
316 // 相手の履歴を確認
317 public ArrayList<Bid> getOpponentHistory(Object sender, int num) {
318
319 ArrayList<Bid> recentHistory = new ArrayList<>();
320
321 if (!this.opponentsBidHistory.containsKey(sender)) {
322 return recentHistory;
323 }
324
325 int anum = num > opponentsBidHistory.get(sender).size() ? opponentsBidHistory
326 .get(sender).size() : num;
327 for (int i = 0; i < anum; i++) {
328 recentHistory.add(opponentsBidHistory.get(sender).get(
329 opponentsBidHistory.get(sender).size() - 1 - i));
330 }
331
332 return recentHistory;
333 }
334
335 // 相手の履歴の数を返す
336 public int getOpponentBidNum(Object sender) {
337 return opponentsBidHistory.get(sender).size();
338 }
339
340 // 相手の全体の傾きを求める
341 public double getSlant(Object sender) {
342
343 int num = 20; // 最近の数
344
345 HashMap<Issue, HashMap<Value, Double>> allWeight = getOpponentMaxValues(sender);
346 HashMap<Issue, HashMap<Value, Double>> recentWeight = getRecentMaxWeight(
347 sender, num);
348
349 double sumSlant = 0.0;
350
351 for (Issue issue : getIssues()) {
352
353 for (Value v : allWeight.get(issue).keySet()) {
354
355 // maxValueが異なる場合
356 if (!recentWeight.get(issue).containsKey(v)) {
357 continue;
358 }
359
360 double rawSlant = allWeight.get(issue).get(v)
361 - recentWeight.get(issue).get(v);
362
363 // 傾きがマイナスの場合
364 if (rawSlant < 0) {
365 continue;
366 } else {
367 double slant = rawSlant * allWeight.get(issue).get(v);
368 sumSlant += slant;
369 }
370 }
371 }
372
373 return sumSlant;
374 }
375
376 // 相手の最近の論点の回数を求める
377 public HashMap<Issue, HashMap<Value, Integer>> getRecentCount(
378 Object sender, int num) {
379 HashMap<Issue, HashMap<Value, Integer>> recentCount = initIssueWeight();
380 for (Bid bid : getOpponentHistory(sender, num)) {
381 for (Issue issue : bid.getIssues()) {
382 Value v = bid.getValue(issue.getNumber());
383 int c = recentCount.get(issue).get(v);
384 recentCount.get(issue).put(v, c + 1);
385 }
386 }
387
388 return recentCount;
389 }
390
391 // 相手の最近の論点の重みを求める
392 public HashMap<Issue, HashMap<Value, Double>> getRecentWeight(
393 Object sender, int num) {
394
395 HashMap<Issue, HashMap<Value, Double>> recentWeight = initRecentWeight();
396 HashMap<Issue, HashMap<Value, Integer>> recentCount = getRecentCount(
397 sender, num);
398
399 for (Issue issue : getIssues()) {
400 int sum = 0;
401
402 for (Value value : getValues(issue)) {
403 sum += recentCount.get(issue).get(value);
404 }
405
406 for (Value value : getValues(issue)) {
407 recentWeight.get(issue).put(value,
408 (recentCount.get(issue).get(value) + 0.0) / sum);
409 }
410 }
411
412 return recentWeight;
413 }
414
415 public HashMap<Issue, HashMap<Value, Double>> getRecentMaxWeight(
416 Object sender, int num) {
417
418 HashMap<Issue, HashMap<Value, Double>> recentMaxWeight = initRecentWeight();
419 HashMap<Issue, HashMap<Value, Double>> recentWeight = getRecentWeight(
420 sender, num);
421
422 for (Issue issue : getIssues()) {
423 Value maxValue = null;
424 for (Map.Entry<Value, Double> e : recentWeight.get(issue)
425 .entrySet()) {
426 if (maxValue == null) {
427 maxValue = e.getKey();
428 } else {
429 if (e.getValue() > recentWeight.get(issue).get(maxValue)) {
430 maxValue = e.getKey();
431 }
432 }
433 }
434 HashMap<Value, Double> weight = new HashMap<>();
435 weight.put(maxValue, recentWeight.get(issue).get(maxValue));
436 recentMaxWeight.put(issue, weight);
437 }
438
439 return recentMaxWeight;
440 }
441
442 // 初期化
443 private HashMap<Issue, HashMap<Value, Double>> initRecentWeight() {
444 HashMap<Issue, HashMap<Value, Double>> recentWeight = new HashMap<>();
445
446 for (Issue issue : getIssues()) {
447 HashMap<Value, Double> weights = new HashMap<>();
448 for (Value value : this.getValues(issue)) {
449 weights.put(value, 0.0);
450 }
451
452 recentWeight.put(issue, weights);
453 }
454
455 return recentWeight;
456 }
457
458 // 論点の重みを更新
459 public void updateOpponentIssueWeight(Object sender, Bid bid) {
460 // 初期化
461 if (!opponentsIssueWeight.containsKey(sender)) {
462 opponentsIssueWeight.put(sender, initIssueWeight());
463 }
464
465 for (Issue issue : bid.getIssues()) {
466 int current = opponentsIssueWeight.get(sender).get(issue)
467 .get(bid.getValue(issue.getNumber()));
468 opponentsIssueWeight.get(sender).get(issue)
469 .put(bid.getValue(issue.getNumber()), current + 1);
470 }
471 }
472
473 // 論点の重みを獲得
474 public HashMap<Issue, HashMap<Value, Integer>> getWeights(Object sender) {
475 return opponentsIssueWeight.get(sender);
476 }
477
478 // 論点の重みを獲得
479 public HashMap<Value, Integer> getWeight(Object sender, Issue issue) {
480 return opponentsIssueWeight.get(sender).get(issue);
481 }
482
483 public int getCount(Object sender, Issue issue, Value value) {
484 return getWeight(sender, issue).get(value);
485 }
486
487 // 論点Mapの初期化
488 private HashMap<Issue, HashMap<Value, Integer>> initIssueWeight() {
489
490 HashMap<Issue, HashMap<Value, Integer>> IssueWeight = new HashMap<>();
491
492 for (Issue issue : getIssues()) {
493 HashMap<Value, Integer> values = new HashMap<>();
494 for (Value value : getValues(issue)) {
495 values.put(value, 0);
496 }
497 IssueWeight.put(issue, values);
498 }
499
500 return IssueWeight;
501 }
502
503 public HashMap<Issue, HashMap<Value, Double>> getOpponentMaxValues(
504 Object sender) {
505
506 HashMap<Issue, HashMap<Value, Double>> opponentMaxValues = new HashMap<>();
507
508 for (Issue issue : getIssues()) {
509 Value maxValue = null;
510 double sum = 0;
511 for (Value value : getWeight(sender, issue).keySet()) {
512 if (maxValue == null) {
513 maxValue = value;
514 } else if (getCount(sender, issue, maxValue) < getCount(sender,
515 issue, value)) {
516 maxValue = value;
517 }
518
519 sum += getCount(sender, issue, value);
520 }
521
522 HashMap<Value, Double> temp = new HashMap<>();
523 temp.put(maxValue, getCount(sender, issue, maxValue) / sum);
524 opponentMaxValues.put(issue, temp);
525 }
526
527 return opponentMaxValues;
528 }
529
530 public HashMap<Issue, Value> getCriticalIssues(Object sender) {
531
532 HashMap<Issue, Value> criticalIssues = new HashMap<>();
533
534 for (Map.Entry<Issue, HashMap<Value, Double>> e : getOpponentMaxValues(
535 sender).entrySet()) {
536 for (Value value : e.getValue().keySet()) {
537 double weight = e.getValue().get(value);
538 if (weight > 0.95) {
539 criticalIssues.put(e.getKey(), value);
540 }
541 }
542 }
543
544 return criticalIssues;
545 }
546
547 /* ------------------------------- */
548}
Note: See TracBrowser for help on using the repository browser.