1 | package nego2020.group9;
|
---|
2 |
|
---|
3 | import java.util.ArrayList;
|
---|
4 | import java.util.Arrays;
|
---|
5 | import java.util.Collections;
|
---|
6 | import java.util.Comparator;
|
---|
7 | import java.util.HashMap;
|
---|
8 | import java.util.HashSet;
|
---|
9 | import java.util.List;
|
---|
10 | import java.util.Map;
|
---|
11 | import java.util.Random;
|
---|
12 | import java.util.Set;
|
---|
13 | import java.util.logging.Level;
|
---|
14 |
|
---|
15 | import org.apache.commons.math3.stat.regression.OLSMultipleLinearRegression;
|
---|
16 |
|
---|
17 | import geniusweb.actions.Accept;
|
---|
18 | import geniusweb.actions.Action;
|
---|
19 | import geniusweb.actions.Comparison;
|
---|
20 | import geniusweb.actions.Offer;
|
---|
21 | import geniusweb.actions.PartyId;
|
---|
22 | import geniusweb.inform.ActionDone;
|
---|
23 | import geniusweb.inform.Finished;
|
---|
24 | import geniusweb.inform.Inform;
|
---|
25 | import geniusweb.inform.Settings;
|
---|
26 | import geniusweb.inform.YourTurn;
|
---|
27 | import geniusweb.issuevalue.Bid;
|
---|
28 | import geniusweb.issuevalue.DiscreteValue;
|
---|
29 | import geniusweb.issuevalue.NumberValue;
|
---|
30 | import geniusweb.issuevalue.Value;
|
---|
31 | import geniusweb.issuevalue.ValueSet;
|
---|
32 | import geniusweb.party.Capabilities;
|
---|
33 | import geniusweb.party.DefaultParty;
|
---|
34 | import geniusweb.profile.Profile;
|
---|
35 | import geniusweb.profileconnection.ProfileConnectionFactory;
|
---|
36 | import geniusweb.profileconnection.ProfileInterface;
|
---|
37 | import geniusweb.progress.Progress;
|
---|
38 | import geniusweb.progress.ProgressRounds;
|
---|
39 | import tudelft.utilities.logging.Reporter;
|
---|
40 |
|
---|
41 | public class DUOAgent extends DefaultParty {
|
---|
42 |
|
---|
43 | private Bid lastReceivedBid = null;
|
---|
44 | private PartyId me;
|
---|
45 | private Random random;
|
---|
46 | private OLSMultipleLinearRegression regression;
|
---|
47 | protected ProfileInterface profileint;
|
---|
48 | private SimpleLinearOrdering estimatedProfile = null;
|
---|
49 | private List<List<String>> allPossibleBids;
|
---|
50 | private List<Bid> sortedPredictedBids;
|
---|
51 | private int turn_count = 0;
|
---|
52 | private List<Bid> opponets_bid;
|
---|
53 | private List<Bid> my_bids;
|
---|
54 | private int current_bid;
|
---|
55 | private int total_round;
|
---|
56 | private boolean dont_repeat = true;
|
---|
57 | private int repeating_count = 0;
|
---|
58 | private double least_w = Double.MAX_VALUE;
|
---|
59 |
|
---|
60 | public DUOAgent() {
|
---|
61 | }
|
---|
62 |
|
---|
63 | public DUOAgent(Reporter reporter) {
|
---|
64 | super(reporter);
|
---|
65 | }
|
---|
66 |
|
---|
67 | @Override
|
---|
68 | public Capabilities getCapabilities() {
|
---|
69 | return new Capabilities(new HashSet<>(Arrays.asList("SHAOP")), Collections.singleton(Profile.class));
|
---|
70 | }
|
---|
71 |
|
---|
72 | @Override
|
---|
73 | public String getDescription() {
|
---|
74 | return "DUO AGENT";
|
---|
75 | }
|
---|
76 |
|
---|
77 | @Override
|
---|
78 | public void notifyChange(Inform info) {
|
---|
79 | try {
|
---|
80 | if (info instanceof Settings) {
|
---|
81 | Settings settings = (Settings) info;
|
---|
82 | this.profileint = ProfileConnectionFactory.create(settings.getProfile().getURI(), getReporter());
|
---|
83 | this.me = settings.getID();
|
---|
84 | Progress progress = settings.getProgress();
|
---|
85 | if (progress instanceof ProgressRounds) {
|
---|
86 | total_round = ((ProgressRounds) progress).getTotalRounds();
|
---|
87 | }
|
---|
88 | this.opponets_bid = new ArrayList<>();
|
---|
89 | this.sortedPredictedBids = new ArrayList<>();
|
---|
90 | this.my_bids = new ArrayList<>();
|
---|
91 | current_bid = 0;
|
---|
92 | estimatedProfile = new SimpleLinearOrdering(profileint.getProfile());
|
---|
93 | elicitation();
|
---|
94 | } else if (info instanceof ActionDone) {
|
---|
95 | Action otheract = ((ActionDone) info).getAction();
|
---|
96 | if (otheract instanceof Offer) {
|
---|
97 | lastReceivedBid = ((Offer) otheract).getBid();
|
---|
98 | opponets_bid.add(lastReceivedBid);
|
---|
99 | } else if (otheract instanceof Comparison) {
|
---|
100 |
|
---|
101 | estimatedProfile = estimatedProfile.with(((Comparison) otheract).getBid(),
|
---|
102 | ((Comparison) otheract).getWorse());
|
---|
103 | turn_count++;
|
---|
104 | myTurn();
|
---|
105 | }
|
---|
106 | } else if (info instanceof YourTurn) {
|
---|
107 | turn_count++;
|
---|
108 | myTurn();
|
---|
109 | } else if (info instanceof Finished) {
|
---|
110 | getReporter().log(Level.INFO, "Final outcome:" + info);
|
---|
111 | }
|
---|
112 | } catch (Exception e) {
|
---|
113 | throw new RuntimeException("Failed to handle info", e);
|
---|
114 | }
|
---|
115 |
|
---|
116 | }
|
---|
117 |
|
---|
118 | public void myTurn() throws Exception {
|
---|
119 |
|
---|
120 | Action actiontotake;
|
---|
121 | boolean chec = true;
|
---|
122 | boolean last_turns = false;
|
---|
123 |
|
---|
124 | if (total_round - 1 < opponets_bid.size() / 2) {
|
---|
125 | actiontotake = new Accept(me, lastReceivedBid);
|
---|
126 | getConnection().send(actiontotake);
|
---|
127 | last_turns = true;
|
---|
128 |
|
---|
129 | }
|
---|
130 | if (turn_count > 15 && !last_turns) {
|
---|
131 | // acceptance
|
---|
132 | if (my_bids.size() > 1 && calculate_weight(lastReceivedBid) >= least_w) {
|
---|
133 | actiontotake = new Accept(me, lastReceivedBid);
|
---|
134 | getConnection().send(actiontotake);
|
---|
135 | chec = false;
|
---|
136 | }
|
---|
137 |
|
---|
138 | }
|
---|
139 | // bidding
|
---|
140 | if (chec && !last_turns) {
|
---|
141 | Bid bid = opponentSituation();
|
---|
142 | my_bids.add(bid);
|
---|
143 | actiontotake = new Offer(me, bid);
|
---|
144 | if (calculate_weight(bid) < least_w)
|
---|
145 | least_w = calculate_weight(bid);
|
---|
146 | current_bid++;
|
---|
147 | getConnection().send(actiontotake);
|
---|
148 | }
|
---|
149 | }
|
---|
150 |
|
---|
151 | public Bid opponentSituation() {
|
---|
152 | Map<Bid, Integer> last10round = new HashMap<>();
|
---|
153 | int max_repeated_count = Integer.MIN_VALUE;
|
---|
154 | int bid_count = 0;
|
---|
155 | if (opponets_bid.size() > 9) {
|
---|
156 | for (int i = opponets_bid.size() - 10; i < opponets_bid.size(); i++) {
|
---|
157 | if (last10round.containsKey(opponets_bid.get(i))) {
|
---|
158 | last10round.replace(opponets_bid.get(i), last10round.get(opponets_bid.get(i)) + 1);
|
---|
159 | if (last10round.get(opponets_bid.get(i)) > max_repeated_count)
|
---|
160 | max_repeated_count = last10round.get(opponets_bid.get(i));
|
---|
161 | } else {
|
---|
162 | last10round.put(opponets_bid.get(i), 1);
|
---|
163 | if (max_repeated_count == Integer.MIN_VALUE)
|
---|
164 | max_repeated_count = 1;
|
---|
165 | bid_count++;
|
---|
166 | }
|
---|
167 | }
|
---|
168 |
|
---|
169 | if (max_repeated_count >= 5 && dont_repeat) {
|
---|
170 |
|
---|
171 | current_bid = current_bid - max_repeated_count > 0 ? current_bid - max_repeated_count : 0;
|
---|
172 | dont_repeat = false;
|
---|
173 | } else if (bid_count < 5 && dont_repeat) {
|
---|
174 | current_bid = current_bid - (5 - bid_count) > 0 ? current_bid - 5 + bid_count : 0;
|
---|
175 | dont_repeat = false;
|
---|
176 | } else {
|
---|
177 | random = new Random();
|
---|
178 | double rr = random.nextDouble();
|
---|
179 | repeating_count++;
|
---|
180 | if (repeating_count > 3) {
|
---|
181 | dont_repeat = true;
|
---|
182 | repeating_count = 0;
|
---|
183 | }
|
---|
184 | if (rr < 0.5)
|
---|
185 | current_bid = current_bid - (int) (rr * 10) > 0 ? current_bid - (int) (rr * 10) : current_bid;
|
---|
186 | }
|
---|
187 | }
|
---|
188 |
|
---|
189 | return sortedPredictedBids.get(current_bid);
|
---|
190 | }
|
---|
191 |
|
---|
192 | public double calculate_weight(Bid x) {
|
---|
193 | return 1.0 - ((double) sortedPredictedBids.indexOf(x) / (double) sortedPredictedBids.size());
|
---|
194 | }
|
---|
195 |
|
---|
196 | public static List<List<String>> generateAllPossibleBids(List<List<String>> input, int i) {
|
---|
197 |
|
---|
198 | if (i == input.size()) {
|
---|
199 | List<List<String>> result = new ArrayList<>();
|
---|
200 | result.add(new ArrayList<>());
|
---|
201 | return result;
|
---|
202 | }
|
---|
203 |
|
---|
204 | List<List<String>> result = new ArrayList<>();
|
---|
205 | List<List<String>> recursive = generateAllPossibleBids(input, i + 1);
|
---|
206 |
|
---|
207 | for (int j = 0; j < input.get(i).size(); j++) {
|
---|
208 | for (int k = 0; k < recursive.size(); k++) {
|
---|
209 | List<String> newList = new ArrayList<String>(recursive.get(k));
|
---|
210 | newList.add(input.get(i).get(j));
|
---|
211 | result.add(newList);
|
---|
212 | }
|
---|
213 | }
|
---|
214 | return result;
|
---|
215 | }
|
---|
216 |
|
---|
217 | public void elicitation() {
|
---|
218 | int howmanyvalue = 0;
|
---|
219 | try {
|
---|
220 |
|
---|
221 | List<List<String>> allValues = new ArrayList<>();
|
---|
222 | List<List<Value>> allValuesAsValues = new ArrayList<>();
|
---|
223 | List<String> types = new ArrayList<>();
|
---|
224 | Set<String> issues = profileint.getProfile().getDomain().getIssues();
|
---|
225 |
|
---|
226 | for (String s : issues) {
|
---|
227 | ArrayList<String> temp = new ArrayList<>();
|
---|
228 | ArrayList<Value> temp_v = new ArrayList<>();
|
---|
229 | ValueSet vs = profileint.getProfile().getDomain().getValues(s);
|
---|
230 | for (Value v : vs) {
|
---|
231 | howmanyvalue++;
|
---|
232 | if (v instanceof DiscreteValue) {
|
---|
233 | temp.add(((DiscreteValue) v).getValue());
|
---|
234 | temp_v.add(v);
|
---|
235 | types.add("Discrete");
|
---|
236 | } else if (v instanceof NumberValue) {
|
---|
237 | temp.add(((NumberValue) v).getValue().toString());
|
---|
238 | temp_v.add(v);
|
---|
239 | types.add("Number");
|
---|
240 | }
|
---|
241 | }
|
---|
242 | allValues.add(temp);
|
---|
243 | allValuesAsValues.add(temp_v);
|
---|
244 | }
|
---|
245 | this.allPossibleBids = generateAllPossibleBids(allValues, 0);
|
---|
246 | double[][] encodedValues = oneHotEncoder(allPossibleBids, howmanyvalue, allValuesAsValues);
|
---|
247 |
|
---|
248 | List<List<String>> givenBids = new ArrayList<>();
|
---|
249 | List<Bid> sb = estimatedProfile.getSortedBids((profileint.getProfile()));
|
---|
250 | for (Bid b : sb) {
|
---|
251 | List<String> temp_ls = new ArrayList<>();
|
---|
252 | for (String is : issues) {
|
---|
253 | if (b.getValue(is) instanceof DiscreteValue) {
|
---|
254 | temp_ls.add(((DiscreteValue) b.getValue(is)).getValue());
|
---|
255 | } else if (b.getValue(is) instanceof NumberValue) {
|
---|
256 | temp_ls.add(((NumberValue) b.getValue(is)).getValue().toString());
|
---|
257 | }
|
---|
258 | }
|
---|
259 | givenBids.add(temp_ls);
|
---|
260 | }
|
---|
261 | double[][] encodedTrainValues = oneHotEncoder(givenBids, howmanyvalue, allValuesAsValues);
|
---|
262 |
|
---|
263 | double[] indexes = new double[encodedTrainValues.length];
|
---|
264 | for (int i = 1; i <= indexes.length; i++)
|
---|
265 | indexes[i - 1] = i * 2;
|
---|
266 | regression = new OLSMultipleLinearRegression();
|
---|
267 | double[] bid_prediction = new double[encodedValues.length];
|
---|
268 | boolean axet = true;
|
---|
269 | try {
|
---|
270 | regression.newSampleData(indexes, encodedTrainValues);
|
---|
271 | } catch (Exception e) {
|
---|
272 | for (int i = 0; i < encodedValues.length; i++) {
|
---|
273 | random = new Random();
|
---|
274 | bid_prediction[i] = random.nextDouble();
|
---|
275 | axet = false;
|
---|
276 | }
|
---|
277 | }
|
---|
278 |
|
---|
279 | try {
|
---|
280 | for (int i = 0; i < encodedValues.length && axet; i++) {
|
---|
281 | bid_prediction[i] = predict(regression, encodedValues[i]);
|
---|
282 | }
|
---|
283 | } catch (Exception e) {
|
---|
284 | for (int i = 0; i < encodedValues.length; i++) {
|
---|
285 | random = new Random();
|
---|
286 | bid_prediction[i] = random.nextDouble();
|
---|
287 | }
|
---|
288 | }
|
---|
289 | List<Bid> lob = new ArrayList<>();
|
---|
290 | for (int i = 0; i < encodedValues.length; i++) {
|
---|
291 | Map<String, Value> msv = new HashMap<>();
|
---|
292 | for (String s : issues) {
|
---|
293 | for (int j = 0; j < allPossibleBids.get(i).size(); j++) {
|
---|
294 | if (types.get(j).equals("Discrete") && profileint.getProfile().getDomain().getValues(s)
|
---|
295 | .toString().contains(allPossibleBids.get(i).get(j)))
|
---|
296 | msv.put(s, new DiscreteValue(allPossibleBids.get(i).get(j)));
|
---|
297 | else if (types.get(j).equals("Number") && profileint.getProfile().getDomain().getValues(s)
|
---|
298 | .toString().contains(allPossibleBids.get(i).get(j)))
|
---|
299 | msv.put(s, new NumberValue(allPossibleBids.get(i).get(j)));
|
---|
300 | }
|
---|
301 | }
|
---|
302 | sortedPredictedBids.add(new Bid(msv));
|
---|
303 | lob.add(new Bid(msv));
|
---|
304 | }
|
---|
305 |
|
---|
306 | sortedPredictedBids.sort(Comparator.comparing(s -> bid_prediction[lob.indexOf(s)]));
|
---|
307 |
|
---|
308 | } catch (Exception e) {
|
---|
309 | System.out.println("Couldn't elicitate");
|
---|
310 | e.printStackTrace();
|
---|
311 | }
|
---|
312 | }
|
---|
313 |
|
---|
314 | public static double[][] oneHotEncoder(List<List<String>> bidOrder, int countAll, List<List<Value>> allIssues) {
|
---|
315 | double[][] oneHotEncoded = new double[bidOrder.size()][countAll];
|
---|
316 | int count = 0;
|
---|
317 | for (int i = 0; i < oneHotEncoded.length; i++) {
|
---|
318 | for (int j = 0; j < oneHotEncoded[0].length; j++) {
|
---|
319 | for (int k = 0; k < bidOrder.get(i).size(); k++) {
|
---|
320 | for (int l = 0; l < allIssues.get(k).size(); l++) {
|
---|
321 | boolean cget = true;
|
---|
322 | if (bidOrder.get(i).get(k) == null)
|
---|
323 | oneHotEncoded[i][count] = 0.5;
|
---|
324 | else if (allIssues.get(k).get(l) instanceof DiscreteValue) {
|
---|
325 | if (bidOrder.get(i).get(k).equals(((DiscreteValue) allIssues.get(k).get(l)).getValue())) {
|
---|
326 | oneHotEncoded[i][count] = 1.0;
|
---|
327 | cget = false;
|
---|
328 | }
|
---|
329 | } else if (allIssues.get(i).get(k) instanceof NumberValue) {
|
---|
330 | if (bidOrder.get(i).get(k)
|
---|
331 | .equals(((NumberValue) allIssues.get(k).get(l)).getValue().toString())) {
|
---|
332 | oneHotEncoded[i][count] = 1.0;
|
---|
333 | cget = false;
|
---|
334 | }
|
---|
335 | }
|
---|
336 | if (cget) {
|
---|
337 | oneHotEncoded[i][count] = 0.0;
|
---|
338 | }
|
---|
339 | count++;
|
---|
340 | }
|
---|
341 | }
|
---|
342 | count = 0;
|
---|
343 | }
|
---|
344 | }
|
---|
345 | return oneHotEncoded;
|
---|
346 | }
|
---|
347 |
|
---|
348 | public static double predict(OLSMultipleLinearRegression regression, double[] x) {
|
---|
349 | if (regression == null) {
|
---|
350 | throw new IllegalArgumentException("Null Object");
|
---|
351 | }
|
---|
352 | double[] params = regression.estimateRegressionParameters();
|
---|
353 | double prediction = params[0];
|
---|
354 | for (int i = 1; i < params.length; i++) {
|
---|
355 | prediction += params[i] * x[i - 1];
|
---|
356 | }
|
---|
357 | return prediction;
|
---|
358 | }
|
---|
359 |
|
---|
360 | }
|
---|