source: src/main/java/negotiator/boaframework/opponentmodel/HardHeadedFrequencyModel.java@ 58

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

@21 refactoring improve code in hardheaded frequency model

File size: 6.3 KB
Line 
1package negotiator.boaframework.opponentmodel;
2
3import java.util.HashMap;
4import java.util.HashSet;
5import java.util.Map;
6import java.util.Map.Entry;
7import java.util.Set;
8
9import genius.core.Bid;
10import genius.core.bidding.BidDetails;
11import genius.core.boaframework.BOAparameter;
12import genius.core.boaframework.NegotiationSession;
13import genius.core.boaframework.OpponentModel;
14import genius.core.issue.Issue;
15import genius.core.issue.IssueDiscrete;
16import genius.core.issue.Objective;
17import genius.core.issue.ValueDiscrete;
18import genius.core.utility.AdditiveUtilitySpace;
19import genius.core.utility.Evaluator;
20import genius.core.utility.EvaluatorDiscrete;
21
22/**
23 * BOA framework implementation of the HardHeaded Frequecy Model.
24 *
25 * Default: learning coef l = 0.2; learnValueAddition v = 1.0
26 *
27 * paper: https://ii.tudelft.nl/sites/default/files/boa.pdf
28 */
29public class HardHeadedFrequencyModel extends OpponentModel {
30
31 /*
32 * the learning coefficient is the weight that is added each turn to the
33 * issue weights which changed. It's a trade-off between concession speed
34 * and accuracy.
35 */
36 private double learnCoef;
37 /*
38 * value which is added to a value if it is found. Determines how fast the
39 * value weights converge.
40 */
41 private int learnValueAddition;
42 private int amountOfIssues;
43 private double goldenValue;
44
45 @Override
46 public void init(NegotiationSession negotiationSession,
47 Map<String, Double> parameters) {
48 this.negotiationSession = negotiationSession;
49 if (parameters != null && parameters.get("l") != null) {
50 learnCoef = parameters.get("l");
51 } else {
52 learnCoef = 0.2;
53 }
54 learnValueAddition = 1;
55 opponentUtilitySpace = (AdditiveUtilitySpace) negotiationSession
56 .getUtilitySpace().copy();
57 amountOfIssues = opponentUtilitySpace.getDomain().getIssues().size();
58 /*
59 * This is the value to be added to weights of unchanged issues before
60 * normalization. Also the value that is taken as the minimum possible
61 * weight, (therefore defining the maximum possible also).
62 */
63 goldenValue = learnCoef / amountOfIssues;
64
65 initializeModel();
66
67 }
68
69 @Override
70 public void updateModel(Bid opponentBid, double time) {
71 if (negotiationSession.getOpponentBidHistory().size() < 2) {
72 return;
73 }
74 int numberOfUnchanged = 0;
75 BidDetails oppBid = negotiationSession.getOpponentBidHistory()
76 .getHistory()
77 .get(negotiationSession.getOpponentBidHistory().size() - 1);
78 BidDetails prevOppBid = negotiationSession.getOpponentBidHistory()
79 .getHistory()
80 .get(negotiationSession.getOpponentBidHistory().size() - 2);
81 HashMap<Integer, Integer> lastDiffSet = determineDifference(prevOppBid,
82 oppBid);
83
84 // count the number of changes in value
85 for (Integer i : lastDiffSet.keySet()) {
86 if (lastDiffSet.get(i) == 0)
87 numberOfUnchanged++;
88 }
89
90 // The total sum of weights before normalization.
91 double totalSum = 1D + goldenValue * numberOfUnchanged;
92 // The maximum possible weight
93 double maximumWeight = 1D - (amountOfIssues) * goldenValue / totalSum;
94
95 // re-weighing issues while making sure that the sum remains 1
96 for (Integer i : lastDiffSet.keySet()) {
97 Objective issue = opponentUtilitySpace.getDomain()
98 .getObjectivesRoot().getObjective(i);
99 double weight = opponentUtilitySpace.getWeight(i);
100 double newWeight;
101
102 if (lastDiffSet.get(i) == 0 && weight < maximumWeight) {
103 newWeight = (weight + goldenValue) / totalSum;
104 } else {
105 newWeight = weight / totalSum;
106 }
107 opponentUtilitySpace.setWeight(issue, newWeight);
108 }
109
110 // Then for each issue value that has been offered last time, a constant
111 // value is added to its corresponding ValueDiscrete.
112 try {
113 for (Entry<Objective, Evaluator> e : opponentUtilitySpace
114 .getEvaluators()) {
115 EvaluatorDiscrete value = (EvaluatorDiscrete) e.getValue();
116 IssueDiscrete issue = ((IssueDiscrete) e.getKey());
117 /*
118 * add constant learnValueAddition to the current preference of
119 * the value to make it more important
120 */
121 ValueDiscrete issuevalue = (ValueDiscrete) oppBid.getBid()
122 .getValue(issue.getNumber());
123 value.setEvaluation(oppBid.getBid().getValue(issue.getNumber()),
124 (learnValueAddition + value.getEvaluationNotNormalized(
125 issuevalue)));
126 }
127 } catch (Exception ex) {
128 ex.printStackTrace();
129 }
130 }
131
132 @Override
133 public double getBidEvaluation(Bid bid) {
134 double result = 0;
135 try {
136 result = opponentUtilitySpace.getUtility(bid);
137 } catch (Exception e) {
138 e.printStackTrace();
139 }
140 return result;
141 }
142
143 @Override
144 public String getName() {
145 return "HardHeaded Frequency Model";
146 }
147
148 @Override
149 public Set<BOAparameter> getParameterSpec() {
150 Set<BOAparameter> set = new HashSet<BOAparameter>();
151 set.add(new BOAparameter("l", 0.2,
152 "The learning coefficient determines how quickly the issue weights are learned"));
153 return set;
154 }
155
156 private void initializeModel() {
157 double commonWeight = 1D / amountOfIssues;
158
159 // initialize the weights
160 for (Entry<Objective, Evaluator> e : opponentUtilitySpace
161 .getEvaluators()) {
162
163 opponentUtilitySpace.unlock(e.getKey());
164 e.getValue().setWeight(commonWeight);
165 try {
166 // set all value weights to one (they are normalized when
167 // calculating the utility)
168 for (ValueDiscrete vd : ((IssueDiscrete) e.getKey())
169 .getValues())
170 ((EvaluatorDiscrete) e.getValue()).setEvaluation(vd, 1);
171 } catch (Exception ex) {
172 ex.printStackTrace();
173 }
174 }
175 }
176
177 /**
178 * Determines the difference between bids. For each issue, it is determined
179 * if the value changed. If this is the case, a 1 is stored in a hashmap for
180 * that issue, else a 0.
181 *
182 * @param a
183 * bid of the opponent
184 * @param another
185 * bid
186 * @return
187 */
188 private HashMap<Integer, Integer> determineDifference(BidDetails first,
189 BidDetails second) {
190
191 HashMap<Integer, Integer> diff = new HashMap<Integer, Integer>();
192 try {
193 for (Issue i : opponentUtilitySpace.getDomain().getIssues()) {
194 diff.put(i.getNumber(),
195 (((ValueDiscrete) first.getBid()
196 .getValue(i.getNumber()))
197 .equals(second.getBid()
198 .getValue(i.getNumber()))) ? 0
199 : 1);
200 }
201 } catch (Exception ex) {
202 ex.printStackTrace();
203 }
204
205 return diff;
206 }
207
208}
Note: See TracBrowser for help on using the repository browser.