source: src/main/java/parties/in4010/q12015/group8/Group8.java@ 33

Last change on this file since 33 was 1, checked in by Wouter Pasman, 6 years ago

Initial import : Genius 9.0.0

File size: 6.7 KB
Line 
1package parties.in4010.q12015.group8;
2
3import java.util.ArrayList;
4import java.util.HashMap;
5import java.util.List;
6import java.util.Map;
7
8import genius.core.AgentID;
9import genius.core.Bid;
10import genius.core.actions.Accept;
11import genius.core.actions.Action;
12import genius.core.actions.Offer;
13import genius.core.issue.ISSUETYPE;
14import genius.core.issue.Issue;
15import genius.core.issue.IssueDiscrete;
16import genius.core.issue.Value;
17import genius.core.issue.ValueDiscrete;
18import genius.core.parties.AbstractNegotiationParty;
19import genius.core.parties.NegotiationInfo;
20import genius.core.utility.AdditiveUtilitySpace;
21
22/**
23 * TODO: 1. Support multiple issue types? 2. It could be possible that
24 * calculating bids will take forever if the domain is too broad (multiple
25 * issues with a lot of values) we should be protected against such cases.
26 */
27
28public class Group8 extends AbstractNegotiationParty {
29 private static final double MINIMUM_BID_UTILITY = 0.81; // minimum utility
30 private static final double GIVE_IN_THRESHOLD = 0.9; // time/total or
31 // round/total
32 // threshold
33 private static double BID_UTILITY = 0.88; // start threshold
34 private static final double FILTER_THRESHOLD = 5; // start opponent modeling
35 // after 5 rounds
36 private static final double FILTER_STOP = 14; // stop filtering after some
37 // rounds
38
39 private ArrayList<Bid> enemyBids = new ArrayList<Bid>();
40 private ArrayList<Bid> history = new ArrayList<Bid>();
41
42 private ArrayList<Bid> agentBids = null;
43 private int nextBid = -1;
44
45 private Map<AgentID, OpponentModel> opponentModels = new HashMap<AgentID, OpponentModel>();
46
47 @Override
48 public void init(NegotiationInfo info) {
49 super.init(info);
50 // utilSpace.getReservationValueUndiscounted();
51 // TODO: getReservationValueUndiscounted returns the least favourable
52 // point at which one will accept, so not really needed?
53 }
54
55 private void initBids() throws Exception {
56 agentBids = new ArrayList<Bid>();
57 for (HashMap<Integer, Value> bid : getAllBids()) {
58 Bid b = new Bid(utilitySpace.getDomain(), bid);
59 if (canAccept(b)) {
60 agentBids.add(b);
61 }
62 }
63 }
64
65 /**
66 * When this function is called, it is expected that the Party chooses one
67 * of the actions from the possible action list and returns an instance of
68 * the chosen action.
69 *
70 * @param possibleActions
71 * @return accept or offer
72 */
73 @Override
74 public Action chooseAction(List<Class<? extends Action>> possibleActions) {
75 // Threshold value will become slowly lower
76 if (getTimeLeft() >= GIVE_IN_THRESHOLD) {
77 // linear slope downwards starting at GIVE_IN_THRESHOLD time
78 BID_UTILITY = Math.max(MINIMUM_BID_UTILITY, BID_UTILITY
79 - (1.0 - MINIMUM_BID_UTILITY) / (1.0 - GIVE_IN_THRESHOLD) * (getTimeLeft() - GIVE_IN_THRESHOLD));
80
81 try {
82 initBids(); // re-init our bids
83 } catch (Exception e) {
84 e.printStackTrace();
85 }
86 }
87
88 try {
89 // accept if last offer is good enough and we have played a couple
90 // of rounds
91 if (possibleActions.contains(Accept.class) && canAccept(enemyBids.get(enemyBids.size() - 1))
92 && enemyBids.size() > MINIMUM_BID_UTILITY) {
93 return new Accept(getPartyId(), enemyBids.get(enemyBids.size() - 1));
94 } else {
95 // do a new bid
96 Offer offer = generateBid();
97 history.add(offer.getBid());
98 return offer;
99 }
100 } catch (Exception e) {
101 System.err.println("Exception in chooseAction: " + e.getMessage());
102 // prevent returning nothing
103 return new Accept(getPartyId(), enemyBids.get(enemyBids.size() - 1));
104 }
105 }
106
107 /**
108 * Checks if the utility is high enough.
109 *
110 * @param b
111 * @return
112 */
113 public boolean canAccept(Bid b) {
114 return getUtility(b) > BID_UTILITY;
115 }
116
117 @Override
118 public String getDescription() {
119 return "Group 8 Agent";
120 }
121
122 @Override
123 public void receiveMessage(AgentID sender, Action action) {
124 if (action instanceof Offer) {
125 Offer offer = (Offer) action;
126 Bid curBid = offer.getBid();
127 enemyBids.add(curBid); // remember all the bids
128
129 if (opponentModels.get(action.getAgent()) == null) {
130 opponentModels.put(action.getAgent(), new OpponentModel((AdditiveUtilitySpace) utilitySpace));
131 }
132 opponentModels.get(offer.getAgent()).updateOpponentModel(curBid);
133
134 // filter dangerous bids
135 if (enemyBids.size() < FILTER_STOP)
136 filterBids();
137 }
138 }
139
140 private Offer generateBid() throws Exception {
141 if (agentBids == null)
142 initBids();
143
144 nextBid = nextBid == agentBids.size() - 1 ? 0 : ++nextBid;
145 return new Offer(getPartyId(), agentBids.get(nextBid));
146 }
147
148 /**
149 * Returns a list of possible bids, a bid is a mapping of an integer to a
150 * value.
151 *
152 * @throws Exception
153 */
154 private List<HashMap<Integer, Value>> getAllBids() throws Exception {
155 List<Issue> issues = utilitySpace.getDomain().getIssues();
156 return getAllBidsForIssue(issues, 0); // recursively generate bids by
157 // traversing the tree
158 }
159
160 private List<HashMap<Integer, Value>> getAllBidsForIssue(List<Issue> issues, int i) throws Exception {
161
162 if (issues.get(i).getType() != ISSUETYPE.DISCRETE) {
163 return null;
164 }
165
166 List<HashMap<Integer, Value>> bids;
167 if (i == issues.size() - 1) {
168 bids = new ArrayList<HashMap<Integer, Value>>();
169 bids.add(new HashMap<Integer, Value>());
170 } else {
171 bids = getAllBidsForIssue(issues, i + 1); // we get all the bids for
172 }
173
174 List<HashMap<Integer, Value>> newBids = new ArrayList<HashMap<Integer, Value>>();
175
176 IssueDiscrete issue = (IssueDiscrete) issues.get(i);
177 for (ValueDiscrete v : issue.getValues()) {
178 for (HashMap<Integer, Value> bid : bids) {
179 HashMap<Integer, Value> newBid = new HashMap<Integer, Value>(bid);
180 newBid.put(issue.getNumber(), v);
181 newBids.add(newBid); // we add a bid for each value of this
182 // issue (rest of the bid is recursively
183 // calculated)
184 }
185 }
186
187 return newBids;
188 }
189
190 /**
191 * @return return the number of round/time left with respect to the total.
192 */
193 private double getTimeLeft() {
194 return getTimeLine().getTime();
195 }
196
197 /**
198 * Filter all the bids that are "dangerous" unless the bids are really that
199 * good for us.
200 */
201 private void filterBids() {
202
203 if (history.size() >= FILTER_THRESHOLD) {
204 for (Map.Entry<AgentID, OpponentModel> om : opponentModels.entrySet()) {
205 if (om.getValue().isAccurate()) {
206 for (Bid b : agentBids) {
207 if (om.getValue().isDangerousBid(b)) {
208 System.out.println("removed bid " + b);
209 agentBids.remove(b);
210 }
211 }
212 } else {
213 // System.out.println("Agent " + om.getKey() +
214 // " is not accurate enough to calculate dangerous bids");
215 }
216 }
217 }
218
219 }
220
221}
Note: See TracBrowser for help on using the repository browser.