source: src/main/java/agents/anac/y2017/agentf/etc/negotiationInfo.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: 18.8 KB
Line 
1package agents.anac.y2017.agentf.etc;
2
3import java.util.ArrayList;
4import java.util.Collections;
5import java.util.Comparator;
6import java.util.HashMap;
7import java.util.List;
8import java.util.Random;
9
10import genius.core.Bid;
11import genius.core.issue.Issue;
12import genius.core.issue.IssueDiscrete;
13import genius.core.issue.IssueInteger;
14import genius.core.issue.Value;
15import genius.core.issue.ValueDiscrete;
16import genius.core.issue.ValueInteger;
17import genius.core.list.Tuple;
18import genius.core.utility.AbstractUtilitySpace;
19
20public class negotiationInfo {
21 private AbstractUtilitySpace utilitySpace; // 効用空間
22 private ArrayList<Issue> issues; // 論点
23 private ArrayList<Object> opponents; // 自身以外の交渉参加者のList
24 private ArrayList<Bid> MyBidHistory = null; // 提案履歴
25 private ArrayList<Bid> BOBHistory = null; // BestOfferedBidの更新履歴
26 private ArrayList<Bid> PBList = null; // BestPopularBidのリスト
27 private HashMap<Object, Integer> opponentsAcceptNum; // acceptした回数
28 private HashMap<Object, ArrayList<Bid>> opponentsBidHistory = null; // 提案履歴
29 private HashMap<Object, Double> opponentsAverage; // 平均
30 private HashMap<Object, Double> opponentsVariance; // 分散
31 private HashMap<Object, Double> opponentsSum; // 和
32 private HashMap<Object, Double> opponentsPowSum; // 二乗和
33 private HashMap<Object, Double> opponentsStandardDeviation; // 標準偏差
34 private HashMap<Issue, HashMap<Value, Double>> valueRelativeUtility = null; // 自身の効用空間における各論点値の相対効用値行列(線形効用空間用)
35 private HashMap<Issue, HashMap<Value, Integer>> allValueFrequency = null; // 全員分の頻度行列
36 private HashMap<Object, HashMap<Issue, HashMap<Value, Integer>>> opponentsValueFrequency = null; // 交渉者別の頻度行列
37 private HashMap<Object, HashMap<Issue, ArrayList<Tuple<Value, Integer>>>> opponentsValueOrdinalScale = null; // 交渉者別の各issueごとの順序尺度
38 private double BOU = 0.0; // BestOfferedUtility 2者間交渉以外では使わない
39 private double MPBU = 0.0; // MaxPopularBidUtility
40 private double time_scale = 0.0; // 自分の手番が回ってくる時間間隔
41 private int round = 0; // 自分の手番数
42 private int negotiatorNum = 3; // 交渉者数(不具合が生じた場合に備えて3人で初期化)
43 private boolean isLinerUtilitySpace = true; // 線形効用空間であるかどうか
44
45 private boolean isPrinting = false;
46
47 public negotiationInfo(AbstractUtilitySpace utilitySpace, boolean isPrinting) {
48 // 初期化
49 this.isPrinting = isPrinting;
50 this.utilitySpace = utilitySpace;
51 issues = (ArrayList<Issue>) utilitySpace.getDomain().getIssues();
52 opponents = new ArrayList<Object>();
53 MyBidHistory = new ArrayList<>();
54 BOBHistory = new ArrayList<>();
55 PBList = new ArrayList<>();
56 opponentsAcceptNum = new HashMap<Object, Integer>();
57 opponentsBidHistory = new HashMap<Object, ArrayList<Bid>>();
58 opponentsAverage = new HashMap<Object, Double>();
59 opponentsVariance = new HashMap<Object, Double>();
60 opponentsSum = new HashMap<Object, Double>();
61 opponentsPowSum = new HashMap<Object, Double>();
62 opponentsStandardDeviation = new HashMap<Object, Double>();
63 valueRelativeUtility = new HashMap<Issue, HashMap<Value, Double>>();
64 allValueFrequency = new HashMap<Issue, HashMap<Value, Integer>>();
65 opponentsValueFrequency = new HashMap<Object, HashMap<Issue, HashMap<Value, Integer>>>();
66 opponentsValueOrdinalScale = new HashMap<Object, HashMap<Issue, ArrayList<Tuple<Value, Integer>>>>();
67
68 try {
69 initAllValueFrequency();
70 } catch (Exception e1) {
71 System.out.println("全員分の頻度行列の初期化に失敗しました");
72 e1.printStackTrace();
73 }
74 try {
75 initValueRelativeUtility();
76 } catch (Exception e) {
77 System.out.println("相対効用行列の初期化に失敗しました");
78 e.printStackTrace();
79 }
80
81 if (this.isPrinting) {
82 System.out.println("negotiationInfo:success");
83 }
84 }
85
86 public void initOpponent(Object sender) {
87 initNegotiatingInfo(sender); // 交渉情報を初期化
88 try {
89 initOpponentsValueFrequency(sender);
90 initOpponentValueOrdinalScale(sender);
91 opponentsAcceptNum.put(sender, 0);
92 } // senderの頻度行列を初期化
93 catch (Exception e) {
94 System.out.println("交渉参加者の頻度行列の初期化に失敗しました");
95 e.printStackTrace();
96 }
97 opponents.add(sender); // 交渉参加者にsenderを追加
98 }
99
100 public void updateInfo(Object sender, Bid offeredBid) {
101 try {
102 updateNegotiatingInfo(sender, offeredBid);
103 } // 交渉情報の更新
104 catch (Exception e1) {
105 System.out.println("交渉情報の更新に失敗しました");
106 e1.printStackTrace();
107 }
108 try {
109 updateFrequencyList(sender, offeredBid);
110 updateOrdinalScale(sender, offeredBid);
111 } // senderの頻度行列の更新
112 catch (Exception e) {
113 System.out.println("頻度行列の更新に失敗しました");
114 e.printStackTrace();
115 }
116 }
117
118 private void initNegotiatingInfo(Object sender) {
119 opponentsBidHistory.put(sender, new ArrayList<Bid>());
120 opponentsAverage.put(sender, 0.0);
121 opponentsVariance.put(sender, 0.0);
122 opponentsSum.put(sender, 0.0);
123 opponentsPowSum.put(sender, 0.0);
124 opponentsStandardDeviation.put(sender, 0.0);
125 }
126
127 private void initOpponentsValueFrequency(Object sender) throws Exception {
128 opponentsValueFrequency.put(sender, new HashMap<Issue, HashMap<Value, Integer>>()); // senderの頻度行列の初期化
129 for (Issue issue : issues) {
130 opponentsValueFrequency.get(sender).put(issue, new HashMap<Value, Integer>()); // 頻度行列における論点行の初期化
131 ArrayList<Value> values = getValues(issue);
132 for (Value value : values) {
133 opponentsValueFrequency.get(sender).get(issue).put(value, 0);
134 } // 論点行の要素出現数の初期化
135 }
136 }
137
138 public void initOpponentValueOrdinalScale(Object sender) throws Exception {
139 opponentsValueOrdinalScale.put(sender, new HashMap<Issue, ArrayList<Tuple<Value, Integer>>>()); // senderの頻度行列の初期化
140 for (Issue issue : issues) {
141 opponentsValueOrdinalScale.get(sender).put(issue, new ArrayList<Tuple<Value, Integer>>()); // 頻度行列における論点行の初期化
142 }
143 }
144
145 // 全員分の頻度行列の初期化
146 private void initAllValueFrequency() throws Exception {
147 ArrayList<Value> values = null;
148 for (Issue issue : issues) {
149 allValueFrequency.put(issue, new HashMap<Value, Integer>()); // 論点行の初期化
150 values = getValues(issue);
151 for (Value value : values) {
152 allValueFrequency.get(issue).put(value, 0);
153 } // 論点行の要素の初期化
154 }
155 }
156
157 // 相対効用行列の初期化
158 private void initValueRelativeUtility() throws Exception {
159 ArrayList<Value> values = null;
160 for (Issue issue : issues) {
161 valueRelativeUtility.put(issue, new HashMap<Value, Double>()); // 論点行の初期化
162 values = getValues(issue);
163 for (Value value : values) {
164 valueRelativeUtility.get(issue).put(value, 0.0);
165 } // 論点行の要素の初期化
166 }
167 }
168
169 // 相対効用行列の導出
170 public void setValueRelativeUtility(Bid maxBid) throws Exception {
171 ArrayList<Value> values = null;
172 Bid currentBid = null;
173 for (Issue issue : issues) {
174 currentBid = new Bid(maxBid);
175 values = getValues(issue);
176 for (Value value : values) {
177 currentBid = currentBid.putValue(issue.getNumber(), value);
178 valueRelativeUtility.get(issue).put(value,
179 utilitySpace.getUtility(currentBid) - utilitySpace.getUtility(maxBid));
180 }
181 }
182 }
183
184 public void updateNegotiatingInfo(Object sender, Bid offeredBid) throws Exception {
185 opponentsBidHistory.get(sender).add(offeredBid); // 提案履歴
186
187 double util = utilitySpace.getUtility(offeredBid);
188 opponentsSum.put(sender, opponentsSum.get(sender) + util); // 和
189 opponentsPowSum.put(sender, opponentsPowSum.get(sender) + Math.pow(util, 2)); // 二乗和
190
191 int round_num = opponentsBidHistory.get(sender).size();
192 opponentsAverage.put(sender, opponentsSum.get(sender) / round_num); // 平均
193 opponentsVariance.put(sender,
194 (opponentsPowSum.get(sender) / round_num) - Math.pow(opponentsAverage.get(sender), 2)); // 分散
195
196 if (opponentsVariance.get(sender) < 0) {
197 opponentsVariance.put(sender, 0.0);
198 }
199 opponentsStandardDeviation.put(sender, Math.sqrt(opponentsVariance.get(sender))); // 標準偏差
200
201 if (util > BOU) {
202 BOBHistory.add(offeredBid); // BOUの更新履歴に追加
203 BOU = util; // BOUの更新
204 }
205 }
206
207 public void updateAcceptNum(Object sender) {
208 opponentsAcceptNum.put(sender, opponentsAcceptNum.get(sender) + 1);
209 }
210
211 public HashMap<Issue, ArrayList<Tuple<Value, Integer>>> getValueOrdinalScale() {
212 // AcceptNumが多いエージェントを選びやすくしてる。
213 int allAcceptNum = 0;
214 for (Object agent : opponentsAcceptNum.keySet()) {
215 allAcceptNum += opponentsAcceptNum.get(agent);
216 }
217 Object selectedAgent = null;
218 if (allAcceptNum != 0) {
219 double rand = Math.random();
220 int acceptNum = 0;
221 for (Object agent : opponentsAcceptNum.keySet()) {
222 acceptNum += opponentsAcceptNum.get(agent);
223 if (rand <= acceptNum / allAcceptNum) {
224 selectedAgent = agent;
225 break;
226 }
227 }
228 } else {
229 int rand = (new Random()).nextInt(opponents.size());
230 int acceptNum = 0;
231 for (Object agent : opponentsAcceptNum.keySet()) {
232 acceptNum++;
233 if (rand <= acceptNum) {
234 selectedAgent = agent;
235 break;
236 }
237 }
238 }
239 // nullを返すことはないはず。
240 return opponentsValueOrdinalScale.get(selectedAgent);
241 }
242
243 // 頻度行列を更新
244 private void updateFrequencyList(Object sender, Bid offeredBid) throws Exception {
245 for (Issue issue : issues) {
246 Value value = offeredBid.getValue(issue.getNumber());
247 opponentsValueFrequency.get(sender).get(issue).put(value,
248 opponentsValueFrequency.get(sender).get(issue).get(value) + 1); // リストを更新
249 allValueFrequency.get(issue).put(value, allValueFrequency.get(issue).get(value) + 1); // リストを更新
250 }
251 }
252
253 // 順序尺度行列を更新
254 private void updateOrdinalScale(Object sender, Bid offeredBid) throws Exception {
255 for (Issue issue : issues) {
256 Value value = offeredBid.getValue(issue.getNumber());
257 int i = 0;
258 for (Tuple<Value, Integer> tuple : opponentsValueOrdinalScale.get(sender).get(issue)) {
259 if (tuple.get1().equals(value)) {
260 opponentsValueOrdinalScale.get(sender).get(issue).set(i,
261 new Tuple<Value, Integer>(value, tuple.get2() + 1));
262 break;
263 }
264 i++;
265 }
266 if (opponentsValueOrdinalScale.get(sender).get(issue).size() == i)
267 opponentsValueOrdinalScale.get(sender).get(issue).add(new Tuple<Value, Integer>(value, 1));
268 }
269 }
270
271 // 順序尺度行列をソート
272 public void sortOrdinalScale() throws Exception {
273 for (Object opponent : opponents) {
274 for (Issue issue : issues) {
275 Tuple<Value, Integer> tuplePre = opponentsValueOrdinalScale.get(opponent).get(issue)
276 .get(opponentsValueOrdinalScale.get(opponent).get(issue).size() - 1);
277 for (int i = opponentsValueOrdinalScale.get(opponent).get(issue).size() - 2; i >= 0; i--) {
278 if (opponentsValueOrdinalScale.get(opponent).get(issue).get(i).get2() < tuplePre.get2()) {
279 opponentsValueOrdinalScale.get(opponent).get(issue).set(i + 1,
280 opponentsValueOrdinalScale.get(opponent).get(issue).get(i));
281 opponentsValueOrdinalScale.get(opponent).get(issue).set(i, tuplePre);
282 }
283 tuplePre = opponentsValueOrdinalScale.get(opponent).get(issue).get(i);
284 }
285 }
286 }
287 }
288
289 // 交渉者数を返す
290 public void updateOpponentsNum(int num) {
291 negotiatorNum = num;
292 }
293
294 // 線形効用空間でない場合
295 public void utilitySpaceTypeisNonLiner() {
296 isLinerUtilitySpace = false;
297 }
298
299 // 自身の提案情報の更新
300 public void updateMyBidHistory(Bid offerBid) {
301 MyBidHistory.add(offerBid);
302 }
303
304 // 提案時間間隔を返す
305 public void updateTimeScale(double time) {
306 round = round + 1;
307 time_scale = time / round;
308 }
309
310 // PopularBidListを返す
311 public void updatePBList(Bid popularBid) throws Exception {
312 if (!PBList.contains(popularBid)) { // 一意に記録
313 PBList.add(popularBid);
314 MPBU = Math.max(MPBU, utilitySpace.getUtility(popularBid));
315 Collections.sort(PBList, new UtilityComparator()); // ソート
316
317 if (isPrinting) {
318 System.out.println("ranking");
319 for (int i = 0; i < PBList.size(); i++) {
320 System.out.println(utilitySpace.getUtility(PBList.get(i)));
321 }
322 System.out
323 .println("Size:" + PBList.size() + ", Min:" + utilitySpace.getUtility(PBList.get(0)) + ", Max:"
324 + utilitySpace.getUtility(PBList.get(PBList.size() - 1)) + ", Opponents:" + opponents);
325 }
326 }
327 }
328
329 public class UtilityComparator implements Comparator<Bid> {
330 public int compare(Bid a, Bid b) {
331 try {
332 double u1 = utilitySpace.getUtility(a);
333 double u2 = utilitySpace.getUtility(b);
334 if (u1 < u2) {
335 return 1;
336 }
337 if (u1 == u2) {
338 return 0;
339 }
340 if (u1 > u2) {
341 return -1;
342 }
343 } catch (Exception e) {
344 System.out.println("効用値に基づくソートに失敗しました");
345 e.printStackTrace();
346 }
347 return 0; // 例外処理
348 }
349 }
350
351 // 平均
352 public double getAverage(Object sender) {
353 return opponentsAverage.get(sender);
354 }
355
356 // 分散
357 public double getVariancer(Object sender) {
358 return opponentsVariance.get(sender);
359 }
360
361 // 標準偏差
362 public double getStandardDeviation(Object sender) {
363 return opponentsStandardDeviation.get(sender);
364 }
365
366 // 相手の提案履歴の要素数を返す
367 public int getPartnerBidNum(Object sender) {
368 return opponentsBidHistory.get(sender).size();
369 }
370
371 // 相手の提案履歴の頻度を返す
372 public HashMap<Issue, HashMap<Value, Integer>> getHistory(Object sender) {
373 return opponentsValueFrequency.get(sender);
374 }
375
376 // 自身のラウンド数を返す
377 public int getRound() {
378 return round;
379 }
380
381 // 交渉者数を返す
382 public int getNegotiatorNum() {
383 return negotiatorNum;
384 }
385
386 // 相対効用行列を返す
387 public HashMap<Issue, HashMap<Value, Double>> getValueRelativeUtility() {
388 return valueRelativeUtility;
389 }
390
391 // 線形効用空間であるかどうかを返す
392 public boolean isLinerUtilitySpace() {
393 return isLinerUtilitySpace;
394 }
395
396 // 論点一覧を返す
397 public ArrayList<Issue> getIssues() {
398 return issues;
399 }
400
401 // BestOfferedUtilityを返す
402 public double getBOU() {
403 return BOU;
404 }
405
406 // MaxPopularBidUtilityを返す
407 public double getMPBU() {
408 return MPBU;
409 }
410
411 // 交渉者全体のBOBHistoryを返す
412 public ArrayList<Bid> getBOBHistory() {
413 return BOBHistory;
414 }
415
416 // PBListを返す
417 public ArrayList<Bid> getPBList() {
418 return PBList;
419 }
420
421 // 提案時間間隔を返す
422 public double getTimeScale() {
423 return time_scale;
424 }
425
426 // 論点における取り得る値の一覧を返す
427 public ArrayList<Value> getValues(Issue issue) {
428 ArrayList<Value> values = new ArrayList<Value>();
429 switch (issue.getType()) {
430 case DISCRETE:
431 List<ValueDiscrete> valuesDis = ((IssueDiscrete) issue).getValues();
432 for (Value value : valuesDis) {
433 values.add(value);
434 }
435 break;
436 case INTEGER:
437 int min_value = ((IssueInteger) issue).getLowerBound();
438 // int min_value = ((IssueInteger)issue).getUpperBound();
439 int max_value = ((IssueInteger) issue).getUpperBound();
440 for (int j = min_value; j <= max_value; j++) {
441 ValueInteger valueObject = new ValueInteger(j);
442 values.add((Value) valueObject);
443 }
444 break;
445 default:
446 try {
447 throw new Exception("issue type " + issue.getType() + " not supported by Atlas3");
448 } catch (Exception e) {
449 System.out.println("論点の取り得る値の取得に失敗しました");
450 e.printStackTrace();
451 }
452 }
453 return values;
454 }
455
456 // 交渉相手の一覧を返す
457 public ArrayList<Object> getOpponents() {
458 return opponents;
459 }
460
461 // FrequencyListの頻度に基づき,要素を返す
462 public Value getValuebyFrequencyList(Object sender, Issue issue) {
463 int current_f = 0;
464 int max_f = 0; // 最頻出要素の出現数
465 Value max_value = null; // 最頻出要素
466 ArrayList<Value> randomOrderValues = getValues(issue);
467 Collections.shuffle(randomOrderValues); // ランダムに並び替える(毎回同じ順番で評価した場合,出現数が同値の場合に返却値が偏るため)
468
469 for (Value value : randomOrderValues) {
470 current_f = opponentsValueFrequency.get(sender).get(issue).get(value);
471 // 最頻出要素を記録
472 if (max_value == null || current_f > max_f) {
473 max_f = current_f;
474 max_value = value;
475 }
476 }
477 return max_value;
478 }
479
480 // 全員分のFrequencyListの頻度に基づき,要素を返す
481 public Value getValuebyAllFrequencyList(Issue issue) {
482 int current_f = 0;
483 int max_f = 0; // 最頻出要素の出現数
484 Value max_value = null; // 最頻出要素
485 ArrayList<Value> randomOrderValues = getValues(issue);
486 Collections.shuffle(randomOrderValues); // ランダムに並び替える(毎回同じ順番で評価した場合,出現数が同値の場合に返却値が偏るため)
487
488 for (Value value : randomOrderValues) {
489 current_f = allValueFrequency.get(issue).get(value);
490 // 最頻出要素を記録
491 if (max_value == null || current_f > max_f) {
492 max_f = current_f;
493 max_value = value;
494 }
495 }
496 return max_value;
497 }
498
499 // Wouter: DISABLED this #1534.
500
501 // public void saveFrequency() {
502 // try {
503 // File file = new File("opponentBid.txt");
504 // FileWriter filewriter = new FileWriter(file);
505 //
506 // for (Object opponent : opponents) {
507 // for (Issue issue : issues) {
508 // filewriter.write(opponent.toString() + "\n");
509 // HashMap<Value, Integer> values =
510 // opponentsValueFrequency.get(opponent).get(issue);
511 // // List 生成 (ソート用)
512 // List<Map.Entry<Value, Integer>> entries = new ArrayList<Map.Entry<Value,
513 // Integer>>(
514 // values.entrySet());
515 // Collections.sort(entries, new Comparator<Map.Entry<Value, Integer>>() {
516 // @Override
517 // public int compare(Entry<Value, Integer> entry1, Entry<Value, Integer>
518 // entry2) {
519 // return ((Integer) entry2.getValue()).compareTo((Integer)
520 // entry1.getValue());
521 // }
522 // });
523 //
524 // // 内容を表示
525 // for (Entry<Value, Integer> s : entries) {
526 // filewriter.write(s.getKey() + " , " + s.getValue() + "\n");
527 // }
528 // }
529 // }
530 // filewriter.close();
531 // } catch (IOException e) {
532 // System.out.println(e);
533 // }
534 // }
535 //
536 // public void saveSort() {
537 // try {
538 // File file = new File("sortBid.txt");
539 // FileWriter filewriter = new FileWriter(file);
540 // filewriter.write("save sort" + "\n");
541 //
542 // // for(Object opponent: opponents){
543 // // filewriter.write(opponent.toString()+"\n");
544 // // for(Issue issue: issues){
545 // // filewriter.write(issue.toString()+"\n");
546 // // ArrayList<Tuple<Value, Integer>> values =
547 // // opponentsValueOrdinalScale.get(opponent).get(issue);
548 // // 内容を表示
549 // // for (Tuple<Value,Integer> s : values) {
550 // // System.out.print("("+s.get1()+","+s.get2()+"):");
551 // // }
552 // // }
553 // // System.out.println("");
554 // // }
555 // for (Bid s : MyBidHistory) {
556 // filewriter.write(s + " , " + (1 - utilitySpace.getUtility(s)) + "\n");
557 // }
558 // filewriter.close();
559 // } catch (IOException e) {
560 // System.out.println(e);
561 // }
562 // }
563}
Note: See TracBrowser for help on using the repository browser.