source: src/test/java/boaexample/HardHeadedFrequencyModel.java@ 37

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

Initial import : Genius 9.0.0

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