package agents.ai2014.group12; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import genius.core.Bid; import genius.core.Domain; import genius.core.issue.IssueDiscrete; import genius.core.issue.Objective; import genius.core.issue.Value; import genius.core.issue.ValueDiscrete; import genius.core.utility.AdditiveUtilitySpace; import genius.core.utility.Evaluator; import genius.core.utility.EvaluatorDiscrete; /** * The Preference class will hold the issues, their weights and for each issue * their values and the order of these values. Only compatible with * {@link AdditiveUtilitySpace}. * */ public class Preference { ArrayList preferenceList = new ArrayList(); /** * First constructor for the Preference class, this is to create a * Preference profile for the agent that is currently in turn. This * Preference object will not be updated. The Utilityspace is used to fill * the values of each issue and their order. * * @param utilitySpace * of the player in turn */ public Preference(AdditiveUtilitySpace utilitySpace) { Domain domain = utilitySpace.getDomain(); int size = utilitySpace.getEvaluators().size(); System.out.println("size: " + size); List objectives = domain.getObjectives(); for (int i = 1; i <= size; i++) { IssueDiscrete issue = (IssueDiscrete) objectives.get(i); Double weight = utilitySpace.getWeight(i); Evaluator evalor = utilitySpace.getEvaluator(i); EvaluatorDiscrete evalorDis = (EvaluatorDiscrete) evalor; // Define each issue with every weight attached PreferenceBlock prefBlock = new PreferenceBlock(evalorDis, issue.getName(), weight); prefBlock.normalizeNodeValues(); Node highest = prefBlock.getHighestPreference(); highest.setFlag(true); preferenceList.add(prefBlock); } // Possibility to randomize the other values of each issue. } /** * This constructor is used to create a Preference object for an Agent of * which you have received a bid for the first time. The utilitySpace of the * agent receiving the message will be used for the initial issue, value and * order setup. This will be later updated using the bids of the agent to * which this preference belongs to. * * @param utilitySpace * of the agent receiving the message * @param bid */ public Preference(AdditiveUtilitySpace utilitySpace, Bid bid) { Domain domain = utilitySpace.getDomain(); int size = utilitySpace.getEvaluators().size(); System.out.println("size: " + size); List objectives = domain.getObjectives(); for (int i = 1; i <= size; i++) { IssueDiscrete issue = (IssueDiscrete) objectives.get(i); double weight = 1.0 / size; Evaluator evalor = utilitySpace.getEvaluator(i); System.out.println(evalor); EvaluatorDiscrete evalorDis = (EvaluatorDiscrete) evalor; // Define an issue with all weights the same PreferenceBlock prefBlock = new PreferenceBlock(evalorDis, issue.getName(), weight); prefBlock.normalizeNodeValues(); Node highest = prefBlock.getHighestPreference(); highest.setFlag(true); preferenceList.add(prefBlock); } setHighestIssuePreference(bid); // Possibility to randomize the other values of each issue. } /** * Updates the preference of a party given the current bid. It considers the * first bid to be the agents highest utility bid. It will not take into * account the nodes flagged value for this first bid. * * @param bid */ public void setHighestIssuePreference(Bid bid) { HashMap values = bid.getValues(); for (int i = 1; i <= values.size(); i++) { ValueDiscrete value = (ValueDiscrete) values.get(i); PreferenceBlock preferBlock = preferenceList.get(i - 1); Node currentHighest = preferBlock.getHighestPreference(); if (!currentHighest.getName().equals(value.getValue())) { // preferBlock.orderNodesLowToHigh(); ArrayList nodes = preferBlock.nodeList; int index = preferBlock.indexOf(value.getValue()); for (int j = index; j < nodes.size() - 1; j++) { nodes.get(j).setName(nodes.get(j + 1).getName()); } nodes.get(nodes.size() - 1).setName(value.getValue()); } } } /** * This method updates the preference order of an already initialized * preference object This will used the flagged status to determine what * nodes have alreay been set. It will determine what values have been * changed and were not yet flagged and will set those in the appropriate * order and update their flagged status. * * @param bid */ public void updatePreferenceOrder(Bid bid) { // First update the sequence of the values of an issue HashMap values = bid.getValues(); for (int i = 1; i <= values.size(); i++) { ValueDiscrete value = (ValueDiscrete) values.get(i); PreferenceBlock preferBlock = preferenceList.get(i - 1); ArrayList nodesWithoutFlag = preferBlock .getValuesWithoutFlag(); for (int j = 0; i < nodesWithoutFlag.size(); i++) { // If not flagged yet, flag it and set it to the next value // after the last flagged if (nodesWithoutFlag.get(i).getName().equals(value.getValue())) { int highestIndexWithoutFlag = preferBlock .getHighestIndexWithoutFlag(); ArrayList nodes = preferBlock.nodeList; int index = preferBlock.indexOf(value.getValue()); for (int k = index; k < nodes.size() - 1 && !nodes.get(k + 1).getFlag(); k++) { nodes.get(k).setName(nodes.get(k + 1).getName()); } nodes.get(highestIndexWithoutFlag) .setName(value.getValue()); nodes.get(highestIndexWithoutFlag).setFlag(true); } } } } /** * This method updates the issue weights given the previous bid and the new * bid. Each weight of an issue that has been changed will be decreased and * then normalized. * * @param previousBids * @param newBid */ public void updateIssueWeights(ArrayList previousBids, Bid newBid) { Bid previousBid = previousBids.get(previousBids.size() - 1); ArrayList changedIssues = getChangedIndices(previousBid, newBid); // Decrease the weights that have been changed for (int i = 0; i < changedIssues.size(); i++) { preferenceList.get(changedIssues.get(i)).weight -= 0.50 / changedIssues .size(); } // Sum the weights double sum = 0.0; for (int i = 0; i < preferenceList.size(); i++) { sum += preferenceList.get(i).weight; } // Normalize the weights for (int i = 0; i < preferenceList.size(); i++) { preferenceList.get(i).weight = preferenceList.get(i).weight / sum; } } /** * Method that returns the changed indices by comparing the previous bid and * the new bid * * @param previousBid * @param newBid * @return list of integers with the changed indices */ public ArrayList getChangedIndices(Bid previousBid, Bid newBid) { ArrayList indices = new ArrayList(); HashMap valuesNewBid = newBid.getValues(); HashMap valuesPreviousBid = previousBid.getValues(); for (int i = 1; i <= valuesNewBid.size(); i++) { ValueDiscrete valueNewBid = (ValueDiscrete) valuesNewBid.get(i); ValueDiscrete valuePreviousBid = (ValueDiscrete) valuesPreviousBid .get(i); if (!valueNewBid.getValue().equals(valuePreviousBid.getValue())) { // i-1 to get the right index in the preferenceList indices.add(i - 1); } } return indices; } /** * Calculates the utility value for a bid given the current preference * profile. This gives the agent the possibility to calculate other agents * utilities without knowing their exact preference profile. * * @param bid * @return double */ public double getUtilityValue(Bid bid) { HashMap bidvalues = bid.getValues(); double returnUtility = 0; for (PreferenceBlock block : preferenceList) { double weight = block.weight; for (Map.Entry entry : bidvalues.entrySet()) { Value value = entry.getValue(); for (Node node : block.nodeList) { if (node.getName() == value.toString()) { returnUtility += node.getValue() * weight; } } } } return returnUtility; } }