1 | package negotiator.boaframework.offeringstrategy.anac2010;
|
---|
2 |
|
---|
3 | import java.util.HashMap;
|
---|
4 | import java.util.List;
|
---|
5 | import java.util.Map;
|
---|
6 | import java.util.Random;
|
---|
7 |
|
---|
8 | import genius.core.Bid;
|
---|
9 | import genius.core.bidding.BidDetails;
|
---|
10 | import genius.core.boaframework.NegotiationSession;
|
---|
11 | import genius.core.boaframework.NoModel;
|
---|
12 | import genius.core.boaframework.OMStrategy;
|
---|
13 | import genius.core.boaframework.OfferingStrategy;
|
---|
14 | import genius.core.boaframework.OpponentModel;
|
---|
15 | import genius.core.boaframework.SortedOutcomeSpace;
|
---|
16 | import genius.core.issue.ISSUETYPE;
|
---|
17 | import genius.core.issue.Issue;
|
---|
18 | import genius.core.issue.IssueDiscrete;
|
---|
19 | import genius.core.issue.IssueInteger;
|
---|
20 | import genius.core.issue.IssueReal;
|
---|
21 | import genius.core.issue.Value;
|
---|
22 | import genius.core.issue.ValueDiscrete;
|
---|
23 | import genius.core.issue.ValueInteger;
|
---|
24 | import genius.core.issue.ValueReal;
|
---|
25 | import genius.core.misc.Range;
|
---|
26 | import genius.core.utility.AdditiveUtilitySpace;
|
---|
27 | import genius.core.utility.Evaluator;
|
---|
28 | import genius.core.utility.EvaluatorDiscrete;
|
---|
29 | import negotiator.boaframework.opponentmodel.DefaultModel;
|
---|
30 | import negotiator.boaframework.sharedagentstate.anac2010.NozomiSAS;
|
---|
31 |
|
---|
32 | /**
|
---|
33 | * This is the decoupled Offering Strategy for Nozomi (ANAC2010). The code was
|
---|
34 | * taken from the ANAC2010 Nozomi and adapted to work within the BOA framework.
|
---|
35 | *
|
---|
36 | * DEFAULT OM: None
|
---|
37 | *
|
---|
38 | * Decoupling Negotiating Agents to Explore the Space of Negotiation Strategies
|
---|
39 | * T. Baarslag, K. Hindriks, M. Hendrikx, A. Dirkzwager, C.M. Jonker
|
---|
40 | *
|
---|
41 | * @author Alex Dirkzwager, Mark Hendrikx
|
---|
42 | */
|
---|
43 | public class Nozomi_Offering extends OfferingStrategy {
|
---|
44 |
|
---|
45 | private double maxUtility = 0.0;
|
---|
46 | private Bid prevBid = null;
|
---|
47 | private Bid prevPartnerBid = null;
|
---|
48 | private int continuousCompromiseBid = 0;
|
---|
49 | private int continuousPartnerCompromiseBid = 0;
|
---|
50 | private int continuousKeep = 0;
|
---|
51 | private int measureT = 1;
|
---|
52 | private static double COMPROMISE_PROBABILITY = 0.70;
|
---|
53 | private static double KEEP_PROBABILITY = 0.15;
|
---|
54 |
|
---|
55 | private static enum BidType {
|
---|
56 | COMPROMISE, KEEP, APPROACH, RESTORE, RANDOM
|
---|
57 | };
|
---|
58 |
|
---|
59 | private final boolean TEST_EQUIVALENCE = false;
|
---|
60 | private Random random100;
|
---|
61 | private Random random200;
|
---|
62 |
|
---|
63 | /**
|
---|
64 | * Empty constructor called by BOA framework.
|
---|
65 | */
|
---|
66 | public Nozomi_Offering() {
|
---|
67 | }
|
---|
68 |
|
---|
69 | @Override
|
---|
70 | public void init(NegotiationSession domainKnow, OpponentModel model, OMStrategy oms, Map<String, Double> parameters)
|
---|
71 | throws Exception {
|
---|
72 | initializeAgent(domainKnow, model, oms);
|
---|
73 | }
|
---|
74 |
|
---|
75 | public void initializeAgent(NegotiationSession negoSession, OpponentModel om, OMStrategy oms) {
|
---|
76 | if (om instanceof DefaultModel) {
|
---|
77 | om = new NoModel();
|
---|
78 | }
|
---|
79 | this.negotiationSession = negoSession;
|
---|
80 | this.opponentModel = om;
|
---|
81 | this.omStrategy = oms;
|
---|
82 | helper = new NozomiSAS(negoSession, null);
|
---|
83 |
|
---|
84 | if (TEST_EQUIVALENCE) {
|
---|
85 | random100 = new Random(100);
|
---|
86 | random200 = new Random(200);
|
---|
87 | } else {
|
---|
88 | random100 = new Random();
|
---|
89 | random200 = new Random();
|
---|
90 | }
|
---|
91 | if (!(opponentModel instanceof NoModel)) {
|
---|
92 | SortedOutcomeSpace space = new SortedOutcomeSpace(negotiationSession.getUtilitySpace());
|
---|
93 | negotiationSession.setOutcomeSpace(space);
|
---|
94 | }
|
---|
95 | maxUtility = negotiationSession.getMaxBidinDomain().getMyUndiscountedUtil();
|
---|
96 | ((NozomiSAS) helper).setPrevAverageUtility(maxUtility);
|
---|
97 | ((NozomiSAS) helper).setMaxCompromiseUtility(maxUtility * 0.95);
|
---|
98 | }
|
---|
99 |
|
---|
100 | @Override
|
---|
101 | public BidDetails determineOpeningBid() {
|
---|
102 | BidDetails bid;
|
---|
103 | if (negotiationSession.getOpponentBidHistory().getHistory().isEmpty()) {
|
---|
104 | bid = negotiationSession.getMaxBidinDomain();
|
---|
105 | prevBid = bid.getBid();
|
---|
106 |
|
---|
107 | } else {
|
---|
108 | bid = determineNextBid();
|
---|
109 | }
|
---|
110 |
|
---|
111 | try {
|
---|
112 | } catch (Exception e) {
|
---|
113 | e.printStackTrace();
|
---|
114 | }
|
---|
115 |
|
---|
116 | return bid;
|
---|
117 | }
|
---|
118 |
|
---|
119 | @Override
|
---|
120 | public BidDetails determineNextBid() {
|
---|
121 | nextBid = chooseBidAction();
|
---|
122 | prevPartnerBid = negotiationSession.getOpponentBidHistory().getLastBidDetails().getBid();
|
---|
123 | try {
|
---|
124 | } catch (Exception e) {
|
---|
125 | e.printStackTrace();
|
---|
126 | }
|
---|
127 | return nextBid;
|
---|
128 | }
|
---|
129 |
|
---|
130 | private BidDetails chooseBidAction() {
|
---|
131 | BidDetails partnerBid = negotiationSession.getOpponentBidHistory().getLastBidDetails();
|
---|
132 |
|
---|
133 | double partnerUtility = partnerBid.getMyUndiscountedUtil();
|
---|
134 |
|
---|
135 | // This if is located in the isAccepted (AC)
|
---|
136 | if (partnerUtility > ((NozomiSAS) helper).getMaxUtilityOfPartnerBid()) {
|
---|
137 | ((NozomiSAS) helper).setMaxUtilityPartnerBidDetails(partnerBid);
|
---|
138 | ((NozomiSAS) helper).setUpdateMaxPartnerUtility(true);
|
---|
139 | }
|
---|
140 | try {
|
---|
141 | if (prevPartnerBid == null) {
|
---|
142 | ((NozomiSAS) helper).setMaxUtilityPartnerBidDetails(partnerBid);
|
---|
143 | nextBid = negotiationSession.getMaxBidinDomain();
|
---|
144 | prevBid = nextBid.getBid();
|
---|
145 | return nextBid;
|
---|
146 | } else {
|
---|
147 | ((NozomiSAS) helper).setBidNumber(((NozomiSAS) helper).getBidNumber() + 1);
|
---|
148 | double prevPartnerUtility = negotiationSession.getUtilitySpace().getUtility(prevPartnerBid);
|
---|
149 |
|
---|
150 | double averageUtil = ((NozomiSAS) helper).getAveragePartnerUtility();
|
---|
151 | averageUtil += partnerUtility;
|
---|
152 | ((NozomiSAS) helper).setAveragePartnerUtility(averageUtil);
|
---|
153 |
|
---|
154 | if (partnerUtility < prevPartnerUtility) {
|
---|
155 | if (continuousPartnerCompromiseBid < 0)
|
---|
156 | continuousPartnerCompromiseBid = 0;
|
---|
157 | continuousPartnerCompromiseBid++;
|
---|
158 | } else if (partnerUtility > prevPartnerUtility) {
|
---|
159 | if (continuousPartnerCompromiseBid > 0)
|
---|
160 | continuousPartnerCompromiseBid = 0;
|
---|
161 | continuousPartnerCompromiseBid--;
|
---|
162 | } else {
|
---|
163 | continuousPartnerCompromiseBid = 0;
|
---|
164 | }
|
---|
165 |
|
---|
166 | double time = negotiationSession.getTime() * 100;
|
---|
167 |
|
---|
168 | if (((NozomiSAS) helper).getMaxUtilityOfPartnerBid() > ((NozomiSAS) helper).getMaxCompromiseUtility()) {
|
---|
169 | ((NozomiSAS) helper).setMaxCompromiseUtility(((NozomiSAS) helper).getMaxUtilityOfPartnerBid());
|
---|
170 | }
|
---|
171 |
|
---|
172 | if (time > 90 && ((NozomiSAS) helper).getMaxCompromiseUtility()
|
---|
173 | - ((NozomiSAS) helper).getMaxUtilityOfPartnerBid() < 0.1) {
|
---|
174 | ((NozomiSAS) helper).setMaxCompromiseUtility((((NozomiSAS) helper).getMaxCompromiseUtility() * 7.0
|
---|
175 | + ((NozomiSAS) helper).getMaxUtilityOfPartnerBid() * 3.0) / 10.0);
|
---|
176 | }
|
---|
177 | if (((NozomiSAS) helper).getMaxCompromiseUtility() > maxUtility * 0.95) {
|
---|
178 | ((NozomiSAS) helper).setMaxCompromiseUtility(maxUtility * 0.95);
|
---|
179 | }
|
---|
180 | Bid bid2Offer = prevBid;
|
---|
181 | BidType bidType = chooseBidType(partnerBid.getBid());
|
---|
182 |
|
---|
183 | switch (bidType) {
|
---|
184 | case RESTORE:
|
---|
185 | bid2Offer = ((NozomiSAS) helper).getRestoreBid();
|
---|
186 | break;
|
---|
187 | case APPROACH:
|
---|
188 |
|
---|
189 | bid2Offer = getApproachBid(partnerBid.getBid());
|
---|
190 |
|
---|
191 | if (negotiationSession.getUtilitySpace().getUtility(bid2Offer) < ((NozomiSAS) helper)
|
---|
192 | .getMaxCompromiseUtility()
|
---|
193 | || negotiationSession.getUtilitySpace().getUtility(
|
---|
194 | bid2Offer) > ((NozomiSAS) helper).getMaxCompromiseUtility() * 105 / 95) {
|
---|
195 | bid2Offer = getBetweenBid(bid2Offer, partnerBid.getBid(),
|
---|
196 | ((NozomiSAS) helper).getMaxCompromiseUtility(),
|
---|
197 | ((NozomiSAS) helper).getMaxCompromiseUtility() * 105 / 95);
|
---|
198 | }
|
---|
199 | break;
|
---|
200 | case COMPROMISE:
|
---|
201 | bid2Offer = getCompromiseBid(partnerBid.getBid());
|
---|
202 |
|
---|
203 | if (negotiationSession.getUtilitySpace().getUtility(bid2Offer) < ((NozomiSAS) helper)
|
---|
204 | .getMaxCompromiseUtility()) {
|
---|
205 | bid2Offer = getBetweenBid(bid2Offer, partnerBid.getBid(),
|
---|
206 | ((NozomiSAS) helper).getMaxCompromiseUtility(),
|
---|
207 | ((NozomiSAS) helper).getMaxCompromiseUtility() * 105 / 95);
|
---|
208 | }
|
---|
209 |
|
---|
210 | if (continuousCompromiseBid < 0)
|
---|
211 | continuousCompromiseBid = 0;
|
---|
212 | continuousCompromiseBid++;
|
---|
213 | break;
|
---|
214 | case KEEP:
|
---|
215 | bid2Offer = prevBid;
|
---|
216 | continuousCompromiseBid /= 2;
|
---|
217 | break;
|
---|
218 | }
|
---|
219 |
|
---|
220 | if (negotiationSession.getUtilitySpace()
|
---|
221 | .getUtility(bid2Offer) <= negotiationSession.getUtilitySpace().getUtility(prevBid) / 2.0) {
|
---|
222 | bid2Offer = getApproachBid(partnerBid.getBid());
|
---|
223 |
|
---|
224 | if (negotiationSession.getUtilitySpace().getUtility(bid2Offer) < ((NozomiSAS) helper)
|
---|
225 | .getMaxCompromiseUtility()
|
---|
226 | || negotiationSession.getUtilitySpace().getUtility(
|
---|
227 | bid2Offer) > ((NozomiSAS) helper).getMaxCompromiseUtility() * 105 / 95) {
|
---|
228 | bid2Offer = getBetweenBid(bid2Offer, partnerBid.getBid(),
|
---|
229 | ((NozomiSAS) helper).getMaxCompromiseUtility(),
|
---|
230 | ((NozomiSAS) helper).getMaxCompromiseUtility() * 105 / 95);
|
---|
231 | }
|
---|
232 | }
|
---|
233 |
|
---|
234 | if (((negotiationSession.getUtilitySpace().getUtility(bid2Offer) < ((NozomiSAS) helper)
|
---|
235 | .getMaxCompromiseUtility()
|
---|
236 | || negotiationSession.getUtilitySpace()
|
---|
237 | .getUtility(bid2Offer) > ((NozomiSAS) helper).getMaxCompromiseUtility() * 105 / 95)
|
---|
238 | && continuousKeep < 20)
|
---|
239 | || negotiationSession.getUtilitySpace()
|
---|
240 | .getUtility(bid2Offer) <= negotiationSession.getUtilitySpace().getUtility(prevBid) / 2.0
|
---|
241 | || negotiationSession.getUtilitySpace().getUtility(bid2Offer) < ((NozomiSAS) helper)
|
---|
242 | .getMaxUtilityOfPartnerBid()) {
|
---|
243 | bid2Offer = ((NozomiSAS) helper).getRestoreBid();
|
---|
244 | }
|
---|
245 |
|
---|
246 | double util = ((NozomiSAS) helper).getAverageUtility();
|
---|
247 | util += negotiationSession.getUtilitySpace().getUtility(bid2Offer);
|
---|
248 | ((NozomiSAS) helper).setAverageUtility(util);
|
---|
249 |
|
---|
250 | if (continuousKeep <= 0) {
|
---|
251 | ((NozomiSAS) helper).updateRestoreBid(bid2Offer);
|
---|
252 | }
|
---|
253 |
|
---|
254 | if (time > (double) measureT * 3.0) {
|
---|
255 | ((NozomiSAS) helper).checkCompromise(time);
|
---|
256 | ((NozomiSAS) helper).setAverageUtility(0.0);
|
---|
257 | ((NozomiSAS) helper).setAveragePartnerUtility(0.0);
|
---|
258 | ((NozomiSAS) helper).setBidNumber(1);
|
---|
259 | measureT++;
|
---|
260 | }
|
---|
261 |
|
---|
262 | if (negotiationSession.getUtilitySpace().getUtility(bid2Offer) == negotiationSession.getUtilitySpace()
|
---|
263 | .getUtility(prevBid)) {
|
---|
264 | continuousKeep++;
|
---|
265 | } else {
|
---|
266 | continuousKeep = 0;
|
---|
267 | }
|
---|
268 |
|
---|
269 | if (continuousKeep > 30 && time > 90.0) {
|
---|
270 | double utility = ((NozomiSAS) helper).getMaxCompromiseUtility();
|
---|
271 | utility *= 0.99;
|
---|
272 |
|
---|
273 | ((NozomiSAS) helper).setMaxCompromiseUtility(utility);
|
---|
274 |
|
---|
275 | continuousKeep = 0;
|
---|
276 | }
|
---|
277 | nextBid = new BidDetails(bid2Offer, negotiationSession.getUtilitySpace().getUtility(bid2Offer),
|
---|
278 | negotiationSession.getTime());
|
---|
279 | prevBid = bid2Offer;
|
---|
280 |
|
---|
281 | return nextBid;
|
---|
282 | }
|
---|
283 | } catch (Exception e) {
|
---|
284 | // should throw an accept when fail
|
---|
285 | e.printStackTrace();
|
---|
286 | }
|
---|
287 | return null;
|
---|
288 | }
|
---|
289 |
|
---|
290 | private BidType chooseBidType(Bid partnerBid) {
|
---|
291 | BidType bidType = null;
|
---|
292 |
|
---|
293 | try {
|
---|
294 | double time = negotiationSession.getTime();
|
---|
295 | double prevUtility = negotiationSession.getUtilitySpace().getUtility(prevBid);
|
---|
296 | double partnerUtility = negotiationSession.getUtilitySpace().getUtility(partnerBid);
|
---|
297 | double gap = Math.abs(prevUtility - partnerUtility);
|
---|
298 |
|
---|
299 | if (gap < 0.05)
|
---|
300 | return BidType.APPROACH;
|
---|
301 |
|
---|
302 | // this is alway 0 thus I made it so
|
---|
303 | // gap = Math.abs(prevAverageUtility - prevAverageUtility);
|
---|
304 | gap = 0;
|
---|
305 | if (gap < 0.10 && time > 0.80)
|
---|
306 | return BidType.APPROACH;
|
---|
307 |
|
---|
308 | if (random100.nextInt(20) <= 0)
|
---|
309 | return BidType.RESTORE;
|
---|
310 |
|
---|
311 | int approachBorder = 5;
|
---|
312 | if (time > 0.9) {
|
---|
313 | approachBorder = (int) Math.round((time * 100) / 10);
|
---|
314 | }
|
---|
315 | if (random100.nextInt(20) <= approachBorder)
|
---|
316 | return BidType.RESTORE;
|
---|
317 |
|
---|
318 | if (prevUtility > ((NozomiSAS) helper).getMaxCompromiseUtility() * 105 / 95) {
|
---|
319 | return BidType.COMPROMISE;
|
---|
320 | }
|
---|
321 | if (continuousKeep > 20 && time > 0.60 && random100.nextDouble() > 0.60)
|
---|
322 | return BidType.APPROACH;
|
---|
323 |
|
---|
324 | } catch (Exception e) {
|
---|
325 | bidType = BidType.RESTORE; // bidType;
|
---|
326 | }
|
---|
327 |
|
---|
328 | double rnd = random100.nextDouble();
|
---|
329 | double compromiseProbability = getCompromiseProbability();
|
---|
330 |
|
---|
331 | if (rnd < compromiseProbability) {
|
---|
332 | bidType = BidType.COMPROMISE;
|
---|
333 |
|
---|
334 | } else if (rnd < getKeepProbability(compromiseProbability) + compromiseProbability) {
|
---|
335 | bidType = BidType.KEEP;
|
---|
336 | }
|
---|
337 | if (bidType == null)
|
---|
338 | bidType = BidType.RESTORE;
|
---|
339 | return bidType;
|
---|
340 | }
|
---|
341 |
|
---|
342 | private double getCompromiseProbability() {
|
---|
343 | double compromiseProbabilty = 0.0;
|
---|
344 |
|
---|
345 | try {
|
---|
346 | double prevUtility = negotiationSession.getUtilitySpace().getUtility(prevBid);
|
---|
347 | double prevUtilityOfPartnerBid = negotiationSession.getUtilitySpace().getUtility(prevPartnerBid);
|
---|
348 | // Below Values are less and less, more and more compromised.
|
---|
349 | double compromiseDegree = prevUtility / maxUtility;
|
---|
350 |
|
---|
351 | double compromisePartnerDegree = 1.0 - prevUtilityOfPartnerBid / maxUtility;
|
---|
352 |
|
---|
353 | double continuous = ((double) continuousCompromiseBid + (double) Math.abs(continuousPartnerCompromiseBid)
|
---|
354 | + 0.001) / 2.0;
|
---|
355 | double ratioUtilityToMaxUtility = prevUtility / (maxUtility * 0.9);
|
---|
356 |
|
---|
357 | compromiseProbabilty = (compromiseDegree + compromisePartnerDegree) / 2.0;
|
---|
358 |
|
---|
359 | compromiseProbabilty /= 1.0 + continuous / 8.0;
|
---|
360 | compromiseProbabilty *= ratioUtilityToMaxUtility;
|
---|
361 | } catch (Exception e) {
|
---|
362 | compromiseProbabilty = COMPROMISE_PROBABILITY;
|
---|
363 | }
|
---|
364 |
|
---|
365 | return compromiseProbabilty;
|
---|
366 | }
|
---|
367 |
|
---|
368 | private double getKeepProbability(double compromiseProbability) {
|
---|
369 | double keepProbability = 1.0 - compromiseProbability;
|
---|
370 |
|
---|
371 | try {
|
---|
372 | double time = negotiationSession.getTime();
|
---|
373 | double prevUtility = negotiationSession.getUtilitySpace().getUtility(prevBid);
|
---|
374 | double prevUtilityOfPartnerBid = negotiationSession.getUtilitySpace().getUtility(prevPartnerBid);
|
---|
375 | double ratioUtilityToMaxUtility = prevUtility / (maxUtility * 0.8);
|
---|
376 |
|
---|
377 | if (prevUtility > prevUtilityOfPartnerBid) {
|
---|
378 | keepProbability *= (prevUtility - prevUtilityOfPartnerBid) / maxUtility;
|
---|
379 | keepProbability *= time;
|
---|
380 | keepProbability *= 1.0 + (double) Math.abs(continuousCompromiseBid) / 4.0;
|
---|
381 | keepProbability *= ratioUtilityToMaxUtility;
|
---|
382 | } else {
|
---|
383 | keepProbability = 0.0;
|
---|
384 | }
|
---|
385 | } catch (Exception e) {
|
---|
386 | keepProbability = KEEP_PROBABILITY;
|
---|
387 | }
|
---|
388 |
|
---|
389 | return keepProbability;
|
---|
390 | }
|
---|
391 |
|
---|
392 | private Bid getCompromiseBid(Bid partnerBid) {
|
---|
393 | Bid compromiseBid = prevBid;
|
---|
394 | try {
|
---|
395 | double compromiseUtility = 0.0;
|
---|
396 | double prevUtility = negotiationSession.getUtilitySpace().getUtility(prevBid);
|
---|
397 | double basicUtility = prevUtility;
|
---|
398 | double gap = Math.abs(prevUtility - negotiationSession.getUtilitySpace().getUtility(partnerBid));
|
---|
399 | HashMap<Integer, Value> values = new HashMap<Integer, Value>();
|
---|
400 | List<Issue> issues = negotiationSession.getUtilitySpace().getDomain().getIssues();
|
---|
401 |
|
---|
402 | for (Issue issue : issues) {
|
---|
403 | values.put(issue.getNumber(), prevBid.getValue(issue.getNumber()));
|
---|
404 | }
|
---|
405 |
|
---|
406 | Integer changeIssueID = -1;
|
---|
407 | for (Issue compromiseIssue : issues) {
|
---|
408 | Integer compromiseIssueID = compromiseIssue.getNumber();
|
---|
409 |
|
---|
410 | if ((!prevPartnerBid.getValue(compromiseIssueID).equals(partnerBid.getValue(compromiseIssueID))
|
---|
411 | && gap > 0.05 && continuousKeep < 20)
|
---|
412 | || prevBid.getValue(compromiseIssueID).equals(partnerBid.getValue(compromiseIssueID))
|
---|
413 | || compromiseIssueID == changeIssueID) {
|
---|
414 | continue;
|
---|
415 | }
|
---|
416 |
|
---|
417 | HashMap<Integer, Value> candidateValues = new HashMap<Integer, Value>(values);
|
---|
418 | candidateValues.remove(compromiseIssueID);
|
---|
419 | candidateValues.put(compromiseIssueID, getCompromiseValue(compromiseIssue,
|
---|
420 | prevBid.getValue(compromiseIssueID), partnerBid.getValue(compromiseIssueID)));
|
---|
421 | Bid candidateBid = new Bid(negotiationSession.getUtilitySpace().getDomain(), candidateValues);
|
---|
422 | double candidateUtility = negotiationSession.getUtilitySpace().getUtility(candidateBid);
|
---|
423 |
|
---|
424 | if (candidateUtility > compromiseUtility && candidateUtility < basicUtility) {
|
---|
425 |
|
---|
426 | compromiseUtility = candidateUtility;
|
---|
427 | compromiseBid = candidateBid;
|
---|
428 | changeIssueID = compromiseIssueID;
|
---|
429 | }
|
---|
430 | }
|
---|
431 |
|
---|
432 | } catch (Exception e) {
|
---|
433 | e.printStackTrace();
|
---|
434 | compromiseBid = ((NozomiSAS) helper).getRestoreBid(); // best guess
|
---|
435 | // if things
|
---|
436 | // go wrong.
|
---|
437 | }
|
---|
438 | try {
|
---|
439 | } catch (Exception e) {
|
---|
440 | e.printStackTrace();
|
---|
441 | }
|
---|
442 | return compromiseBid;
|
---|
443 | }
|
---|
444 |
|
---|
445 | private Value getCompromiseValue(Issue issue, Value val, Value partnerVal) {
|
---|
446 | Value compromiseVal = null;
|
---|
447 | Evaluator eval = ((AdditiveUtilitySpace) negotiationSession.getUtilitySpace()).getEvaluator(issue.getNumber());
|
---|
448 |
|
---|
449 | switch (issue.getType()) {
|
---|
450 | case DISCRETE:
|
---|
451 | EvaluatorDiscrete evalDiscrete = (EvaluatorDiscrete) eval;
|
---|
452 | compromiseVal = (ValueDiscrete) val;
|
---|
453 | Integer evaluation = evalDiscrete.getValue((ValueDiscrete) val);
|
---|
454 | IssueDiscrete issueDiscrete = (IssueDiscrete) issue;
|
---|
455 | Integer compromiseEvaluation = 0;
|
---|
456 | for (int i = 0; i < issueDiscrete.getNumberOfValues(); i++) {
|
---|
457 | ValueDiscrete candidateVal = issueDiscrete.getValue(i);
|
---|
458 | Integer candidateEvaluation = evalDiscrete.getValue(candidateVal);
|
---|
459 | if (candidateEvaluation >= compromiseEvaluation && candidateEvaluation < evaluation) {
|
---|
460 | compromiseVal = candidateVal;
|
---|
461 | compromiseEvaluation = candidateEvaluation;
|
---|
462 | }
|
---|
463 | }
|
---|
464 | break;
|
---|
465 | case INTEGER:
|
---|
466 | ValueInteger valInt = (ValueInteger) val;
|
---|
467 | int compromiseInt = valInt.getValue();
|
---|
468 | ValueInteger partnerValInt = (ValueInteger) partnerVal;
|
---|
469 | if (compromiseInt > partnerValInt.getValue()) {
|
---|
470 | compromiseInt--;
|
---|
471 | } else {
|
---|
472 | compromiseInt++;
|
---|
473 | }
|
---|
474 | compromiseVal = new ValueInteger(compromiseInt);
|
---|
475 | break;
|
---|
476 | case REAL:
|
---|
477 | ValueReal valReal = (ValueReal) val;
|
---|
478 | double compromiseReal = valReal.getValue();
|
---|
479 | ValueReal partnerValReal = (ValueReal) partnerVal;
|
---|
480 | compromiseReal += new Random().nextDouble() * (partnerValReal.getValue() - compromiseReal) / 10;
|
---|
481 | compromiseVal = new ValueReal(compromiseReal);
|
---|
482 | break;
|
---|
483 | default:
|
---|
484 | compromiseVal = val;
|
---|
485 | break;
|
---|
486 | }
|
---|
487 | return compromiseVal;
|
---|
488 | }
|
---|
489 |
|
---|
490 | private Bid getBetweenBid(Bid basicBid, Bid partnerBid, double minUtility, double maxUtility) {
|
---|
491 | Bid betweenBid = basicBid;
|
---|
492 | if (opponentModel instanceof NoModel) {
|
---|
493 | try {
|
---|
494 | List<Issue> issues = negotiationSession.getUtilitySpace().getDomain().getIssues();
|
---|
495 | HashMap<Integer, Value> values = new HashMap<Integer, Value>();
|
---|
496 |
|
---|
497 | for (Issue issue : issues) {
|
---|
498 | values.put(issue.getNumber(), basicBid.getValue(issue.getNumber()));
|
---|
499 | }
|
---|
500 |
|
---|
501 | double utility = negotiationSession.getUtilitySpace().getUtility(basicBid);
|
---|
502 | for (int i = 0; i < 1000; i++) {
|
---|
503 | Issue issue = issues.get(random200.nextInt(issues.size()));
|
---|
504 |
|
---|
505 | int issueID = issue.getNumber();
|
---|
506 |
|
---|
507 | if (prevBid.getValue(issueID).equals(partnerBid.getValue(issueID))) {
|
---|
508 | continue;
|
---|
509 | }
|
---|
510 |
|
---|
511 | Value value = values.get(issueID);
|
---|
512 | values.remove(issueID);
|
---|
513 | if (utility > maxUtility) {
|
---|
514 | values.put(issueID, getLowerValue(issue, value, values));
|
---|
515 | } else {
|
---|
516 | values.put(issueID, getHigherValue(issue, value, values));
|
---|
517 | }
|
---|
518 |
|
---|
519 | Bid candidateBid = new Bid(negotiationSession.getUtilitySpace().getDomain(), values);
|
---|
520 | utility = negotiationSession.getUtilitySpace().getUtility(candidateBid);
|
---|
521 | if (utility > minUtility && utility < maxUtility) {
|
---|
522 | betweenBid = candidateBid;
|
---|
523 | break;
|
---|
524 | }
|
---|
525 | }
|
---|
526 | } catch (Exception e) {
|
---|
527 | betweenBid = ((NozomiSAS) helper).getRestoreBid();
|
---|
528 | }
|
---|
529 | } else {
|
---|
530 | betweenBid = omStrategy.getBid(negotiationSession.getOutcomeSpace(), new Range(minUtility, maxUtility))
|
---|
531 | .getBid();
|
---|
532 | }
|
---|
533 | return betweenBid;
|
---|
534 | }
|
---|
535 |
|
---|
536 | private Value getHigherValue(Issue issue, Value value, HashMap<Integer, Value> values) {
|
---|
537 | Value higher = null;
|
---|
538 | Evaluator eval = ((AdditiveUtilitySpace) negotiationSession.getUtilitySpace()).getEvaluator(issue.getNumber());
|
---|
539 |
|
---|
540 | switch (issue.getType()) {
|
---|
541 | case DISCRETE:
|
---|
542 | EvaluatorDiscrete evalDiscrete = (EvaluatorDiscrete) eval;
|
---|
543 |
|
---|
544 | Integer evaluation = evalDiscrete.getValue((ValueDiscrete) value);
|
---|
545 | IssueDiscrete issueDiscrete = (IssueDiscrete) issue;
|
---|
546 | higher = evalDiscrete.getMaxValue();
|
---|
547 | Integer highEvaluation = evalDiscrete.getValue((ValueDiscrete) higher);
|
---|
548 | for (int i = 0; i < issueDiscrete.getNumberOfValues(); i++) {
|
---|
549 | ValueDiscrete candidateVal = issueDiscrete.getValue(i);
|
---|
550 | Integer candidateEvaluation = evalDiscrete.getValue(candidateVal);
|
---|
551 | if (candidateEvaluation < highEvaluation && candidateEvaluation > evaluation) {
|
---|
552 | higher = candidateVal;
|
---|
553 | highEvaluation = candidateEvaluation;
|
---|
554 | }
|
---|
555 | }
|
---|
556 | break;
|
---|
557 | case INTEGER:
|
---|
558 | IssueInteger issueInt = (IssueInteger) issue;
|
---|
559 | ValueInteger valInt = (ValueInteger) value;
|
---|
560 | try {
|
---|
561 | Bid bid = new Bid(negotiationSession.getUtilitySpace().getDomain(), values);
|
---|
562 | values.remove(issueInt.getNumber());
|
---|
563 | values.put(issueInt.getNumber(), new ValueInteger(valInt.getValue() - 1));
|
---|
564 | Bid candidateBid = new Bid(negotiationSession.getUtilitySpace().getDomain(), values);
|
---|
565 | if (negotiationSession.getUtilitySpace().getUtility(candidateBid) > negotiationSession.getUtilitySpace()
|
---|
566 | .getUtility(bid)) {
|
---|
567 | higher = new ValueInteger(valInt.getValue() - 1);
|
---|
568 | } else {
|
---|
569 | higher = new ValueInteger(valInt.getValue() + 1);
|
---|
570 | }
|
---|
571 | } catch (Exception e) {
|
---|
572 | higher = valInt;
|
---|
573 | }
|
---|
574 | break;
|
---|
575 | case REAL:
|
---|
576 | IssueReal issueReal = (IssueReal) issue;
|
---|
577 | ValueReal valReal = (ValueReal) value;
|
---|
578 | try {
|
---|
579 | Bid bid = new Bid(negotiationSession.getUtilitySpace().getDomain(), values);
|
---|
580 | values.remove(issueReal.getNumber());
|
---|
581 | values.put(issueReal.getNumber(),
|
---|
582 | new ValueReal(valReal.getValue() - (valReal.getValue() - issueReal.getLowerBound()) / 10));
|
---|
583 | Bid candidateBid = new Bid(negotiationSession.getUtilitySpace().getDomain(), values);
|
---|
584 | if (negotiationSession.getUtilitySpace().getUtility(candidateBid) > negotiationSession.getUtilitySpace()
|
---|
585 | .getUtility(bid)) {
|
---|
586 | higher = new ValueReal(valReal.getValue()
|
---|
587 | - new Random().nextDouble() * (valReal.getValue() - issueReal.getLowerBound()) / 10);
|
---|
588 | } else {
|
---|
589 | higher = new ValueReal(valReal.getValue()
|
---|
590 | + new Random().nextDouble() * (issueReal.getUpperBound() - valReal.getValue()) / 10);
|
---|
591 | }
|
---|
592 | } catch (Exception e) {
|
---|
593 | higher = valReal;
|
---|
594 | }
|
---|
595 | break;
|
---|
596 | default:
|
---|
597 | higher = value;
|
---|
598 | break;
|
---|
599 | }
|
---|
600 |
|
---|
601 | return higher;
|
---|
602 | }
|
---|
603 |
|
---|
604 | private Value getLowerValue(Issue issue, Value value, HashMap<Integer, Value> values) {
|
---|
605 | Value lower = null;
|
---|
606 | Evaluator eval = ((AdditiveUtilitySpace) negotiationSession.getUtilitySpace()).getEvaluator(issue.getNumber());
|
---|
607 |
|
---|
608 | switch (issue.getType()) {
|
---|
609 | case DISCRETE:
|
---|
610 | EvaluatorDiscrete evalDiscrete = (EvaluatorDiscrete) eval;
|
---|
611 |
|
---|
612 | Integer evaluation = evalDiscrete.getValue((ValueDiscrete) value);
|
---|
613 | IssueDiscrete issueDiscrete = (IssueDiscrete) issue;
|
---|
614 | lower = evalDiscrete.getMinValue();
|
---|
615 | Integer lowEvaluation = evalDiscrete.getValue((ValueDiscrete) lower);
|
---|
616 | for (int i = 0; i < issueDiscrete.getNumberOfValues(); i++) {
|
---|
617 | ValueDiscrete candidateVal = issueDiscrete.getValue(i);
|
---|
618 | Integer candidateEvaluation = evalDiscrete.getValue(candidateVal);
|
---|
619 | if (candidateEvaluation > lowEvaluation && candidateEvaluation < evaluation) {
|
---|
620 | lower = candidateVal;
|
---|
621 | lowEvaluation = candidateEvaluation;
|
---|
622 | }
|
---|
623 | }
|
---|
624 | break;
|
---|
625 | case INTEGER:
|
---|
626 | IssueInteger issueInt = (IssueInteger) issue;
|
---|
627 | ValueInteger valInt = (ValueInteger) value;
|
---|
628 | try {
|
---|
629 | Bid bid = new Bid(negotiationSession.getUtilitySpace().getDomain(), values);
|
---|
630 | values.remove(issueInt.getNumber());
|
---|
631 | values.put(issueInt.getNumber(), new ValueInteger(valInt.getValue() - 1));
|
---|
632 | Bid candidateBid = new Bid(negotiationSession.getUtilitySpace().getDomain(), values);
|
---|
633 | if (negotiationSession.getUtilitySpace().getUtility(candidateBid) < negotiationSession.getUtilitySpace()
|
---|
634 | .getUtility(bid)) {
|
---|
635 | lower = new ValueInteger(valInt.getValue() - 1);
|
---|
636 | } else {
|
---|
637 | lower = new ValueInteger(valInt.getValue() + 1);
|
---|
638 | }
|
---|
639 | } catch (Exception e) {
|
---|
640 | lower = valInt;
|
---|
641 | }
|
---|
642 | break;
|
---|
643 | case REAL:
|
---|
644 | IssueReal issueReal = (IssueReal) issue;
|
---|
645 | ValueReal valReal = (ValueReal) value;
|
---|
646 | try {
|
---|
647 | Bid bid = new Bid(negotiationSession.getUtilitySpace().getDomain(), values);
|
---|
648 | values.remove(issueReal.getNumber());
|
---|
649 | values.put(issueReal.getNumber(),
|
---|
650 | new ValueReal(valReal.getValue() - (valReal.getValue() - issueReal.getLowerBound()) / 10));
|
---|
651 | Bid candidateBid = new Bid(negotiationSession.getUtilitySpace().getDomain(), values);
|
---|
652 | if (negotiationSession.getUtilitySpace().getUtility(candidateBid) < negotiationSession.getUtilitySpace()
|
---|
653 | .getUtility(bid)) {
|
---|
654 | lower = new ValueReal(valReal.getValue()
|
---|
655 | - new Random().nextDouble() * (valReal.getValue() - issueReal.getLowerBound()) / 10);
|
---|
656 | } else {
|
---|
657 | lower = new ValueReal(valReal.getValue()
|
---|
658 | + new Random().nextDouble() * (issueReal.getUpperBound() - valReal.getValue()) / 10);
|
---|
659 | }
|
---|
660 | } catch (Exception e) {
|
---|
661 | lower = valReal;
|
---|
662 | }
|
---|
663 | break;
|
---|
664 | default:
|
---|
665 | lower = value;
|
---|
666 | break;
|
---|
667 | }
|
---|
668 | return lower;
|
---|
669 | }
|
---|
670 |
|
---|
671 | private Bid getApproachBid(Bid partnerBid) {
|
---|
672 | Bid approachBid = prevBid;
|
---|
673 | try {
|
---|
674 | HashMap<Integer, Value> values = new HashMap<Integer, Value>();
|
---|
675 | HashMap<Integer, Value> approachValues = new HashMap<Integer, Value>();
|
---|
676 | List<Issue> issues = negotiationSession.getUtilitySpace().getDomain().getIssues();
|
---|
677 |
|
---|
678 | for (Issue issue : issues) {
|
---|
679 | values.put(issue.getNumber(), prevBid.getValue(issue.getNumber()));
|
---|
680 | }
|
---|
681 | approachValues = values;
|
---|
682 |
|
---|
683 | double candidateUtility = 0.0;
|
---|
684 | for (Issue issue : issues) {
|
---|
685 | int issueID = issue.getNumber();
|
---|
686 |
|
---|
687 | if (issue.getType() == ISSUETYPE.REAL) {
|
---|
688 | IssueReal issueReal = (IssueReal) issue;
|
---|
689 | ValueReal valueReal = (ValueReal) prevBid.getValue(issueID);
|
---|
690 | ValueReal partnerValueReal = (ValueReal) partnerBid.getValue(issueID);
|
---|
691 | ValueReal prevPartnerValueReal = (ValueReal) prevPartnerBid.getValue(issueID);
|
---|
692 | double gap = Math.abs(valueReal.getValue() - partnerValueReal.getValue());
|
---|
693 | double gapPartnerValue = Math.abs(partnerValueReal.getValue() - prevPartnerValueReal.getValue());
|
---|
694 | if (gap < (issueReal.getUpperBound() - issueReal.getLowerBound()) / 100
|
---|
695 | || !(gapPartnerValue < (issueReal.getUpperBound() - issueReal.getLowerBound()) / 100)) {
|
---|
696 | continue;
|
---|
697 | }
|
---|
698 | }
|
---|
699 |
|
---|
700 | if (prevBid.getValue(issueID).equals(partnerBid.getValue(issueID))) {
|
---|
701 | continue;
|
---|
702 | }
|
---|
703 |
|
---|
704 | HashMap<Integer, Value> candidateValues = new HashMap<Integer, Value>(values);
|
---|
705 |
|
---|
706 | candidateValues.remove(issueID);
|
---|
707 | candidateValues.put(issueID,
|
---|
708 | getApproachValue(issue, prevBid.getValue(issueID), partnerBid.getValue(issueID)));
|
---|
709 | Bid candidateBid = new Bid(negotiationSession.getUtilitySpace().getDomain(), candidateValues);
|
---|
710 | if (negotiationSession.getUtilitySpace().getUtility(candidateBid) > candidateUtility) {
|
---|
711 | candidateUtility = negotiationSession.getUtilitySpace().getUtility(candidateBid);
|
---|
712 | approachBid = candidateBid;
|
---|
713 | approachValues = candidateValues;
|
---|
714 | }
|
---|
715 | }
|
---|
716 |
|
---|
717 | while (true) {
|
---|
718 | candidateUtility = 0.0;
|
---|
719 | HashMap<Integer, Value> candidateValues = new HashMap<Integer, Value>(approachValues);
|
---|
720 | for (Issue issue : issues) {
|
---|
721 | HashMap<Integer, Value> tempValues = new HashMap<Integer, Value>(approachValues);
|
---|
722 |
|
---|
723 | int issueID = issue.getNumber();
|
---|
724 |
|
---|
725 | if (issue.getType() == ISSUETYPE.REAL) {
|
---|
726 | IssueReal issueReal = (IssueReal) issue;
|
---|
727 | ValueReal valueReal = (ValueReal) prevBid.getValue(issueID);
|
---|
728 | ValueReal partnerValueReal = (ValueReal) partnerBid.getValue(issueID);
|
---|
729 | double gap = Math.abs(valueReal.getValue() - partnerValueReal.getValue());
|
---|
730 | if (gap < (issueReal.getUpperBound() - issueReal.getLowerBound()) / 100) {
|
---|
731 | continue;
|
---|
732 | }
|
---|
733 | }
|
---|
734 |
|
---|
735 | if (prevBid.getValue(issueID).equals(partnerBid.getValue(issueID))) {
|
---|
736 | continue;
|
---|
737 | }
|
---|
738 |
|
---|
739 | tempValues.remove(issueID);
|
---|
740 | tempValues.put(issueID,
|
---|
741 | getApproachValue(issue, prevBid.getValue(issueID), partnerBid.getValue(issueID)));
|
---|
742 |
|
---|
743 | Bid tempBid = new Bid(negotiationSession.getUtilitySpace().getDomain(), tempValues);
|
---|
744 | if (negotiationSession.getUtilitySpace().getUtility(tempBid) > candidateUtility) {
|
---|
745 | candidateValues = tempValues;
|
---|
746 | candidateUtility = negotiationSession.getUtilitySpace().getUtility(tempBid);
|
---|
747 | }
|
---|
748 | }
|
---|
749 | if (candidateUtility >= negotiationSession.getUtilitySpace().getUtility(approachBid)
|
---|
750 | && !candidateValues.equals(approachValues)) {
|
---|
751 | Bid candidateBid = new Bid(negotiationSession.getUtilitySpace().getDomain(), candidateValues);
|
---|
752 | approachBid = candidateBid;
|
---|
753 | approachValues = candidateValues;
|
---|
754 | } else {
|
---|
755 | break;
|
---|
756 | }
|
---|
757 | }
|
---|
758 | } catch (Exception e) {
|
---|
759 | approachBid = ((NozomiSAS) helper).getRestoreBid(); // best guess if
|
---|
760 | // things go
|
---|
761 | // wrong.
|
---|
762 | }
|
---|
763 | return approachBid;
|
---|
764 | }
|
---|
765 |
|
---|
766 | private Value getApproachValue(Issue issue, Value myVal, Value partnerVal) {
|
---|
767 | Value approachVal = null;
|
---|
768 |
|
---|
769 | switch (issue.getType()) {
|
---|
770 | case DISCRETE:
|
---|
771 | IssueDiscrete issueDiscrete = (IssueDiscrete) issue;
|
---|
772 |
|
---|
773 | boolean checkMyVal = false;
|
---|
774 | boolean checkPartnerVal = false;
|
---|
775 | for (Value value : issueDiscrete.getValues()) {
|
---|
776 | if (checkMyVal) {
|
---|
777 | approachVal = value;
|
---|
778 | break;
|
---|
779 | }
|
---|
780 |
|
---|
781 | if (myVal.equals(value)) {
|
---|
782 | if (checkPartnerVal) {
|
---|
783 | break;
|
---|
784 | } else {
|
---|
785 | checkMyVal = true;
|
---|
786 | }
|
---|
787 | }
|
---|
788 |
|
---|
789 | if (partnerVal.equals(value)) {
|
---|
790 | if (checkMyVal) {
|
---|
791 | approachVal = value;
|
---|
792 | break;
|
---|
793 | } else {
|
---|
794 | checkPartnerVal = true;
|
---|
795 | }
|
---|
796 | }
|
---|
797 |
|
---|
798 | approachVal = value;
|
---|
799 | }
|
---|
800 | break;
|
---|
801 | case INTEGER:
|
---|
802 | ValueInteger valInt = (ValueInteger) myVal;
|
---|
803 | int approachInt = valInt.getValue();
|
---|
804 | ValueInteger partnerValInt = (ValueInteger) partnerVal;
|
---|
805 | if (approachInt > partnerValInt.getValue()) {
|
---|
806 | approachInt--;
|
---|
807 | } else {
|
---|
808 | approachInt++;
|
---|
809 | }
|
---|
810 | approachVal = new ValueInteger(approachInt);
|
---|
811 | break;
|
---|
812 | case REAL:
|
---|
813 | ValueReal valReal = (ValueReal) myVal;
|
---|
814 | double approachReal = valReal.getValue();
|
---|
815 | ValueReal partnerValReal = (ValueReal) partnerVal;
|
---|
816 | approachReal += new Random().nextDouble() * (partnerValReal.getValue() - approachReal) / 10;
|
---|
817 | approachVal = new ValueReal(approachReal);
|
---|
818 | break;
|
---|
819 | default:
|
---|
820 | approachVal = myVal;
|
---|
821 | break;
|
---|
822 | }
|
---|
823 | return approachVal;
|
---|
824 | }
|
---|
825 |
|
---|
826 | @Override
|
---|
827 | public String getName() {
|
---|
828 | return "2010 - Nozomi";
|
---|
829 | }
|
---|
830 | }
|
---|