package negotiator.boaframework.opponentmodel; import java.util.ArrayList; import java.util.Map; import genius.core.Bid; import genius.core.boaframework.NegotiationSession; import genius.core.boaframework.OpponentModel; import genius.core.issue.Issue; import genius.core.issue.IssueDiscrete; import genius.core.issue.Value; import genius.core.issue.ValueDiscrete; import genius.core.utility.AdditiveUtilitySpace; import negotiator.boaframework.opponentmodel.agentx.DiscreteIssueProcessor; import negotiator.boaframework.opponentmodel.agentx.DiscreteValueProcessor; import negotiator.boaframework.opponentmodel.tools.UtilitySpaceAdapter; /** * Class for building an opponent model in discrete space. Contains value- and * issue-processors to deal with opponent bids. * * Adapted by Mark Hendrikx to be compatible with the BOA framework. * * Tim Baarslag, Koen Hindriks, Mark Hendrikx, Alex Dirkzwager and Catholijn M. * Jonker. Decoupling Negotiating Agents to Explore the Space of Negotiation * Strategies * * @author E. Jacobs, Mark Hendrikx */ public class AgentXFrequencyModel extends OpponentModel { private DiscreteIssueProcessor issueProcessor; private ArrayList discreteIssueList = new ArrayList(); private ArrayList valueProcessList = new ArrayList(); private int startingBidIssue = 0; /** * Creates an opponent model for the given utility space * * @param u * The utility space */ @Override public void init(NegotiationSession negotiationSession, Map parameters) { this.negotiationSession = negotiationSession; issueProcessor = new DiscreteIssueProcessor(negotiationSession.getUtilitySpace().getDomain()); discreteIssueList = issueProcessor.getIssueList(); createValueProcessors(); while (!testIndexOfFirstIssue(negotiationSession.getUtilitySpace().getDomain().getRandomBid(null), startingBidIssue)) { startingBidIssue++; } } /** * Just an auxiliar funtion to calculate the index where issues start on a * bid because we found out that it depends on the domain. * * @return true when the received index is the proper index */ private boolean testIndexOfFirstIssue(Bid bid, int i) { try { @SuppressWarnings("unused") ValueDiscrete valueOfIssue = (ValueDiscrete) bid.getValue(i); } catch (Exception e) { return false; } return true; } /** * Creates discreteValueProcessors for all issues */ private void createValueProcessors() { for (IssueDiscrete i : discreteIssueList) { valueProcessList.add(new DiscreteValueProcessor(i.getValues())); } } /** * Returns a DiscreteValueProcessor, allowing the use of several methods * * @param i * The issue for which a ValueProcessor is needed * @return a DiscreteValueProcessor for the issue */ public DiscreteValueProcessor getValueProcessor(IssueDiscrete i) { int index = discreteIssueList.indexOf(i); if (index != -1) return valueProcessList.get(index); return null; } /** * Gives the discreteIssueProcessor for this opponent model * * @return The discreteIssueProcessor */ public DiscreteIssueProcessor getIssueProcessor() { return issueProcessor; } /** * Processes a bid, possibly changing value ranks for the internal opponent * model. Currently, values on which more bids are made are ranked higher. * * @param b * The bid done by the opponent * @param time * Time at which the bid was done */ public void updateModel(Bid b, double time) { issueProcessor.adaptWeightsByBid(b, time); for (IssueDiscrete i : discreteIssueList) { Value v = null; try { v = b.getValue(i.getNumber()); } catch (Exception e) { } if (v != null) { ValueDiscrete vDisc = (ValueDiscrete) v; getValueProcessor(i).addBidForValue(vDisc); } } } /** * Gives the normalized value rank of some value within a certain Issue * * @param issueIndex * The index of the issue. Same index as in the ArrayList * provided by utilitySpace.getDomain().getIssues() * @param valueOfIssue * The value from that issue for which the normalized rank is * required * @return The normalized valueRank for the value of the issue given */ public double getEvaluationOfValue(int issueIndex, ValueDiscrete valueOfIssue) { return valueProcessList.get(issueIndex).getNormalizedValueRank(valueOfIssue); } /** * Calculates the utility to our opponent of the bid received as a parameter * using the current knowledge given by our opponent model * * @param bid * @return utility value for our opponent */ public double getBidEvaluation(Bid bid) { double utility = 0; // Taking into account that Opponent Issue list is in the same our of // the domain int nrIssues = negotiationSession.getUtilitySpace().getDomain().getIssues().size(); for (int i = 0; i < nrIssues; i++) { try { // It was needed to use an auxiliar variable startingBidIssue, // because we found out it varies from domain to domain ValueDiscrete valueOfIssue = (ValueDiscrete) bid.getValue(i + startingBidIssue); double w = getIssueProcessor().getWeightByIssue( (IssueDiscrete) negotiationSession.getUtilitySpace().getDomain().getIssues().get(i)); double eval = getEvaluationOfValue(i, valueOfIssue); utility += w * eval; } catch (Exception e) { // e.printStackTrace(); } } return utility; } /** * @return the weight of the issue. */ public double getWeight(Issue issue) { return getIssueProcessor().getWeightByIssue((IssueDiscrete) issue); } /** * @return utilityspace created by using the opponent model adapter. */ public AdditiveUtilitySpace getOpponentUtilitySpace() { return new UtilitySpaceAdapter(this, negotiationSession.getUtilitySpace().getDomain()); } public String getName() { return "AgentX Frequency Model"; } }