source: src/main/java/parties/in4010/q12015/group19/Group19.java@ 127

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

Initial import : Genius 9.0.0

File size: 10.8 KB
Line 
1package parties.in4010.q12015.group19;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import genius.core.AgentID;
7import genius.core.Bid;
8import genius.core.BidHistory;
9import genius.core.actions.Accept;
10import genius.core.actions.Action;
11import genius.core.actions.DefaultAction;
12import genius.core.actions.Offer;
13import genius.core.bidding.BidDetails;
14import genius.core.parties.AbstractNegotiationParty;
15
16/**
17 * Group19 negotiation Agent version 0.2 - 23-10-15 D2 assignment
18 */
19public class Group19 extends AbstractNegotiationParty {
20
21 private Action lastOfferedBidAction = null; // the last opponent offer
22 // action (not Accept)
23 private static double MINIMUM_BID_UTILITY = 0.0; // minimum acceptable
24 // utility (MAU)
25 private static double DISC_SENSITIVITY = 1; // Discount factor sensitivity
26 // (larger->faster convergence
27 // to mean)
28 private static int RAND_BID_AMOUNT = 30; // amount of randomly generated
29 // bids to compare for closest
30 // to mean
31 private static double MEAN_POW_COEFF = 1.25; // power coefficient of mean,
32 // for minutil calculation
33 private static double MIN_UTIL_BOUND = 0.4; // minimal boundary utility
34 // limit
35
36 private int issueN = 0; // number of issues
37 private int partiesN = 0; // number of parties
38 private int lastOffsteps = 0; // number of steps since last offer
39 private int bidNum = -1; // negotiation counter, updates for every received
40 // message and action chosen
41 private double lowBoundUtil = 0.95; // minimum utility boundary used for
42 // acceptance and offering
43 private double discMeanUtil = 0.95; // discounted mean utility value of
44 // opponent bids
45 private ArrayList<BidHistory> BidHist; // Bid History array of all parties
46 private ArrayList<ArrayList<Integer>> IssueAmounts = new ArrayList<ArrayList<Integer>>(); // counter
47 // of
48 // total
49 // offered
50 // issue
51 // arguments
52 private ArrayList<ArrayList<String>> IssueNames = new ArrayList<ArrayList<String>>(); // list
53 // of
54 // issue
55 // arguments
56 private ArrayList<ArrayList<Double>> normIssueVals = new ArrayList<ArrayList<Double>>(); // normalised
57 // issue
58 // amounts
59
60 private void initfunc() throws Exception {
61 partiesN = getNumberOfParties();
62 MINIMUM_BID_UTILITY = utilitySpace.getReservationValueUndiscounted();
63 /* Opponent model initialisation */
64 issueN = getRandBid(0).getIssues().size();
65 /* Setup BidHistory structure */
66 BidHist = new ArrayList<BidHistory>();
67 for (int i = 0; i < partiesN; i++) {
68 BidHist.add(new BidHistory());
69 }
70
71 /* Setup IssueAmounts structure */
72 for (int k = 0; k < issueN; k++) {
73 IssueAmounts.add(new ArrayList<Integer>());
74 IssueNames.add(new ArrayList<String>());
75 normIssueVals.add(new ArrayList<Double>());
76 }
77 }
78
79 /*
80 * chooseAction method; needs to always return a valid action (Accept or
81 * counter offer)
82 */
83 @Override
84 public Action chooseAction(List<Class<? extends Action>> validActions) {
85 if (bidNum == -1) {
86 try {
87 initfunc();
88 } catch (Exception e) {
89 System.out.println("!!!initialization failed!!!");
90 e.printStackTrace();
91 }
92 }
93 bidNum = bidNum + 1;
94 double OppBidUtil = 0;
95 /* get Utility value of last opponent action */
96 if (DefaultAction.getBidFromAction(lastOfferedBidAction) != null) {
97 Bid OppBid = DefaultAction.getBidFromAction(lastOfferedBidAction);
98 OppBidUtil = getUtility(OppBid);
99 } else {
100 OppBidUtil = 0;
101 }
102 /* should we accept? (checked with isAcceptable) */
103 try {
104 /*
105 * accept if the opponent offer is better than our acceptance value
106 * (still calculate new acceptance value)
107 */
108 if (validActions.contains(Accept.class) && isAcceptable(OppBidUtil)) {
109 lastOffsteps = lastOffsteps + 1;
110 Bid lastBid = BidHist.get((bidNum - lastOffsteps) % partiesN)
111 .getLastBid();
112 BH_update(bidNum % partiesN, lastBid);
113
114 return new Accept(getPartyId(), lastBid);
115 } else {
116 /* otherwise give new offer */
117 lastOffsteps = 0;
118 return new Offer(getPartyId(), getBid());
119 }
120 } catch (Exception e) {
121 e.printStackTrace();
122 System.out.println("unable to check acceptance");
123 return new Offer(getPartyId(), getRandBid(lowBoundUtil));
124 }
125 }
126
127 @Override
128 public void receiveMessage(AgentID sender, Action action) {
129 super.receiveMessage(sender, action);
130 // if just started, initialise group19
131 if (bidNum == -1) {
132 try {
133 initfunc();
134 } catch (Exception e) {
135 System.out.println("!!!initialization failed!!!");
136 e.printStackTrace();
137 }
138 }
139 bidNum = bidNum + 1;
140 Bid lastBid = null;
141 /* store action as variable and add it to the bid history */
142 if (DefaultAction.getBidFromAction(action) != null) {
143
144 lastOffsteps = 0;
145 lastOfferedBidAction = action;
146 lastBid = DefaultAction.getBidFromAction(lastOfferedBidAction);
147 BH_update((bidNum % partiesN), lastBid);
148 } else {
149 lastOffsteps = lastOffsteps + 1;
150 /* add last made offer to the bid history */
151 lastBid = BidHist.get(
152 ((bidNum + partiesN) - lastOffsteps) % partiesN)
153 .getLastBid();
154 BH_update(bidNum % partiesN, lastBid);
155 }
156 if (lastBid != null) {
157 if (Math.floor(bidNum / partiesN) > 0) {
158 //
159 lowBoundUtil_update(getUtility(lastBid));
160 }
161 try {
162 // update offered issues arguments counter
163 Counter_update(lastBid);
164 } catch (Exception e) {
165 System.out.println("-- ERROR -- unable to update mean");
166 e.printStackTrace();
167 }
168 }
169 }
170
171 @Override
172 public String getDescription() {
173 return "Group 19 - Grandma";
174 }
175
176 /*
177 * Checks if the utility of the offered bid is higher than the minimum
178 * accepted (reservation value) and if it is higher than the Lower Boundary
179 * Utility
180 */
181 private boolean isAcceptable(double offered) {
182 if (offered > lowBoundUtil && offered > MINIMUM_BID_UTILITY) {
183 return true;
184 } else {
185 return false;
186 }
187 }
188
189 /* private function to get a new valid Bid */
190 private Bid getRandBid(double minUtil) {
191 Bid newbid;
192 int loopcheck = 0;
193 do {
194 loopcheck++;
195 newbid = generateRandomBid();
196 } while (getUtility(newbid) < minUtil && loopcheck < 100000);
197 return newbid;
198 }
199
200 /* --- update Bid History of opponent oppID with bid newBid --- */
201 private void BH_update(int oppID, Bid newBid) {
202 if (oppID > -1 && oppID < partiesN) {
203 BidDetails tempBD = new BidDetails(newBid, getUtility(newBid));
204 BidHist.get(oppID).add(tempBD);
205 }
206 }
207
208 /*
209 * Update counter of offered issue arguments used to calculate the proximity
210 * of eventual bids to the issues most offered by the opponents
211 */
212 private void Counter_update(Bid recBid) throws Exception {
213 for (int k = 0; k < issueN; k++) {
214 boolean found = false;
215 if (IssueNames.get(k).isEmpty()) {
216 IssueNames.get(k).add(recBid.getValue(k + 1).toString());
217 IssueAmounts.get(k).add(1);
218 found = true;
219 } else {
220 // for all existing IssueNames
221 for (int j = 0; j < IssueNames.get(k).size(); j++)
222 /*
223 * compare bid issue value (ex. "Beer") to existing names in
224 * IssueNames, if it does add one to IssueValues, otherwise
225 * create new IssueNames name and IssueValues value, and add
226 * 1 to it
227 */
228 if (recBid.getValue(k + 1).toString()
229 .equals(IssueNames.get(k).get(j))) {
230 int newval = IssueAmounts.get(k).get(j) + 1;
231 ArrayList<Integer> newArr = IssueAmounts.get(k);
232 newArr.set(j, newval);
233 IssueAmounts.set(k, newArr);
234 found = true;
235 }
236 }
237 if (!found) {
238 IssueNames.get(k).add(recBid.getValue(k + 1).toString());
239 IssueAmounts.get(k).add(1);
240 }
241 }
242 /*
243 * uncomment to display issue arguments count
244 * System.out.println(IssueNames); System.out.println(IssueAmounts);
245 */
246 }
247
248 /* calculates normalised issue mean amounts */
249 private void normaliseMean() {
250 for (int i = 0; i < IssueAmounts.size(); i++) {
251 double tot = 0;
252 for (int k = 0; k < IssueAmounts.get(i).size(); k++) {
253 tot = tot + IssueAmounts.get(i).get(k);
254 }
255 normIssueVals.get(i).clear();
256 ArrayList<Double> issValList = new ArrayList<Double>();
257 for (int j = 0; j < IssueAmounts.get(i).size(); j++) {
258 issValList.add(IssueAmounts.get(i).get(j) / tot);
259 }
260 normIssueVals.set(i, issValList);
261 }
262 }
263
264 /*
265 * Offering strategy get minimum utility value (boundary) -> generate n
266 * random bids above boundary -> -> calculate their proximity to opponents
267 * offering mean -> return bid with highest value
268 */
269 private Bid getBid() {
270 // set min utility
271 double minUt = lowBoundUtil;
272 double maxmeanUt = 0;
273 Bid finalBid = new Bid(getUtilitySpace().getDomain());
274 // if already in 2nd round
275 if (Math.floor(bidNum / partiesN) > 0) {
276 ArrayList<Bid> BidArr = new ArrayList<Bid>();
277 ArrayList<Double> proxArr = new ArrayList<Double>();
278 // normalise mean values
279 normaliseMean();
280 // generate random bids
281 for (int i = 0; i < RAND_BID_AMOUNT; i++) {
282 BidArr.add(getRandBid(minUt));
283 try {
284 // calculate proximity value to the opponents offering mean
285 proxArr.add(getProx(BidArr.get(i)));
286 } catch (Exception e) {
287 System.out.println("Unable to calculate mean utility");
288 e.printStackTrace();
289 }
290 }
291 // find best proximity value
292 for (int p = 0; p < proxArr.size(); p++) {
293 if (proxArr.get(p) > maxmeanUt) {
294 maxmeanUt = proxArr.get(p);
295 }
296 }
297 // return bid with maximum proximity
298 finalBid = BidArr.get(proxArr.indexOf(maxmeanUt));
299 } else {
300 finalBid = getRandBid(minUt);
301 }
302 return finalBid;
303 }
304
305 /*
306 * calculate the proximity of a bid to the normalised mean point bids with
307 * issue values equal to the most offered ones get higher scores this
308 * results in them being preferred to those with lower values
309 */
310 private double getProx(Bid bid) throws Exception {
311 double proxVal = 0;
312 for (int i = 0; i < IssueNames.size(); i++) {
313 for (int k = 0; k < IssueNames.get(i).size(); k++) {
314 if (bid.getValue(i + 1).toString()
315 .equals(IssueNames.get(i).get(k))) {
316 proxVal = proxVal + normIssueVals.get(i).get(k);
317 }
318 }
319 }
320 return proxVal;
321 }
322
323 /*
324 * Update the Lower Boundary Utility the utility calculated is dependent on
325 * the discounted mean utility and on a time factor (see report)
326 */
327 private void lowBoundUtil_update(double lastUt) {
328 double time = timeline.getTime();
329 // discount factor for discounted mean utility (should stay constant
330 // trough negotiation)
331 double discFact = DISC_SENSITIVITY
332 / ((bidNum * (partiesN - 1)) / (partiesN * time));
333 discMeanUtil = (1 - discFact) * discMeanUtil + discFact * lastUt;
334 double tfact = 1 - Math.pow(time, 30);
335 // System.out.println("time factor:"+tfact);
336 lowBoundUtil = (MIN_UTIL_BOUND + (1 - MIN_UTIL_BOUND)
337 * Math.pow(discMeanUtil, MEAN_POW_COEFF))
338 * tfact;
339 // System.out.println("min utility:"+lowBoundUtil);
340 }
341}
Note: See TracBrowser for help on using the repository browser.