1 | package parties.in4010.q12015.group6;
|
---|
2 |
|
---|
3 | import java.util.List;
|
---|
4 | import java.util.Random;
|
---|
5 | import java.util.Set;
|
---|
6 | import java.util.TreeMap;
|
---|
7 |
|
---|
8 | import genius.core.Bid;
|
---|
9 | import genius.core.actions.Accept;
|
---|
10 | import genius.core.actions.Action;
|
---|
11 | import genius.core.actions.Offer;
|
---|
12 | import genius.core.parties.AbstractNegotiationParty;
|
---|
13 |
|
---|
14 | /**
|
---|
15 | * This is your negotiation party.
|
---|
16 | */
|
---|
17 | public class Group6 extends AbstractNegotiationParty {
|
---|
18 | // Make data available throughout the code
|
---|
19 | private Bid opponentbestbid = null;
|
---|
20 | private Bid myBid;
|
---|
21 | private Boolean firstround = true;
|
---|
22 | private Bid bestBid = null;
|
---|
23 | private double utilBestbid = 0D;
|
---|
24 | private Bid partnerBid;
|
---|
25 | private double offeredUtilFromOpponent = 0;
|
---|
26 | private TreeMap<Double, Bid> OpponentModel = new TreeMap<Double, Bid>();
|
---|
27 | private double oppUtil;
|
---|
28 |
|
---|
29 | private Action actionOfPartner = null;
|
---|
30 | private Bid oppBid;
|
---|
31 |
|
---|
32 | /**
|
---|
33 | * init is called when a next session starts with the same opponent.
|
---|
34 | */
|
---|
35 | // Initially we initialized our opponentModel here but this gave a
|
---|
36 | // nullpointerexception.
|
---|
37 | public void init() {
|
---|
38 |
|
---|
39 | }
|
---|
40 |
|
---|
41 | // Receive the incoming action of the other agents.
|
---|
42 | public void receiveMessage(java.lang.Object sender, Action opponentAction) {
|
---|
43 | // actionOfPartner is defined in the beginning of the code and is
|
---|
44 | // defined as private
|
---|
45 | // Meaning that other parts of the code can access the opponentAction.
|
---|
46 | actionOfPartner = opponentAction;
|
---|
47 |
|
---|
48 | // The opponent model is only update if the action of partner is an
|
---|
49 | // offer.
|
---|
50 | if (actionOfPartner instanceof Offer) {
|
---|
51 | oppBid = ((Offer) actionOfPartner).getBid();
|
---|
52 | oppUtil = getUtility(oppBid);
|
---|
53 | // The current offer is inserted into the opponent model
|
---|
54 | updateOpponentModel(oppUtil, oppBid);
|
---|
55 | }
|
---|
56 | // System.out.println("Size: "+ OpponentModel.size());
|
---|
57 | }
|
---|
58 |
|
---|
59 | // The Action that is send to genius based on the opponentAction is
|
---|
60 | // generated here.
|
---|
61 | @Override
|
---|
62 | public Action chooseAction(List<Class<? extends Action>> validActions) {
|
---|
63 |
|
---|
64 | // The Utility threshold is retrieved, this will be used to choose
|
---|
65 | // whether to accept or make a counter bid.
|
---|
66 | double minUtil = getNewThreshold();
|
---|
67 | Action action = null;
|
---|
68 | try {
|
---|
69 | if (validActions.contains(Accept.class)) {
|
---|
70 | // if action of partner is instance of accept.
|
---|
71 | // decide to accept or offer.
|
---|
72 |
|
---|
73 | // System.out.println("Minimum Util: " + minUtil);
|
---|
74 |
|
---|
75 | // If the offered utility of the opponent is higher than the
|
---|
76 | // utility of
|
---|
77 | // our threshold a Accept will be returned.
|
---|
78 | if (oppUtil > minUtil) {
|
---|
79 | return new Accept(getPartyId(), oppBid);
|
---|
80 | }
|
---|
81 |
|
---|
82 | // A bid will be retrieved from our bidselector.
|
---|
83 | action = chooseRandomBidAction(minUtil);
|
---|
84 |
|
---|
85 | Bid myBid = ((Offer) action).getBid();
|
---|
86 | double myOfferedUtil = getUtility(myBid);
|
---|
87 | System.out.println("Generated bid: " + myOfferedUtil);
|
---|
88 |
|
---|
89 | // A set of all the opponent best bids that have been stored are
|
---|
90 | // generated.
|
---|
91 | Set<Double> keys = OpponentModel.keySet();
|
---|
92 |
|
---|
93 | // A random number is generated to
|
---|
94 | // randomly select a bid from the opponentModel.
|
---|
95 | Random randomGenerator = new Random();
|
---|
96 | int randomInt = randomGenerator.nextInt(5) + 1;
|
---|
97 | int keyId = 1;
|
---|
98 |
|
---|
99 | // The key of a bid is given an ID so that
|
---|
100 | // using the randomInt a bid can be retrieved from
|
---|
101 | // the opponentModel.
|
---|
102 | for (Double key : keys) {
|
---|
103 | if (keyId == randomInt) {
|
---|
104 | bestBid = OpponentModel.get(key);
|
---|
105 | }
|
---|
106 | keyId++;
|
---|
107 | }
|
---|
108 |
|
---|
109 | // The utility of the retrieved bid is generated here
|
---|
110 | utilBestbid = getUtility(bestBid);
|
---|
111 | System.out.println("Best bid: " + utilBestbid);
|
---|
112 |
|
---|
113 | // Based on the utility of the bestBid that was retrieved
|
---|
114 | // a offer will be made. If the utility of the best bid is
|
---|
115 | // higher than the offered utility of the opponent a new
|
---|
116 | // bid will be placed.
|
---|
117 | if (myOfferedUtil < utilBestbid) {
|
---|
118 | // System.out.println("Util: " + utilBestbid + " Bid: " +
|
---|
119 | // bestBid);
|
---|
120 | action = new Offer(getPartyId(), bestBid);
|
---|
121 | }
|
---|
122 | }
|
---|
123 |
|
---|
124 | if (!validActions.contains(Accept.class))
|
---|
125 | // if action of partner is not instance of accept
|
---|
126 | // choose to offer a counter bid.
|
---|
127 | {
|
---|
128 | action = chooseRandomBidAction(minUtil);
|
---|
129 |
|
---|
130 | }
|
---|
131 |
|
---|
132 | // If anything goes wrong
|
---|
133 | } catch (Exception e) {
|
---|
134 | System.out.println("Exception in ChooseAction:" + e.getMessage());
|
---|
135 | action = new Accept(getPartyId(), oppBid); // best guess if things
|
---|
136 | // go wrong.
|
---|
137 | }
|
---|
138 | return action;
|
---|
139 | }
|
---|
140 |
|
---|
141 | // This is our Bid selector which choose a bid based on
|
---|
142 | // a given floor entry. The bid selector works by randomly
|
---|
143 | // generating bids. As soon as a bid goes above the utility
|
---|
144 | // Threshold the bid will be returned.
|
---|
145 | private Action chooseRandomBidAction(Double minUtil) {
|
---|
146 | Bid nextBid = null;
|
---|
147 | // generate the random bids.
|
---|
148 | nextBid = generateRandomBid();
|
---|
149 | double util = getUtility(nextBid);
|
---|
150 |
|
---|
151 | System.out.println("Minimum Util: " + minUtil);
|
---|
152 |
|
---|
153 | // The a new bid will be generated if the utility of
|
---|
154 | // the previous random bid is bellow the threshold.
|
---|
155 | // Once the generated bid goes above the threshold
|
---|
156 | // the nextBid becomes myBid.
|
---|
157 | while (util < minUtil) {
|
---|
158 | nextBid = generateRandomBid();
|
---|
159 | util = getUtility(nextBid);
|
---|
160 | System.out.println("Util: " + util);
|
---|
161 | }
|
---|
162 | // This returns accept if anything goes wrong.
|
---|
163 | if (nextBid == null)
|
---|
164 | return (new Accept(getPartyId(), oppBid));
|
---|
165 |
|
---|
166 | // This returns myBid as an offer.
|
---|
167 | return (new Offer(getPartyId(), nextBid));
|
---|
168 | }
|
---|
169 |
|
---|
170 | // The threshold is generated using a time based
|
---|
171 | // method. Based on the time the negotiation has
|
---|
172 | // been running a threshold is calculated.
|
---|
173 | private double getNewThreshold() {
|
---|
174 | double utilThreshold = 0.0;
|
---|
175 | double time = timeline.getTime(); // retrieve the elapsed time
|
---|
176 | if (time <= (60.0 / 180.0)) {
|
---|
177 | utilThreshold = 0.85 + 0.1 * time; // Generate an increasing
|
---|
178 | // threshold, starting at 0.85
|
---|
179 | }
|
---|
180 | if (time <= (140.0 / 180.0) && time >= (60.0 / 180.0)) {
|
---|
181 | utilThreshold = 0.85; // The threshold remains steady
|
---|
182 | }
|
---|
183 | if (time > (140.0 / 180.0) && time < (160.0 / 180.0)) {
|
---|
184 | utilThreshold = 1.1 - 0.38 * time; // utilThreshold starts at 0.80
|
---|
185 | // and decreases to 0.74
|
---|
186 | }
|
---|
187 | if (time > (160.0 / 180.0)) {
|
---|
188 | utilThreshold = 1.18 - 0.5 * time; // utilThreshold starts at 0.72
|
---|
189 | // and decreases to 0.65
|
---|
190 | }
|
---|
191 | // System.out.println("Time: " + time);
|
---|
192 | // System.out.println("Util: " + utilThreshold);
|
---|
193 | // Return the calculated threshold
|
---|
194 | return utilThreshold;
|
---|
195 | }
|
---|
196 |
|
---|
197 | // The opponentModel works by placing the opponent bids in order.
|
---|
198 | // A max of 5 bids are stored, meaning that the lowest bid will be discarded
|
---|
199 | // if the amount of bids exceeds the maximum amount of 5.
|
---|
200 | public TreeMap<Double, Bid> updateOpponentModel(double OfferedUtil, Bid OfferedBid) {
|
---|
201 | // If the max size is below 5 or the offered utility is above the lowest
|
---|
202 | // utility
|
---|
203 | // update the opponentmodel.
|
---|
204 | if (OpponentModel.size() < 5 || OpponentModel.firstEntry().getKey() < OfferedUtil) {
|
---|
205 | // if oppentmodel size is already 5 remove the lowest bid and add
|
---|
206 | // the new higher bid.
|
---|
207 | if (OpponentModel.size() == 5) {
|
---|
208 | // System.out.println("Removed Opponent Model utility:"
|
---|
209 | // +OpponentModel.firstEntry().getKey());
|
---|
210 | OpponentModel.remove(OpponentModel.firstEntry().getKey());
|
---|
211 | }
|
---|
212 | // Add the new bid to the opponentmodel
|
---|
213 | OpponentModel.put(OfferedUtil, OfferedBid);
|
---|
214 | // System.out.println("With utility:" + OfferedUtil);
|
---|
215 | }
|
---|
216 | // System.out.println("check size: "+ OpponentModel.size());
|
---|
217 | return OpponentModel;
|
---|
218 | }
|
---|
219 |
|
---|
220 | @Override
|
---|
221 | public String getDescription() {
|
---|
222 | return "in4010.q12015.group6";
|
---|
223 | }
|
---|
224 | }
|
---|