source: src/main/java/genius/core/parties/AbstractNegotiationParty.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: 9.4 KB
Line 
1package genius.core.parties;
2
3import java.util.HashMap;
4import java.util.Random;
5
6import genius.core.AgentID;
7import genius.core.Bid;
8import genius.core.Deadline;
9import genius.core.Domain;
10import genius.core.actions.Action;
11import genius.core.actions.Inform;
12import genius.core.issue.Issue;
13import genius.core.issue.IssueDiscrete;
14import genius.core.issue.IssueInteger;
15import genius.core.issue.IssueReal;
16import genius.core.issue.Value;
17import genius.core.issue.ValueInteger;
18import genius.core.issue.ValueReal;
19import genius.core.persistent.PersistentDataContainer;
20import genius.core.protocol.MultilateralProtocol;
21import genius.core.protocol.StackedAlternatingOffersProtocol;
22import genius.core.timeline.TimeLineInfo;
23import genius.core.uncertainty.AdditiveUtilitySpaceFactory;
24import genius.core.uncertainty.BidRanking;
25import genius.core.uncertainty.User;
26import genius.core.uncertainty.UserModel;
27import genius.core.utility.AbstractUtilitySpace;
28
29/**
30 * A basic implementation of the {@link NegotiationParty} interface. This basic
31 * implementation sets up some common variables for you.
32 *
33 * @author Tim Baarslag
34 * @author David Festen
35 * @author Reyhan (The random bid generator)
36 */
37public abstract class AbstractNegotiationParty implements NegotiationParty
38{
39 /**
40 * Time line used by the party if time deadline is set.
41 */
42 protected TimeLineInfo timeline;// should be final after init
43
44 /**
45 * Random seed used by this party.
46 */
47 protected Random rand;// should be final after init
48
49 /**
50 * utility space used by this party (set in constructor).
51 * Used directly by lots of implementations.
52 */
53 protected AbstractUtilitySpace utilitySpace;// should be final after init
54
55 /** Instead of a {@link AbstractUtilitySpace}, the agent may receive a user model (i.e. uncertain preferences). */
56 protected UserModel userModel;
57
58 /**
59 * Under preference uncertainty, the agent will receive its corresponding user.
60 */
61 protected User user;
62 /**
63 * Last received action, or null
64 */
65 private Action lastReceivedAction = null;
66
67 private int numberOfParties = -1;
68
69 private NegotiationInfo info;
70
71 @Override
72 public void init(NegotiationInfo info)
73 {
74 this.info = info;
75 this.rand = new Random(info.getRandomSeed());
76 this.timeline = info.getTimeline();
77 this.userModel = info.getUserModel();
78 this.user = info.getUser();
79
80 // If the agent has uncertain preferences, the utility space provided to the agent by Genius will be null.
81 // In that case, the utility space is estimated with a simple heuristic so that any agent can
82 // deal with preference uncertainty. This method can be overridden by the agent to provide better estimates.
83 if (hasPreferenceUncertainty())
84 {
85 AbstractUtilitySpace passedUtilitySpace = info.getUtilitySpace();
86 AbstractUtilitySpace estimatedUtilitySpace = estimateUtilitySpace();
87 estimatedUtilitySpace.setReservationValue(passedUtilitySpace.getReservationValue());
88 estimatedUtilitySpace.setDiscount(passedUtilitySpace.getDiscountFactor());
89 info.setUtilSpace(estimatedUtilitySpace);
90 }
91 // Use either the provided utility space, or the hotswapped estimated utility space
92 this.utilitySpace = info.getUtilitySpace();
93 }
94
95 /**
96 * Returns an estimate of the utility space given uncertain preferences specified by the user model.
97 * By default, the utility space is estimated with a simple counting heuristic so that any agent can
98 * deal with preference uncertainty.
99 *
100 * This method can be overridden by the agent to provide better estimates.
101 */
102 public AbstractUtilitySpace estimateUtilitySpace()
103 {
104 return defaultUtilitySpaceEstimator(getDomain(), userModel);
105 }
106
107 /**
108 * Provides a simple estimate of a utility space given the partial preferences of a {@link UserModel}.
109 * This is constructed as a static funtion so that other agents (that are not an {@link AbstractNegotiationParty})
110 * can also benfit from this functionality.
111 */
112 public static AbstractUtilitySpace defaultUtilitySpaceEstimator(Domain domain, UserModel um)
113 {
114 AdditiveUtilitySpaceFactory factory = new AdditiveUtilitySpaceFactory(domain);
115 BidRanking bidRanking = um.getBidRanking();
116 factory.estimateUsingBidRanks(bidRanking);
117 return factory.getUtilitySpace();
118 }
119
120 /**
121 * Returns the domain defined in either the utilityspace or user model of the agent.
122 */
123 public Domain getDomain()
124 {
125 if (utilitySpace != null)
126 return utilitySpace.getDomain();
127 return userModel.getDomain();
128 }
129
130 /**
131 * Generates a random bid which will be generated using this.utilitySpace.
132 *
133 * @return A random bid
134 */
135 protected Bid generateRandomBid() {
136 try {
137 // Pairs <issue number, chosen value string>
138 HashMap<Integer, Value> values = new HashMap<Integer, Value>();
139
140 // For each issue, put a random value
141 for (Issue currentIssue : utilitySpace.getDomain().getIssues()) {
142 values.put(currentIssue.getNumber(), getRandomValue(currentIssue));
143 }
144
145 // return the generated bid
146 return new Bid(utilitySpace.getDomain(), values);
147
148 } catch (Exception e) {
149
150 // return empty bid if an error occurred
151 return new Bid(utilitySpace.getDomain());
152 }
153 }
154
155 /**
156 * Gets a random value for the given issue.
157 *
158 * @param currentIssue
159 * The issue to generate a random value for
160 * @return The random value generated for the issue
161 * @throws Exception
162 * if the issues type is not Discrete, Real or Integer.
163 */
164 protected Value getRandomValue(Issue currentIssue) throws Exception {
165
166 Value currentValue;
167 int index;
168
169 switch (currentIssue.getType()) {
170 case DISCRETE:
171 IssueDiscrete discreteIssue = (IssueDiscrete) currentIssue;
172 index = (rand.nextInt(discreteIssue.getNumberOfValues()));
173 currentValue = discreteIssue.getValue(index);
174 break;
175 case REAL:
176 IssueReal realIss = (IssueReal) currentIssue;
177 index = rand.nextInt(realIss.getNumberOfDiscretizationSteps()); // check
178 // this!
179 currentValue = new ValueReal(
180 realIss.getLowerBound() + (((realIss.getUpperBound() - realIss.getLowerBound()))
181 / (realIss.getNumberOfDiscretizationSteps())) * index);
182 break;
183 case INTEGER:
184 IssueInteger integerIssue = (IssueInteger) currentIssue;
185 index = rand.nextInt(integerIssue.getUpperBound() - integerIssue.getLowerBound() + 1);
186 currentValue = new ValueInteger(integerIssue.getLowerBound() + index);
187 break;
188 default:
189 throw new Exception("issue type " + currentIssue.getType() + " not supported");
190 }
191
192 return currentValue;
193 }
194
195 /**
196 * Gets the utility for the given bid.
197 *
198 * @param bid
199 * The bid to get the utility for
200 * @return A double value between [0, 1] (inclusive) that represents the
201 * bids utility
202 */
203 public double getUtility(Bid bid) {
204 try {
205 // throws exception if bid incomplete or not in utility space
206 return bid == null ? 0 : utilitySpace.getUtility(bid);
207 } catch (Exception e) {
208 e.printStackTrace();
209 return 0;
210 }
211 }
212
213 /**
214 * Gets the time discounted utility for the given bid.
215 *
216 * @param bid
217 * The bid to get the utility for
218 * @return A double value between [0, 1] (inclusive) that represents the
219 * bids utility
220 */
221 public double getUtilityWithDiscount(Bid bid) {
222 if (bid == null) {
223 // utility is null if no bid
224 return 0;
225 } else if (timeline == null) {
226 // return undiscounted utility if no timeline given
227 return getUtility(bid);
228 } else {
229 // otherwise, return discounted utility
230 return utilitySpace.getUtilityWithDiscount(bid, timeline);
231 }
232 }
233
234 /**
235 * Gets this agent's utility space.
236 *
237 * @return The utility space
238 */
239 public final AbstractUtilitySpace getUtilitySpace() {
240 return utilitySpace;
241 }
242
243 /**
244 * Gets this agent's time line.
245 *
246 * @return The time line for this agent
247 */
248 public TimeLineInfo getTimeLine() {
249 return timeline;
250 }
251
252 /**
253 * Returns a human readable string representation of this party.
254 *
255 * @return the string representation of party id
256 */
257 @Override
258 public String toString() {
259 return info.getAgentID().toString();
260 }
261
262 @Override
263 public void receiveMessage(AgentID sender, Action act) {
264 lastReceivedAction = act;
265 if (act instanceof Inform) {
266 numberOfParties = (Integer) ((Inform) act).getValue();
267 }
268 }
269
270 /**
271 *
272 * @return last received {@link Action} or null if nothing received yet.
273 */
274 public Action getLastReceivedAction() {
275 return lastReceivedAction;
276 }
277
278 public int getNumberOfParties() {
279 if (numberOfParties == -1) {
280 System.out.println("Make sure that you call the super class in receiveMessage() method.");
281 }
282 return numberOfParties;
283 }
284
285 final public AgentID getPartyId() {
286 return info.getAgentID();
287 }
288
289 /**
290 * @return Whether the agent's preference profile has preference uncertainty enabled
291 */
292 public boolean hasPreferenceUncertainty()
293 {
294 return (userModel != null);
295 }
296
297 @Override
298 public Class<? extends MultilateralProtocol> getProtocol() {
299 return StackedAlternatingOffersProtocol.class;
300 }
301
302 @Override
303 public HashMap<String, String> negotiationEnded(Bid acceptedBid) {
304 return null;
305 }
306
307 /**
308 * @return persistent data
309 */
310 public PersistentDataContainer getData() {
311 return info.getPersistentData();
312 }
313
314 public Deadline getDeadlines() {
315 return info.getDeadline();
316 }
317
318 public UserModel getUserModel() {
319 return userModel;
320 }
321
322}
Note: See TracBrowser for help on using the repository browser.