[126] | 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 | }
|
---|