source: src/main/java/agents/anac/y2019/kagent/boacomponents/HardHeadedFrequencyModel.java@ 345

Last change on this file since 345 was 202, checked in by Katsuhide Fujita, 5 years ago

Add ANAC 2019 agents (3)

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