1 | package agents.qoagent;
|
---|
2 |
|
---|
3 | /**
|
---|
4 | * @author raz
|
---|
5 | * This class should hold all your logic for your automated agent
|
---|
6 | * Examples are provided inline and marked as examples
|
---|
7 | *
|
---|
8 | */
|
---|
9 | public class AbstractAutomatedAgent {
|
---|
10 | AgentTools agentTools = null;
|
---|
11 |
|
---|
12 | public AbstractAutomatedAgent() {}
|
---|
13 |
|
---|
14 | /**
|
---|
15 | * Constructor
|
---|
16 | * Save a pointer to the AgentTools class
|
---|
17 | * @param agentTools - pointer to the AgentTools class
|
---|
18 | */
|
---|
19 | public AbstractAutomatedAgent(AgentTools agentTools) {
|
---|
20 | this.agentTools = agentTools;
|
---|
21 | }
|
---|
22 |
|
---|
23 | /**
|
---|
24 | * Called before the the nagotiation starts.
|
---|
25 | * Add any logic you need here.
|
---|
26 | * For example, calculate the very first offer you'll
|
---|
27 | * offer the opponent
|
---|
28 | * @param agentType - the automated agent
|
---|
29 | */
|
---|
30 | public void initialize(AutomatedAgentType agentType, String sOpponentType) {
|
---|
31 | /* Negotiation is about to start
|
---|
32 | * You can add logic if needed to receiveMessage your agent
|
---|
33 | * @@EXAMPLE@@
|
---|
34 | * For example: calculate the first offer the
|
---|
35 | * automated agent offers the opponent and send it
|
---|
36 | */
|
---|
37 |
|
---|
38 | /********************************
|
---|
39 | * Start example code
|
---|
40 | ********************************/
|
---|
41 | // calculate Automated Agent first offer
|
---|
42 | calculateOfferAgainstOpponent(agentType, sOpponentType, 1);
|
---|
43 | /********************************
|
---|
44 | * End example code
|
---|
45 | ********************************/
|
---|
46 | }
|
---|
47 |
|
---|
48 | /**
|
---|
49 | * Called when a message of type:
|
---|
50 | * QUERY, COUNTER_OFFER, OFFER or PROMISE
|
---|
51 | * is received
|
---|
52 | * Note that if you accept a message, the accepted message is saved in the
|
---|
53 | * appropriate structure, so no need to add logic for this.
|
---|
54 | * @param nMessageType - the message type
|
---|
55 | * @param CurrentAgreementIdx - the agreement indices
|
---|
56 | * @param sOriginalMessage - the message itself as string
|
---|
57 | */
|
---|
58 | public void calculateResponse(int nMessageType, int CurrentAgreementIdx[], String sOriginalMessage) {
|
---|
59 | //Calculating the response
|
---|
60 | //You can decide on your actions for that turn
|
---|
61 | //You can decide on different logic based on the message type
|
---|
62 | //In case you accept an offer, you might decide NOT to
|
---|
63 | //send an offer you calculated before and just waited for
|
---|
64 | //it to be sent. To do so, use the "send flag" as in
|
---|
65 | //the example below
|
---|
66 | //@@EXAMPLE@@
|
---|
67 | //For example:
|
---|
68 | //1 - if the newly offer has lower utility values than already
|
---|
69 | //accepted agreement, reject it;
|
---|
70 | //2 - if the automated agent is going to propose an offer with lower utility values to
|
---|
71 | //it in the next turn, accept the opponent's offer and
|
---|
72 | //don't send any offer of your own
|
---|
73 | //3 - else, always accept
|
---|
74 |
|
---|
75 | /********************************
|
---|
76 | * Start example code
|
---|
77 | ********************************/
|
---|
78 | // decide whether to accept the message or reject it:
|
---|
79 | double dOppOfferValueForAgent = AutomatedAgentType.VERY_SMALL_NUMBER;
|
---|
80 | double dAutomatedAgentNextOfferValueForAgent = AutomatedAgentType.VERY_SMALL_NUMBER;
|
---|
81 |
|
---|
82 | // Check the utility value of the opponent's offer
|
---|
83 | dOppOfferValueForAgent = agentTools.getAgreementValue(CurrentAgreementIdx);
|
---|
84 |
|
---|
85 | // 1. check whether previous accepted agreement is better - if so, reject
|
---|
86 | double dAcceptedAgreementValue = agentTools.getAcceptedAgreementsValue();
|
---|
87 |
|
---|
88 | if (dAcceptedAgreementValue >= dOppOfferValueForAgent)
|
---|
89 | {
|
---|
90 | // reject offer
|
---|
91 | agentTools.rejectMessage(sOriginalMessage);
|
---|
92 | return;
|
---|
93 | }
|
---|
94 |
|
---|
95 | // 2. check the value of the automated agent in the next turn
|
---|
96 | agentTools.calculateNextTurnOffer();
|
---|
97 | dAutomatedAgentNextOfferValueForAgent = agentTools.getNextTurnOfferValue();
|
---|
98 |
|
---|
99 | if (dOppOfferValueForAgent >= dAutomatedAgentNextOfferValueForAgent)
|
---|
100 | {
|
---|
101 | // accept offer
|
---|
102 | agentTools.acceptMessage(sOriginalMessage);
|
---|
103 |
|
---|
104 | //prevent sending future offer in this turn
|
---|
105 | agentTools.setSendOfferFlag(false);
|
---|
106 |
|
---|
107 | /* @@ You accepted opponent's message
|
---|
108 | * The automated agent accepts a messsage here
|
---|
109 | * You can add logic if needed to receiveMessage your agent
|
---|
110 | * Note: The accepted message is saved in the
|
---|
111 | * appropriate structure. No need to add logic for this
|
---|
112 | */
|
---|
113 | }
|
---|
114 | else
|
---|
115 | {
|
---|
116 | // accept offer
|
---|
117 | agentTools.acceptMessage(sOriginalMessage);
|
---|
118 |
|
---|
119 | //prevent sending future offer in this turn
|
---|
120 | agentTools.setSendOfferFlag(false);
|
---|
121 |
|
---|
122 | /* @@ You accepted opponent's message
|
---|
123 | * The automated agent accepts a messsage here
|
---|
124 | * You can add logic if needed to receiveMessage your agent
|
---|
125 | * Note: The accepted message is saved in the
|
---|
126 | * appropriate structure. No need to add logic for this
|
---|
127 | */
|
---|
128 | }
|
---|
129 | /********************************
|
---|
130 | * End example code
|
---|
131 | ********************************/
|
---|
132 | }
|
---|
133 |
|
---|
134 | /***********************************************
|
---|
135 | * @@ Logic for receiving messages
|
---|
136 | * Below are messages the opponent sends to the automated agent
|
---|
137 | * You can add logic if needed to receiveMessage your agent per message type
|
---|
138 | ***********************************************/
|
---|
139 |
|
---|
140 | /**
|
---|
141 | * called whenever we get a comment from the opponent
|
---|
142 | * You can add logic to receiveMessage your agent
|
---|
143 | * @param sComment -the received comment
|
---|
144 | */
|
---|
145 | public void commentReceived(String sComment) {
|
---|
146 | /* @@ Received a comment from the opponent
|
---|
147 | * You can add logic if needed to receiveMessage your agent
|
---|
148 | */
|
---|
149 | }
|
---|
150 |
|
---|
151 | /**
|
---|
152 | * called whenever we get a threat from the opponent
|
---|
153 | * You can add logic to receiveMessage your agent
|
---|
154 | * @param sThreat - the received threat
|
---|
155 | */
|
---|
156 | public void threatReceived(String sThreat) {
|
---|
157 | /* @@ Received a threat from the opponent
|
---|
158 | * You can add logic if needed to receiveMessage your agent
|
---|
159 | */
|
---|
160 | }
|
---|
161 |
|
---|
162 | /**
|
---|
163 | * called whenever the opponent agreed to one of your massages (promise, query, offer or counter offer).
|
---|
164 | * NOTE: if an OFFER is accepted, it is saved in the appropriate structure. No need to add logic for this.
|
---|
165 | * @param nMessageType - the type of massage the oppnent aggreed to, can be
|
---|
166 | * AutomatedAgentMessages.PROMISE, QUERY, OFFER, COUNTER_OFFER
|
---|
167 | * @param CurrentAgreementIdx - the indices of the agreement the opponent agreed to
|
---|
168 | * @param sOriginalMessage - the original message that was accepted
|
---|
169 | */
|
---|
170 | public void opponentAgreed(int nMessageType, int CurrentAgreementIdx[], String sOriginalMessage) {
|
---|
171 | /* @@ Received a message: opponent accepted the offer/promise/query/counter offer.
|
---|
172 | * You can add logic if needed to receiveMessage your agent
|
---|
173 | * For example, if the message was a promise, you can now try and offer it as
|
---|
174 | * a formal offer...
|
---|
175 | */
|
---|
176 | }
|
---|
177 |
|
---|
178 | /**
|
---|
179 | * called whenever the opponent rejected one of your massages (promise, query, offer or counter offer)
|
---|
180 | * @param nMessageType - the type of massage the oppnent rejected, can be
|
---|
181 | * AutomatedAgentMessages.PROMISE, QUERY, OFFER, COUNTER_OFFER
|
---|
182 | * @param CurrentAgreementIdx - the indices of the agreement the opponent agreed to
|
---|
183 | * @param sOriginalMessage - the original message that was rejected
|
---|
184 | */
|
---|
185 | public void opponentRejected(int nMessageType, int CurrentAgreementIdx[], String sOriginalMessage) {
|
---|
186 | /* @@ Received a message: opponent rejected the offer/promise/query/counter offer.
|
---|
187 | * You can add logic if needed to receiveMessage your agent
|
---|
188 | */
|
---|
189 | }
|
---|
190 |
|
---|
191 | /***********************************************
|
---|
192 | * @@ End of methods for receiving message
|
---|
193 | ***********************************************/
|
---|
194 |
|
---|
195 |
|
---|
196 | /**
|
---|
197 | * called to decide which offer to propose the opponent at a given turn
|
---|
198 | * This method is always called when beginning a new turn
|
---|
199 | * You can also call it during the turn if needed
|
---|
200 | * @param agentType - the automated agent's type
|
---|
201 | * @param sOpponentType - the opponent's type
|
---|
202 | * @param nCurrentTurn - the current turn
|
---|
203 | */
|
---|
204 | public void calculateOfferAgainstOpponent(AutomatedAgentType agentType, String sOpponentType, int nCurrentTurn) {
|
---|
205 | //@@ Add any logic to calculate offer (or several offers)
|
---|
206 | // and decide which to send to the opponent in a given turn
|
---|
207 |
|
---|
208 | /** @@EXAMPLE@@
|
---|
209 | * In the following example, ONE offer is chosen to be
|
---|
210 | * send to the opponent based on the following logic:
|
---|
211 | * It will be sent only if it has a value higher than
|
---|
212 | * an offer already accepted.
|
---|
213 | *
|
---|
214 | * You can see in the example how to:
|
---|
215 | * a) obtain the different possible types of opponent
|
---|
216 | * b) get the total number of issues in the negotiation
|
---|
217 | * c) get the total number of agreements in the negotiation
|
---|
218 | * d) get the maximal value of a certain issue for each agent
|
---|
219 | * e) go over all possible agreements and evaluate them
|
---|
220 | * f) compare the agreement to previously accepted agreement
|
---|
221 | * g) save one offer for later references
|
---|
222 | *
|
---|
223 | *
|
---|
224 | /********************************
|
---|
225 | * Start example code
|
---|
226 | ********************************/
|
---|
227 | // calculate Automated Agent offer
|
---|
228 | double dCurrentAgentAgreementValue = AutomatedAgentType.VERY_SMALL_NUMBER;
|
---|
229 |
|
---|
230 | int totalIssuesNum = agentTools.getTotalIssues(agentType);
|
---|
231 | int totalAgreementsNumber = agentTools.getTotalAgreements(agentType);
|
---|
232 |
|
---|
233 | int CurrentAgreementIdx[] = new int[totalIssuesNum];
|
---|
234 | int MaxIssueValues[] = new int[totalIssuesNum];
|
---|
235 |
|
---|
236 | for (int i = 0; i < totalIssuesNum; ++i)
|
---|
237 | {
|
---|
238 | CurrentAgreementIdx[i] = 0;
|
---|
239 | MaxIssueValues[i] = agentTools.getMaxValuePerIssue(agentType, i);
|
---|
240 | }
|
---|
241 |
|
---|
242 | // the different possible agents for the opponent side
|
---|
243 | AutomatedAgentType agentOpponentCompromise = null;
|
---|
244 | AutomatedAgentType agentOpponentLongTerm = null;
|
---|
245 | AutomatedAgentType agentOpponentShortTerm = null;
|
---|
246 |
|
---|
247 | agentOpponentCompromise = agentTools.getCurrentTurnSideAgentType(sOpponentType, AutomatedAgentsCore.COMPROMISE_TYPE_IDX);
|
---|
248 | agentOpponentLongTerm = agentTools.getCurrentTurnSideAgentType(sOpponentType, AutomatedAgentsCore.LONG_TERM_TYPE_IDX);
|
---|
249 | agentOpponentShortTerm = agentTools.getCurrentTurnSideAgentType(sOpponentType, AutomatedAgentsCore.SHORT_TERM_TYPE_IDX);
|
---|
250 |
|
---|
251 | // Now, we go over all the possible agreements,
|
---|
252 | // First, we calculate the value of each agreement for the automated agent;
|
---|
253 | // Then, we calculate the value of each such agreement for the different possible opponent types
|
---|
254 | // We only save the last value calculated.
|
---|
255 | // You can change this logic, of course...
|
---|
256 |
|
---|
257 | //In this example, we only calculate for the long term orientation
|
---|
258 | int OpponentLongTermIdx[] = new int[totalIssuesNum];
|
---|
259 | double dOpponentLongTermAgreementValue = AutomatedAgentType.VERY_SMALL_NUMBER;
|
---|
260 |
|
---|
261 | double dAutomatedAgentAgreementValue = AutomatedAgentType.VERY_SMALL_NUMBER;
|
---|
262 |
|
---|
263 | for (int i = 0; i < totalAgreementsNumber; ++i)
|
---|
264 | {
|
---|
265 | dAutomatedAgentAgreementValue = agentTools.getAgreementValue(agentType, CurrentAgreementIdx, nCurrentTurn);
|
---|
266 |
|
---|
267 | // @@ You can add here logic regarding how to calculate agreements
|
---|
268 | // based on the different possible agent types (long/short/compromise orientation
|
---|
269 | //@@EXAMPLE@@
|
---|
270 | //Calculating the agreement values for the long term opponent
|
---|
271 | //saving all the time the last calculated agreement (no logic...)
|
---|
272 |
|
---|
273 | dOpponentLongTermAgreementValue = agentTools.getAgreementValue(agentOpponentLongTerm, CurrentAgreementIdx, nCurrentTurn);
|
---|
274 | // save the indices of that offer
|
---|
275 | for (int j = 0; j < totalIssuesNum; ++j) {
|
---|
276 | OpponentLongTermIdx[j] = CurrentAgreementIdx[j];
|
---|
277 | }
|
---|
278 |
|
---|
279 | agentTools.getNextAgreement(totalIssuesNum, CurrentAgreementIdx, MaxIssueValues);// get the next agreement indices
|
---|
280 | } // end for - going over all possible agreements
|
---|
281 |
|
---|
282 | //select which offer to propose
|
---|
283 | //In this example, selecting the last offer that was calculated
|
---|
284 | if (dOpponentLongTermAgreementValue > agentTools.getCurrentTurnAutomatedAgentValue())
|
---|
285 | {
|
---|
286 | // you can save the values for later reference ($1)
|
---|
287 | agentTools.setCurrentTurnAutomatedAgentValue(dOpponentLongTermAgreementValue);
|
---|
288 | agentTools.setCurrentTurnOpponentSelectedValue(agentOpponentLongTerm.getAgreementValue(OpponentLongTermIdx, nCurrentTurn));
|
---|
289 | agentTools.setCurrentTurnAgreementString(agentType.getAgreementStr(OpponentLongTermIdx));
|
---|
290 | }
|
---|
291 |
|
---|
292 | // Now, the agent's core holds the new selected agreement
|
---|
293 |
|
---|
294 | // check the value of the offer (the one saved before, see $1...)
|
---|
295 | double dNextAgreementValue = agentTools.getSelectedOfferValue();
|
---|
296 |
|
---|
297 | // get the value of previously accepted agreement
|
---|
298 | double dAcceptedAgreementValue = agentTools.getAcceptedAgreementsValue();
|
---|
299 |
|
---|
300 | // Now, check whether the offer the agent intends to propose in the next turn is better
|
---|
301 | // for it than previously accepted agreement
|
---|
302 |
|
---|
303 | // if the value of the offer is lower than already accepted offer, don't send it...
|
---|
304 | if (dAcceptedAgreementValue >= dNextAgreementValue)
|
---|
305 | {
|
---|
306 | // default behavior is to send offer
|
---|
307 | // however... now we don't want to send the offer
|
---|
308 | // previously accepted offer has better score
|
---|
309 |
|
---|
310 | // so - don't send the offer
|
---|
311 | }
|
---|
312 |
|
---|
313 | // if decided to send offer - then send the offer
|
---|
314 | //Get the offer as string and format it as an offer
|
---|
315 | String sOffer = agentTools.getSelectedOffer();
|
---|
316 | agentTools.sendOffer(sOffer);
|
---|
317 | /********************************
|
---|
318 | * End example code
|
---|
319 | ********************************/
|
---|
320 | }
|
---|
321 |
|
---|
322 | /**
|
---|
323 | * called to calculate the values of the different possible agreements for the agent
|
---|
324 | * @param agentType - the automated agent's type
|
---|
325 | * @param nCurrentTurn - the current turn
|
---|
326 | */
|
---|
327 | public void calculateValues(AutomatedAgentType agentType, int nCurrentTurn) {
|
---|
328 | //Calculate agreements values for a given turn
|
---|
329 |
|
---|
330 | // initialization - DO NOT CHANGE
|
---|
331 | int nIssuesNum = agentTools.getTotalIssues(agentType);
|
---|
332 |
|
---|
333 | int CurrentAgreementIdx[] = new int[nIssuesNum];
|
---|
334 | int MaxIssueValues[] = new int[nIssuesNum];
|
---|
335 |
|
---|
336 | int totalAgreementsNumber = agentTools.getTotalAgreements(agentType);
|
---|
337 |
|
---|
338 | for (int i = 0; i < nIssuesNum; ++i)
|
---|
339 | {
|
---|
340 | CurrentAgreementIdx[i] = 0;
|
---|
341 | MaxIssueValues[i] = agentTools.getMaxValuePerIssue(agentType, i);
|
---|
342 | }
|
---|
343 | //end initialization
|
---|
344 |
|
---|
345 | // @@EXAMPLE@@
|
---|
346 | // Currently, the method calculates the best agreement, worst agreement
|
---|
347 | // and the utility value per agreement
|
---|
348 | /********************************
|
---|
349 | * Start example code
|
---|
350 | ********************************/
|
---|
351 | double dAgreementValue = 0;
|
---|
352 |
|
---|
353 | agentTools.initializeBestAgreement(agentType);
|
---|
354 | agentTools.initializeWorstAgreement(agentType);
|
---|
355 |
|
---|
356 | //To obtain infromation from the utility you can use getters from the AgentType class
|
---|
357 | //@@EXample@@
|
---|
358 | //Get the value of the Status Quo and Opting-Out values as time increases
|
---|
359 | double dAgreementTimeEffect = agentTools.getAgreementTimeEffect(agentType);
|
---|
360 | double dStatusQuoValue = agentTools.getSQValue(agentType);
|
---|
361 | double dOptOutValue = agentTools.getOptOutValue(agentType);
|
---|
362 |
|
---|
363 | // going over all agreements and calculating the best/worst agreement
|
---|
364 | for (int i = 0; i < totalAgreementsNumber; ++i)
|
---|
365 | {
|
---|
366 | //Note: the agreements are saved based on their indices
|
---|
367 | //At the end of the loop the indices are incremeneted
|
---|
368 | dAgreementValue = agentTools.getAgreementValue(agentType, CurrentAgreementIdx, nCurrentTurn);
|
---|
369 |
|
---|
370 | // check for best agreement
|
---|
371 | if (dAgreementValue > agentTools.getBestAgreementValue(agentType))
|
---|
372 | {
|
---|
373 | agentTools.setBestAgreementValue(agentType, dAgreementValue);
|
---|
374 |
|
---|
375 | // save agreement
|
---|
376 | agentTools.setBestAgreementIndices(agentType, CurrentAgreementIdx);
|
---|
377 | }
|
---|
378 |
|
---|
379 | // check for worst agreement
|
---|
380 | if (dAgreementValue < agentType.getWorstAgreementValue())
|
---|
381 | {
|
---|
382 | agentTools.setWorstAgreementValue(agentType, dAgreementValue);
|
---|
383 |
|
---|
384 | // save agreement
|
---|
385 | agentTools.setWorstAgreementIndices(agentType, CurrentAgreementIdx);
|
---|
386 | }
|
---|
387 |
|
---|
388 | agentTools.getNextAgreement(nIssuesNum, CurrentAgreementIdx, MaxIssueValues);// get the next agreement indices
|
---|
389 | } // end for - going over all possible agreements
|
---|
390 | /********************************
|
---|
391 | * End example code
|
---|
392 | ********************************/
|
---|
393 | }
|
---|
394 | }
|
---|