[1] | 1 | package agents.ai2014.group8;
|
---|
| 2 |
|
---|
| 3 | import java.util.ArrayList;
|
---|
| 4 | import java.util.Comparator;
|
---|
| 5 | import java.util.HashMap;
|
---|
| 6 | import java.util.Iterator;
|
---|
| 7 | import java.util.List;
|
---|
| 8 | import java.util.Map;
|
---|
| 9 | import java.util.TreeMap;
|
---|
| 10 |
|
---|
| 11 | import genius.core.AgentID;
|
---|
| 12 | import genius.core.Bid;
|
---|
| 13 | import genius.core.issue.Issue;
|
---|
| 14 | import genius.core.issue.Value;
|
---|
| 15 |
|
---|
| 16 | /**
|
---|
| 17 | * Class that models opponent preference profile
|
---|
| 18 | *
|
---|
| 19 | */
|
---|
| 20 | public class OpponentModel {
|
---|
| 21 |
|
---|
| 22 | // agent being modeled
|
---|
| 23 | public AgentID agent;
|
---|
| 24 |
|
---|
| 25 | // list of bids made by agent
|
---|
| 26 | private List<Bid> bidsMadeByAgent;
|
---|
| 27 |
|
---|
| 28 | // list of issues and their associated weights
|
---|
| 29 | private Map<Issue, Double> issueWeights;
|
---|
| 30 |
|
---|
| 31 | // mapping of Issues to their values and number of bids made for each value
|
---|
| 32 | private Map<Issue, Map<Value, Integer>> issueValueFrequencies;
|
---|
| 33 |
|
---|
| 34 | // mapping of Issues to their values and number of bids made for each value
|
---|
| 35 | private Map<Issue, Map<Value, Integer>> sortedIssueValueFrequencies;
|
---|
| 36 |
|
---|
| 37 | // mapping of Issues to their values and number of bids made for each value
|
---|
| 38 | private Map<Issue, Map<Value, Double>> issueEvaluationValues;
|
---|
| 39 |
|
---|
| 40 | /**
|
---|
| 41 | * class constructor
|
---|
| 42 | *
|
---|
| 43 | * @param opponentAgent
|
---|
| 44 | * agent whose preference is being modeled
|
---|
| 45 | */
|
---|
| 46 | public OpponentModel(AgentID opponentAgent, List<Issue> issues) {
|
---|
| 47 |
|
---|
| 48 | this.agent = opponentAgent;
|
---|
| 49 |
|
---|
| 50 | this.bidsMadeByAgent = new ArrayList<Bid>();
|
---|
| 51 |
|
---|
| 52 | // get the issues that are in the domain
|
---|
| 53 | List<Issue> issuesInDomain = issues;
|
---|
| 54 |
|
---|
| 55 | this.issueWeights = new HashMap<Issue, Double>();
|
---|
| 56 | this.issueValueFrequencies = new HashMap<Issue, Map<Value, Integer>>();
|
---|
| 57 | this.issueEvaluationValues = new HashMap<Issue, Map<Value, Double>>();
|
---|
| 58 |
|
---|
| 59 | // for each issue in domain, add an entry in list of preferences
|
---|
| 60 | // initialize each issue with the initial weights
|
---|
| 61 | for (Issue issue : issuesInDomain) {
|
---|
| 62 | this.issueWeights.put(issue, 0.0);
|
---|
| 63 |
|
---|
| 64 | this.issueValueFrequencies
|
---|
| 65 | .put(issue, new HashMap<Value, Integer>());
|
---|
| 66 |
|
---|
| 67 | this.issueEvaluationValues.put(issue, new HashMap<Value, Double>());
|
---|
| 68 | }
|
---|
| 69 | }
|
---|
| 70 |
|
---|
| 71 | /**
|
---|
| 72 | * store bids made by this opponent for preference analysis
|
---|
| 73 | *
|
---|
| 74 | * @param bid
|
---|
| 75 | */
|
---|
| 76 | public void AddBid(Bid bid) {
|
---|
| 77 | if (bid != null) {
|
---|
| 78 | this.bidsMadeByAgent.add(bid);
|
---|
| 79 |
|
---|
| 80 | this.UpdateIssueValueFrequencies(bid);
|
---|
| 81 | }
|
---|
| 82 |
|
---|
| 83 | this.AnalyzeIssueValuePreferences();
|
---|
| 84 | }
|
---|
| 85 |
|
---|
| 86 | /**
|
---|
| 87 | * update the count of bids made for every issue value
|
---|
| 88 | *
|
---|
| 89 | * @param newBid
|
---|
| 90 | * the bid based on which to update frequencies
|
---|
| 91 | */
|
---|
| 92 | public void UpdateIssueValueFrequencies(Bid newBid) {
|
---|
| 93 | for (int i = 0; i < newBid.getIssues().size(); i++) {
|
---|
| 94 | Issue issue = newBid.getIssues().get(i);
|
---|
| 95 | Value issueValue = null;
|
---|
| 96 |
|
---|
| 97 | try {
|
---|
| 98 | issueValue = newBid.getValue(i + 1);
|
---|
| 99 | } catch (Exception e) {
|
---|
| 100 | e.printStackTrace();
|
---|
| 101 | return;
|
---|
| 102 | }
|
---|
| 103 |
|
---|
| 104 | Map<Value, Integer> valueMapping = issueValueFrequencies.get(issue);
|
---|
| 105 |
|
---|
| 106 | int currentFrequency = 0;
|
---|
| 107 | if (valueMapping.containsKey(issueValue)) {
|
---|
| 108 | currentFrequency = valueMapping.get(issueValue);
|
---|
| 109 | currentFrequency++;
|
---|
| 110 |
|
---|
| 111 | valueMapping.put(issueValue, currentFrequency);
|
---|
| 112 | } else {
|
---|
| 113 | currentFrequency++;
|
---|
| 114 | valueMapping.put(issueValue, currentFrequency);
|
---|
| 115 | }
|
---|
| 116 | }
|
---|
| 117 | }
|
---|
| 118 |
|
---|
| 119 | /**
|
---|
| 120 | * method to analyze agent issue value preferences by bid frequency analysis
|
---|
| 121 | */
|
---|
| 122 | public void AnalyzeIssueValuePreferences() {
|
---|
| 123 | Iterator it = this.issueValueFrequencies.entrySet().iterator();
|
---|
| 124 |
|
---|
| 125 | sortedIssueValueFrequencies = new HashMap<Issue, Map<Value, Integer>>();
|
---|
| 126 |
|
---|
| 127 | while (it.hasNext()) {
|
---|
| 128 | Map.Entry<Issue, Map<Value, Integer>> pair = (Map.Entry<Issue, Map<Value, Integer>>) it
|
---|
| 129 | .next();
|
---|
| 130 | Issue issue = pair.getKey();
|
---|
| 131 | Map<Value, Integer> valueFrequencies = pair.getValue();
|
---|
| 132 |
|
---|
| 133 | // assign issue weights as inverse of number of different choices
|
---|
| 134 | // made for the issue
|
---|
| 135 | double issueWeight = 1 / (double) valueFrequencies.size();
|
---|
| 136 | this.issueWeights.put(issue, issueWeight);
|
---|
| 137 |
|
---|
| 138 | // sort the issue values by frequency of bids that target the
|
---|
| 139 | // particular value
|
---|
| 140 | ValueComparator bvc = new ValueComparator(valueFrequencies);
|
---|
| 141 | TreeMap<Value, Integer> sorted_map = new TreeMap<Value, Integer>(
|
---|
| 142 | bvc);
|
---|
| 143 | sorted_map.putAll(valueFrequencies);
|
---|
| 144 |
|
---|
| 145 | int highestFrequency = sorted_map.firstEntry().getValue();
|
---|
| 146 | Iterator valueIterator = sorted_map.entrySet().iterator();
|
---|
| 147 | Map<Value, Double> evals = new HashMap<Value, Double>();
|
---|
| 148 |
|
---|
| 149 | // evaluation value of an issue value is the number of times the
|
---|
| 150 | // value was bid for
|
---|
| 151 | // divided by the number of times the highest bid value was bid for
|
---|
| 152 | while (valueIterator.hasNext()) {
|
---|
| 153 | Map.Entry<Value, Integer> valuePair = (Map.Entry<Value, Integer>) valueIterator
|
---|
| 154 | .next();
|
---|
| 155 |
|
---|
| 156 | int valueFrequency = valuePair.getValue();
|
---|
| 157 |
|
---|
| 158 | double evaluationValue = valueFrequency
|
---|
| 159 | / (double) highestFrequency;
|
---|
| 160 |
|
---|
| 161 | evals.put(valuePair.getKey(), evaluationValue);
|
---|
| 162 | }
|
---|
| 163 |
|
---|
| 164 | this.issueEvaluationValues.put(issue, evals);
|
---|
| 165 | this.sortedIssueValueFrequencies.put(issue, sorted_map);
|
---|
| 166 | }
|
---|
| 167 |
|
---|
| 168 | this.UpdateIssueWeights();
|
---|
| 169 | }
|
---|
| 170 |
|
---|
| 171 | /**
|
---|
| 172 | * method to estimate issue weights
|
---|
| 173 | */
|
---|
| 174 | public void UpdateIssueWeights() {
|
---|
| 175 | Iterator it = this.issueWeights.entrySet().iterator();
|
---|
| 176 | double weightSum = 0.0;
|
---|
| 177 |
|
---|
| 178 | while (it.hasNext()) {
|
---|
| 179 | Map.Entry<Value, Double> weightPair = (Map.Entry<Value, Double>) it
|
---|
| 180 | .next();
|
---|
| 181 |
|
---|
| 182 | weightSum += weightPair.getValue();
|
---|
| 183 | }
|
---|
| 184 |
|
---|
| 185 | it = this.issueWeights.entrySet().iterator();
|
---|
| 186 |
|
---|
| 187 | while (it.hasNext()) {
|
---|
| 188 | Map.Entry<Value, Double> weightPair = (Map.Entry<Value, Double>) it
|
---|
| 189 | .next();
|
---|
| 190 |
|
---|
| 191 | weightPair.setValue(weightPair.getValue() / weightSum);
|
---|
| 192 | }
|
---|
| 193 | }
|
---|
| 194 |
|
---|
| 195 | /**
|
---|
| 196 | * method to evaluate the utility of a bid for this agent
|
---|
| 197 | *
|
---|
| 198 | * @param bidToEvaluate
|
---|
| 199 | * bid whose utility to evaluate
|
---|
| 200 | * @return utility of bid for this agent
|
---|
| 201 | */
|
---|
| 202 | public double EvaluateBidUtility(Bid bidToEvaluate) {
|
---|
| 203 | double utilityValue = 0.0;
|
---|
| 204 |
|
---|
| 205 | // utility value = u1 * w1 + u2 * w2 + ...
|
---|
| 206 | for (int i = 0; i < bidToEvaluate.getIssues().size(); i++) {
|
---|
| 207 | Issue issue = bidToEvaluate.getIssues().get(i);
|
---|
| 208 | Value issueValue = null;
|
---|
| 209 |
|
---|
| 210 | try {
|
---|
| 211 | issueValue = bidToEvaluate.getValue(i + 1);
|
---|
| 212 | } catch (Exception e) {
|
---|
| 213 | e.printStackTrace();
|
---|
| 214 | }
|
---|
| 215 |
|
---|
| 216 | if (issueValue != null) {
|
---|
| 217 | double issueWeight = this.issueWeights.get(issue);
|
---|
| 218 |
|
---|
| 219 | Map<Value, Double> evaluationValues = this.issueEvaluationValues
|
---|
| 220 | .get(issue);
|
---|
| 221 | double evaluationValue = 0.0;
|
---|
| 222 |
|
---|
| 223 | if (evaluationValues.isEmpty() == false
|
---|
| 224 | && evaluationValues.containsKey(issueValue)) {
|
---|
| 225 | evaluationValue = evaluationValues.get(issueValue);
|
---|
| 226 | }
|
---|
| 227 |
|
---|
| 228 | utilityValue += issueWeight * evaluationValue;
|
---|
| 229 | }
|
---|
| 230 | }
|
---|
| 231 |
|
---|
| 232 | return utilityValue;
|
---|
| 233 | }
|
---|
| 234 |
|
---|
| 235 | /**
|
---|
| 236 | * overridden equals method to compare two OpponentModel objects they are
|
---|
| 237 | * equal if they model the same agent, determined by agentID
|
---|
| 238 | *
|
---|
| 239 | * @param object
|
---|
| 240 | * object being compared
|
---|
| 241 | */
|
---|
| 242 | @Override
|
---|
| 243 | public boolean equals(Object object) {
|
---|
| 244 | boolean result = false;
|
---|
| 245 |
|
---|
| 246 | if (object instanceof OpponentModel) {
|
---|
| 247 | OpponentModel toCompare = (OpponentModel) object;
|
---|
| 248 |
|
---|
| 249 | if (this.agent.equals(toCompare.agent)) {
|
---|
| 250 | result = true;
|
---|
| 251 | }
|
---|
| 252 | }
|
---|
| 253 |
|
---|
| 254 | return result;
|
---|
| 255 | }
|
---|
| 256 |
|
---|
| 257 | /**
|
---|
| 258 | * Class that is used to compare issue values
|
---|
| 259 | *
|
---|
| 260 | */
|
---|
| 261 | class ValueComparator implements Comparator<Value> {
|
---|
| 262 | Map<Value, Integer> base;
|
---|
| 263 |
|
---|
| 264 | public ValueComparator(Map<Value, Integer> base) {
|
---|
| 265 | this.base = base;
|
---|
| 266 | }
|
---|
| 267 |
|
---|
| 268 | // Note: this comparator imposes orderings that are inconsistent with
|
---|
| 269 | // equals.
|
---|
| 270 | public int compare(Value a, Value b) {
|
---|
| 271 | if (base.get(a) >= base.get(b)) {
|
---|
| 272 | return -1;
|
---|
| 273 | } else {
|
---|
| 274 | return 1;
|
---|
| 275 | }
|
---|
| 276 | }
|
---|
| 277 | }
|
---|
| 278 | }
|
---|