1 | package agents.anac.y2016.terra.etc;
|
---|
2 |
|
---|
3 | import java.util.HashMap;
|
---|
4 |
|
---|
5 | import genius.core.Bid;
|
---|
6 | import genius.core.utility.AbstractUtilitySpace;
|
---|
7 |
|
---|
8 | // 戦略
|
---|
9 | // 提案+合意の双方を考える必要性
|
---|
10 | // 序盤、中盤、終盤で交渉のまとめ方を変える
|
---|
11 | // 前半(0~90)
|
---|
12 | // 基本的には自分の効用値の高いオファー行う(相手が自分の提案から良いのを見つけてくれる可能性も高まるため)
|
---|
13 | // 効用値の閾値は高め
|
---|
14 | // 留保価格を考え早めに交渉がまとまるのであればまとめてしまう
|
---|
15 | // 中盤 ~終盤(90~170)
|
---|
16 | // 自分にとって欲張ってどのくらい相手に提案を飲ませられるかの最大値を提示
|
---|
17 | // 終盤(170~180)
|
---|
18 | // まとめの時期
|
---|
19 | // 相手のこれまでの行動により自分の閾値を決める(基本は相手が妥協してくれそうなギリギリのラインを狙う)
|
---|
20 | // 相手が提案(二人の提案の最大値のうち小さい方)よりも低い値で提案+合意を行わないようにする
|
---|
21 | // また、minの値を決めそれより低い数値では提案+合意を行わない
|
---|
22 | //
|
---|
23 | // その他のアイデア
|
---|
24 | //
|
---|
25 | //
|
---|
26 |
|
---|
27 | public class negotiationStrategy {
|
---|
28 | private AbstractUtilitySpace utilitySpace;
|
---|
29 | private negotiationInfo negotiationInfo;
|
---|
30 | private double rv;// 留保価格
|
---|
31 |
|
---|
32 | //
|
---|
33 | public negotiationStrategy(AbstractUtilitySpace utilitySpace,
|
---|
34 | negotiationInfo negotiationInfo) {
|
---|
35 | this.utilitySpace = utilitySpace;
|
---|
36 | this.negotiationInfo = negotiationInfo;
|
---|
37 | rv = utilitySpace.getReservationValue();
|
---|
38 | }
|
---|
39 |
|
---|
40 | // 受容判定
|
---|
41 | public boolean selectAccept(Bid offeredBid, double time) {
|
---|
42 | try {
|
---|
43 | if (utilitySpace.getUtility(offeredBid) >= getThreshold(time)/*-0.1*(1-time)*/) {
|
---|
44 | return true;
|
---|
45 | } else {
|
---|
46 | if (time > (173.0 / 180.0)
|
---|
47 | || (time > (15.0 / 180.0) && utilitySpace
|
---|
48 | .getDiscountFactor() < 0.9)
|
---|
49 | || (negotiationInfo.getIssues().size() < 5 && time > (10.0 / 180.0))) {
|
---|
50 | HashMap<Object, Double> recentOfferedUtility = negotiationInfo
|
---|
51 | .getUtilityAverage(negotiationInfo
|
---|
52 | .getRecentOfferedList());
|
---|
53 | if (recentOfferedUtility.isEmpty())
|
---|
54 | return false;
|
---|
55 | double ave = 0;
|
---|
56 | for (Double tave : recentOfferedUtility.values()) {
|
---|
57 | ave += tave;
|
---|
58 | }
|
---|
59 | ave /= 2;
|
---|
60 | if (time < (178.0 / 180.0)) {
|
---|
61 | if (time < (30.0 / 180.0)) {
|
---|
62 | if ((utilitySpace.getUtility(offeredBid) > 0.72))
|
---|
63 | return true;
|
---|
64 | else
|
---|
65 | return false;
|
---|
66 | }
|
---|
67 | if ((utilitySpace.getUtility(offeredBid) - utilitySpace
|
---|
68 | .getUtility(offeredBid)
|
---|
69 | * (1.0 - utilitySpace.getDiscountFactor())
|
---|
70 | * time)
|
---|
71 | - (ave - ave
|
---|
72 | * (1.0 - utilitySpace
|
---|
73 | .getDiscountFactor()) * time) > 0.0)
|
---|
74 | return true;
|
---|
75 | } else
|
---|
76 | return true;
|
---|
77 | }
|
---|
78 | return false;
|
---|
79 | }
|
---|
80 | } catch (Exception e) {
|
---|
81 | System.out.println("受容判定に失敗しました");
|
---|
82 | e.printStackTrace();
|
---|
83 | return false;
|
---|
84 | }
|
---|
85 | }
|
---|
86 |
|
---|
87 | // 交渉終了判定
|
---|
88 | public boolean selectEndNegotiation(double time) {
|
---|
89 | HashMap<Object, Double> recentOfferedUtility = negotiationInfo
|
---|
90 | .getUtilityAverage(negotiationInfo.getRecentOfferedList());
|
---|
91 |
|
---|
92 | // System.out.println(utilitySpace.getDiscountFactor());
|
---|
93 | if (recentOfferedUtility.isEmpty() || time < (15.0 / 180.0) || rv < 0.1)
|
---|
94 | return false;
|
---|
95 |
|
---|
96 | double ave = 0;
|
---|
97 | for (Double tave : recentOfferedUtility.values()) {
|
---|
98 | ave += tave;
|
---|
99 | }
|
---|
100 | ave /= 2;
|
---|
101 |
|
---|
102 | if ((ave - ave * (1.0 - utilitySpace.getDiscountFactor()) * time)
|
---|
103 | - (rv - rv * (1.0 - utilitySpace.getDiscountFactor() * time)) <= 0)
|
---|
104 | return true;
|
---|
105 | return false;
|
---|
106 | }
|
---|
107 |
|
---|
108 | enum NegotiationPhase {
|
---|
109 | FIRST_Claim, Claim, SUMMARIZE
|
---|
110 | };
|
---|
111 |
|
---|
112 | private NegotiationPhase selectPhase(double time, double ave) {
|
---|
113 | if ((time < (30.0 / 180.0))
|
---|
114 | || (utilitySpace.getDiscountFactor() > 0.9
|
---|
115 | && time < (170.0 / 180.0) || (rv < 0.1)))
|
---|
116 | return NegotiationPhase.FIRST_Claim;
|
---|
117 | if ((ave - ave * (1.0 - utilitySpace.getDiscountFactor()) * time) > 0.3)
|
---|
118 | return NegotiationPhase.Claim;
|
---|
119 | return NegotiationPhase.SUMMARIZE;
|
---|
120 | }
|
---|
121 |
|
---|
122 | public double getThreshold(double time) {
|
---|
123 | HashMap<Object, Double> recentOfferedUtility = negotiationInfo
|
---|
124 | .getUtilityAverage(negotiationInfo.getRecentOfferedList());
|
---|
125 | double ave = 0;
|
---|
126 | for (Double tave : recentOfferedUtility.values()) {
|
---|
127 | ave += tave;
|
---|
128 | }
|
---|
129 | ave /= 2;
|
---|
130 | NegotiationPhase phase = selectPhase(time, ave);
|
---|
131 |
|
---|
132 | if (phase == NegotiationPhase.FIRST_Claim) {
|
---|
133 | double threshold = 0;
|
---|
134 |
|
---|
135 | if (utilitySpace.getDiscountFactor() > 0.9) {// 割引効用がない場合
|
---|
136 | if (time < (60.0 / 180.0))
|
---|
137 | threshold = 1.0 - time * 0.5;//
|
---|
138 | else
|
---|
139 | threshold = 0.9;
|
---|
140 | } else {// ある場合
|
---|
141 | // System.out.println(time*(1-utilitySpace.getDiscountFactor()));
|
---|
142 | threshold = 1 - time * (1 - utilitySpace.getDiscountFactor())
|
---|
143 | * 2.3;// Math.pow(time*time*time,(1-utilitySpace.getDiscountFactor()));
|
---|
144 | // threshold=1.0-time*0.5;
|
---|
145 | if (threshold < 0.7)
|
---|
146 | threshold = 0.7;
|
---|
147 | }
|
---|
148 | return threshold;
|
---|
149 | } else if (phase == NegotiationPhase.Claim) {
|
---|
150 | HashMap<Object, Double> utilityMax = new HashMap<>();
|
---|
151 | HashMap<Object, Double> agreedUtilityMax = negotiationInfo
|
---|
152 | .getUtilityMax(negotiationInfo.getAgreedList());
|
---|
153 | HashMap<Object, Double> offeredUtilityAverage = negotiationInfo
|
---|
154 | .getUtilityAverage(negotiationInfo.getRecentOfferedList());
|
---|
155 |
|
---|
156 | for (Object agent : negotiationInfo.getOpponet()) {
|
---|
157 | if (agreedUtilityMax.containsKey(agent)) {
|
---|
158 | if (offeredUtilityAverage.get(agent) > agreedUtilityMax
|
---|
159 | .get(agent)) {
|
---|
160 | utilityMax.put(agent, offeredUtilityAverage.get(agent));
|
---|
161 | } else {
|
---|
162 | utilityMax.put(agent, agreedUtilityMax.get(agent));
|
---|
163 | }
|
---|
164 | } else {
|
---|
165 | utilityMax.put(agent, offeredUtilityAverage.get(agent));
|
---|
166 | }
|
---|
167 | }
|
---|
168 |
|
---|
169 | double threshold = 0.5;
|
---|
170 | double p1 = 1.3;
|
---|
171 | for (double tvalue : utilityMax.values()) {
|
---|
172 | if (threshold < tvalue)
|
---|
173 | threshold = tvalue;
|
---|
174 | }
|
---|
175 | if (threshold * p1 > 0.9)
|
---|
176 | return threshold = 0.9;
|
---|
177 | return threshold = threshold * p1;
|
---|
178 | } else {
|
---|
179 | // minを相手が合意するできるだけmaxに設定
|
---|
180 | // HashMap<Object, Double>
|
---|
181 | // offeredUtilityMax=negotiationInfo.getUtilityMax(negotiationInfo.getOfferedList());
|
---|
182 | HashMap<Object, Double> offeredUtilityMax = negotiationInfo
|
---|
183 | .getUtilityAverage(negotiationInfo.getRecentOfferedList());
|
---|
184 | HashMap<Object, Double> agreedUtilityMax = negotiationInfo
|
---|
185 | .getUtilityMax(negotiationInfo.getAgreedList());
|
---|
186 |
|
---|
187 | HashMap<Object, Double> utilityMax = new HashMap<>();
|
---|
188 | for (Object agent : negotiationInfo.getOpponet()) {
|
---|
189 | if (agreedUtilityMax.containsKey(agent)) {
|
---|
190 | if (offeredUtilityMax.get(agent) > agreedUtilityMax
|
---|
191 | .get(agent)) {
|
---|
192 | utilityMax.put(agent, offeredUtilityMax.get(agent));
|
---|
193 | } else {
|
---|
194 | utilityMax.put(agent, agreedUtilityMax.get(agent));
|
---|
195 | }
|
---|
196 | } else {
|
---|
197 | utilityMax.put(agent, offeredUtilityMax.get(agent));
|
---|
198 | }
|
---|
199 | }
|
---|
200 | double threshold = 2.0;// 2人のうち小さい方の効用値を閾値とする
|
---|
201 |
|
---|
202 | double min = 0.75 - time * (1 - utilitySpace.getDiscountFactor())
|
---|
203 | * 0.5;
|
---|
204 | // if(negotiationInfo.getRound()<100)min=0.55; //minよりも閾値が小さくならないように
|
---|
205 |
|
---|
206 | for (double tvalue : utilityMax.values()) {
|
---|
207 | if (threshold > tvalue)
|
---|
208 | threshold = tvalue;
|
---|
209 | }
|
---|
210 | if (threshold < min)
|
---|
211 | threshold = min;
|
---|
212 | return threshold;
|
---|
213 | }
|
---|
214 |
|
---|
215 | }
|
---|
216 | }
|
---|