source: src/main/java/agents/ABMPAgent2.java@ 209

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

Initial import : Genius 9.0.0

File size: 13.1 KB
Line 
1package agents;
2
3import java.util.HashMap;
4import java.util.List;
5
6import genius.core.Agent;
7import genius.core.Bid;
8import genius.core.SupportedNegotiationSetting;
9import genius.core.actions.Accept;
10import genius.core.actions.Action;
11import genius.core.actions.EndNegotiation;
12import genius.core.actions.Offer;
13import genius.core.issue.ISSUETYPE;
14import genius.core.issue.Issue;
15import genius.core.issue.IssueDiscrete;
16import genius.core.issue.Value;
17import genius.core.issue.ValueDiscrete;
18import genius.core.issue.ValueReal;
19import genius.core.utility.AdditiveUtilitySpace;
20import genius.core.utility.EvaluatorDiscrete;
21import genius.core.utility.EvaluatorReal;
22
23/**
24 *
25 * @author Dmytro Tykhonov & Koen Hindriks
26 */
27
28public class ABMPAgent2 extends Agent {
29
30 private Action messageOpponent;
31 // private int nrOfIssues;
32 private Bid myLastBid = null;
33 private Action myLastAction = null;
34
35 // private double[] fIssueWeight;
36 private enum ACTIONTYPE {
37 START, OFFER, ACCEPT, BREAKOFF
38 };
39
40 private double fOldTargetUtility;
41 // Paraters used in ABMP strategy
42 // TODO: Include these parameters as agent parameters in agent's utility
43 // template.
44 // QUESTION: How to do that nicely, since these parameters are strategy
45 // specific?
46 private static final double NEGOTIATIONSPEED = 0.1; // TODO: Probably still
47 // somewhere a bug. When
48 // you set this too low
49 // (e.g. 0.05), no deal
50 // is reached and no
51 // concession is done!
52 private static final double CONCESSIONFACTOR = 1;
53 private static final double CONFTOLERANCE = 0;
54 private static final double UTIlITYGAPSIZE = 0.02; // Accept when utility
55 // gap is <=
56 // UTILITYGAPSIZE.
57
58 // CHECK: Utility gap size needed since concession steps get VERY small when
59 // opponent's last bid utility is
60 // close to own last bid utility.
61
62 // Code is independent from AMPO vs CITY case, but some specifics about
63 // using this case as test are specified below.
64 // ****************************************************************************************************
65 // AMPO VS CITY: Outcome space has size of about 7 milion.
66 // ****************************************************************************************************
67 // ********************************************************
68 // *******************************************
69 // CHECK: ABMP gets stuck on the Car Example with a negotiation speed of
70 // less than 0.05!!
71 // ABMP "gets stuck" on AMPO vs CITY. The search through the space is not
72 // effective in discrete outcome
73 // spaces. Even with very high negotiation speed parameters (near 1) no bid
74 // can be found with the target utility
75 // at a certain point. In a discrete space, the evaluation distance between
76 // two different values on an
77 // issue need to be taken into account, which may differ from value to
78 // value... In such spaces one strategy
79 // would be to consider which combination of concessions on a set of issues
80 // would provide
81 // ********************************************************
82 // *******************************************
83
84 /** Creates a new instance of MyAgent */
85
86 public ABMPAgent2() {
87 super();
88 }
89
90 @Override
91 public void init() {
92 super.init();
93 messageOpponent = null;
94 myLastBid = null;
95 myLastAction = null;
96 fOldTargetUtility = 1;
97
98 }
99
100 public void ReceiveMessage(Action opponentAction) {
101 messageOpponent = opponentAction;
102 }
103
104 private Action proposeInitialBid() throws Exception {
105 Bid lBid;
106
107 // Return (one of the) possible bid(s) with maximal utility.
108 lBid = utilitySpace.getMaxUtilityBid();
109 lBid = getBidRandomWalk(utilitySpace.getUtility(lBid) * 0.95,
110 utilitySpace.getUtility(lBid));
111 myLastBid = lBid;
112 return new Offer(this.getAgentID(), lBid);
113 }
114
115 private Action proposeNextBid(Bid lOppntBid) {
116 Bid lBid = null;
117 double lMyUtility, lOppntUtility = 1, lTargetUtility;
118 // Both parties have made an initial bid. Compute associated utilities
119 // from my point of view.
120 lMyUtility = fOldTargetUtility;// utilitySpace.getUtility(myLastBid);
121 try {
122 lOppntUtility = utilitySpace.getUtility(lOppntBid);
123 } catch (Exception e) {
124 e.printStackTrace();
125 }
126 lTargetUtility = getTargetUtility(lMyUtility, lOppntUtility);
127 try {
128 lBid = getBidABMPsimple(lTargetUtility);
129 } catch (Exception e) {
130 e.printStackTrace();
131 }
132 myLastBid = lBid;
133 fOldTargetUtility = lTargetUtility;
134 return new Offer(this.getAgentID(), lBid);
135 }
136
137 public Action chooseAction() {
138 Action lAction = null;
139 ACTIONTYPE lActionType;
140 Bid lOppntBid = null;
141
142 lActionType = getActionType(messageOpponent);
143 switch (lActionType) {
144 case OFFER: // Offer received from opponent
145 try {
146 lOppntBid = ((Offer) messageOpponent).getBid();
147 if (myLastAction == null)
148 // Other agent started, lets propose my initial bid.
149 lAction = proposeInitialBid();
150 // DT Accept if utility gap is smaller than my target utility
151 // (instead of actual utility of my previous bid)
152 else if (utilitySpace.getUtility(lOppntBid) >= /*
153 * (utilitySpace.
154 * getUtility
155 * (myLastBid))
156 */fOldTargetUtility
157 - UTIlITYGAPSIZE)
158 // Opponent bids equally, or outbids my previous bid, so
159 // lets accept.
160 lAction = new Accept(getAgentID(), lOppntBid);
161 else
162 // Propose counteroffer. Get next bid.
163 lAction = proposeNextBid(lOppntBid);
164 } catch (Exception e) {
165 e.printStackTrace();
166 }
167 break;
168 case ACCEPT: // Presumably, opponent accepted last bid, but let's
169 // check...
170 /*
171 * lOppntBid = ((Accept) messageOpponent).getBid(); if
172 * (lOppntBid.equals(myLastBid)) lAction = new Accept(this,
173 * myLastBid); else lAction = new Offer(this, myLastBid); break;
174 */
175 case BREAKOFF:
176 // nothing left to do. Negotiation ended, which should be checked by
177 // Negotiator...
178 break;
179 default:
180 // I am starting, but not sure whether Negotiator checks this, so
181 // lets check also myLastAction...
182 if (myLastAction == null)
183 try {
184 lAction = proposeInitialBid();
185 } catch (Exception e) {
186 e.printStackTrace();
187 }
188 else
189 // simply repeat last action
190 lAction = myLastAction;
191 break;
192 }
193
194 myLastAction = lAction;
195 return lAction;
196 }
197
198 private ACTIONTYPE getActionType(Action lAction) {
199 ACTIONTYPE lActionType = ACTIONTYPE.START;
200
201 if (lAction instanceof Offer)
202 lActionType = ACTIONTYPE.OFFER;
203 else if (lAction instanceof Accept)
204 lActionType = ACTIONTYPE.ACCEPT;
205 else if (lAction instanceof EndNegotiation)
206 lActionType = ACTIONTYPE.BREAKOFF;
207 return lActionType;
208 }
209
210 /*
211 * public void loadUtilitySpace(String fileName) {
212 *
213 * utilitySpace = new
214 * SimpleUtilitySpace(getNegotiationTemplate().getDomain(), fileName);
215 *
216 * nrOfIssues = getNegotiationTemplate().getDomain().getNumberOfIssues();
217 * fIssueWeight = new double[nrOfIssues]; for (int i=0; i<nrOfIssues; i++) {
218 * fIssueWeight[i] = this.utilitySpace.getWeight(i); } }
219 */
220 // ABMP Specific Code
221
222 private Bid getBidABMPsimple(double targetUtility) throws Exception {
223 int nrOfIssues = utilitySpace.getDomain().getIssues().size();
224 double[] lIssueWeight = new double[nrOfIssues];
225 int i = 0;
226 for (Issue lIssue : utilitySpace.getDomain().getIssues()) {
227 lIssueWeight[i] = ((AdditiveUtilitySpace) utilitySpace)
228 .getWeight(lIssue.getNumber());
229 i++;
230 }
231 List<Issue> lIssues = utilitySpace.getDomain().getIssues();
232 Value[] lIssueIndex = new Value[nrOfIssues];
233 double[] lIssueAlpha = new double[nrOfIssues];
234 double[] lBE = new double[nrOfIssues];
235 double[] lBTE = new double[nrOfIssues];
236 double[] lTE = new double[nrOfIssues];
237 double lUtility = 0, lNF = 0, lAlpha, lUtilityGap, lTotalConcession = 0;
238
239 // ASSUMPTION: Method computes a second bid. Method proposeInitialBid is
240 // used to compute first bid.
241 lUtilityGap = targetUtility - utilitySpace.getUtility(myLastBid);
242 for (i = 0; i < nrOfIssues; i++) {
243 lBE[i] = (Double) (((AdditiveUtilitySpace) utilitySpace)
244 .getEvaluator(lIssues.get(i).getNumber()).getEvaluation(
245 ((AdditiveUtilitySpace) utilitySpace), myLastBid, lIssues
246 .get(i).getNumber()));
247 }
248
249 // STEP 1: Retrieve issue value for last bid and compute concession on
250 // each issue.
251 for (i = 0; i < nrOfIssues; i++) {
252 lAlpha = (1 - lIssueWeight[i]) * lBE[i]; // CHECK: (1 - lBE[i]);
253 // This factor is not
254 // right??
255 lNF = lNF + lIssueWeight[i] * lAlpha;
256 lIssueAlpha[i] = lAlpha;
257 }
258
259 // Compute basic target evaluations per issue
260 for (i = 0; i < nrOfIssues; i++) {
261 lBTE[i] = lBE[i] + (lIssueAlpha[i] / lNF) * lUtilityGap;
262 }
263
264 // STEP 2: Add configuration tolerance for opponent's bid
265 for (i = 0; i < nrOfIssues; i++) {
266 lUtility = (Double) (((AdditiveUtilitySpace) utilitySpace)
267 .getEvaluator(lIssues.get(i).getNumber()).getEvaluation(
268 ((AdditiveUtilitySpace) utilitySpace),
269 ((Offer) messageOpponent).getBid(), lIssues.get(i)
270 .getNumber()));
271 lTE[i] = (1 - CONFTOLERANCE) * lBTE[i] + CONFTOLERANCE * lUtility;
272 }
273
274 // STEP 3: Find bid in outcome space with issue target utilities
275 // corresponding with those computed above.
276 // ASSUMPTION: There is always a UNIQUE issue value with utility closest
277 // to the target evaluation.
278 // First determine new values for discrete-valued issues.
279 double lEvalValue;
280 int lNrOfRealIssues = 0;
281 for (i = 0; i < nrOfIssues; i++) {
282 lUtility = 1; // ASSUMPTION: Max utility = 1.
283 Issue lIssue = lIssues.get(i);// getNegotiationTemplate().getDomain().getIssue(i);
284 if (lIssue.getType() == ISSUETYPE.DISCRETE) {
285 IssueDiscrete lIssueDiscrete = (IssueDiscrete) lIssue;
286 for (int j = 0; j < lIssueDiscrete.getNumberOfValues(); j++) {
287 lEvalValue = ((EvaluatorDiscrete) ((AdditiveUtilitySpace) utilitySpace)
288 .getEvaluator(lIssues.get(i).getNumber()))
289 .getEvaluation(lIssueDiscrete.getValue(j));
290 if (Math.abs(lTE[i] - lEvalValue) < lUtility) {
291 lIssueIndex[i] = lIssueDiscrete.getValue(j);
292 lUtility = Math.abs(lTE[i] - lEvalValue);
293 }// if
294 }// for
295 lTotalConcession += lIssueWeight[i]
296 * (lBE[i] - ((EvaluatorDiscrete) ((AdditiveUtilitySpace) utilitySpace)
297 .getEvaluator(lIssues.get(i).getNumber()))
298 .getEvaluation((ValueDiscrete) lIssueIndex[i]));
299 } else if (lIssue.getType() == ISSUETYPE.REAL)
300 lNrOfRealIssues += 1;
301 }
302
303 // TODO: Still need to integrate integer-valued issues somewhere here.
304 // Low priority.
305
306 // STEP 4: RECOMPUTE size of remaining concession step
307 // Reason: Issue value may not provide exact match with basic target
308 // evaluation value.
309 // NOTE: This recomputation also includes any concession due to
310 // configuration tolerance parameter...
311 // First compute difference between actual concession on issue and
312 // target evaluation.
313 // TODO: Think about how to (re)distribute remaining concession over
314 // MULTIPLE real issues. In car example
315 // not important. Low priority.
316 double lRestUtitility = lUtilityGap + lTotalConcession;
317 // Distribute remaining utility of real issues. Integers still to be
318 // done. See above.
319 for (i = 0; i < nrOfIssues; i++) {
320 Issue lIssue = lIssues.get(i);// getNegotiationTemplate().getDomain().getIssue(i);
321 if (lIssue.getType() == ISSUETYPE.REAL) {
322 lTE[i] += lRestUtitility / lNrOfRealIssues;
323 EvaluatorReal lRealEvaluator = (EvaluatorReal) (((AdditiveUtilitySpace) utilitySpace)
324 .getEvaluator(lIssues.get(i).getNumber()));
325 double r = lRealEvaluator.getValueByEvaluation(lTE[i]);
326 lIssueIndex[i] = new ValueReal(r);
327 }
328 }
329 HashMap<Integer, Value> lValues = new HashMap<Integer, Value>();
330 for (i = 0; i < nrOfIssues; i++) {
331 lValues.put(lIssues.get(i).getNumber(), lIssueIndex[i]);
332 }
333 return new Bid(utilitySpace.getDomain(), lValues);
334 }
335
336 private double getTargetUtility(double myUtility, double oppntUtility) {
337 return myUtility + getConcessionStep(myUtility, oppntUtility);
338 }
339
340 private double getNegotiationSpeed() {
341 return NEGOTIATIONSPEED;
342 }
343
344 private double getConcessionFactor() {
345 // The more the agent is willing to concess on its aspiration value, the
346 // higher this factor.
347 return CONCESSIONFACTOR;
348 }
349
350 private double getConcessionStep(double myUtility, double oppntUtility) {
351 double lConcessionStep = 0, lMinUtility = 0, lUtilityGap = 0;
352
353 // Compute concession step
354 lMinUtility = 1 - getConcessionFactor();
355 lUtilityGap = (oppntUtility - myUtility);
356 lConcessionStep = getNegotiationSpeed() * (1 - lMinUtility / myUtility)
357 * lUtilityGap;
358 System.out.println(lConcessionStep);
359 return lConcessionStep;
360 }
361
362 private Bid getBidRandomWalk(double lowerBound, double upperBoud)
363 throws Exception {
364 Bid lBid = null, lBestBid = null;
365
366 // Return bid that gets closest to target utility in a "random walk"
367 // search.
368 lBestBid = utilitySpace.getDomain().getRandomBid(null);
369 while (true) {
370 lBid = utilitySpace.getDomain().getRandomBid(null);
371 if ((utilitySpace.getUtility(lBid) > lowerBound)
372 && (utilitySpace.getUtility(lBestBid) < upperBoud)) {
373 lBestBid = lBid;
374 break;
375 }
376
377 }
378 return lBestBid;
379 }
380
381 @Override
382 public SupportedNegotiationSetting getSupportedNegotiationSetting() {
383 return SupportedNegotiationSetting.getLinearUtilitySpaceInstance();
384 }
385
386 @Override
387 public String getVersion() {
388 return "1.0";
389 }
390}
Note: See TracBrowser for help on using the repository browser.