source: src/main/java/genius/core/parties/NegotiationPartyInternal.java

Last change on this file was 232, checked in by Adel Magra, 5 years ago

Created a User class that implements an elicit functionality.

Created a Top_3 Agent with the BOA framework to showcase this functionality.

File size: 12.0 KB
Line 
1package genius.core.parties;
2
3import java.util.List;
4
5import java.util.ArrayList;
6import java.util.Map;
7
8import java.io.IOException;
9import java.io.Serializable;
10
11import genius.core.AgentID;
12import genius.core.Bid;
13import genius.core.actions.Action;
14import genius.core.actions.ActionWithBid;
15import genius.core.exceptions.NegotiatorException;
16import genius.core.list.ReadonlyList;
17import genius.core.list.Tuple;
18import genius.core.persistent.DefaultPersistentDataContainer;
19import genius.core.persistent.DefaultStandardInfo;
20import genius.core.persistent.PersistentDataType;
21import genius.core.persistent.StandardInfo;
22import genius.core.persistent.StandardInfoList;
23import genius.core.repository.ParticipantRepItem;
24import genius.core.repository.ProfileRepItem;
25import genius.core.session.RepositoryException;
26import genius.core.session.Session;
27import genius.core.timeline.Timeline;
28import genius.core.uncertainty.UNCERTAINTYTYPE;
29import genius.core.uncertainty.UncertainPreferenceContainer;
30import genius.core.uncertainty.User;
31import genius.core.uncertainty.UserModel;
32import genius.core.utility.AbstractUtilitySpace;
33import genius.core.utility.UncertainAdditiveUtilitySpace;
34import genius.core.utility.UtilitySpace;
35
36/**
37 * Only for use in the core. Keeps a NegotiationParty along with core-private
38 * information.
39 *
40 * @author W.Pasman 21jul15
41 */
42public class NegotiationPartyInternal implements PartyWithUtility {
43
44 private NegotiationParty party;
45 private UtilitySpace utilitySpace;
46 private Session session;
47 /**
48 * ID that should be unique for this party.
49 */
50 private AgentID ID;
51 private SessionsInfo sessionsInfo;
52 private ProfileRepItem profileRepItem;
53 private DefaultPersistentDataContainer storageMap;
54 private ParticipantRepItem partyRepItem;
55 private UncertainPreferenceContainer uncertainModel;
56 private User user;
57
58 /**
59 * Creates a new {@link NegotiationParty} from repository items and
60 * initializes it.
61 *
62 * @param partyRepItem
63 * the party reference
64 * @param profileRepItem
65 * the profile to use for this party
66 * @param session
67 * the session in which this runs
68 * @param agentID
69 * the unique agentId to use, or null. If null, a unique ID will
70 * be generated. For all default implementations, this has either
71 * the format "ClassName" if only one such an agent exists (in
72 * case of mediator for example [mediator always has the name
73 * "mediator"]), "Party N" or it has the format "ClassName@N"
74 * with N a unique integer if multiple agents of the same type
75 * can exists.
76 * @param info
77 * a SessionsInfo object that contains info shared with other
78 * sessions.
79 * @throws RepositoryException
80 * @throws NegotiatorException
81 */
82 public NegotiationPartyInternal(ParticipantRepItem partyRepItem,
83 ProfileRepItem profileRepItem, Session session, SessionsInfo info,
84 AgentID agentID) throws RepositoryException, NegotiatorException {
85 if (agentID == null) {
86 throw new NullPointerException("agentID");
87 }
88 this.session = session;
89 this.sessionsInfo = info;
90 this.ID = agentID;
91 this.uncertainModel = uncertainModel;
92 init(partyRepItem, profileRepItem, session, agentID);
93 }
94
95 /**
96 * @return the agent implementation
97 */
98 public NegotiationParty getParty() {
99 return party;
100 }
101
102 public double getUtility(Bid bid) {
103 try {
104 // throws exception if bid incomplete or not in utility space
105 return bid == null ? 0 : utilitySpace.getUtility(bid);
106 } catch (Exception e) {
107 e.printStackTrace();
108 return 0;
109 }
110 }
111
112 public double getUtilityWithDiscount(Bid bid) {
113 if (bid == null) {
114 // utility is null if no bid
115 return 0;
116 } else if (session.getTimeline() == null) {
117 // return undiscounted utility if no timeline given
118 return getUtility(bid);
119 } else {
120 // otherwise, return discounted utility
121 return utilitySpace.discount(utilitySpace.getUtility(bid),
122 session.getTimeline().getTime());
123 }
124
125 }
126
127 /**
128 * Gets the agent's utility space.
129 *
130 * @return the agent's utility space
131 */
132 @Override
133 public UtilitySpace getUtilitySpace() {
134 return utilitySpace;
135 }
136
137 /**
138 * Gets the timeline for this agent.
139 *
140 * @return The timeline object or null if no timeline object (no time
141 * constraints) set
142 */
143 public Timeline getTimeLine() {
144 return session.getTimeline();
145 }
146
147 /**
148 * Get the session that this party is using.
149 *
150 * @return {@link Session}.
151 */
152 public Session getSession() {
153 return session;
154 }
155
156 @Override
157 public String toString() {
158 return ID.toString();
159 }
160
161 @Override
162 public int hashCode() {
163 final int prime = 31;
164 int result = 1;
165 result = prime * result + ((party == null) ? 0 : party.hashCode());
166 return result;
167 }
168
169 @Override
170 public boolean equals(Object obj) {
171 if (this == obj)
172 return true;
173 if (obj == null)
174 return false;
175 if (getClass() != obj.getClass())
176 return false;
177 NegotiationPartyInternal other = (NegotiationPartyInternal) obj;
178 if (party == null) {
179 if (other.party != null)
180 return false;
181 } else if (!party.equals(other.party))
182 return false;
183 return true;
184 }
185
186 /************************* support functions ******************/
187
188 /**
189 * Creates a new {@link NegotiationParty} from repository items and
190 * initializes it. This call is not sandboxed.
191 *
192 * @param partyRepItem
193 * Party Repository item to createFrom party from
194 * @param profileRepItem
195 * Profile Repository item to createFrom party from
196 * @return new Party
197 * @throws RepositoryException
198 * @throws java.lang.NoSuchMethodException
199 * If requested Party does not have a constructor accepting only
200 * preference profiles
201 * @throws java.lang.ClassNotFoundException
202 * If requested Party class can not be found.
203 */
204 private NegotiationParty init(ParticipantRepItem partyRepItem,
205 ProfileRepItem profileRepItem, Session session, AgentID agentID)
206 throws RepositoryException, NegotiatorException {
207 this.profileRepItem = profileRepItem;
208 this.partyRepItem = partyRepItem;
209 this.utilitySpace = profileRepItem.create();
210 if (!(utilitySpace instanceof AbstractUtilitySpace)) {
211 throw new IllegalArgumentException("utilityspace in "
212 + profileRepItem
213 + " is not extending AbstractUtilitySpace and currently not supported for negotiation parties");
214 }
215 String err = utilitySpace.isComplete();
216 if (err != null) {
217 throw new IllegalArgumentException("utilityspace in "
218 + profileRepItem + " is not ready to run:" + err);
219 }
220 long randomSeed = System.currentTimeMillis();
221 try {
222 party = partyRepItem.load();
223 } catch (Exception e) {
224 throw new RepositoryException("failed to load " + partyRepItem, e);
225 }
226
227 getPersistentData(partyRepItem, profileRepItem);
228
229 // Either a copy of the utility space is passed, or the estimate of the user model
230 if (utilitySpace instanceof UncertainAdditiveUtilitySpace)
231 {
232 this.uncertainModel = new UncertainPreferenceContainer((UncertainAdditiveUtilitySpace) utilitySpace,
233 UNCERTAINTYTYPE.PAIRWISECOMP);
234
235 UserModel pairwiseCompUserModel = this.uncertainModel.getPairwiseCompUserModel();
236
237 this.user = new User((UncertainAdditiveUtilitySpace) utilitySpace);
238 // put into NegoInfo
239
240 // estimate the utility space for any NegotiationParty for backwards compatibility
241 // For an AbstractNegotiationParty, this is overriden in the init
242 AbstractUtilitySpace passedUtilitySpace = AbstractNegotiationParty.defaultUtilitySpaceEstimator(utilitySpace.getDomain(), pairwiseCompUserModel);
243 passedUtilitySpace.setReservationValue(utilitySpace.getReservationValue());
244 passedUtilitySpace.setDiscount(((AbstractUtilitySpace) utilitySpace).getDiscountFactor());
245
246 party.init(new NegotiationInfo(passedUtilitySpace,
247 pairwiseCompUserModel, user,
248 session.getDeadlines(), session.getTimeline(), randomSeed,
249 agentID, storageMap));
250 }
251 else
252 {
253 // Otherwise, pass a copy of the utility space to the agent to prevent modification, with a null user model
254 party.init(new NegotiationInfo(
255 (AbstractUtilitySpace) utilitySpace.copy(), null, null,
256 session.getDeadlines(), session.getTimeline(), randomSeed,
257 agentID, storageMap));
258
259 }
260 return party;
261 }
262
263 /**
264 * Try to get the persistent storage data.
265 *
266 * @param partyRepItem
267 * @param profileRepItem
268 */
269 private void getPersistentData(ParticipantRepItem partyRepItem,
270 ProfileRepItem profileRepItem) {
271 PersistentDataType type = sessionsInfo.getPersistentDataType();
272 Serializable data = null;
273 switch (type) {
274 case SERIALIZABLE:
275 case STANDARD:
276 try {
277 data = sessionsInfo.getStorage(partyRepItem, profileRepItem);
278 } catch (Exception e) {
279 e.printStackTrace();
280 }
281 break;
282 default:
283 data = null;
284 break;
285 }
286 if (data == null && type == PersistentDataType.STANDARD) {
287 data = new DefaultStandardInfoList();
288 }
289
290 storageMap = new DefaultPersistentDataContainer(data, type);
291 }
292
293 /**
294 * Saves the persistent storage , see {@link SessionsInfo}.
295 *
296 * @param actions
297 * the actions that have been done in the last session. This is
298 * added to the data first, if possible.
299 * @param agreement
300 * agreement information: Bid and utility of the bid for this
301 * party. Null if no agreement was reached.
302 * @profiles a list of [AgentID, profile-of-agent] names.
303 *
304 * @throws IOException
305 */
306 public void saveStorage(List<Action> actions, Map<String, String> profiles,
307 Tuple<Bid, Double> agreement) throws IOException {
308 if (storageMap.getPersistentDataType() == PersistentDataType.DISABLED)
309 return;
310 if (storageMap.getPersistentDataType() == PersistentDataType.STANDARD) {
311 // update the data. bit hacky
312 String startingagent = actions.isEmpty() ? "-"
313 : actions.get(0).getAgent().toString();
314 DefaultStandardInfoList data = (DefaultStandardInfoList) storageMap
315 .get();
316 List<Tuple<String, Double>> utilities = new ArrayList<>();
317 for (Action action : actions) {
318 if (action instanceof ActionWithBid) {
319 utilities.add(new Tuple<String, Double>(
320 action.getAgent().toString(),
321 getUtility(((ActionWithBid) action).getBid())));
322 }
323 }
324
325 data.addInternal(new DefaultStandardInfo(profiles, startingagent,
326 utilities, session.getDeadlines(), agreement));
327 }
328
329 sessionsInfo.saveStorage(storageMap.get(), partyRepItem,
330 profileRepItem);
331 }
332
333 /**
334 *
335 * @return true iff htis party is a {@link Mediator}.
336 */
337 public boolean isMediator() {
338 return party instanceof Mediator;
339 }
340
341 public boolean isUncertain() {
342 if (uncertainModel != null)
343 return true;
344 else
345 return false;
346 }
347
348 @Override
349 public AgentID getID() {
350 return ID;
351 }
352
353 /**
354 *
355 * @return {@link UncertainPreferenceContainer} or null if the profile was
356 * not an {@link UncertainProfileRepItem}.
357 */
358 public UncertainPreferenceContainer getUncertainModel() {
359 return uncertainModel;
360 }
361
362 /**
363 *
364 * @return {@link User} or null if the profile was
365 * not an {@link User}.
366 */
367 public User getUser() {
368 return user;
369 }
370
371 /**
372 * Inner class, to prevent others casting to this. static to prevent
373 * serializer to serialize the superclass.
374 */
375 @SuppressWarnings("serial")
376 static class DefaultStandardInfoList extends ReadonlyList<StandardInfo>
377 implements StandardInfoList, Serializable {
378
379 public DefaultStandardInfoList(List<StandardInfo> infos) {
380 super(infos);
381 }
382
383 public DefaultStandardInfoList() {
384 super(new ArrayList<StandardInfo>());
385 }
386
387 /**
388 * backdoor for the usual {@link #add(StandardInfo)} this can be called
389 * only from the encapculating class.
390 *
391 * @param e
392 * the item to add to the list.
393 */
394 public void addInternal(StandardInfo e) {
395 list.add(e);
396 }
397 }
398
399}
Note: See TracBrowser for help on using the repository browser.