1 | package parties.feedbackmediator;
|
---|
2 |
|
---|
3 | import java.util.ArrayList;
|
---|
4 | import java.util.List;
|
---|
5 | import java.util.Random;
|
---|
6 |
|
---|
7 | import genius.core.AgentID;
|
---|
8 | import genius.core.Bid;
|
---|
9 | import genius.core.Feedback;
|
---|
10 | import genius.core.Vote;
|
---|
11 | import genius.core.actions.Action;
|
---|
12 | import genius.core.actions.EndNegotiationWithAnOffer;
|
---|
13 | import genius.core.actions.GiveFeedback;
|
---|
14 | import genius.core.actions.NoAction;
|
---|
15 | import genius.core.actions.OfferForFeedback;
|
---|
16 | import genius.core.issue.Issue;
|
---|
17 | import genius.core.issue.Value;
|
---|
18 | import genius.core.parties.AbstractNegotiationParty;
|
---|
19 | import genius.core.parties.Mediator;
|
---|
20 | import genius.core.parties.NegotiationInfo;
|
---|
21 | import genius.core.protocol.DefaultMultilateralProtocol;
|
---|
22 | import genius.core.protocol.MediatorFeedbackBasedProtocol;
|
---|
23 | import parties.feedbackmediator.partialopponentmodel.PartialPreferenceModels;
|
---|
24 |
|
---|
25 | public class SmartMediatorOnlyFeedback extends AbstractNegotiationParty implements Mediator {
|
---|
26 |
|
---|
27 | private Bid currentBid; // the current bid
|
---|
28 | private Bid lastBid; // the bid that is offered in the previous round
|
---|
29 |
|
---|
30 | private Vote isAcceptable;
|
---|
31 | private int lastAcceptedRoundNumber;
|
---|
32 | private Bid lastAcceptedBid; // keeping the last accepted bid by all parties
|
---|
33 |
|
---|
34 | private int currentIndex;
|
---|
35 | private List<GiveFeedback> currentFeedbackList;
|
---|
36 |
|
---|
37 | private int currentRound = 0;
|
---|
38 |
|
---|
39 | /*
|
---|
40 | * the model is learned by the mediator during the negotiation
|
---|
41 | */
|
---|
42 | private PartialPreferenceModels preferenceList;
|
---|
43 | private Random randomnr;
|
---|
44 |
|
---|
45 | public SmartMediatorOnlyFeedback() {
|
---|
46 |
|
---|
47 | super();
|
---|
48 | lastAcceptedBid = null;
|
---|
49 | currentBid = null;
|
---|
50 | lastBid = null;
|
---|
51 | currentFeedbackList = new ArrayList<GiveFeedback>();
|
---|
52 | isAcceptable = Vote.ACCEPT;
|
---|
53 |
|
---|
54 | }
|
---|
55 |
|
---|
56 | @Override
|
---|
57 | public void init(NegotiationInfo info) {
|
---|
58 | super.init(info);
|
---|
59 | randomnr = new Random(info.getRandomSeed());
|
---|
60 | }
|
---|
61 |
|
---|
62 | @Override
|
---|
63 | public void receiveMessage(AgentID sender, Action opponentAction) {
|
---|
64 |
|
---|
65 | if (opponentAction instanceof GiveFeedback)
|
---|
66 | currentFeedbackList.add((GiveFeedback) opponentAction);
|
---|
67 |
|
---|
68 | }
|
---|
69 |
|
---|
70 | @Override
|
---|
71 | public Class<? extends DefaultMultilateralProtocol> getProtocol() {
|
---|
72 | return MediatorFeedbackBasedProtocol.class;
|
---|
73 | }
|
---|
74 |
|
---|
75 | @Override
|
---|
76 | public Action chooseAction(List<Class<? extends Action>> validActions) {
|
---|
77 | currentRound++;
|
---|
78 | /**
|
---|
79 | * FIXME this was calling negotiator.session.Timeline#isDeadlineReached
|
---|
80 | * which makes no sense, as we would not be here if the deadline had
|
---|
81 | * been reached. Instead we chose to use 5% time remaining
|
---|
82 | */
|
---|
83 | if (timeline.getCurrentTime() > 0.95) {
|
---|
84 | /*
|
---|
85 | * If the deadline is reached, end negotiation with last accepted
|
---|
86 | * bid by all parties..
|
---|
87 | */
|
---|
88 | // writePreferenceStream.println("Session:"+getSessionNo());
|
---|
89 | // writePreferenceStream.println(preferenceList.toString());
|
---|
90 | // writePreferenceStream.println("**********************************************");
|
---|
91 |
|
---|
92 | System.out.println("Last Accepted Bid:" + lastAcceptedBid + " in " + lastAcceptedRoundNumber + "th round");
|
---|
93 |
|
---|
94 | return new EndNegotiationWithAnOffer(getPartyId(), lastAcceptedBid);
|
---|
95 | }
|
---|
96 |
|
---|
97 | try {
|
---|
98 |
|
---|
99 | if (validActions.contains(NoAction.class)) {
|
---|
100 |
|
---|
101 | isAcceptable = Feedback.isAcceptable(currentFeedbackList());
|
---|
102 |
|
---|
103 | if (isAcceptable == Vote.ACCEPT) {
|
---|
104 | lastAcceptedBid = new Bid(currentBid);
|
---|
105 | lastAcceptedRoundNumber = currentRound;
|
---|
106 | }
|
---|
107 |
|
---|
108 | return new NoAction(getPartyId());
|
---|
109 |
|
---|
110 | } else if (currentRound == 1) {
|
---|
111 | /*
|
---|
112 | * initially generate a random bid and create the preference
|
---|
113 | * model
|
---|
114 | */
|
---|
115 | currentBid = generateRandomBid();
|
---|
116 | lastBid = new Bid(currentBid);
|
---|
117 | preferenceList = new PartialPreferenceModels(new Bid(currentBid), null);// FIXME
|
---|
118 | return (new OfferForFeedback(getPartyId(), currentBid));
|
---|
119 | // when we stop searching part and start voting, inform the
|
---|
120 | // agents about the last accepted bid by all
|
---|
121 | } else {
|
---|
122 |
|
---|
123 | if (currentRound > 2) {
|
---|
124 |
|
---|
125 | preferenceList.updateIssuePreferenceList(currentIndex, lastBid.getValue(currentIndex),
|
---|
126 | currentBid.getValue(currentIndex), currentFeedbackList);
|
---|
127 | lastBid = new Bid(currentBid);
|
---|
128 | }
|
---|
129 |
|
---|
130 | currentFeedbackList.clear();
|
---|
131 | currentBid = modifyLastBid();
|
---|
132 |
|
---|
133 | if (currentBid == null) {
|
---|
134 | /*
|
---|
135 | * if we are not able to generate bids;
|
---|
136 | */
|
---|
137 | System.out.println("Last Accepted Round Number:" + lastAcceptedRoundNumber);
|
---|
138 | System.out.println(preferenceList.toString());
|
---|
139 | return (new EndNegotiationWithAnOffer(getPartyId(), lastAcceptedBid));
|
---|
140 | }
|
---|
141 |
|
---|
142 | }
|
---|
143 | } catch (Exception e) {
|
---|
144 | System.out.println(
|
---|
145 | currentRound + " :Cannnot generate random bid or update preference list problem:" + e.getMessage());
|
---|
146 |
|
---|
147 | }
|
---|
148 |
|
---|
149 | return (new OfferForFeedback(getPartyId(), currentBid));
|
---|
150 | }
|
---|
151 |
|
---|
152 | /**
|
---|
153 | * modifies the last bid by changing the Nth issue value where N is the
|
---|
154 | * currentIndex. If not yet halfway the deadline, we use
|
---|
155 | * {@link #searchForNewValue()}, otherwise we pick randomly between
|
---|
156 | * {@link #searchForNewValue()} and {@link #getNashValue()}.
|
---|
157 | *
|
---|
158 | * @return the modified bid
|
---|
159 | */
|
---|
160 |
|
---|
161 | private Bid modifyLastBid() throws Exception {
|
---|
162 |
|
---|
163 | Bid modifiedBid = new Bid(lastBid);
|
---|
164 |
|
---|
165 | // epsilon= distance to deadline, in [1,0].
|
---|
166 | double epsilon = 1f - getTimeLine().getTime();
|
---|
167 | Value selectedValue = null;
|
---|
168 |
|
---|
169 | if (epsilon < 0.5 || (epsilon > Math.random())) {
|
---|
170 | selectedValue = searchForNewValue();
|
---|
171 | }
|
---|
172 |
|
---|
173 | if (selectedValue == null) {
|
---|
174 | selectedValue = getNashValue();
|
---|
175 | }
|
---|
176 |
|
---|
177 | if (selectedValue == null)
|
---|
178 | return null;
|
---|
179 |
|
---|
180 | modifiedBid = modifiedBid.putValue(currentIndex, selectedValue);
|
---|
181 |
|
---|
182 | return modifiedBid;
|
---|
183 |
|
---|
184 | }
|
---|
185 |
|
---|
186 | private Value searchForNewValue() throws Exception {
|
---|
187 |
|
---|
188 | List<Issue> issues = utilitySpace.getDomain().getIssues();
|
---|
189 | Issue currentIssue;
|
---|
190 | Value newValue = null;
|
---|
191 |
|
---|
192 | ArrayList<Issue> checkedIssues = new ArrayList<Issue>(issues);
|
---|
193 | int checkID;
|
---|
194 | do {
|
---|
195 | checkID = randomnr.nextInt(checkedIssues.size());
|
---|
196 | currentIssue = checkedIssues.get(checkID);
|
---|
197 | currentIndex = currentIssue.getNumber();
|
---|
198 | newValue = preferenceList.getMissingValue(currentIndex);
|
---|
199 | if (newValue != null)
|
---|
200 | return newValue;
|
---|
201 | checkedIssues.remove(checkID);
|
---|
202 | } while (checkedIssues.size() > 0);
|
---|
203 |
|
---|
204 | checkedIssues = new ArrayList<Issue>(issues);
|
---|
205 | do {
|
---|
206 | checkID = randomnr.nextInt(checkedIssues.size());
|
---|
207 | currentIssue = checkedIssues.get(checkID);
|
---|
208 | currentIndex = currentIssue.getNumber();
|
---|
209 |
|
---|
210 | for (Value incomparable : preferenceList.getIncomparableValues(currentIndex,
|
---|
211 | lastBid.getValue(currentIndex))) {
|
---|
212 | if (incomparable != null)
|
---|
213 | return incomparable;
|
---|
214 | }
|
---|
215 | checkedIssues.remove(checkID);
|
---|
216 |
|
---|
217 | } while (checkedIssues.size() > 0);
|
---|
218 |
|
---|
219 | checkedIssues = new ArrayList<Issue>(issues);
|
---|
220 | do {
|
---|
221 | checkID = randomnr.nextInt(checkedIssues.size());
|
---|
222 | currentIssue = checkedIssues.get(checkID);
|
---|
223 | currentIndex = currentIssue.getNumber();
|
---|
224 |
|
---|
225 | ArrayList<Value> allValues = preferenceList.getAllPossibleValues(currentIndex);
|
---|
226 | do {
|
---|
227 | newValue = allValues.get(randomnr.nextInt(allValues.size()));
|
---|
228 | if ((!newValue.equals(lastBid.getValue(currentIndex)))
|
---|
229 | && (preferenceList.mayImproveAll(currentIndex, lastBid.getValue(currentIndex), newValue)))
|
---|
230 | return newValue;
|
---|
231 | allValues.remove(newValue);
|
---|
232 | } while (allValues.size() > 0);
|
---|
233 |
|
---|
234 | checkedIssues.remove(checkID);
|
---|
235 |
|
---|
236 | } while (checkedIssues.size() > 0);
|
---|
237 |
|
---|
238 | return null;
|
---|
239 | }
|
---|
240 |
|
---|
241 | private Value getNashValue() throws Exception {
|
---|
242 | List<Issue> issues = utilitySpace.getDomain().getIssues();
|
---|
243 | Issue currentIssue;
|
---|
244 | Value newValue = null;
|
---|
245 |
|
---|
246 | ArrayList<Issue> checkedIssues = new ArrayList<Issue>(issues);
|
---|
247 | int checkID;
|
---|
248 |
|
---|
249 | do {
|
---|
250 | checkID = randomnr.nextInt(checkedIssues.size());
|
---|
251 | currentIssue = checkedIssues.get(checkID);
|
---|
252 | currentIndex = currentIssue.getNumber();
|
---|
253 |
|
---|
254 | ArrayList<Value> allNashValues = preferenceList.getNashValues(currentIndex);
|
---|
255 | do {
|
---|
256 | newValue = allNashValues.get(randomnr.nextInt(allNashValues.size()));
|
---|
257 |
|
---|
258 | // if ((newValue!=lastBid.getValue(currentIndex)))
|
---|
259 | if ((!newValue.equals(lastBid.getValue(currentIndex)))
|
---|
260 | && (preferenceList.mayImproveAll(currentIndex, lastBid.getValue(currentIndex), newValue)))
|
---|
261 | return newValue;
|
---|
262 | allNashValues.remove(newValue);
|
---|
263 | } while (allNashValues.size() > 0);
|
---|
264 |
|
---|
265 | checkedIssues.remove(checkID);
|
---|
266 |
|
---|
267 | } while (checkedIssues.size() > 0);
|
---|
268 |
|
---|
269 | return newValue;
|
---|
270 |
|
---|
271 | }
|
---|
272 |
|
---|
273 | /**
|
---|
274 | *
|
---|
275 | * @return just the Feedback elements of the currentFeedbacklist.
|
---|
276 | */
|
---|
277 | private List<Feedback> currentFeedbackList() {
|
---|
278 | List<Feedback> feedbacklist = new ArrayList<>();
|
---|
279 | for (GiveFeedback feedback : currentFeedbackList) {
|
---|
280 | feedbacklist.add(feedback.getFeedback());
|
---|
281 | }
|
---|
282 | return feedbacklist;
|
---|
283 | }
|
---|
284 |
|
---|
285 | @Override
|
---|
286 | public String getDescription() {
|
---|
287 | return "Smart Mediator Feedback only";
|
---|
288 | }
|
---|
289 |
|
---|
290 | }
|
---|