source: anac2020/AhBuNeAgent/src/main/java/negotiator/ahbuneagent/AhBuNeAgent.java

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

#5 fix supported profile type

File size: 12.5 KB
Line 
1package negotiator.ahbuneagent;
2
3import static java.lang.Math.pow;
4
5import java.io.IOException;
6import java.math.BigDecimal;
7import java.math.BigInteger;
8import java.util.ArrayList;
9import java.util.Arrays;
10import java.util.Collections;
11import java.util.HashSet;
12import java.util.LinkedHashMap;
13import java.util.Map;
14import java.util.Random;
15import java.util.Set;
16import java.util.logging.Level;
17
18import javax.websocket.DeploymentException;
19
20import geniusweb.actions.Accept;
21import geniusweb.actions.Action;
22import geniusweb.actions.Comparison;
23import geniusweb.actions.ElicitComparison;
24import geniusweb.actions.EndNegotiation;
25import geniusweb.actions.Offer;
26import geniusweb.actions.PartyId;
27import geniusweb.bidspace.AllBidsList;
28import geniusweb.inform.ActionDone;
29import geniusweb.inform.Finished;
30import geniusweb.inform.Inform;
31import geniusweb.inform.Settings;
32import geniusweb.inform.YourTurn;
33import geniusweb.issuevalue.Bid;
34import geniusweb.party.Capabilities;
35import geniusweb.party.DefaultParty;
36import geniusweb.profile.FullOrdering;
37import geniusweb.profile.PartialOrdering;
38import geniusweb.profileconnection.ProfileConnectionFactory;
39import geniusweb.profileconnection.ProfileInterface;
40import geniusweb.progress.Progress;
41import geniusweb.progress.ProgressRounds;
42import negotiator.ahbuneagent.impmap.OppSimilarityMap;
43import negotiator.ahbuneagent.impmap.SimilarityMap;
44import negotiator.ahbuneagent.linearorder.OppSimpleLinearOrdering;
45import negotiator.ahbuneagent.linearorder.SimpleLinearOrdering;
46import tudelft.utilities.logging.Reporter;
47
48public class AhBuNeAgent extends DefaultParty {
49
50 private final Random random = new Random();
51
52 private int ourNumFirstBids;
53 private int ourNumLastBids;
54 private int oppNumFirstBids;
55 private int ourKnownBidNum = 0;
56 private int oppKnownBidNum = 0;
57
58 protected ProfileInterface profileInterface;
59 private PartyId partyId;
60 private Progress progress;
61 private double time = 0.0;
62
63 private AllBidsList allPossibleBids;
64 private BigInteger allPossibleBidsSize;
65 private SimpleLinearOrdering ourLinearPartialOrdering = null;
66 private OppSimpleLinearOrdering oppLinearPartialOrdering = null;
67 private SimilarityMap ourSimilarityMap = null;
68 private OppSimilarityMap oppSimilarityMap = null;
69
70 private Bid lastReceivedBid = null;
71 private double utilityLowerBound = 1.0;
72 private final double ourMaxCompromise = 0.1;
73
74 // Initially no loss
75 private double lostElicitScore = 0.00;
76 // Set default as 0.01 by Genius Framework
77 private double elicitationCost = 0.01;
78 private final BigDecimal maxElicitationLost = new BigDecimal("0.05");
79 private int leftElicitationNumber = 0;
80 Bid elicitationBid = null;
81 ArrayList<Map.Entry<Bid, Integer>> mostCompromisedBids = new ArrayList<>();
82 ArrayList<Bid> oppElicitatedBid = new ArrayList<>();
83 private Bid reservationBid = null;
84
85 public AhBuNeAgent() {
86 }
87
88 public AhBuNeAgent(Reporter reporter) {
89 super(reporter);
90 }
91
92 @Override
93 public Capabilities getCapabilities() {
94 return new Capabilities(new HashSet<>(Arrays.asList("SHAOP", "SAOP")),
95 Collections.singleton(PartialOrdering.class));
96 }
97
98 @Override
99 public String getDescription() {
100 return "AhBuNe Agent";
101 }
102
103 @Override
104 public void notifyChange(Inform info) {
105 try {
106 if (info instanceof Settings) {
107 Settings settings = (Settings) info;
108 init(settings);
109 } else if (info instanceof ActionDone) {
110 Action lastReceivedAction = ((ActionDone) info).getAction();
111 if (lastReceivedAction instanceof Offer) {
112 lastReceivedBid = ((Offer) lastReceivedAction).getBid();
113 } else if (lastReceivedAction instanceof Comparison) {
114 ourLinearPartialOrdering = ourLinearPartialOrdering.with(((Comparison) lastReceivedAction).getBid(),
115 ((Comparison) lastReceivedAction).getWorse());
116 myTurn();
117 }
118 } else if (info instanceof YourTurn) {
119 if (progress instanceof ProgressRounds) {
120 progress = ((ProgressRounds) progress).advance();
121 }
122 myTurn();
123 } else if (info instanceof Finished) {
124 }
125 } catch (Exception exception) {
126 throw new RuntimeException("Failed to handle info", exception);
127 }
128 }
129
130 private void init(Settings settings) throws IOException, DeploymentException {
131 this.partyId = settings.getID();
132 this.progress = settings.getProgress();
133 this.profileInterface = ProfileConnectionFactory.create(settings.getProfile().getURI(), getReporter());
134
135 if (profileInterface.getProfile() instanceof FullOrdering) {
136 throw new UnsupportedOperationException("Only <DefaultPartialOrdering> is supported");
137 } else if (profileInterface.getProfile() instanceof PartialOrdering) {
138 PartialOrdering partialProfile = (PartialOrdering) profileInterface.getProfile();
139 this.allPossibleBids = new AllBidsList(partialProfile.getDomain());
140 this.allPossibleBidsSize = allPossibleBids.size();
141 this.ourSimilarityMap = new SimilarityMap(partialProfile);
142 this.oppSimilarityMap = new OppSimilarityMap(partialProfile);
143 this.ourLinearPartialOrdering = new SimpleLinearOrdering(profileInterface.getProfile());
144 this.oppLinearPartialOrdering = new OppSimpleLinearOrdering();
145 this.ourSimilarityMap.update(ourLinearPartialOrdering);
146 getReservationRatio();
147 getElicitationCost(settings);
148 } else {
149 throw new UnsupportedOperationException("Only <DefaultPartialOrdering> is supported");
150 }
151
152 }
153
154 private Action selectAction() {
155 if (doWeMakeElicitation()) {
156 lostElicitScore += elicitationCost;
157 leftElicitationNumber -= 1;
158 return new ElicitComparison(partyId, elicitationBid, ourLinearPartialOrdering.getBids());
159 }
160
161 if (lastReceivedBid == null) {
162 return makeAnOffer();
163 }
164 if (doWeEndTheNegotiation()) {
165 return new EndNegotiation(partyId);
166 } else if (doWeAccept(lastReceivedBid)) {
167 return new Accept(partyId, lastReceivedBid);
168 }
169 return makeAnOffer();
170
171 }
172
173 private void myTurn() throws IOException {
174 time = progress.get(System.currentTimeMillis());
175 strategySelection();
176 Action action = selectAction();
177 getConnection().send(action);
178 }
179
180 private boolean doWeEndTheNegotiation() {
181 if (reservationBid != null && ourSimilarityMap.isCompatibleWithSimilarity(reservationBid, ourNumFirstBids,
182 ourNumLastBids, 0.9 - time * 0.1)) {
183 return true;
184 }
185 return false;
186 }
187
188 private Bid elicitationRandomBidGenerator() {
189 Bid foundBid = allPossibleBids.get(random.nextInt(allPossibleBids.size().intValue()));
190 while (ourLinearPartialOrdering.getBids().contains(foundBid)) {
191 foundBid = allPossibleBids.get(random.nextInt(allPossibleBids.size().intValue()));
192 }
193 return foundBid;
194 }
195
196 private Action makeAnOffer() {
197 if (time > 0.96) {
198 for (int i = ourLinearPartialOrdering.getKnownBidsSize() - 1; i >= 0; i--) {
199 Bid testBid = ourLinearPartialOrdering.getBidByIndex(i);
200 if (oppElicitatedBid.contains(testBid) && doWeAccept(testBid)) {
201 return new Offer(partyId, testBid);
202 }
203 }
204 }
205 Bid oppMaxBid = oppLinearPartialOrdering.getMaxBid();
206 Bid ourOffer = ourSimilarityMap.findBidCompatibleWithSimilarity(ourNumFirstBids, ourNumLastBids,
207 utilityLowerBound, oppMaxBid);
208 if (time < 0.015) {
209 if (oppLinearPartialOrdering.isAvailable()) {
210 int count = 0;
211 while (count < 500 && !oppSimilarityMap.isCompromised(ourOffer, oppNumFirstBids, 0.85)
212 && ourOffer.equals(ourLinearPartialOrdering.getMaxBid())) {
213 ourOffer = ourSimilarityMap.findBidCompatibleWithSimilarity(ourNumFirstBids, ourNumLastBids, 0.85,
214 oppMaxBid);
215 count++;
216 }
217 } else {
218 int count = 0;
219 while (count < 500 && ourOffer.equals(ourLinearPartialOrdering.getMaxBid())) {
220 ourOffer = ourSimilarityMap.findBidCompatibleWithSimilarity(ourNumFirstBids, ourNumLastBids, 0.85,
221 oppMaxBid);
222 count++;
223 }
224 }
225 } else if (lastReceivedBid != null) {
226 if (ourSimilarityMap.isCompatibleWithSimilarity(lastReceivedBid, ourNumFirstBids, ourNumLastBids, 0.9)) {
227 return new Offer(partyId, lastReceivedBid);
228 }
229 if (ourSimilarityMap.isCompatibleWithSimilarity(oppMaxBid, ourNumFirstBids, ourNumLastBids, 0.9)) {
230 return new Offer(partyId, oppMaxBid);
231 }
232 int count = 0;
233 while (count < 500 && oppLinearPartialOrdering.isAvailable()
234 && !oppSimilarityMap.isCompromised(ourOffer, oppNumFirstBids, utilityLowerBound)) {
235 ourOffer = ourSimilarityMap.findBidCompatibleWithSimilarity(ourNumFirstBids, ourNumLastBids,
236 utilityLowerBound, oppMaxBid);
237 }
238 }
239 return new Offer(partyId, ourOffer);
240 }
241
242 private boolean doWeAccept(Bid bid) {
243 if (ourSimilarityMap.isCompatibleWithSimilarity(bid, ourNumFirstBids, ourNumLastBids, 0.9)) {
244 return true;
245 }
246
247 double startUtilitySearch = utilityLowerBound;
248
249 if (time >= 0.98) {
250 startUtilitySearch = utilityLowerBound - ourMaxCompromise;
251 }
252
253 if (oppLinearPartialOrdering.isAvailable()) {
254 for (int i = (int) (startUtilitySearch * 100); i <= 95; i += 5) {
255 double utilityTest = i / 100.0;
256 if (oppSimilarityMap.isCompromised(bid, oppNumFirstBids, utilityTest)) {
257 if (ourSimilarityMap.isCompatibleWithSimilarity(bid, ourNumFirstBids, ourNumLastBids,
258 utilityTest)) {
259 return true;
260 }
261 break;
262 }
263 }
264 }
265 return false;
266 }
267
268 private boolean doWeMakeElicitation() {
269 if (leftElicitationNumber == 0) {
270 return false;
271 }
272 if (allPossibleBidsSize.intValue() <= 100) {
273 if (ourLinearPartialOrdering.getKnownBidsSize() < allPossibleBidsSize.intValue() * 0.1) {
274 elicitationBid = elicitationRandomBidGenerator();
275 return true;
276 }
277 } else if (ourLinearPartialOrdering.getKnownBidsSize() < 10) {
278 elicitationBid = elicitationRandomBidGenerator();
279 return true;
280 } else if (time > 0.98 && oppLinearPartialOrdering.isAvailable()) {
281 if (mostCompromisedBids.size() > 0) {
282 elicitationBid = mostCompromisedBids.remove(mostCompromisedBids.size() - 1).getKey();
283 oppElicitatedBid.add(elicitationBid);
284 return true;
285 } else {
286 LinkedHashMap<Bid, Integer> mostCompromisedBidsHash = oppSimilarityMap.mostCompromisedBids();
287 Set<Map.Entry<Bid, Integer>> sortedCompromiseMapSet = mostCompromisedBidsHash.entrySet();
288 mostCompromisedBids = new ArrayList<>(sortedCompromiseMapSet);
289 elicitationBid = mostCompromisedBids.remove(mostCompromisedBids.size() - 1).getKey();
290 oppElicitatedBid.add(elicitationBid);
291 return true;
292 }
293 }
294 return false;
295 }
296
297 private void strategySelection() {
298 utilityLowerBound = getUtilityLowerBound(time, lostElicitScore);
299 ourKnownBidNum = ourLinearPartialOrdering.getKnownBidsSize();
300 oppKnownBidNum = oppLinearPartialOrdering.getKnownBidsSize();
301 ourNumFirstBids = getNumFirst(utilityLowerBound, ourKnownBidNum);
302 ourNumLastBids = getNumLast(utilityLowerBound, getUtilityLowerBound(1.0, lostElicitScore), ourKnownBidNum);
303 if (lastReceivedBid != null) {
304 oppLinearPartialOrdering.updateBid(lastReceivedBid);
305 oppSimilarityMap.update(oppLinearPartialOrdering);
306 oppNumFirstBids = getOppNumFirst(utilityLowerBound, oppKnownBidNum);
307 }
308 }
309
310 private void getElicitationCost(Settings settings) {
311 try {
312 elicitationCost = Double.parseDouble(settings.getParameters().get("elicitationcost").toString());
313 leftElicitationNumber = (int) (maxElicitationLost.doubleValue() / elicitationCost);
314 reporter.log(Level.INFO, "leftElicitationNumber: " + leftElicitationNumber);
315 } catch (Exception e) {
316 elicitationCost = 0.01;
317 leftElicitationNumber = (int) (maxElicitationLost.doubleValue() / elicitationCost);
318 reporter.log(Level.INFO, "catch leftElicitationNumber: " + leftElicitationNumber);
319 }
320 }
321
322 private void getReservationRatio() {
323 try {
324 reservationBid = profileInterface.getProfile().getReservationBid();
325 } catch (Exception e) {
326 reservationBid = null;
327 }
328 }
329
330 double getUtilityLowerBound(double time, double lostElicitScore) {
331 if (time < 0.5) {
332 return -pow((time - 0.25), 2) + 0.9 + lostElicitScore;
333 } else if (time < 0.7) {
334 return -pow((1.5 * (time - 0.7)), 2) + 0.9 + lostElicitScore;
335 }
336 return (3.25 * time * time) - (6.155 * time) + 3.6105 + lostElicitScore;
337 }
338
339 int getNumFirst(double utilityLowerBound, int knownBidNum) {
340 return ((int) (knownBidNum * (1 - utilityLowerBound)) + 1);
341 }
342
343 int getNumLast(double utilityLowerBound, double minUtilityLowerBound, int ourKnownBidNum) {
344 return ((int) (ourKnownBidNum * (1 - minUtilityLowerBound)) - (int) (ourKnownBidNum * (1 - utilityLowerBound))
345 + 1);
346 }
347
348 int getOppNumFirst(double utilityLowerBound, int oppKnownBidNum) {
349 return ((int) (oppKnownBidNum * (1 - utilityLowerBound)) + 1);
350 }
351}
Note: See TracBrowser for help on using the repository browser.