1 | package parties.in4010.q12015.group4;
|
---|
2 |
|
---|
3 | import java.util.ArrayList;
|
---|
4 | import java.util.HashMap;
|
---|
5 | import java.util.Map;
|
---|
6 |
|
---|
7 | import genius.core.Bid;
|
---|
8 | import genius.core.Domain;
|
---|
9 | import genius.core.issue.Issue;
|
---|
10 | import genius.core.issue.IssueDiscrete;
|
---|
11 | import genius.core.issue.ValueDiscrete;
|
---|
12 |
|
---|
13 | /**
|
---|
14 | * Opponent modeling using frequency analysis heuristic
|
---|
15 | *
|
---|
16 | */
|
---|
17 | public class Group4OpponentModel {
|
---|
18 | private Map<IssueDiscrete, Map<ValueDiscrete, Integer>> issueValueCount;
|
---|
19 | private Map<IssueDiscrete, Double> weights;
|
---|
20 |
|
---|
21 | public Group4OpponentModel(Domain domain) {
|
---|
22 | issueValueCount = new HashMap<>();
|
---|
23 | weights = new HashMap<>();
|
---|
24 | for (Issue issue : domain.getIssues()) {
|
---|
25 | IssueDiscrete issueDiscrete = (IssueDiscrete) issue;
|
---|
26 | issueValueCount.put(issueDiscrete,
|
---|
27 | new HashMap<ValueDiscrete, Integer>());
|
---|
28 | // let each value be 1 at first
|
---|
29 | for (ValueDiscrete value : issueDiscrete.getValues()) {
|
---|
30 | issueValueCount.get(issueDiscrete).put(value, 1);
|
---|
31 | }
|
---|
32 | // initiate the weights
|
---|
33 | weights.put(issueDiscrete, 1.0 / domain.getIssues().size());
|
---|
34 | }
|
---|
35 | }
|
---|
36 |
|
---|
37 | /**
|
---|
38 | * Evaluates the predicted utility of a given bid, using the information
|
---|
39 | * provided thus far.
|
---|
40 | *
|
---|
41 | * @param bid
|
---|
42 | * the bid to be evaluated
|
---|
43 | * @return a value from 0.0 to 1.0 giving the predicted utility of the bid
|
---|
44 | */
|
---|
45 | public double evaluateBid(Bid bid) {
|
---|
46 | double utility = 0.0;
|
---|
47 |
|
---|
48 | // update the weights
|
---|
49 | // weights = computeWeights();
|
---|
50 |
|
---|
51 | try {
|
---|
52 | for (Issue issueRaw : bid.getIssues()) {
|
---|
53 | double maxValue = 0;
|
---|
54 | ValueDiscrete value = (ValueDiscrete) bid.getValue(issueRaw
|
---|
55 | .getNumber());
|
---|
56 | IssueDiscrete issue = (IssueDiscrete) issueRaw;
|
---|
57 |
|
---|
58 | double issueWeight = weights.get(issue);
|
---|
59 | double issueValue = ((double) issueValueCount.get(issue).get(
|
---|
60 | value));
|
---|
61 |
|
---|
62 | // add 1 to the current value
|
---|
63 | // issueValueCount.get(issue).put(value, (int) ((issueValue +
|
---|
64 | // 1)));
|
---|
65 |
|
---|
66 | // normalize the value to make the max of the value equals 1
|
---|
67 | for (ValueDiscrete eachValue : issue.getValues()) {
|
---|
68 | double tempValue = ((double) issueValueCount.get(issue)
|
---|
69 | .get(eachValue));
|
---|
70 | if (tempValue > maxValue)
|
---|
71 | maxValue = tempValue;
|
---|
72 | }
|
---|
73 |
|
---|
74 | // update and normalize the value to make the max of the value
|
---|
75 | // equals 1
|
---|
76 | // to keep track of the history, only the value that is going to
|
---|
77 | // be computed
|
---|
78 | // in the utility is normalized
|
---|
79 | issueValue /= maxValue;
|
---|
80 |
|
---|
81 | // compute the utility
|
---|
82 | utility += issueWeight * issueValue;
|
---|
83 | }
|
---|
84 | } catch (Exception e) {
|
---|
85 | e.printStackTrace();
|
---|
86 | }
|
---|
87 |
|
---|
88 | return utility;
|
---|
89 | }
|
---|
90 |
|
---|
91 | public void UpdateOpponentModel(ArrayList<Bid> historicalBid) {
|
---|
92 | if (historicalBid.size() > 1) {
|
---|
93 | computeWeights(historicalBid.get(historicalBid.size() - 2),
|
---|
94 | historicalBid.get(historicalBid.size() - 1));
|
---|
95 | }
|
---|
96 | if (historicalBid.size() > 0) {
|
---|
97 | computeValueCounts(historicalBid.get(historicalBid.size() - 1));
|
---|
98 | for (Issue issueRaw : historicalBid.get(historicalBid.size() - 1)
|
---|
99 | .getIssues()) {
|
---|
100 | IssueDiscrete issueDiscrete = (IssueDiscrete) issueRaw;
|
---|
101 | System.out.println(issueRaw.getName() + ": "
|
---|
102 | + weights.get(issueRaw));
|
---|
103 | for (ValueDiscrete value : issueDiscrete.getValues()) {
|
---|
104 | System.out.println(value.getValue() + ": "
|
---|
105 | + issueValueCount.get(issueDiscrete).get(value));
|
---|
106 | }
|
---|
107 | }
|
---|
108 | }
|
---|
109 | }
|
---|
110 |
|
---|
111 | /**
|
---|
112 | * Given the current data about the opponent, return the predicted weight
|
---|
113 | * for each issue. If the opponent suggests many different values for that
|
---|
114 | * issue, we assume that it is unimportant for it.
|
---|
115 | *
|
---|
116 | * @return a map of issues to their respective weights, normalized such that
|
---|
117 | * the sum of the weights is 1.0
|
---|
118 | */
|
---|
119 | private void computeWeights(Bid lastBid, Bid currentBid) {
|
---|
120 | try {
|
---|
121 | int count = 0;
|
---|
122 | ArrayList<Double> weight_Temp = new ArrayList<Double>();
|
---|
123 | // Map<IssueDiscrete, Double> weights = new HashMap<>();
|
---|
124 | for (Issue issueRaw : lastBid.getIssues()) {
|
---|
125 | // ValueDiscrete lastBidValue = (ValueDiscrete)
|
---|
126 | // lastBid.getValue(issueRaw.getNumber());
|
---|
127 | // ValueDiscrete currentBidValue = (ValueDiscrete)
|
---|
128 | // currentBid.getValue(issueRaw.getNumber());
|
---|
129 | if (lastBid.getValue(issueRaw.getNumber()).equals(
|
---|
130 | currentBid.getValue(issueRaw.getNumber()))) {
|
---|
131 | weight_Temp.add(weights.get(issueRaw) + 0.1);
|
---|
132 | count++;
|
---|
133 | } else {
|
---|
134 | weight_Temp.add(weights.get(issueRaw));
|
---|
135 | }
|
---|
136 | /*
|
---|
137 | * double variance = computeVariance(issue); weights.put(issue,
|
---|
138 | * 1.0/variance);
|
---|
139 | */
|
---|
140 | }
|
---|
141 | for (Issue issueRaw : lastBid.getIssues()) {
|
---|
142 | weights.put((IssueDiscrete) issueRaw,
|
---|
143 | weight_Temp.get(issueRaw.getNumber() - 1)
|
---|
144 | / (1 + 0.1 * count));
|
---|
145 | }
|
---|
146 | } catch (Exception e) {
|
---|
147 | e.printStackTrace();
|
---|
148 | }
|
---|
149 |
|
---|
150 | // Normalize weights: make them sum to 1.0
|
---|
151 | // double sum = weights.values().stream().reduce(0.0, Double::sum);
|
---|
152 | // weights.forEach((k, v) -> weights.put(k, v / sum));
|
---|
153 | }
|
---|
154 |
|
---|
155 | private void computeValueCounts(Bid bid) {
|
---|
156 | try {
|
---|
157 | for (Issue issueRaw : bid.getIssues()) {
|
---|
158 | ValueDiscrete bidValue = (ValueDiscrete) bid.getValue(issueRaw
|
---|
159 | .getNumber());
|
---|
160 | int count = issueValueCount.get(issueRaw).get(bidValue);
|
---|
161 | issueValueCount.get(issueRaw).put(bidValue, count + 1);
|
---|
162 | }
|
---|
163 | } catch (Exception e) {
|
---|
164 | e.printStackTrace();
|
---|
165 | }
|
---|
166 | }
|
---|
167 |
|
---|
168 | /*
|
---|
169 | * private double computeVariance(IssueDiscrete issue){ double variance =
|
---|
170 | * 0.0; List<Integer> counts = new
|
---|
171 | * ArrayList<>(issueValueCount.get(issue).values()); int max =
|
---|
172 | * counts.stream().max(Integer::compare).get(); List<Double> weightedCounts
|
---|
173 | * = counts.stream() .mapToDouble(i -> (((double) i) / max)).boxed()
|
---|
174 | * .collect(Collectors.toList());
|
---|
175 | *
|
---|
176 | * double avg = weightedCounts.stream().reduce(0.0, Double::sum) /
|
---|
177 | * weightedCounts.size(); double variance = weightedCounts.stream()
|
---|
178 | * .mapToDouble(d -> (d - avg) * (d - avg)).sum() / weightedCounts.size();
|
---|
179 | * return variance; }
|
---|
180 | */
|
---|
181 |
|
---|
182 | } |
---|