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

Last change on this file was 160, checked in by Tim Baarslag, 6 years ago

Cleanup of agent names to improve the readability of the party repository

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