1 | package parties.in4010.q12015.group18;
|
---|
2 |
|
---|
3 | import java.util.ArrayList;
|
---|
4 | import java.util.List;
|
---|
5 |
|
---|
6 | import genius.core.AgentID;
|
---|
7 | import genius.core.Bid;
|
---|
8 | import genius.core.actions.Accept;
|
---|
9 | import genius.core.actions.Action;
|
---|
10 | import genius.core.actions.DefaultAction;
|
---|
11 | import genius.core.actions.Offer;
|
---|
12 | import genius.core.issue.IssueDiscrete;
|
---|
13 | import genius.core.issue.ValueDiscrete;
|
---|
14 | import genius.core.parties.AbstractNegotiationParty;
|
---|
15 | import genius.core.utility.AdditiveUtilitySpace;
|
---|
16 | import genius.core.utility.EvaluatorDiscrete;
|
---|
17 |
|
---|
18 | /**
|
---|
19 | * This is our negotiation agent.
|
---|
20 | */
|
---|
21 | public class Group18 extends AbstractNegotiationParty {
|
---|
22 |
|
---|
23 | private int LastSenderId;
|
---|
24 | private Bid LastBid;
|
---|
25 | private boolean bidListInit = false;
|
---|
26 | private ArrayList<Bid>[] partiesBidList;
|
---|
27 | private ArrayList<String> partiesNameList = new ArrayList<String>();
|
---|
28 | private ArrayList<AdditiveUtilitySpace> OpponentUtilities = new ArrayList<AdditiveUtilitySpace>();
|
---|
29 |
|
---|
30 | // This function will give the final action by calling the BiddingStrategy
|
---|
31 | // and the AcceptStrategie
|
---|
32 | @Override
|
---|
33 | public Action chooseAction(List<Class<? extends Action>> validActions) {
|
---|
34 |
|
---|
35 | Action upcomingBid = BiddingStrategy();
|
---|
36 | Action finalAction = AcceptStrategy(validActions, upcomingBid);
|
---|
37 | return finalAction;
|
---|
38 | }
|
---|
39 |
|
---|
40 | // This function determines the next bid you are going to propose
|
---|
41 | public Action BiddingStrategy() {
|
---|
42 | Bid[] PossibleBids = new Bid[((AdditiveUtilitySpace) utilitySpace)
|
---|
43 | .getNrOfEvaluators()];
|
---|
44 | Double[] UtilityPossibleBids = new Double[((AdditiveUtilitySpace) utilitySpace)
|
---|
45 | .getNrOfEvaluators()];
|
---|
46 |
|
---|
47 | Bid MyBestBid;
|
---|
48 | try {// gets the best bid, if this doesnt work, it will use a random bid
|
---|
49 | // to have some thing to work with
|
---|
50 | MyBestBid = this.getUtilitySpace().getMaxUtilityBid();
|
---|
51 | } catch (Exception e) {
|
---|
52 | e.printStackTrace();
|
---|
53 | MyBestBid = generateRandomBid();
|
---|
54 | }// generates the max utility bid, in case this can not be found returns
|
---|
55 | // a random bid, is bad should be a better solution.
|
---|
56 |
|
---|
57 | double TimePercentage = this.getTimeLine().getTime();// should give a
|
---|
58 | // percentage of
|
---|
59 | // the max time
|
---|
60 | double TimeFactor;
|
---|
61 | if (TimePercentage < .75) {
|
---|
62 | TimeFactor = .9;
|
---|
63 | } else if (TimePercentage < .9) {
|
---|
64 | TimeFactor = .8;
|
---|
65 | } else {
|
---|
66 | TimeFactor = .7;
|
---|
67 | }// values herein are just arbitrary selected, but because the results
|
---|
68 | // are good, they are used
|
---|
69 |
|
---|
70 | Bid RandomBid;
|
---|
71 | for (int RandomBidNo = 0; RandomBidNo < ((AdditiveUtilitySpace) utilitySpace)
|
---|
72 | .getNrOfEvaluators(); RandomBidNo++) {
|
---|
73 | do {
|
---|
74 | RandomBid = generateRandomBid();
|
---|
75 | } while (this.getUtility(RandomBid) < this.getUtility(MyBestBid)
|
---|
76 | * TimeFactor);
|
---|
77 | PossibleBids[RandomBidNo] = RandomBid;
|
---|
78 |
|
---|
79 | if (TimePercentage > 0.25) {
|
---|
80 | double TotalOpponentUtilityRandomBid = 0;
|
---|
81 | double MaxOpponentUtilityRandomBid = 0;
|
---|
82 | for (AdditiveUtilitySpace Opponent : OpponentUtilities) {
|
---|
83 | try {
|
---|
84 | TotalOpponentUtilityRandomBid = TotalOpponentUtilityRandomBid
|
---|
85 | + Opponent
|
---|
86 | .getUtility(PossibleBids[RandomBidNo]);
|
---|
87 | if (Opponent.getUtility(PossibleBids[RandomBidNo]) > MaxOpponentUtilityRandomBid) {
|
---|
88 | MaxOpponentUtilityRandomBid = Opponent
|
---|
89 | .getUtility(PossibleBids[RandomBidNo]);
|
---|
90 | }
|
---|
91 | Opponent.getUtility(PossibleBids[RandomBidNo]);
|
---|
92 | } catch (Exception e) {
|
---|
93 | e.printStackTrace();
|
---|
94 | }
|
---|
95 | }
|
---|
96 | UtilityPossibleBids[RandomBidNo] = TotalOpponentUtilityRandomBid
|
---|
97 | / OpponentUtilities.size()
|
---|
98 | + getUtility(PossibleBids[RandomBidNo])
|
---|
99 | - MaxOpponentUtilityRandomBid;
|
---|
100 | } else {
|
---|
101 | UtilityPossibleBids[RandomBidNo] = getUtility(RandomBid);
|
---|
102 | }
|
---|
103 | }
|
---|
104 |
|
---|
105 | double BestBidValue = 0;
|
---|
106 | int BestBidNo = 0;
|
---|
107 | for (int RandomBidNo = 0; RandomBidNo < ((AdditiveUtilitySpace) utilitySpace)
|
---|
108 | .getNrOfEvaluators(); RandomBidNo++) {
|
---|
109 | if (UtilityPossibleBids[RandomBidNo] > BestBidValue) {
|
---|
110 | BestBidValue = UtilityPossibleBids[RandomBidNo];
|
---|
111 | BestBidNo = RandomBidNo;
|
---|
112 | }
|
---|
113 | }
|
---|
114 | return new Offer(getPartyId(), PossibleBids[BestBidNo]);
|
---|
115 | }
|
---|
116 |
|
---|
117 | // This function determines if the current bid should be accepted based your
|
---|
118 | // new bid
|
---|
119 | public Action AcceptStrategy(List<Class<? extends Action>> validActions,
|
---|
120 | Action upcomingBid) {
|
---|
121 |
|
---|
122 | double TimePercentage = this.getTimeLine().getTime();
|
---|
123 | double TimeFactor;
|
---|
124 |
|
---|
125 | if (TimePercentage < 0.25) {
|
---|
126 | TimeFactor = 0.9; // for the first 25% of the time only accept 0.9
|
---|
127 | // or higher
|
---|
128 | } else {
|
---|
129 | TimeFactor = (0.5) * (1 - TimePercentage) + 0.5; // after that
|
---|
130 | // linearly
|
---|
131 | // decrease to 0
|
---|
132 | // at time = 1
|
---|
133 | }
|
---|
134 |
|
---|
135 | // System.out.print(timeFactor);
|
---|
136 | if (validActions.contains(Accept.class)
|
---|
137 | && (this.getUtility(LastBid) > TimeFactor || this
|
---|
138 | .getUtility(LastBid) > this.getUtility(DefaultAction
|
---|
139 | .getBidFromAction(upcomingBid)))) {
|
---|
140 |
|
---|
141 | try {
|
---|
142 | if (TimePercentage > .25
|
---|
143 | && TimePercentage < .95
|
---|
144 | && OpponentUtilities.get(LastSenderId).getUtility(
|
---|
145 | LastBid) > this.utilitySpace
|
---|
146 | .getUtility(LastBid)) {
|
---|
147 | return upcomingBid;
|
---|
148 | }
|
---|
149 | } catch (Exception e) {
|
---|
150 | e.printStackTrace();
|
---|
151 | }
|
---|
152 |
|
---|
153 | return new Accept(getPartyId(), LastBid); // accept if accept is
|
---|
154 | // possible and
|
---|
155 | // bid is
|
---|
156 | // higher then our own bid or bid is higher
|
---|
157 | // then the reference which decreases with
|
---|
158 | // time.
|
---|
159 | } else {
|
---|
160 | return upcomingBid;
|
---|
161 | }
|
---|
162 |
|
---|
163 | }
|
---|
164 |
|
---|
165 | // This function receives the message, stores the bid and calls the function
|
---|
166 | // UpdateOpponentModel
|
---|
167 | @Override
|
---|
168 | public void receiveMessage(AgentID sender, Action action) {
|
---|
169 | super.receiveMessage(sender, action);
|
---|
170 |
|
---|
171 | int OpponentIDNo = 0;
|
---|
172 |
|
---|
173 | if (!(bidListInit)) {
|
---|
174 | initializeBidList(); // initialize structures to keep track of all
|
---|
175 | // bids
|
---|
176 | } else {
|
---|
177 | if (!(sender == null)) {
|
---|
178 | String OpponentID = sender.toString(); // determine the sender
|
---|
179 | // of
|
---|
180 | // the bid
|
---|
181 | if (partiesNameList.indexOf(OpponentID) == -1) {
|
---|
182 | partiesNameList.add(OpponentID); // if the sender is not yet
|
---|
183 | // in the list of
|
---|
184 | // participants, add it
|
---|
185 | }
|
---|
186 | OpponentIDNo = partiesNameList.indexOf(OpponentID);
|
---|
187 | LastSenderId = OpponentIDNo;
|
---|
188 | if (DefaultAction.getBidFromAction(action) != null) {
|
---|
189 | partiesBidList[OpponentIDNo].add(DefaultAction
|
---|
190 | .getBidFromAction(action)); // add the bid to the
|
---|
191 | // list add index of ID
|
---|
192 | }
|
---|
193 | }
|
---|
194 | }
|
---|
195 | LastBid = DefaultAction.getBidFromAction(action); // save bid as last
|
---|
196 | // bid
|
---|
197 | UpdateOpponentModel(sender, action);
|
---|
198 | }
|
---|
199 |
|
---|
200 | // This function is used to update the opponent model
|
---|
201 | public void UpdateOpponentModel(AgentID sender, Action action) {
|
---|
202 | if (sender == null) {
|
---|
203 | return;
|
---|
204 | }
|
---|
205 |
|
---|
206 | int OpponentIDNo = 0;
|
---|
207 | ArrayList<Bid> CurrentBidList = null;
|
---|
208 |
|
---|
209 | // Different Evaluators are weighted.
|
---|
210 | // STEP 0, create structures to save weights
|
---|
211 | double[] EvaluatorWeights = new double[((AdditiveUtilitySpace) utilitySpace)
|
---|
212 | .getNrOfEvaluators()];
|
---|
213 | double sumEvaluatorWeights = 0; // needed to normalize
|
---|
214 |
|
---|
215 | // STEP 1, extract bid list of current opponent
|
---|
216 | String OpponentID = String.valueOf(sender); // determine the sender of
|
---|
217 | // the bid
|
---|
218 |
|
---|
219 | if (partiesNameList.indexOf(OpponentID) == -1) {
|
---|
220 | partiesNameList.add(OpponentID); // if the sender is not yet in the
|
---|
221 | // list of participants, add it
|
---|
222 | }
|
---|
223 | OpponentIDNo = partiesNameList.indexOf(OpponentID);
|
---|
224 | CurrentBidList = partiesBidList[OpponentIDNo]; // add the bid to the
|
---|
225 | // list add index of ID
|
---|
226 |
|
---|
227 | // STEP 2, count number of changes per Evaluator
|
---|
228 | for (int EvaluatorNo = 0; EvaluatorNo < ((AdditiveUtilitySpace) utilitySpace)
|
---|
229 | .getNrOfEvaluators(); EvaluatorNo++) {
|
---|
230 | EvaluatorWeights[EvaluatorNo] = OpponentUtilities.get(OpponentIDNo)
|
---|
231 | .getEvaluator(EvaluatorNo + 1).getWeight();
|
---|
232 | try {
|
---|
233 | if (CurrentBidList.size() > 1) {
|
---|
234 | if (CurrentBidList
|
---|
235 | .get(CurrentBidList.size() - 1)
|
---|
236 | .getValue(EvaluatorNo + 1)
|
---|
237 | .equals(CurrentBidList.get(
|
---|
238 | CurrentBidList.size() - 2).getValue(
|
---|
239 | EvaluatorNo + 1))) {
|
---|
240 | EvaluatorWeights[EvaluatorNo] = EvaluatorWeights[EvaluatorNo] + 0.1;
|
---|
241 | }
|
---|
242 | }
|
---|
243 | } catch (Exception e) {
|
---|
244 | e.printStackTrace();
|
---|
245 | }
|
---|
246 | sumEvaluatorWeights = sumEvaluatorWeights
|
---|
247 | + EvaluatorWeights[EvaluatorNo];
|
---|
248 | }
|
---|
249 |
|
---|
250 | // STEP 3, Normalize and update weights in model
|
---|
251 | for (int EvaluatorNo = 0; EvaluatorNo < ((AdditiveUtilitySpace) utilitySpace)
|
---|
252 | .getNrOfEvaluators(); EvaluatorNo++) {
|
---|
253 | OpponentUtilities
|
---|
254 | .get(OpponentIDNo)
|
---|
255 | .getEvaluator(EvaluatorNo + 1)
|
---|
256 | .setWeight(
|
---|
257 | EvaluatorWeights[EvaluatorNo] / sumEvaluatorWeights);
|
---|
258 | // Different issues in the Evaluators are checked
|
---|
259 | switch (OpponentUtilities.get(OpponentIDNo).getDomain().getIssues()
|
---|
260 | .get(EvaluatorNo).getType()) {
|
---|
261 | case DISCRETE:
|
---|
262 | IssueDiscrete DiscreteIssue = (IssueDiscrete) this.utilitySpace
|
---|
263 | .getDomain().getIssues().get(EvaluatorNo);
|
---|
264 | double[] ValuesAppearance = new double[DiscreteIssue
|
---|
265 | .getNumberOfValues()];
|
---|
266 |
|
---|
267 | // STEP 4, Count number of Appearances of values
|
---|
268 | double MaxAppearance = 0;
|
---|
269 | for (int IssueNo = 0; IssueNo < DiscreteIssue
|
---|
270 | .getNumberOfValues(); IssueNo++) {
|
---|
271 | for (int BidNo = 0; BidNo < partiesBidList[OpponentIDNo]
|
---|
272 | .size(); BidNo++) {
|
---|
273 | try {
|
---|
274 | if (DiscreteIssue.getValue(IssueNo).equals(
|
---|
275 | partiesBidList[OpponentIDNo].get(BidNo)
|
---|
276 | .getValue(EvaluatorNo + 1))) {
|
---|
277 | ValuesAppearance[IssueNo]++;
|
---|
278 | }
|
---|
279 | } catch (Exception e) {
|
---|
280 | e.printStackTrace();
|
---|
281 | }
|
---|
282 | }
|
---|
283 | if (ValuesAppearance[IssueNo] > MaxAppearance) {
|
---|
284 | MaxAppearance = ValuesAppearance[IssueNo];
|
---|
285 | }
|
---|
286 | }
|
---|
287 | // STEP 5, normalize and update value grades
|
---|
288 | for (int IssueNo = 0; IssueNo < DiscreteIssue
|
---|
289 | .getNumberOfValues(); IssueNo++) {
|
---|
290 | ValuesAppearance[IssueNo] = ValuesAppearance[IssueNo]
|
---|
291 | / MaxAppearance;
|
---|
292 | EvaluatorDiscrete CurrentEvaluator = (EvaluatorDiscrete) OpponentUtilities
|
---|
293 | .get(OpponentIDNo).getEvaluator(EvaluatorNo + 1);
|
---|
294 | try {
|
---|
295 | CurrentEvaluator
|
---|
296 | .setEvaluationDouble(
|
---|
297 | (ValueDiscrete) DiscreteIssue
|
---|
298 | .getValue(IssueNo),
|
---|
299 | ValuesAppearance[IssueNo]);
|
---|
300 | } catch (Exception e) {
|
---|
301 | e.printStackTrace();
|
---|
302 | }
|
---|
303 | }
|
---|
304 | break;
|
---|
305 | default:
|
---|
306 | break;
|
---|
307 | }
|
---|
308 | }
|
---|
309 |
|
---|
310 | }
|
---|
311 |
|
---|
312 | // Initialize ArrayLists to record bid by opponents
|
---|
313 | public void initializeBidList() {
|
---|
314 | partiesBidList = new ArrayList[this.getNumberOfParties() - 1];
|
---|
315 | for (int PartyNo = 1; PartyNo < this.getNumberOfParties(); PartyNo++) { // for
|
---|
316 | // every
|
---|
317 | // other
|
---|
318 | // player
|
---|
319 | // make
|
---|
320 | // an
|
---|
321 | // array
|
---|
322 | // list
|
---|
323 | // to
|
---|
324 | // save
|
---|
325 | // all
|
---|
326 | // bids
|
---|
327 | // and
|
---|
328 | // make
|
---|
329 | // a
|
---|
330 | // utility
|
---|
331 | // space
|
---|
332 | // to
|
---|
333 | // save
|
---|
334 | // the
|
---|
335 | // opponent
|
---|
336 | // model
|
---|
337 | partiesBidList[PartyNo - 1] = new ArrayList<Bid>();
|
---|
338 | try {
|
---|
339 | OpponentUtilities.add(new AdditiveUtilitySpace(this
|
---|
340 | .getUtilitySpace().getDomain(), ""));
|
---|
341 | } catch (Exception e) {
|
---|
342 | e.printStackTrace();
|
---|
343 | }
|
---|
344 | for (int EvaluatorNo = 1; EvaluatorNo <= ((AdditiveUtilitySpace) utilitySpace)
|
---|
345 | .getNrOfEvaluators(); EvaluatorNo++) {
|
---|
346 | OpponentUtilities
|
---|
347 | .get(PartyNo - 1)
|
---|
348 | .getEvaluator(EvaluatorNo)
|
---|
349 | .setWeight(
|
---|
350 | 1 / (double) ((AdditiveUtilitySpace) utilitySpace)
|
---|
351 | .getNrOfEvaluators());
|
---|
352 | }
|
---|
353 | }
|
---|
354 |
|
---|
355 | bidListInit = true;
|
---|
356 | }
|
---|
357 |
|
---|
358 | // This function provides GENIUS with the name of this agent
|
---|
359 | @Override
|
---|
360 | public String getDescription() {
|
---|
361 | return "Agent 47, [Group 18]";
|
---|
362 | }
|
---|
363 |
|
---|
364 | }
|
---|