source: anac2020/TheDiceHaggler/src/main/java/geniusweb/bagga/dicehaggler/TheDiceHaggler.java@ 43

Last change on this file since 43 was 43, checked in by wouter, 3 years ago

#3

File size: 13.8 KB
Line 
1package geniusweb.bagga.dicehaggler;
2
3import java.io.IOException;
4import java.util.ArrayList;
5import java.util.Arrays;
6import java.util.Collections;
7import java.util.Comparator;
8import java.util.Dictionary;
9import java.util.HashSet;
10import java.util.Hashtable;
11import java.util.List;
12import java.util.logging.Level;
13
14import javax.websocket.DeploymentException;
15
16import geniusweb.actions.Accept;
17import geniusweb.actions.Action;
18import geniusweb.actions.Comparison;
19import geniusweb.actions.ElicitComparison;
20import geniusweb.actions.Offer;
21import geniusweb.actions.PartyId;
22import geniusweb.bidspace.AllBidsList;
23import geniusweb.inform.ActionDone;
24import geniusweb.inform.Finished;
25import geniusweb.inform.Inform;
26import geniusweb.inform.Settings;
27import geniusweb.inform.YourTurn;
28import geniusweb.issuevalue.Bid;
29import geniusweb.issuevalue.Domain;
30import geniusweb.party.Capabilities;
31import geniusweb.party.DefaultParty;
32import geniusweb.profile.PartialOrdering;
33import geniusweb.profile.Profile;
34import geniusweb.profileconnection.ProfileConnectionFactory;
35import geniusweb.profileconnection.ProfileInterface;
36import geniusweb.progress.Progress;
37import geniusweb.progress.ProgressRounds;
38import tudelft.utilities.logging.Reporter;
39
40public class TheDiceHaggler extends DefaultParty {
41
42 private long startTime;
43 private long endTime;
44 private Action lastReceivedAction;
45 private Bid receivedBid;
46 private Progress progress;
47 private PartyId me;
48 private ProfileInterface profileint;
49 private AllBidsList allbids;
50 private PartialOrdering partialprofile;
51 private List<Bid> givenPartialOrderedBids;
52 private List<Bid> opponentBidHistory = new ArrayList<Bid>();
53 private double time;
54 private DH_OpponentModel om;
55
56 private Domain domain;
57
58 private boolean elicitCounter = true;
59 private double fixedUtility = 0.98;
60 private double dynamicUtility = 1D; // would change over time
61 private double reservationThresholdUtility = 0.85;
62
63 private Dictionary<String, DH_Issue> utilSpace = new Hashtable<String, DH_Issue>();
64 private Dictionary<String, DH_Issue> opponentModel = new Hashtable<String, DH_Issue>();
65 private DH_UserModel userM;
66 private DH_BiddingStrategy bs;
67 private SimpleLinearOrdering estimatedProfile = null;
68
69 public TheDiceHaggler() {
70 super();
71 }
72
73 public TheDiceHaggler(Reporter reporter) {
74 super(reporter);
75 }
76
77 private void init(Settings info) throws IOException, DeploymentException {
78 startTime = System.currentTimeMillis();
79 this.me = info.getID();
80 this.progress = info.getProgress();
81 endTime = progress.getTerminationTime().getTime();
82 this.profileint = ProfileConnectionFactory.create(info.getProfile().getURI(), getReporter());
83 this.partialprofile = (PartialOrdering) profileint.getProfile(); // patial profile also contains the reservation
84 // bid
85
86 allbids = new AllBidsList(this.partialprofile.getDomain()); // total number of possible bids.. all permutations
87 // Wouter we use SimpleLinearOrdering (from shaop party) to get sorted
88 // bids from our profile.
89 this.domain = this.partialprofile.getDomain();
90 this.time = getTime(System.currentTimeMillis());
91 // System.out.println("time "+ time+ " in ms: "+System.currentTimeMillis());
92 System.out.println("############### Now Time is : " + time + " #############");
93 givenPartialOrderedBids = new SimpleLinearOrdering(this.partialprofile).getBids();
94
95 om = new DH_OpponentModel(this.domain);
96 opponentModel = om.initializeOpponentModel();
97
98 userM = new DH_UserModel(this.domain, givenPartialOrderedBids);
99 utilSpace = userM.estimateutilityspace();
100
101 bs = new DH_BiddingStrategy();
102 }
103
104 @Override
105 public void notifyChange(Inform info) {
106 try {
107 if (info instanceof Settings) {
108 System.out.println("............. Initializing Settings ...........");
109 init((Settings) info);
110 } else if (info instanceof ActionDone) {
111 System.out.println("............. Some action has been done ...........");
112
113 lastReceivedAction = ((ActionDone) info).getAction();
114 if (lastReceivedAction instanceof Offer) {
115 System.out.println("............. Opponent has sent an Offer ...........");
116 this.receivedBid = ((Offer) lastReceivedAction).getBid();
117
118 opponentBidHistory.add(this.receivedBid);
119 opponentModel = om.updateOpponentModel(time, opponentBidHistory);
120 } else if (lastReceivedAction instanceof Comparison) {
121 System.out.println("............. COB party has done the comparison ...........");
122
123 estimatedProfile = estimatedProfile.with(((Comparison) lastReceivedAction).getBid(),
124 ((Comparison) lastReceivedAction).getWorse()); // getWorse is a list of worst bids than the
125 // given bid
126
127 System.out.println(" ...... So, let's estimate the user space again .....");
128 userM = new DH_UserModel(domain, estimatedProfile.getBids());
129 utilSpace = userM.estimateutilityspace();
130
131 System.out.println(" ...... Now, we choose the action based on updated user model");
132 chooseAction();
133 }
134 } else if (info instanceof YourTurn) {
135 System.out.println(" ....... HEy! it's my turn to make an action....");
136 chooseAction();
137
138 } else if (info instanceof Finished) {
139 getReporter().log(Level.INFO, "Final outcome:" + info);
140 }
141 } catch (Exception e) {
142 throw new RuntimeException("Failed to handle info", e);
143 }
144 }
145
146 private void chooseAction() throws IOException {
147 this.time = getTime(System.currentTimeMillis());
148 Action action = null;
149
150 if (estimatedProfile == null) {
151 estimatedProfile = new SimpleLinearOrdering(profileint.getProfile());
152 }
153
154 // Start competition
155
156 if (receivedBid == null) {
157 Bid offeredBid = determineOpeningBid();
158 System.out.println("At time " + time + " , I offer an opening bid with util: "
159 + DH_UserModel.getUtility(offeredBid, utilSpace));
160 action = new Offer(me, offeredBid);
161 } else {
162 // if less than 5% of the total possible bids are given in the partial order and
163 // the variance in pairwise correlations is too large, then do elicitation
164 if (elicitCounter && givenPartialOrderedBids.size() < 0.05 * totalNumberOfPossibleBids()
165 && userM.checkVariance()) {
166 // decide which bids to compare with what..and then do the elicitation
167 System.out.println("HEY LISTEN! at time " + time + "I am going to ask the user to compare these bids");
168 action = new ElicitComparison(me, getMyNextBid(time), givenPartialOrderedBids);
169 elicitCounter = false;
170 } else if (isAcceptable(receivedBid)) {
171 System.out.println("At time " + time + " ,I accept the received bid with util: "
172 + DH_UserModel.getUtility(receivedBid, utilSpace));
173 action = new Accept(me, receivedBid);
174 }
175 if (progress instanceof ProgressRounds) {
176 progress = ((ProgressRounds) progress).advance();
177 }
178 }
179 if (action == null) {
180 Bid offeredBid = bs.generateBid(time, domain, utilSpace, opponentModel, opponentBidHistory, allbids);
181 System.out.println("At time " + time + " , I offer a bid with util: "
182 + DH_UserModel.getUtility(offeredBid, utilSpace));
183 action = new Offer(me, offeredBid);
184 }
185 getConnection().send(action);
186
187 }
188
189 private double getTime(long currentTimeMillis) {
190 // TODO Auto-generated method stub
191 long duration = endTime - startTime;
192 long delta = currentTimeMillis - startTime;
193 Double ratio = delta / (double) duration;
194 return ratio;
195 }
196
197//
198// private List<Bid> getListOfTwoMostVariedBids(List<Bid> givenBids) {
199//
200// List<Bid> list = new ArrayList<>();
201// double sum = 0D;
202// for( Bid bid: givenBids) {
203// sum += DH_UserModel.getUtility(bid, utilSpace);
204// }
205// double mean = sum/givenBids.size();
206//
207// double maxSum = 0D;
208// Bid topVariedBid = null;
209// Bid secondTopBid = null;
210// int index = 0;
211// int topIndex = 0;
212// for( Bid bid: givenBids) {
213// index++;
214// if(maxSum < Math.pow(DH_UserModel.getUtility(bid, utilSpace) - mean, 2)) {
215// maxSum = Math.pow(DH_UserModel.getUtility(bid, utilSpace) - mean, 2);
216// topVariedBid = bid;
217// topIndex = index;
218// }
219// }
220// givenBids.remove(topIndex);
221// for( Bid bid: givenBids) {
222// if(maxSum < Math.pow(DH_UserModel.getUtility(bid, utilSpace) - mean, 2)) {
223// maxSum = Math.pow(DH_UserModel.getUtility(bid, utilSpace) - mean, 2);
224// secondTopBid = bid;
225// }
226// }
227// list.add(topVariedBid);
228// list.add(secondTopBid);
229// return list;
230// }
231//
232// private boolean checkVariance(List<Bid> givenBids) {
233// double sum = 0D;
234// for( Bid bid: givenBids) {
235// sum += DH_UserModel.getUtility(bid, utilSpace);
236// }
237// double mean = sum/givenBids.size();
238//
239// double sum1 = 0D;
240// for( Bid bid: givenBids) {
241// sum1 += Math.pow(DH_UserModel.getUtility(bid, utilSpace) - mean, 2);
242// }
243// double variance = sum1/(givenBids.size()-1);
244// return (variance > 0.6);
245// }
246
247 private Bid getMyNextBid(double time) {
248 return bs.generateBid(time, domain, utilSpace, opponentModel, opponentBidHistory, allbids);
249 }
250
251 private boolean isAcceptable(Bid receivedBid) {
252 this.time = getTime(System.currentTimeMillis());
253
254 DH_TargetUtility t_u = new DH_TargetUtility(domain, time, opponentBidHistory, opponentModel,
255 allbids.size().intValue());
256
257 // time = progress.get(System.currentTimeMillis());
258 if (time >= 0.7) {
259 System.out.println("time is greater than 0.7, let's calculate the dynamic threshold");
260 try {
261 dynamicUtility = t_u.calculateTargetValue();
262 System.out.println("at time t = " + time + "the dynamic threshold utility is: " + dynamicUtility);
263 if (dynamicUtility < reservationThresholdUtility)
264 dynamicUtility = reservationThresholdUtility;
265 } catch (Exception e) {
266 e.printStackTrace();
267 }
268 }
269 double myFutureBidUtility = DH_UserModel.getUtility(getMyNextBid(time), utilSpace);
270 double lastReceivedBidUtility = DH_UserModel.getUtility(getMyNextBid(time), utilSpace);
271
272 boolean accept;
273 if ((time < 0.4 && lastReceivedBidUtility >= fixedUtility) || (time >= 0.4 && time < 0.5
274 & lastReceivedBidUtility >= DH_UserModel.getUtility(getOpponentBestBidDetails(), utilSpace))
275 // why dynamic threshold is not considered here.. because my future bid utility
276 // will always be higher than that my threshold value
277 || (time >= 0.5 && time < 0.6 & lastReceivedBidUtility >= myFutureBidUtility
278 & lastReceivedBidUtility > bestOfQquantileOpponentBids(0.9))
279 // best out of the bottom 90% of the received bids in the ordered utility from
280 // high to less
281 || (time >= 0.6 && time < 0.7 && lastReceivedBidUtility >= myFutureBidUtility
282 && lastReceivedBidUtility > bestOfQquantileOpponentBids(0.8))
283 // best out of the bottom 80% of the received bids
284 || (time >= 0.7 && time < 0.8 && lastReceivedBidUtility >= dynamicUtility
285 && lastReceivedBidUtility > bestOfQquantileOpponentBids(0.7))
286 // best out of the bottom 70% of the bids
287 || (time >= 0.8 && time < 0.9 && lastReceivedBidUtility >= dynamicUtility
288 && lastReceivedBidUtility > bestOfQquantileOpponentBids(0.6))
289 // best out of the bottom 60% of the bids
290 || (time >= 0.9 && lastReceivedBidUtility >= dynamicUtility)) {
291 accept = true;
292 } else {
293 System.out
294 .println("At time " + time + " , I am going to reject the received offer and propose a new offer");
295 accept = false;
296 }
297
298 return accept;
299 }
300
301 private double bestOfQquantileOpponentBids(double q) {
302 List<Bid> sortedOpponentHistory = getSortedHistory(opponentBidHistory); // in an increasing order
303 double util = 0D;
304 // int k = (int) (Math.ceil((1-q) * sortedOpponentHistory.size()) - 1); //if the
305 // list is in a decreasing order
306 int k = (int) (Math.ceil((q) * sortedOpponentHistory.size()) - 1); // if the list is in an increasing order
307
308 util = DH_UserModel.getUtility(sortedOpponentHistory.get(k), utilSpace);
309 System.out
310 .println("Q = " + q + " size = " + sortedOpponentHistory.size() + " index = " + k + " util = " + util);
311 return util;
312 }
313
314 private List<Bid> getSortedHistory(List<Bid> opponentBidHistory2) {
315 System.out.println("I am going to get the sorted opponent history");
316 List<Bid> sortedOpponentHistory = new ArrayList<Bid>(); // in an ascending order
317 Collections.sort(sortedOpponentHistory, new Comparator<Bid>() {
318 @Override
319 public int compare(Bid b1, Bid b2) {
320 if (b1 == null || b2 == null)
321 throw new NullPointerException();
322 if (b1.equals(b2))
323 return 0;
324 if (DH_UserModel.getUtility(b1, utilSpace) > DH_UserModel.getUtility(b2, utilSpace))
325 return -1;
326 else if (DH_UserModel.getUtility(b1, utilSpace) < DH_UserModel.getUtility(b2, utilSpace))
327 return 1;
328 else
329 return ((Integer) b1.hashCode()).compareTo(b2.hashCode());
330 }
331 });
332 for (Bid l : sortedOpponentHistory) {
333 System.out.println(DH_UserModel.getUtility(l, utilSpace));
334 }
335 return sortedOpponentHistory;
336 }
337
338 private Bid getOpponentBestBidDetails() {
339 double max = Double.NEGATIVE_INFINITY;
340 Bid bestBid = null;
341 for (Bid b : opponentBidHistory) {
342 double utility = DH_UserModel.getUtility(b, utilSpace);
343 if (utility >= max) {
344 max = utility;
345 bestBid = b;
346 }
347 }
348 return bestBid;
349 }
350
351 private Bid determineOpeningBid() {
352 // maximum bid in the given user domain
353 return givenPartialOrderedBids.get(givenPartialOrderedBids.size() - 1);
354 }
355
356 @Override
357 public Capabilities getCapabilities() {
358 return new Capabilities(new HashSet<>(Arrays.asList("SHAOP")), Collections.singleton(Profile.class));
359 }
360
361 @Override
362 public String getDescription() {
363 return "The Dice Haggler 2020";
364 }
365
366 private int totalNumberOfPossibleBids() {
367 int num = 1;
368 for (String i : domain.getIssues()) {
369 num *= domain.getValues(i).size().intValue();
370 }
371 // System.out.println("I count total bids = " + num + " and real value is: "+
372 // allbids.size());
373 return num;
374
375 }
376}
Note: See TracBrowser for help on using the repository browser.