package geniusweb.exampleparties.simpleshaop; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; import geniusweb.issuevalue.Bid; import geniusweb.issuevalue.Value; import geniusweb.issuevalue.ValueSet; public class NegotiationInfo { private CompRegress compRegress; private List issues; private ArrayList myBidHistory = null; private ArrayList bestOfferedBidHistory = null; private ArrayList opponentBidHistory = null; private BigDecimal opponentSum; private BigDecimal opponentPowSum; private BigDecimal opponentAvg; private BigDecimal opponentVar; private HashMap> valueRelativeUtil = null; private HashMap> opponentValueFreq = null; private BigDecimal bestOfferedUtil = BigDecimal.ZERO; private HashMap opponentTheta; private HashMap> estOpponentUtil; /** * NegotiationInfo - constructor * * @param utilitySpace * @param isPrinting */ public NegotiationInfo(CompRegress compRegress) { this.compRegress = compRegress; this.issues = compRegress.getIssues(); this.myBidHistory = new ArrayList<>(); this.bestOfferedBidHistory = new ArrayList<>(); this.valueRelativeUtil = new HashMap>(); this.opponentBidHistory = new ArrayList(); this.opponentSum = BigDecimal.ZERO; this.opponentPowSum = BigDecimal.ZERO; this.opponentAvg = BigDecimal.ZERO; this.opponentVar = BigDecimal.ZERO; this.opponentValueFreq = new HashMap>(); this.opponentTheta = new HashMap(); this.estOpponentUtil = new HashMap>(); try { initValueRelativeUtil(); } catch (Exception e) { System.out.println("initValueRelativeUtil failed"); e.printStackTrace(); } } /** * initValueRelativeUtil - initialize the relative utilities of all values * * @throws Exception */ private void initValueRelativeUtil() throws Exception { ArrayList values = null; for (String issue : issues) { valueRelativeUtil.put(issue, new HashMap()); values = getValues(issue); for (Value value : values) { valueRelativeUtil.get(issue).put(value, BigDecimal.ZERO); } } } //////////////////////////////////////////////////////////////////////////////// // method initOpponent and its helper functions used in ShaopParty //////////////////////////////////////////////////////////////////////////////// /** * initOpponent - initialize the opponent related parameters * calls private methods initOpponentInfo, initOpponentsValueFreq * * @param sender - the opponent agent to initialize */ public void initOpponent() { initOpponentValueFreq(); } /** * initOpponetsValueFreq - initialize opponent's frequency of all values * * @param sender - the opponent agent to initialize * @throws Exception */ private void initOpponentValueFreq() { for (String issue : issues) { opponentValueFreq.put(issue, new HashMap()); ArrayList values = getValues(issue); for (Value value : values) { opponentValueFreq.get(issue).put(value, 0); } } } //////////////////////////////////////////////////////////////////////////////// // method updateInfo and its helper functions used in ShaopParty //////////////////////////////////////////////////////////////////////////////// /** * updateInfo - updates negotiation information * calls updateNegotiatingInfo, updateFreqLists * * @param sender - the opponent agent to update * @param offeredBid - Bid; the offered Bid */ public void updateInfo(Bid offeredBid) { try { updateNegotiatingInfo(offeredBid); } catch (Exception e) { System.out.println("updateNegotiatingInfo failed"); e.printStackTrace(); } try { updateFreqLists(offeredBid); } catch (Exception e) { System.out.println("updateFreqLists failed"); e.printStackTrace(); } } /** * updateNegotiatingInfo - updates negotiating info of opponent and offered bid * * @param sender - the opponent agent to update * @param offeredBid - Bid; the offered Bid * @throws Exception */ private void updateNegotiatingInfo(Bid offeredBid) throws Exception { BigDecimal util = compRegress.getUtil(offeredBid); opponentBidHistory.add(offeredBid); opponentSum = opponentSum.add(util); opponentPowSum = opponentPowSum.add(util.pow(2)); BigDecimal roundNum = BigDecimal.valueOf(opponentBidHistory.size()); opponentAvg = opponentSum.divide(roundNum); opponentVar = (opponentPowSum.divide(roundNum)).subtract(opponentAvg.pow(2)); if (opponentVar.compareTo(BigDecimal.ZERO) < 0) { opponentVar = BigDecimal.ZERO; } if (util.compareTo(bestOfferedUtil) > 0) { bestOfferedBidHistory.add(offeredBid); bestOfferedUtil = util; } } /** * updateFreqLists - updates the two frequency HashMaps * * @param sender - the opponent agent to update * @param offeredBid - Bid; the offered Bid * @throws Exception */ private void updateFreqLists(Bid offeredBid) throws Exception { for (String issue : issues) { Value value = offeredBid.getValue(issue); opponentValueFreq.get(issue).put(value, opponentValueFreq. get(issue).get(value) + 1); } } //////////////////////////////////////////////////////////////////////////////// // method updateMyBidHistory used in ShaopParty //////////////////////////////////////////////////////////////////////////////// /** * updateMyBidHistory * * @param offerBid - the bid to be added to history list */ public void updateMyBidHistory(Bid offerBid) { myBidHistory.add(offerBid); } /** * getBestOfferedBid * @return the offered bid with the highest estimated utility */ public Bid getBestOfferedBid() { if (bestOfferedBidHistory.isEmpty()) return null; else return bestOfferedBidHistory.get(bestOfferedBidHistory.size()-1); } //////////////////////////////////////////////////////////////////////////////// // public methods used in NegotiationStrategy //////////////////////////////////////////////////////////////////////////////// /** * getBestOfferedUtil - gets the best offered utility * * @return bestOfferedUtil */ public BigDecimal getBestOfferedUtil() { return bestOfferedUtil; } /** * getValues - returns an ArrayList of all the values of an issue * * @param issue - String; the issue name * @return a list of all the values associated with the input issue */ private ArrayList getValues(String issue) { ArrayList values = new ArrayList(); ValueSet valueSet = compRegress.getValues(issue); for (Value value : valueSet) { values.add(value); } return values; } //////////////////////////////////////////////////////////////////////////////// // public methods used to model opponent //////////////////////////////////////////////////////////////////////////////// /** * estimates the theta values and acceptance probabilities of opponent */ public void initOpponentProbs() { TreeMap> importanceMap = new TreeMap>(); for (String issue : issues) { int totalFreq = 0; int squaredSum = 0; int maxFreq = 0; Value maxFreqValue = null; ValueSet values = compRegress.getValues(issue); estOpponentUtil.put(issue, new HashMap()); for (Value value : values) { int freq = opponentValueFreq.get(issue).get(value); totalFreq += freq; squaredSum += freq * freq; if (freq > maxFreq) { maxFreq = freq; maxFreqValue = value; } } for (Value value : values) { int freq = opponentValueFreq.get(issue).get(value); double estUtil; if (value == maxFreqValue) estUtil = 1.0; else { if (totalFreq-maxFreq == 0) estUtil = 0.0; else estUtil = freq*1.0/(totalFreq-maxFreq); } estOpponentUtil.get(issue).put(value, estUtil); } double importance; if (totalFreq - maxFreq == 0) importance = 1.0; else importance = (((squaredSum - maxFreq * maxFreq) * 1.0 / (totalFreq - maxFreq)) + maxFreq) / totalFreq; List issueList; if (importanceMap.get(importance) == null) issueList = new ArrayList(); else issueList = importanceMap.get(importance); issueList.add(issue); importanceMap.put(importance, issueList); } initOpponentTheta(importanceMap); } /** * creates the opponent theta values for corresponding issues * @param importanceMap - map of importance and issues in descending order */ private void initOpponentTheta(TreeMap> importanceMap) { double multInverse = 1.0 / issues.size(); double minTheta = multInverse / 2.0; double incr = multInverse / (issues.size() - 1); int i = 0; for (Map.Entry> mapElement : importanceMap.entrySet()) { List issueList = mapElement.getValue(); int listSize = issueList.size(); double theta = minTheta + incr * (i + 0.5*(listSize - 1)); for (int j = 0; j < listSize; j++) { String issue = issueList.get(j); opponentTheta.put(issue, theta); } i += listSize; } } /** * gets a list of bids in descending order of preference * @param myPrefBids - a list of bids to order * @param time - current time * @return an ordered list of bids based on joint utility */ public List getJointPref(List myPrefBids, double time) { BigDecimal biasFactor = BigDecimal.valueOf(1.8 - time * time * 0.3); TreeMap jointUtil = new TreeMap(Collections.reverseOrder()); for (Bid bid : myPrefBids) { BigDecimal opponentUtil = BigDecimal.valueOf(opponentAcceptProb(bid)); BigDecimal util = compRegress.getUtil(bid).multiply(biasFactor). add(opponentUtil); jointUtil.put(util, bid); } List bidOrder = new ArrayList(); Set> set = jointUtil.entrySet(); Iterator> i = set.iterator(); while (i.hasNext()) { Map.Entry map = (Map.Entry) i.next(); bidOrder.add(map.getValue()); } return bidOrder; } /** * gets the estimated acceptance probability of a bid * @param bid - the bid we want to know the acceptance probability * @return the estimate acceptance probability of the input bid */ private double opponentAcceptProb(Bid bid) { double prob = 0.0; for (String issue : issues) { Value value = bid.getValue(issue); prob += opponentTheta.get(issue) * estOpponentUtil.get(issue).get(value); } return prob; } /** * updates the compRegress * @param newCompRegress - the new compRegress */ public void updateCompRegress(CompRegress newCompRegress) { this.compRegress = newCompRegress; } }