1 | package parties.in4010.q12015.group4;
|
---|
2 |
|
---|
3 | import java.util.ArrayList;
|
---|
4 | import java.util.HashMap;
|
---|
5 | import java.util.List;
|
---|
6 | import java.util.Map;
|
---|
7 |
|
---|
8 | import genius.core.AgentID;
|
---|
9 | import genius.core.Bid;
|
---|
10 | import genius.core.actions.Accept;
|
---|
11 | import genius.core.actions.Action;
|
---|
12 | import genius.core.actions.ActionWithBid;
|
---|
13 | import genius.core.actions.DefaultAction;
|
---|
14 | import genius.core.actions.Offer;
|
---|
15 | import genius.core.issue.Issue;
|
---|
16 | import genius.core.issue.IssueDiscrete;
|
---|
17 | import genius.core.issue.ValueDiscrete;
|
---|
18 | import genius.core.parties.AbstractNegotiationParty;
|
---|
19 |
|
---|
20 | /**
|
---|
21 | * This is an agent for multi-party negotiation
|
---|
22 | */
|
---|
23 |
|
---|
24 | public class Group4 extends AbstractNegotiationParty {
|
---|
25 |
|
---|
26 | /**
|
---|
27 | * opponentAction ------ the most recent Action opponents performed.
|
---|
28 | */
|
---|
29 | private Action opponentAction;
|
---|
30 | /**
|
---|
31 | * MINIMUM_BID_UTILITY ------ the minimum acceptable utility of a bid
|
---|
32 | */
|
---|
33 | private double MINIMUM_BID_UTILITY;
|
---|
34 | /**
|
---|
35 | * MAXIMUM_BID_UTILITY ------ the maximum acceptable utility of a bid,
|
---|
36 | */
|
---|
37 | private double MAXIMUM_BID_UTILITY;
|
---|
38 | /**
|
---|
39 | * BEST_BID_OPPONENT_OFFER ------ the bid opponents has offered that has the
|
---|
40 | * highest utility for this agent
|
---|
41 | */
|
---|
42 | private Bid BEST_BID_OPPONENT_OFFER;
|
---|
43 | /**
|
---|
44 | * BEST_BID_OPPONENT_OFFER_UTILITY; ------ the Utility of
|
---|
45 | * BEST_BID_OPPONENT_OFFER
|
---|
46 | */
|
---|
47 | private double BEST_BID_OPPONENT_OFFER_UTILITY;
|
---|
48 | /**
|
---|
49 | * MY_LAST_BID ------ the last bid this agent offered
|
---|
50 | */
|
---|
51 | private Bid MY_LAST_BID;
|
---|
52 | /**
|
---|
53 | * historicalBid ------ a list of historical bid this agent offered
|
---|
54 | */
|
---|
55 | private ArrayList<Bid> historicalBid;
|
---|
56 | /**
|
---|
57 | * AgentToHistoricalBidMap ------ map which use agentID as the key to store
|
---|
58 | * the historical bids offered by different opponent agents
|
---|
59 | */
|
---|
60 | private Map<AgentID, ArrayList<Bid>> AgentToHistoricalBidMap;
|
---|
61 | /**
|
---|
62 | * opponentModelMap ------ map which use agentID as the key to store the
|
---|
63 | * opponentModels of different opponent agents
|
---|
64 | */
|
---|
65 | private Map<AgentID, Group4OpponentModel> opponentModelMap;
|
---|
66 |
|
---|
67 | public Group4() {
|
---|
68 | init();
|
---|
69 | }
|
---|
70 |
|
---|
71 | /**
|
---|
72 | * initiate the agent When the negotiation start, assume an agent want to
|
---|
73 | * reach its highest utility So set the MINIMUM_BID_UTILITY to 0.9
|
---|
74 | */
|
---|
75 | public void init() {
|
---|
76 | MINIMUM_BID_UTILITY = 0.9;
|
---|
77 | MAXIMUM_BID_UTILITY = 1;
|
---|
78 | BEST_BID_OPPONENT_OFFER = null;
|
---|
79 | MY_LAST_BID = null;
|
---|
80 | BEST_BID_OPPONENT_OFFER_UTILITY = 0;
|
---|
81 | historicalBid = new ArrayList<Bid>();
|
---|
82 | AgentToHistoricalBidMap = new HashMap<>();
|
---|
83 | opponentModelMap = new HashMap<>();
|
---|
84 | }
|
---|
85 |
|
---|
86 | @Override
|
---|
87 | /*
|
---|
88 | * (non-Javadoc)
|
---|
89 | *
|
---|
90 | * @see negotiator.parties.AbstractNegotiationParty#getDescription() Return
|
---|
91 | * the description of the agent
|
---|
92 | */
|
---|
93 | public String getDescription() {
|
---|
94 | return "Group4MultiPartyNegotiationAgent";
|
---|
95 | }
|
---|
96 |
|
---|
97 | @Override
|
---|
98 | /**
|
---|
99 | * (non-Javadoc)
|
---|
100 | * @see negotiator.parties.NegotiationParty#chooseAction(java.util.List)
|
---|
101 | * When the validActions list doesn't contain "Accept", which means there is no bid currently,
|
---|
102 | * offer a bid that is higher than the MINIMUN_BID_UTILITY
|
---|
103 | * When the validActions list contains "Accept" then
|
---|
104 | * accept this bid if it was acceptable, otherwise offer a new bid;
|
---|
105 | */
|
---|
106 | public Action chooseAction(List<Class<? extends Action>> validActions) {
|
---|
107 | // this.showUtilitySpaceDetails();
|
---|
108 | if (!validActions.contains(Accept.class)) {
|
---|
109 | return offerBid();
|
---|
110 | } else {
|
---|
111 | if (isAcceptable(opponentAction))
|
---|
112 | return new Accept(getPartyId(),
|
---|
113 | ((ActionWithBid) opponentAction).getBid());
|
---|
114 | else
|
---|
115 | return offerBid();
|
---|
116 | }
|
---|
117 | }
|
---|
118 |
|
---|
119 | /**
|
---|
120 | * Determine whether a bid is acceptable 1. return true when the utility is
|
---|
121 | * higher or equal to than the MINIMUM_BID_UTILITY 2. return false When the
|
---|
122 | * utility is lower than the MINIMUM_BID_UTILITY
|
---|
123 | *
|
---|
124 | * @param Action
|
---|
125 | * @return true - bid is acceptable false - bid is not acceptable
|
---|
126 | *
|
---|
127 | */
|
---|
128 | public boolean isAcceptable(Action action) {
|
---|
129 | Bid opponentBid = DefaultAction.getBidFromAction(opponentAction);
|
---|
130 | if (opponentAction != null
|
---|
131 | && getUtility(opponentBid) >= MINIMUM_BID_UTILITY) {
|
---|
132 | return true;
|
---|
133 | } else {
|
---|
134 | System.out.println("Current time:" + timeline.getCurrentTime()
|
---|
135 | + " Reservation value:"
|
---|
136 | + utilitySpace.getReservationValue());
|
---|
137 | /*
|
---|
138 | * The MINIMUM_BID_UTILITY decrease over time. Set
|
---|
139 | * MINIMUM_BID_UTILITY to MAX(1 - time
|
---|
140 | * spent,BEST_BID_OPPONENT_OFFER_UTILITY)
|
---|
141 | */
|
---|
142 | setLowerLimit();
|
---|
143 | setUpperLimit();
|
---|
144 | return false;
|
---|
145 | }
|
---|
146 | }
|
---|
147 |
|
---|
148 | @Override
|
---|
149 | /**
|
---|
150 | * (non-Javadoc)
|
---|
151 | * @see negotiator.parties.AbstractNegotiationParty#receiveMessage(java.lang.Object, negotiator.actions.Action)
|
---|
152 | * receive opponents' last action
|
---|
153 | */
|
---|
154 | public void receiveMessage(AgentID sender, Action action) {
|
---|
155 | super.receiveMessage(sender, action);
|
---|
156 | this.opponentAction = action;
|
---|
157 | if (opponentAction.getAgent() != null
|
---|
158 | && !opponentAction.toString().equals("(Accept)")) {
|
---|
159 | System.out.println(opponentAction.getAgent()
|
---|
160 | + opponentAction.toString());
|
---|
161 | saveBestBid(opponentAction);
|
---|
162 | AgentID agentID = opponentAction.getAgent();
|
---|
163 | // this.showBidDetails(opponentBid);
|
---|
164 | saveOpponentHistoricalBid(opponentAction);
|
---|
165 | System.out.println(agentID);
|
---|
166 | opponentModelMap.get(agentID).UpdateOpponentModel(
|
---|
167 | AgentToHistoricalBidMap.get(agentID));
|
---|
168 | }
|
---|
169 | }
|
---|
170 |
|
---|
171 | /**
|
---|
172 | * Bidding strategy is based on random walk strategy the utility of the
|
---|
173 | * chosen bid should be higher than the MINIMUM_BID_UTILITY and lower than
|
---|
174 | * MAXIMUM_BID_UTILITY (agent should offer a bid that is acceptable to
|
---|
175 | * itself and is easier to accept by opponents) the chosen bid should be a
|
---|
176 | * better bid to all opponent compared to their last bid try to find a bid
|
---|
177 | * that meet the requirements above in 1000 loops return the last offered
|
---|
178 | * bid failed to find a bid in 1000 loops
|
---|
179 | *
|
---|
180 | * @return a bid that meet the requirements above;
|
---|
181 | *
|
---|
182 | */
|
---|
183 | public Action offerBid() {
|
---|
184 | // System.out.println("Minimum Utility = " + MINIMUM_BID_UTILITY);
|
---|
185 | // System.out.println("Maximum Utility = " + MAXIMUM_BID_UTILITY);
|
---|
186 | Bid bid = null;
|
---|
187 | int loop = 0;
|
---|
188 | while (loop <= 1000) {
|
---|
189 | bid = utilitySpace.getDomain().getRandomBid(null);
|
---|
190 | if (getUtility(bid) >= MINIMUM_BID_UTILITY
|
---|
191 | && getUtility(bid) <= MAXIMUM_BID_UTILITY) {
|
---|
192 | if (opponentModelMap.isEmpty()) {
|
---|
193 | break;
|
---|
194 | }
|
---|
195 | boolean worseBid = false;
|
---|
196 | for (AgentID id : opponentModelMap.keySet()) {
|
---|
197 | Group4OpponentModel om = opponentModelMap.get(id);
|
---|
198 | ArrayList<Bid> opponentBids = AgentToHistoricalBidMap
|
---|
199 | .get(id);
|
---|
200 | if (opponentBids.size() > 0) {
|
---|
201 | if (om.evaluateBid(bid) < om.evaluateBid(opponentBids
|
---|
202 | .get(opponentBids.size() - 1))) {
|
---|
203 | worseBid = true;
|
---|
204 | break;
|
---|
205 | }
|
---|
206 | }
|
---|
207 | }
|
---|
208 | if (!worseBid) {
|
---|
209 | break;
|
---|
210 | }
|
---|
211 | }
|
---|
212 | loop++;
|
---|
213 | }
|
---|
214 | if (loop < 1000) {
|
---|
215 | // System.out.println(this.getDescription() +
|
---|
216 | // ":Found bid in 1000 loops, Utility =" + getUtility(bid));
|
---|
217 | for (Group4OpponentModel om : opponentModelMap.values()) {
|
---|
218 | System.out.println(om.evaluateBid(bid));
|
---|
219 | }
|
---|
220 | MY_LAST_BID = bid;
|
---|
221 | historicalBid.add(bid);
|
---|
222 | return new Offer(getPartyId(), bid);
|
---|
223 | } else {
|
---|
224 | try {
|
---|
225 | // System.out.println(this.getDescription() +
|
---|
226 | // ": Return maxUtilityBid, Utility =" + getUtility(bid));
|
---|
227 | MY_LAST_BID = bid;
|
---|
228 | historicalBid.add(bid);
|
---|
229 | if (MY_LAST_BID == null) {
|
---|
230 | return new Offer(getPartyId(),
|
---|
231 | utilitySpace.getMaxUtilityBid());
|
---|
232 | } else {
|
---|
233 | return new Offer(getPartyId(), MY_LAST_BID);
|
---|
234 | }
|
---|
235 |
|
---|
236 | } catch (Exception e) {
|
---|
237 | // TODO Auto-generated catch block
|
---|
238 | e.printStackTrace();
|
---|
239 | return null;
|
---|
240 | }
|
---|
241 | }
|
---|
242 | }
|
---|
243 |
|
---|
244 | /**
|
---|
245 | * Save bids offered by opponents
|
---|
246 | *
|
---|
247 | * @param Action
|
---|
248 | */
|
---|
249 | public void saveOpponentHistoricalBid(Action action) {
|
---|
250 | Bid bid = DefaultAction.getBidFromAction(action);
|
---|
251 | AgentID agentID = action.getAgent();
|
---|
252 | ArrayList<Bid> opponentHistoricalBid;
|
---|
253 | if (!AgentToHistoricalBidMap.containsKey(agentID)) {
|
---|
254 | opponentHistoricalBid = new ArrayList<Bid>();
|
---|
255 | opponentModelMap.put(agentID,
|
---|
256 | new Group4OpponentModel(utilitySpace.getDomain()));
|
---|
257 | } else
|
---|
258 | opponentHistoricalBid = AgentToHistoricalBidMap.get(agentID);
|
---|
259 | opponentHistoricalBid.add(bid);
|
---|
260 | AgentToHistoricalBidMap.put(agentID, opponentHistoricalBid);
|
---|
261 | }
|
---|
262 |
|
---|
263 | /**
|
---|
264 | * save the best bid offered by opponents
|
---|
265 | *
|
---|
266 | * @param Action
|
---|
267 | */
|
---|
268 | public void saveBestBid(Action Action) {
|
---|
269 | if (getUtility(DefaultAction.getBidFromAction(Action)) < MAXIMUM_BID_UTILITY) {
|
---|
270 | if (BEST_BID_OPPONENT_OFFER == null) {
|
---|
271 | BEST_BID_OPPONENT_OFFER = DefaultAction
|
---|
272 | .getBidFromAction(Action);
|
---|
273 | BEST_BID_OPPONENT_OFFER_UTILITY = getUtility(BEST_BID_OPPONENT_OFFER);
|
---|
274 | } else {
|
---|
275 | if (getUtility(BEST_BID_OPPONENT_OFFER) < getUtility(DefaultAction
|
---|
276 | .getBidFromAction(Action))) {
|
---|
277 | BEST_BID_OPPONENT_OFFER = DefaultAction
|
---|
278 | .getBidFromAction(Action);
|
---|
279 | BEST_BID_OPPONENT_OFFER_UTILITY = getUtility(BEST_BID_OPPONENT_OFFER);
|
---|
280 | }
|
---|
281 | }
|
---|
282 | }
|
---|
283 | }
|
---|
284 |
|
---|
285 | /**
|
---|
286 | * count the number that how many time this bid was refused by opponent
|
---|
287 | *
|
---|
288 | * @param bid
|
---|
289 | * @return refused times
|
---|
290 | */
|
---|
291 | public int Refuse_Count(Bid bid) {
|
---|
292 | int count = 0;
|
---|
293 | for (Bid hisBid : historicalBid) {
|
---|
294 | if (hisBid.equals(bid)) {
|
---|
295 | count++;
|
---|
296 | }
|
---|
297 | }
|
---|
298 | System.out.println("count =" + count);
|
---|
299 | return count;
|
---|
300 | }
|
---|
301 |
|
---|
302 | /**
|
---|
303 | * set the upper-limit upper-limit = MINIMUM_BID_UTILITY + (0.9 -
|
---|
304 | * MINIMUM_BID_UTILITY) * (0.5 / Refuse Count of MY_LAST_BID) + 0.1 *
|
---|
305 | * (CurrentTime/TotalTime)
|
---|
306 | */
|
---|
307 | public void setUpperLimit() {
|
---|
308 | if (MY_LAST_BID != null) {
|
---|
309 | System.out.println(getUtility(MY_LAST_BID));
|
---|
310 | MAXIMUM_BID_UTILITY = MINIMUM_BID_UTILITY
|
---|
311 | + (0.9 - MINIMUM_BID_UTILITY)
|
---|
312 | * (0.5 / Refuse_Count(MY_LAST_BID)) + 0.1
|
---|
313 | * (timeline.getCurrentTime() / timeline.getTotalTime());
|
---|
314 | }
|
---|
315 | }
|
---|
316 |
|
---|
317 | /**
|
---|
318 | * set the lower-limit lower-limit = Max((0.9 - CurrentTime/TotalTime),
|
---|
319 | * BEST_BID_OPPONENT_OFFER_UTILITY - 0.015 * CurrentTime/TotalTime)
|
---|
320 | */
|
---|
321 | public void setLowerLimit() {
|
---|
322 | MINIMUM_BID_UTILITY = Math
|
---|
323 | .max((0.9 - timeline.getCurrentTime() / timeline.getTotalTime()),
|
---|
324 | BEST_BID_OPPONENT_OFFER_UTILITY
|
---|
325 | - 0.015
|
---|
326 | * (timeline.getCurrentTime() / timeline
|
---|
327 | .getTotalTime()));
|
---|
328 | }
|
---|
329 |
|
---|
330 | /**
|
---|
331 | * show all values for all issues in current utility space (not used)
|
---|
332 | */
|
---|
333 | public void showUtilitySpaceDetails() {
|
---|
334 | for (Issue issue : utilitySpace.getDomain().getIssues()) {
|
---|
335 | IssueDiscrete issueDiscrete = (IssueDiscrete) issue;
|
---|
336 | for (ValueDiscrete value : issueDiscrete.getValues()) {
|
---|
337 | System.out.println("****" + value.getValue());
|
---|
338 | }
|
---|
339 | }
|
---|
340 | }
|
---|
341 |
|
---|
342 | /**
|
---|
343 | * show bid details (not used)
|
---|
344 | */
|
---|
345 | public void showBidDetails(Bid bid) {
|
---|
346 | try {
|
---|
347 | for (Issue issue : bid.getIssues()) {
|
---|
348 | IssueDiscrete issueDiscrete = (IssueDiscrete) issue;
|
---|
349 | System.out.println(bid.getValue(issueDiscrete.getNumber()));
|
---|
350 | }
|
---|
351 | } catch (Exception e) {
|
---|
352 | e.printStackTrace();
|
---|
353 | }
|
---|
354 | }
|
---|
355 | }
|
---|