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