source: src/main/java/genius/core/Agent.java@ 58

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

@21 refactoring improve code in hardheaded frequency model

File size: 12.2 KB
Line 
1package genius.core;
2
3import java.io.Serializable;
4import java.util.Date;
5import java.util.HashMap;
6
7import genius.core.actions.Action;
8import genius.core.exceptions.Warning;
9import genius.core.protocol.BilateralAtomicNegotiationSession;
10import genius.core.timeline.TimeLineInfo;
11import genius.core.timeline.Timeline;
12import genius.core.tournament.VariablesAndValues.AgentParamValue;
13import genius.core.tournament.VariablesAndValues.AgentParameterVariable;
14import genius.core.utility.AbstractUtilitySpace;
15import genius.core.utility.AdditiveUtilitySpace;
16import genius.core.utility.DataObjects;
17
18/**
19 * A basic negotiation agent. You might want to consider using the BOA
20 * framework.
21 *
22 * @author Dmytro Tykhonov
23 * @author W.Pasman
24 */
25public abstract class Agent extends AgentAdapter {
26 /**
27 *
28 */
29 private static final long serialVersionUID = -8831662293608224409L;
30 /**
31 * Technical remarks.
32 *
33 * It would have been much more flexible and cleaner if Agent were an
34 * interface. Unfortunately this was never done and we are now stuck in a
35 * historic, de facto 'standard' that we can not easily change. #915.
36 *
37 */
38
39 /** ID of the agent as assigned by the protocol. */
40 private AgentID agentID;
41 /** Name of the name as set by the method setName. */
42 private String fName = null;
43 /** Preference profile of the agent as assigned by the tournamentrunner. */
44 public AbstractUtilitySpace utilitySpace;
45 /**
46 * Date object specifying when the negotiation started.
47 *
48 * @deprecated Use timeline instead.
49 */
50 @Deprecated
51 public Date startTime;
52 /**
53 * Total time which an agent has to complete the negotiation.
54 *
55 * @deprecated Use timeline instead.
56 */
57 @Deprecated
58 public Integer totalTime; // total time to complete entire nego, in seconds.
59 /** Use timeline for everything time-related. */
60 public TimeLineInfo timeline;
61 /**
62 * A session can be repeated multiple times. This parameter specifies which
63 * match we are at in the range [0, totalMatches - 1].
64 */
65 public int sessionNr;
66 /**
67 * Amount of repetitions of this session, how many times this session is
68 * repeated in total.
69 */
70 public int sessionsTotal;
71 /**
72 * Reference to protocol which is set when experimental setup is enabled.
73 * Usually null, except in some experimental setups.
74 */
75 public BilateralAtomicNegotiationSession fNegotiation;
76 /**
77 * Parameters given to the agent which may be specified in the agent.
78 *
79 * @deprecated
80 */
81 @Deprecated
82 protected HashMap<AgentParameterVariable, AgentParamValue> parametervalues;
83 /**
84 * Parameters given to the agent which may be specified in the agent
85 * repository.
86 */
87 protected StrategyParameters strategyParameters;
88
89 // /**
90 // * A static instance (shared by all UtilitySpace instances) which handles
91 // * saving and loading data for the agents. We set "DataObjects" to be the
92 // * source folder that saves the data.
93 // */
94 // private static DataObjects dataObjects = new DataObjects("DataObjects");
95
96 /**
97 * Empty constructor used to initialize the agent. Later on internalInit is
98 * called to set all variables.
99 */
100 public Agent() {
101 this.strategyParameters = new StrategyParameters();
102 }
103
104 /**
105 * @return version of the agent.
106 */
107 public String getVersion() {
108 return "unknown";
109 };
110
111 /**
112 * This method is called by the protocol every time before starting a new
113 * session after the internalInit method is called. User can override this
114 * method.
115 */
116 public void init() {
117 }
118
119 /**
120 * This method is called by the protocol to initialize the agent with a new
121 * session information.
122 *
123 * @param startTimeP
124 * @param totalTimeP
125 * @param timeline
126 * keeping track of the time in the negotiation.
127 * @param us
128 * utility space of the agent for the session.
129 * @param params
130 * parameters of the agent.
131 */
132 public final void internalInit(int sessionNr, int sessionsTotal,
133 Date startTimeP, Integer totalTimeP, TimeLineInfo timeline,
134 AbstractUtilitySpace us,
135 HashMap<AgentParameterVariable, AgentParamValue> params,
136 AgentID id) {
137 startTime = startTimeP;
138 totalTime = totalTimeP;
139 this.timeline = timeline;
140 this.sessionNr = sessionNr;
141 this.sessionsTotal = sessionsTotal;
142 this.agentID = id;
143 utilitySpace = us;
144 parametervalues = params;
145 if (parametervalues != null && !parametervalues.isEmpty())
146 System.out.println("Agent " + getName()
147 + " initted with parameters " + parametervalues);
148 return;
149 }
150
151 /**
152 * informs you which action the opponent did
153 *
154 * @param opponentAction
155 * the opponent {@link Action}
156 */
157 public void ReceiveMessage(Action opponentAction) {
158 return;
159 }
160
161 /**
162 * this function is called after ReceiveMessage, with an Offer-action.
163 *
164 * @return (should return) the bid-action the agent wants to make.
165 */
166 public abstract Action chooseAction();
167
168 /**
169 * @return name of the agent.
170 */
171 public String getName() {
172 return fName;
173 }
174
175 /**
176 * @return a type of parameters used solely by the BayesianAgent.
177 * @deprecated
178 */
179 @Deprecated
180 public HashMap<AgentParameterVariable, AgentParamValue> getParameterValues() {
181 return parametervalues;
182 }
183
184 /**
185 * Sets the name of the agent to the given name.
186 *
187 * @param pName
188 * to which the agent's name must be set.
189 */
190 public final void setName(String pName) {
191 if (this.fName == null)
192 this.fName = pName;
193 return;
194 }
195
196 /**
197 * A convenience method to get the discounted utility of a bid. This method
198 * will take discount factors into account (if any), using the status of the
199 * current {@link #timeline}.
200 *
201 * @see AdditiveUtilitySpace
202 * @param bid
203 * of which we are interested in the utility.
204 * @return discounted utility of the given bid.
205 */
206 public double getUtility(Bid bid) {
207 return utilitySpace.getUtilityWithDiscount(bid, timeline);
208 }
209
210 /**
211 * Let the agent wait in case of a time-based protocol. Example:<br>
212 * sleep(0.1) will let the agent sleep for 10% of the negotiation time (as
213 * defined by the {@link Timeline}).
214 *
215 * @param fraction
216 * should be between 0 and 1.
217 */
218 public void sleep(double fraction) {
219 if (timeline.getType().equals(Timeline.Type.Time)) {
220 long sleep = (long) ((timeline.getTotalTime() * 1000) * fraction);
221 try {
222 Thread.sleep(sleep);
223 } catch (InterruptedException e) {
224 e.printStackTrace();
225 }
226 }
227 }
228
229 /**
230 * Method which informs an agent about the utility it received.
231 *
232 * @param dUtil
233 * discounted utility of previous session round.
234 */
235 public void endSession(NegotiationResult dUtil) {
236 }
237
238 /**
239 * @return ID of the agent as assigned by the protocol.
240 */
241 public AgentID getAgentID() {
242 return agentID;
243 }
244
245 public StrategyParameters getStrategyParameters() {
246 return strategyParameters;
247 }
248
249 /**
250 * Indicates what negotiation settings are supported by an agent, such as
251 * linear or non-linear utility spaces. The default is non-restrictive, but
252 * can be overriden if the agent can only be used in certain settings.
253 */
254 public SupportedNegotiationSetting getSupportedNegotiationSetting() {
255 return SupportedNegotiationSetting.getDefault();
256 }
257
258 /**
259 * Used to parse parameters presented in the agent repository. The
260 * particular implementation below parses parameters such as time=0.9;e=1.0.
261 *
262 * @param variables
263 * @throws Exception
264 */
265 public void parseStrategyParameters(String variables) throws Exception {
266 if (variables != null) {
267 String[] vars = variables.split(";");
268 for (String var : vars) {
269 String[] expression = var.split("=");
270 if (expression.length == 2) {
271 strategyParameters.addVariable(expression[0],
272 expression[1]);
273 } else {
274 throw new Exception(
275 "Expected variablename and result but got "
276 + expression.length + " elements. "
277 + "Correct in XML or overload the method.");
278 }
279 }
280 }
281 }
282
283 /**
284 * @return which session we are in. If a session is first started it is
285 * zero.
286 */
287 public int getSessionNumber() {
288 return sessionNr;
289 }
290
291 /**
292 * @return total sessions. How many times the session is repeated.
293 */
294 public int getSessionsTotal() {
295 return sessionsTotal;
296 }
297
298 /**
299 * Saves information (dataToSave) about the current session for future
300 * loading by the agent, when negotiating again with the specific preference
301 * profile referred by "filename".
302 *
303 * Important: 1) The dataToSave must implement {@link Serializable}
304 * interface. This is to make sure the data can be saved. 2) If the function
305 * is used more than once regarding the same preference profile, it will
306 * override the data saved from last session with the new Object
307 * "dataToSave".
308 *
309 * @param dataToSave
310 * the data regarding the last session that "agent" wants to
311 * save.
312 * @return true if dataToSave is successfully saved, false otherwise.
313 */
314 final protected boolean saveSessionData(Serializable dataToSave) {
315 String agentClassName = getUniqueIdentifier();
316 try { // utility may be null
317 String prefProfName = utilitySpace.getFileName();
318 return DataObjects.getInstance().saveData(dataToSave,
319 agentClassName, prefProfName);
320 } catch (Exception e) {
321 new Warning("Exception during saving data for agent "
322 + agentClassName + " : " + e.getMessage());
323 e.printStackTrace();
324 return false;
325 }
326 }
327
328 /**
329 * @return unique identifier of the Agent object.
330 */
331 protected String getUniqueIdentifier() {
332 return getClass().getName();
333 }
334
335 /**
336 * Loads the {@link Serializable} data for the agent. If the function
337 * "saveSessionData" wasn't used for this type of agent with the current
338 * preference profile of the agent - the data will be null. Otherwise, it
339 * will load the saved data of the agent for this specific preference
340 * profile.
341 *
342 * @return the {@link Serializable} data if the load is successful, null
343 * otherwise.
344 */
345 final protected Serializable loadSessionData() {
346
347 String agentClassName = getUniqueIdentifier();
348 try { // utility may be null
349 String prefProfName = utilitySpace.getFileName();
350 return DataObjects.getInstance().loadData(agentClassName,
351 prefProfName);
352 } catch (Exception e) {
353 new Warning("Exception during loading data for agent "
354 + agentClassName + " : " + e.getMessage());
355 e.printStackTrace();
356 return null;
357 }
358 }
359
360 @Override
361 public Agent getAgent() {
362 return this;
363 }
364
365 /***
366 * WARNING hashCode and equals are incomplete because we ignore
367 * {@link AgentAdapter} {@link BilateralAtomicNegotiationSession}
368 * {@link StrategyParameters} {@link TimeLineInfo}
369 * {@link AbstractUtilitySpace} because they did not implement
370 * equals/hashcode.
371 */
372 @Override
373 public int hashCode() {
374 final int prime = 31;
375 int result = 1;
376 result = prime * result + ((agentID == null) ? 0 : agentID.hashCode());
377 result = prime * result + ((fName == null) ? 0 : fName.hashCode());
378 result = prime * result + sessionNr;
379 result = prime * result + sessionsTotal;
380 result = prime * result
381 + ((startTime == null) ? 0 : startTime.hashCode());
382 result = prime * result
383 + ((totalTime == null) ? 0 : totalTime.hashCode());
384 return result;
385 }
386
387 @Override
388 public boolean equals(Object obj) {
389 if (this == obj)
390 return true;
391 if (obj == null)
392 return false;
393 if (getClass() != obj.getClass())
394 return false;
395 Agent other = (Agent) obj;
396 if (agentID == null) {
397 if (other.agentID != null)
398 return false;
399 } else if (!agentID.equals(other.agentID))
400 return false;
401 if (fName == null) {
402 if (other.fName != null)
403 return false;
404 } else if (!fName.equals(other.fName))
405 return false;
406 if (sessionNr != other.sessionNr)
407 return false;
408 if (sessionsTotal != other.sessionsTotal)
409 return false;
410 if (startTime == null) {
411 if (other.startTime != null)
412 return false;
413 } else if (!startTime.equals(other.startTime))
414 return false;
415 if (totalTime == null) {
416 if (other.totalTime != null)
417 return false;
418 } else if (!totalTime.equals(other.totalTime))
419 return false;
420 return true;
421 }
422
423}
Note: See TracBrowser for help on using the repository browser.