source: src/main/java/parties/feedbackmediator/FeedbackMediator.java@ 346

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

#41 ROLL BACK of rev.126 . So this version is equal to rev. 125

File size: 8.3 KB
Line 
1package parties.feedbackmediator;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import genius.core.AgentID;
7import genius.core.Bid;
8import genius.core.DeadlineType;
9import genius.core.Feedback;
10import genius.core.actions.Action;
11import genius.core.actions.GiveFeedback;
12import genius.core.actions.OfferForFeedback;
13import genius.core.issue.Issue;
14import genius.core.issue.Value;
15import genius.core.parties.AbstractNegotiationParty;
16import genius.core.parties.Mediator;
17import genius.core.parties.NegotiationInfo;
18import genius.core.parties.NegotiationParty;
19import genius.core.protocol.MediatorFeedbackBasedProtocol;
20import genius.core.protocol.MultilateralProtocol;
21import parties.feedbackmediator.partialopponentmodel.PartialPreferenceModels;
22
23/**
24 * Implementation of a mediator that uses feedback to make a (partial)
25 * preference graph of the participating parties offers.
26 * <p/>
27 * This class was adapted from Reyhan's parties.SmartMediatorOnlyFeedback class
28 * (see svn history for details about that class), and adapted to fit into the
29 * new framework.
30 *
31 * @author W.Pasman (compatibility fixes)
32 * @author David Festen
33 * @author Reyhan (Orignal code)
34 */
35public class FeedbackMediator extends AbstractNegotiationParty implements Mediator {
36
37 private List<GiveFeedback> currentFeedbackList;
38 /**
39 * The current bid
40 */
41 private Bid currentBid;
42 /**
43 * The bid that is offered in the previous round
44 */
45 private Bid lastBid;
46 /**
47 * Keeping the last accepted bid by all parties
48 */
49 private Bid lastAcceptedBid;
50 /**
51 * The model is learned by the mediator during the negotiation
52 */
53 private int roundNumber;
54
55 /**
56 * The index number of the issue we are currently modifying.
57 */
58 private int currentIndex;
59 private PartialPreferenceModels preferenceList;
60
61 @Override
62 public void init(NegotiationInfo info) {
63 super.init(info);
64 lastAcceptedBid = null;
65 currentBid = null;
66 lastBid = null;
67 currentFeedbackList = new ArrayList<GiveFeedback>();
68 }
69
70 public Bid getLastAcceptedBid() {
71 return lastAcceptedBid;
72 }
73
74 /**
75 * When this class is called, it is expected that the Party chooses one of
76 * the actions from the possible action list and returns an instance of the
77 * chosen action. This class is only called if this {@link NegotiationParty}
78 * is in the
79 * {@link genius.core.protocol.Protocol#getRoundStructure(java.util.List, negotiator.session.Session)}
80 * .
81 *
82 * @param possibleActions
83 * List of all actions possible.
84 * @return The chosen action
85 */
86 @Override
87 public Action chooseAction(List<Class<? extends Action>> possibleActions) {
88 roundNumber++;
89
90 if (currentBid == null) {
91 /*
92 * initially generate a random bid and create the preference model
93 */
94 currentBid = generateRandomBid();
95 lastBid = new Bid(currentBid);
96 return (new OfferForFeedback(getPartyId(), currentBid));
97 } else {
98 // we get here from round 2 onwards.
99 if (roundNumber <= 2) {
100 preferenceList = new PartialPreferenceModels(currentBid, currentFeedbackList);
101 } else {
102 /*
103 * Start updating the model from round 3 onward. The feedback on
104 * the first bid makes no sense, as agents need to have 2 bids
105 * before comparing them is possible.
106 */
107 preferenceList.updateIssuePreferenceList(currentIndex, lastBid.getValue(currentIndex),
108 currentBid.getValue(currentIndex), currentFeedbackList);
109 lastBid = currentBid;
110 }
111
112 currentFeedbackList.clear();
113 currentBid = modifyLastBid();
114
115 if (currentBid == null) {
116 throw new NullPointerException("internal error: currentBid=null!");
117 }
118
119 }
120
121 return (new OfferForFeedback(getPartyId(), currentBid));
122 }
123
124 /**
125 * This method is called when an observable action is performed. Observable
126 * actions are defined in
127 * {@link MultilateralProtocol#getActionListeners(java.util.List)}
128 *
129 * @param sender
130 * The initiator of the action
131 * @param action
132 * The action performed by the sender
133 */
134 @Override
135 public void receiveMessage(AgentID sender, Action action) {
136 if (action instanceof GiveFeedback)
137 currentFeedbackList.add((GiveFeedback) action);
138 }
139
140 private Bid modifyLastBid() {
141
142 Bid modifiedBid = lastBid;
143
144 // double epsilon = (double) (getTotalRoundOrTime() - getRound() - 1) /
145 // getTotalRoundOrTime();
146 double epsilon = getNormalizedRound();
147 Value selectedValue = null;
148
149 // if ((getRound() <= ((double) getTotalRoundOrTime() / 2)) || (epsilon
150 // > Math.random()))
151 if (epsilon > 0.5 || epsilon > rand.nextDouble()) {
152 selectedValue = searchForNewValue();
153 }
154
155 if (selectedValue == null) {
156 selectedValue = getNashValue();
157 }
158
159 if (selectedValue == null)
160 return null;
161
162 modifiedBid = modifiedBid.putValue(currentIndex, selectedValue);
163 return modifiedBid;
164
165 }
166
167 /**
168 * @return round number between 0..1 or 1 if no round deadline set
169 */
170 private double getNormalizedRound() {
171 if (getDeadlines().getType() != DeadlineType.ROUND) {
172 return 0d;
173 }
174
175 double totalRounds = getDeadlines().getValue();
176 double currentRound = roundNumber;
177 return (totalRounds - currentRound - 1d) / totalRounds;
178 }
179
180 private Value searchForNewValue() {
181
182 List<Issue> issues = utilitySpace.getDomain().getIssues();
183 Issue currentIssue;
184 Value newValue;
185
186 ArrayList<Issue> checkedIssues = new ArrayList<Issue>(issues);
187 int checkID;
188 do {
189 checkID = rand.nextInt(checkedIssues.size());
190 currentIssue = checkedIssues.get(checkID);
191 currentIndex = currentIssue.getNumber();
192 newValue = preferenceList.getMissingValue(currentIndex);
193 if (newValue != null)
194 return newValue;
195 checkedIssues.remove(checkID);
196 } while (checkedIssues.size() > 0);
197
198 checkedIssues = new ArrayList<Issue>(issues);
199 do {
200 checkID = rand.nextInt(checkedIssues.size());
201 currentIssue = checkedIssues.get(checkID);
202 currentIndex = currentIssue.getNumber();
203
204 for (Value incomparable : preferenceList.getIncomparableValues(currentIndex,
205 lastBid.getValue(currentIndex))) {
206 if (incomparable != null)
207 return incomparable;
208 }
209 checkedIssues.remove(checkID);
210
211 } while (checkedIssues.size() > 0);
212
213 checkedIssues = new ArrayList<Issue>(issues);
214 do {
215 checkID = rand.nextInt(checkedIssues.size());
216 currentIssue = checkedIssues.get(checkID);
217 currentIndex = currentIssue.getNumber();
218
219 ArrayList<Value> allValues = preferenceList.getAllPossibleValues(currentIndex);
220 do {
221 newValue = allValues.get(rand.nextInt(allValues.size()));
222 if ((!newValue.equals(lastBid.getValue(currentIndex)))
223 && (preferenceList.mayImproveAll(currentIndex, lastBid.getValue(currentIndex), newValue)))
224 return newValue;
225 allValues.remove(newValue);
226 } while (allValues.size() > 0);
227
228 checkedIssues.remove(checkID);
229
230 } while (checkedIssues.size() > 0);
231
232 return null;
233 }
234
235 private Value getNashValue() {
236 List<Issue> issues = utilitySpace.getDomain().getIssues();
237 Issue currentIssue;
238 Value newValue;
239
240 ArrayList<Issue> checkedIssues = new ArrayList<Issue>(issues);
241 int checkID;
242
243 do {
244 checkID = rand.nextInt(checkedIssues.size());
245 currentIssue = checkedIssues.get(checkID);
246 currentIndex = currentIssue.getNumber();
247
248 ArrayList<Value> allNashValues = preferenceList.getNashValues(currentIndex);
249 do {
250 newValue = allNashValues.get(rand.nextInt(allNashValues.size()));
251
252 // if ((newValue!=lastBid.getValue(currentIndex)))
253 if ((!newValue.equals(lastBid.getValue(currentIndex)))
254 && (preferenceList.mayImproveAll(currentIndex, lastBid.getValue(currentIndex), newValue)))
255 return newValue;
256 allNashValues.remove(newValue);
257 } while (allNashValues.size() > 0);
258
259 checkedIssues.remove(checkID);
260
261 } while (checkedIssues.size() > 0);
262
263 return newValue;
264
265 }
266
267 /**
268 *
269 * @return just the Feedback elements of the currentFeedbacklist.
270 */
271 private List<Feedback> currentFeedbackList() {
272 List<Feedback> feedbacklist = new ArrayList<>();
273 for (GiveFeedback feedback : currentFeedbackList) {
274 feedbacklist.add(feedback.getFeedback());
275 }
276 return feedbacklist;
277 }
278
279 @Override
280 public Class<? extends MultilateralProtocol> getProtocol() {
281 return MediatorFeedbackBasedProtocol.class;
282 }
283
284 @Override
285 public String getDescription() {
286 return "Feedback Mediator";
287 }
288}
Note: See TracBrowser for help on using the repository browser.