1 | package parties.in4010.q12015.group9;
|
---|
2 |
|
---|
3 | import java.util.AbstractMap.SimpleEntry;
|
---|
4 | import java.util.ArrayList;
|
---|
5 | import java.util.HashMap;
|
---|
6 | import java.util.List;
|
---|
7 | import java.util.Map;
|
---|
8 | import java.util.Map.Entry;
|
---|
9 |
|
---|
10 | import genius.core.Bid;
|
---|
11 | import genius.core.BidHistory;
|
---|
12 | import genius.core.bidding.BidDetails;
|
---|
13 | import genius.core.boaframework.SortedOutcomeSpace;
|
---|
14 | import genius.core.misc.Range;
|
---|
15 | import genius.core.timeline.TimeLineInfo;
|
---|
16 | import genius.core.utility.AdditiveUtilitySpace;
|
---|
17 |
|
---|
18 | import java.util.Random;
|
---|
19 |
|
---|
20 | public class BiddingStrat {
|
---|
21 | private AdditiveUtilitySpace ourUtility;
|
---|
22 | private SortedOutcomeSpace sortedSpace;
|
---|
23 | private Bid ourPreviousBid;
|
---|
24 | private boolean gahboninhoConcReactionDet;
|
---|
25 | private boolean gahboninhoSelfishReactionDet;
|
---|
26 | private HashMap<Object, Double> selfishnessAgainstConceding;
|
---|
27 | private HashMap<Object, Double> selfishnessAgainstHardhead;
|
---|
28 | private boolean hardHeadGahboninho;// learned concession strategy for
|
---|
29 | // Gahboninho, true=hardheaded,
|
---|
30 | // false=slow concession
|
---|
31 | private Random rand;
|
---|
32 | private double gahboninoConcActualDeadline;
|
---|
33 |
|
---|
34 | public BiddingStrat(AdditiveUtilitySpace ownUtility) {
|
---|
35 | ourUtility = ownUtility;
|
---|
36 | sortedSpace = new SortedOutcomeSpace(ourUtility);
|
---|
37 | ourPreviousBid = sortedSpace.getMaxBidPossible().getBid();
|
---|
38 | gahboninhoConcReactionDet = false;
|
---|
39 | gahboninhoSelfishReactionDet = false;
|
---|
40 | hardHeadGahboninho = true;
|
---|
41 | rand = new Random(1);// Constant seed doesn't matter, not like the
|
---|
42 | // opponents will try to predict our bids in
|
---|
43 | // that way
|
---|
44 | gahboninoConcActualDeadline = 0;
|
---|
45 | }
|
---|
46 |
|
---|
47 | // This is called every time an actions needs to be chosen to generate our
|
---|
48 | // candidate bid
|
---|
49 | public Bid createBid(HashMap<Object, BidHistory> previousBids,
|
---|
50 | HashMap<Object, AdditiveUtilitySpace> opponentUtilities,
|
---|
51 | TimeLineInfo timeLine) {
|
---|
52 | ourPreviousBid = getGahboninhoBid(previousBids, opponentUtilities,
|
---|
53 | timeLine);
|
---|
54 | return ourPreviousBid;
|
---|
55 | }
|
---|
56 |
|
---|
57 | // Simple get the best bid method to use when exceptions are thrown in
|
---|
58 | // making a real bid
|
---|
59 | public Bid getBestBid() {
|
---|
60 | return sortedSpace.getMaxBidPossible().getBid();
|
---|
61 | }
|
---|
62 |
|
---|
63 | // Very simple Gahbonino inspired tactic, checks how much the opponents are
|
---|
64 | // conceding, if they are both conceding already don't concede at all, if
|
---|
65 | // they aren't concede a little bit
|
---|
66 | // It's basically boulware against a hardliner and hardliner against
|
---|
67 | // concession agents
|
---|
68 | private Bid getGahboninhoBid(HashMap<Object, BidHistory> previousBids,
|
---|
69 | HashMap<Object, AdditiveUtilitySpace> opponentUtilities,
|
---|
70 | TimeLineInfo timeLine) {
|
---|
71 | // Parameters
|
---|
72 | final double concessionDeadline = 0.05;
|
---|
73 | final double concessionGoal = 0.9;
|
---|
74 | final double selfishnessDeadline = 0.05;
|
---|
75 | final double hardheadMinimumUtility = 0.85;
|
---|
76 | final double nonHardHeadFinalGoal = 0.65;
|
---|
77 | final double nonHardHeadStart = 0.85;
|
---|
78 | final double eps = 0.05;
|
---|
79 | final double rangeSize = 0.4;
|
---|
80 | double t = timeLine.getTime();
|
---|
81 | if (t < concessionDeadline) {// Concession stage
|
---|
82 | return sortedSpace.getBidNearUtility(
|
---|
83 | 1 - (1 - concessionGoal) * (t / concessionDeadline))
|
---|
84 | .getBid();// Concede linearly to concessionGoal to see how
|
---|
85 | // opponents react to conceders
|
---|
86 | } else if (t < (concessionDeadline + selfishnessDeadline)) {// Selfishness
|
---|
87 | // stage
|
---|
88 | if (!gahboninhoConcReactionDet) {
|
---|
89 | gahboninhoConcReactionDet = true;
|
---|
90 | gahboninoConcActualDeadline = timeLine.getCurrentTime();
|
---|
91 | selfishnessAgainstConceding = computeSelfishness(previousBids,
|
---|
92 | 0, gahboninoConcActualDeadline);
|
---|
93 | }
|
---|
94 | return ourPreviousBid;// Don't concede to see how the opponents
|
---|
95 | // react to selfishness
|
---|
96 | } else {// now after selfishnessDeadline+concessionDeadline with
|
---|
97 | // knowledge of how opponent reacts decide strategy
|
---|
98 | if (!gahboninhoSelfishReactionDet) {
|
---|
99 | gahboninhoSelfishReactionDet = true;
|
---|
100 | selfishnessAgainstHardhead = computeSelfishness(previousBids,
|
---|
101 | gahboninoConcActualDeadline, timeLine.getCurrentTime());
|
---|
102 | hardHeadGahboninho = determineGahbinoStrategy(
|
---|
103 | selfishnessAgainstConceding, selfishnessAgainstHardhead);
|
---|
104 | }
|
---|
105 | if (hardHeadGahboninho) {
|
---|
106 | return getBidFromTargetRange(new Range(hardheadMinimumUtility,
|
---|
107 | 1), opponentUtilities);// Get the bid rated best with
|
---|
108 | // utility above
|
---|
109 | // hardheadMinimumUtility
|
---|
110 | } else {
|
---|
111 | double lowerbound = nonHardHeadStart
|
---|
112 | - (nonHardHeadStart - nonHardHeadFinalGoal)
|
---|
113 | * (Math.pow(t, (1 / eps)));
|
---|
114 | return getBidFromTargetRange(
|
---|
115 | new Range(lowerbound, Math.min(lowerbound + rangeSize,
|
---|
116 | 1)), opponentUtilities);// Get the bid rated
|
---|
117 | // best with utility
|
---|
118 | // above
|
---|
119 | // hardheadMinimumUtility
|
---|
120 | }
|
---|
121 | }
|
---|
122 | }
|
---|
123 |
|
---|
124 | // Compute variance of our utility for bids in certain timeframe, used as a
|
---|
125 | // measure of selfishness against our current tactic
|
---|
126 | private HashMap<Object, Double> computeSelfishness(
|
---|
127 | HashMap<Object, BidHistory> previousBids, double startTime,
|
---|
128 | double endTime) {
|
---|
129 | HashMap<Object, Double> selfishMap = new HashMap<Object, Double>();
|
---|
130 | for (Map.Entry<Object, BidHistory> entry : previousBids.entrySet()) {
|
---|
131 | Object key = entry.getKey();
|
---|
132 | double avUtil = entry.getValue()
|
---|
133 | .filterBetweenTime(startTime, endTime).getAverageUtility();
|
---|
134 | double sampleVar = 0;
|
---|
135 | List<BidDetails> history = entry.getValue()
|
---|
136 | .filterBetweenTime(startTime, endTime).getHistory();
|
---|
137 | for (BidDetails detail : history) {
|
---|
138 | sampleVar = sampleVar
|
---|
139 | + Math.pow((detail.getMyUndiscountedUtil() - avUtil),
|
---|
140 | 2.0);
|
---|
141 | }
|
---|
142 | sampleVar = sampleVar / history.size();
|
---|
143 | selfishMap.put(key, sampleVar);
|
---|
144 | }
|
---|
145 | return selfishMap;
|
---|
146 | }
|
---|
147 |
|
---|
148 | // Determine the optimal strategy against current estimated opponent
|
---|
149 | // strategies
|
---|
150 | private boolean determineGahbinoStrategy(
|
---|
151 | HashMap<Object, Double> varianceVSConceding,
|
---|
152 | HashMap<Object, Double> varianceVSHardhead) {
|
---|
153 | final double hardheadLimit = 0.001;// Variance below which opponent is
|
---|
154 | // considered hardhead
|
---|
155 | final double concederLimit = 0.001;// Variance above which opponent is
|
---|
156 | // considered conceding
|
---|
157 | boolean competitiveFound = false;// Currently not used
|
---|
158 | for (Map.Entry<Object, Double> entry : varianceVSConceding.entrySet()) {
|
---|
159 | Object key = entry.getKey();
|
---|
160 | double varianceConceding = entry.getValue();
|
---|
161 | double varianceHardhead = varianceVSHardhead.get(key);
|
---|
162 | System.out.println("varConc:=" + varianceConceding);
|
---|
163 | System.out.println("varHardhead:=" + varianceConceding);
|
---|
164 | if (varianceHardhead > concederLimit) {// The opponent concedes to
|
---|
165 | // hardliners
|
---|
166 | return true;// Abuse the conceder (or inverter) by hardlining
|
---|
167 | } else if ((varianceHardhead < hardheadLimit)
|
---|
168 | & (varianceConceding < hardheadLimit)) {
|
---|
169 | return false;// If any opponent is using a competitive strategy
|
---|
170 | // store this information to use slow conceder
|
---|
171 | // unless someone else is already conceding
|
---|
172 | } else if ((varianceHardhead < hardheadLimit)
|
---|
173 | & (varianceConceding > concederLimit)) {
|
---|
174 | return false;// If any opponent is matching go for concession
|
---|
175 | // strategy to cooperate
|
---|
176 | }
|
---|
177 | }
|
---|
178 | return false;// If all opponents are competitive go for slow concessions
|
---|
179 | }
|
---|
180 |
|
---|
181 | // Find set of bids the opponents would most prefer out of the bids in our
|
---|
182 | // target utility range
|
---|
183 | private Bid getBidFromTargetRange(Range bidRange,
|
---|
184 | HashMap<Object, AdditiveUtilitySpace> opponentUtilities) {
|
---|
185 | final int numberBidsConsider = 3;
|
---|
186 | List<Entry<Bid, Double>> consideredBids = new ArrayList<Entry<Bid, Double>>();
|
---|
187 | List<BidDetails> possibleBids = sortedSpace.getBidsinRange(bidRange);
|
---|
188 | if (possibleBids.isEmpty()) {// Incase something with the range went
|
---|
189 | // wrong
|
---|
190 | return sortedSpace.getMaxBidPossible().getBid();
|
---|
191 | }
|
---|
192 |
|
---|
193 | for (BidDetails candidate : possibleBids) {
|
---|
194 | double opponentUtilMult = 1;
|
---|
195 | for (AdditiveUtilitySpace opponentSpace : opponentUtilities.values()) {
|
---|
196 | try {
|
---|
197 | opponentUtilMult = opponentUtilMult
|
---|
198 | * opponentSpace.getUtility(candidate.getBid());
|
---|
199 | } catch (Exception e) {
|
---|
200 | opponentUtilMult = 0;
|
---|
201 | }
|
---|
202 | }
|
---|
203 | for (int i = 0; i < numberBidsConsider; i++) {
|
---|
204 | if ((consideredBids.size() < (i + 1))
|
---|
205 | || (consideredBids.get(i).getValue() < opponentUtilMult)) {
|
---|
206 | consideredBids.add(i, new SimpleEntry<Bid, Double>(
|
---|
207 | candidate.getBid(), opponentUtilMult));
|
---|
208 | break;
|
---|
209 | }
|
---|
210 | }
|
---|
211 | if (consideredBids.size() > numberBidsConsider) {
|
---|
212 | consideredBids.remove(numberBidsConsider);
|
---|
213 | }
|
---|
214 | }
|
---|
215 | if (consideredBids.size() > 0) {
|
---|
216 | int randomNum = rand.nextInt(consideredBids.size());
|
---|
217 | return consideredBids.get(randomNum).getKey();
|
---|
218 | } else {
|
---|
219 | return sortedSpace.getMaxBidPossible().getBid();// Just in case
|
---|
220 | // something went
|
---|
221 | // wrong in making
|
---|
222 | // the bids
|
---|
223 | }
|
---|
224 | }
|
---|
225 |
|
---|
226 | }
|
---|