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

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

Initial import : Genius 9.0.0

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