source: src/main/java/negotiator/boaframework/opponentmodel/NashFrequencyModel.java@ 184

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

#41 ROLL BACK of rev.126 . So this version is equal to rev. 125

File size: 8.1 KB
Line 
1package negotiator.boaframework.opponentmodel;
2
3import java.util.List;
4import java.util.Map;
5
6import genius.core.Bid;
7import genius.core.boaframework.NegotiationSession;
8import genius.core.boaframework.OpponentModel;
9import genius.core.issue.Issue;
10import genius.core.issue.IssueDiscrete;
11import genius.core.issue.IssueInteger;
12import genius.core.issue.IssueReal;
13import genius.core.issue.Value;
14import genius.core.utility.AdditiveUtilitySpace;
15import negotiator.boaframework.opponentmodel.nash.AIssueEvaluation;
16import negotiator.boaframework.opponentmodel.nash.IssueEvaluationDiscrete;
17import negotiator.boaframework.opponentmodel.nash.IssueEvaluationInteger;
18import negotiator.boaframework.opponentmodel.nash.IssueEvaluationList;
19import negotiator.boaframework.opponentmodel.nash.IssueEvaluationReal;
20import negotiator.boaframework.opponentmodel.nash.Range;
21import negotiator.boaframework.opponentmodel.tools.UtilitySpaceAdapter;
22
23/**
24 * This class holds the model of a negotiator, which will be constructed by it's
25 * bids. The opponentmodel will be based on frequency/distribution analysis.
26 *
27 * - The importance of a discrete issue and it's values will be calculated by
28 * the difference in the number of times a certain value is chosen. - The
29 * importance of a numerical issue will be calculated by the first offered
30 * values and the range in which our own issue has a utility > 0. We will then
31 * interpolate between the max utility value and the min utility value.
32 *
33 * Adapted by Mark Hendrikx to be compatible with the BOA framework.
34 *
35 * Tim Baarslag, Koen Hindriks, Mark Hendrikx, Alex Dirkzwager and Catholijn M.
36 * Jonker. Decoupling Negotiating Agents to Explore the Space of Negotiation
37 * Strategies
38 *
39 * @author Roland van der Linden, Mark Hendrikx
40 */
41public class NashFrequencyModel extends OpponentModel {
42 // **************************************
43 // Fields
44 // **************************************
45
46 // The list of issueEvaluations which hold the analysis.
47 private IssueEvaluationList issueEvaluationList;
48
49 @Override
50 public void init(NegotiationSession domainKnow, Map<String, Double> parameters) {
51 negotiationSession = domainKnow;
52 initModel();
53 }
54
55 /**
56 * This initializes the negotiatormodel, creating an issueEvaluation for
57 * each issue in the utilitySpace.
58 */
59 private void initModel() {
60 List<Issue> issues = negotiationSession.getUtilitySpace().getDomain().getIssues();
61
62 this.issueEvaluationList = new IssueEvaluationList(issues.size());
63
64 // Create an empty issueEvaluation object for each issue in the domain.
65 // This will later contain all information we can gather on the
66 // negotiator.
67 for (int index = 0; index < issues.size(); index++) {
68 Issue issue = issues.get(index);
69 AIssueEvaluation issueEvaluation = null;
70
71 if (issue instanceof IssueDiscrete)
72 issueEvaluation = new IssueEvaluationDiscrete((IssueDiscrete) issue);
73 else if (issue instanceof IssueInteger) {
74 // We use the range in which our utility is non-zero to estimate
75 // the distribution of the opponent.
76 IssueInteger issueI = (IssueInteger) issue;
77 Range ourNonZeroUtilityRange = new Range(issueI.getLowerBound(), issueI.getUpperBound());
78 issueEvaluation = new IssueEvaluationInteger((IssueInteger) issue, ourNonZeroUtilityRange);
79 } else if (issue instanceof IssueReal) {
80 // We use the range in which our utility is non-zero to estimate
81 // the distribution of the opponent.
82 IssueReal issueR = (IssueReal) issue;
83 Range ourNonZeroUtilityRange = new Range(issueR.getLowerBound(), issueR.getUpperBound());
84 issueEvaluation = new IssueEvaluationReal((IssueReal) issue, ourNonZeroUtilityRange);
85 } else
86 throw new UnsupportedOperationException("There is no implementation for that issueType.");
87
88 // Add the new issueEvaluation to the list.
89 this.issueEvaluationList.addIssueEvaluation(issueEvaluation);
90 }
91 }
92
93 // **************************************
94 // Update model
95 // **************************************
96
97 /**
98 * This will receiveMessage the negotiatormodel based on a new bid that has
99 * just been offered by the negotiator.
100 *
101 * @param bid
102 * The bid that has just been offered.
103 */
104 public void updateModel(Bid bid, double time) {
105 if (bid != null) {
106 // We receiveMessage each issueEvaluation with the value that has
107 // been offered in the bid.
108 List<Issue> issues = negotiationSession.getUtilitySpace().getDomain().getIssues();
109 for (Issue issue : issues) {
110 try {
111 int issueID = issue.getNumber();
112 Value offeredValue = bid.getValue(issueID);
113 this.issueEvaluationList.updateIssueEvaluation(issueID, offeredValue);
114 } catch (Exception e) {
115 e.printStackTrace();
116 }
117 }
118 // After all issueEvaluations have been updated, we can calculate
119 // the new
120 // estimated weights for the issues themselves.
121 this.issueEvaluationList.updateIssueWeightMap();
122 }
123 }
124
125 // ****************************************
126 // Utility
127 // ****************************************
128
129 /**
130 * This method estimates the utility of the negotiator given that it has
131 * just offered the given bid. The utility estimation is done by multiplying
132 * the normalized issue weights with the normalized offered-value weight of
133 * that issue.
134 *
135 * Note that the utility of a bid will always be in between 0 - 1. Note that
136 * this method does not take discount into account.
137 *
138 * @param bid
139 * The bid that has just been offered by the negotiator that we
140 * are evaluating.
141 * @return The estimated utility of the bid that has been offered by the
142 * negotiator we are evaluating.
143 */
144 public double getBidEvaluation(Bid bid) {
145 double result = 0;
146 if (issueEvaluationList.isReady()) {
147 List<Issue> issues = negotiationSession.getUtilitySpace().getDomain().getIssues();
148
149 double totalEstimatedUtility = 0;
150 for (Issue issue : issues) {
151 try {
152 int issueID = issue.getNumber();
153
154 // Get the estimated normalized weight of the issue, which
155 // indicates how important the issue is.
156 double issueWeight = this.issueEvaluationList.getNormalizedIssueWeight(issueID);
157
158 // Get the estimated normalized weight of the value of the
159 // issue, which corresponds to the value that has
160 // been offered in the bid.
161 Value offeredValue = bid.getValue(issueID);
162 AIssueEvaluation issueEvaluation = this.issueEvaluationList.getIssueEvaluation(issueID);
163 double offeredValueWeight = issueEvaluation.getNormalizedValueWeight(offeredValue);
164
165 // Since all issueWeights combined should add up to 1, and
166 // the maximum value of the valueWeight is 1,
167 // the estimated utility should be exactly 1 if all offered
168 // valueWeights are 1. So to calculate the partial estimated
169 // utility for this specific issue-value combination, we
170 // need to multiply the weights.
171 totalEstimatedUtility += (issueWeight * offeredValueWeight);
172 } catch (Exception e) {
173 e.printStackTrace();
174 }
175 }
176
177 // Make sure to remove roundoff errors from the utility.
178 result = Math.min(1, Math.max(0, totalEstimatedUtility));
179 }
180 return result;
181 }
182
183 // ****************************************
184 // toString
185 // ****************************************
186
187 /**
188 * This returns a string representation of the negotiatormodel.
189 */
190 public String toString() {
191 return this.issueEvaluationList.toString();
192 }
193
194 public double getWeight(Issue issue) {
195 // Get the estimated normalized weight of the issue, which indicates how
196 // important the issue is.
197 return this.issueEvaluationList.getNormalizedIssueWeight(issue.getNumber());
198 }
199
200 @Override
201 public String getName() {
202 return "NASH Frequency Model";
203 }
204
205 public AdditiveUtilitySpace getOpponentUtilitySpace() {
206 if (issueEvaluationList.isReady()) {
207 return new UtilitySpaceAdapter(this, negotiationSession.getUtilitySpace().getDomain());
208 } else {
209 System.out.println("Returned own utilityspace to avoid an error (normal on first turn).");
210 return (AdditiveUtilitySpace) negotiationSession.getUtilitySpace();
211 }
212 }
213}
Note: See TracBrowser for help on using the repository browser.