package agents.anac.y2017.mosateam; import java.util.List; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import genius.core.AgentID; import genius.core.Bid; import genius.core.actions.Accept; import genius.core.actions.Action; import genius.core.actions.Offer; import genius.core.issue.Issue; import genius.core.issue.IssueDiscrete; import genius.core.issue.IssueInteger; import genius.core.issue.Objective; import genius.core.issue.Value; import genius.core.issue.ValueDiscrete; import genius.core.issue.ValueInteger; import genius.core.list.Tuple; import genius.core.parties.AbstractNegotiationParty; import genius.core.parties.NegotiationInfo; import genius.core.persistent.PersistentDataType; import genius.core.persistent.StandardInfo; import genius.core.persistent.StandardInfoList; import genius.core.utility.AbstractUtilitySpace; import genius.core.utility.Evaluator; import genius.core.utility.EvaluatorDiscrete; import genius.core.utility.EvaluatorInteger; import genius.core.utility.UtilitySpace; import genius.core.xml.SimpleElement; /** * Sample party that accepts the Nth offer, where N is the number of sessions * this [agent-profile] already did. * * Members: Lichun Yuan (Southwest University), Jiancheng Wu (Southwest * University). Affiliation: Southwest University */ public class Mosa extends AbstractNegotiationParty { private Bid lastReceivedBid = null; private int nrChosenActions; private StandardInfoList history; private int numOfIssues; private int numOfParties; private double reservationValue; private double initialUpper; private double initialExponent; private double upper; private double lower; private double exponent; private double acceptUtil; private double utility; private List[] proposedBids; private int[] numOfBids; private Map>[] valueFrequences; private Map[] issueChangeFrequences; private double[] maxUtils; private double[] minUtils; private LinkedList[] proposedMaxBid; private LinkedList[] proposedMinBid; private List[] topBidsInOppsSpace; private LinkedList[] topBidsInMySpace; private Bid myBid; private List fullUtilBids; private int myIndex; private String oppName; private int oppIndex; private boolean[] acceptAction; private PreferModel[] pModel; private Bid lastConcessionPoint; private List[] acceptableBidsWithOppValues; private List candidateBids; private List lastPeriodBidList; private int myNextPartyIndex; private int myLastPartyIndex; private List[] maxProductBids; private List maxUtilAdditionBidByOpps; private double maxUtilAdditionByOpps; private double time1; private double time2; private double time3; private boolean hasHistory; private boolean hasHistWithRightPosition; private boolean hasInitParamByHist; private List> agreements; private boolean hasAgreementHist; private List maxAgreedBids; private Map>[] histUtils; private Map[] maxUtilsInHist; private List[] maxUtilBidsByHist; private List sameBidsInOpps; @Override public void init(NegotiationInfo info) { super.init(info); if (getData().getPersistentDataType() != PersistentDataType.STANDARD) { throw new IllegalStateException("need standard persistent data"); } history = (StandardInfoList) getData().get(); if (!history.isEmpty()) { Map maxutils = new HashMap(); StandardInfo lastinfo = history.get(history.size() - 1); for (Tuple offered : lastinfo.getUtilities()) { String party = offered.get1(); Double util = offered.get2(); maxutils.put(party, maxutils.containsKey(party) ? Math.max(maxutils.get(party), util) : util); } } hasAgreementHist = false; if (!history.isEmpty()) { hasHistory = true; hasInitParamByHist = false; agreements = new ArrayList<>(); maxAgreedBids = new ArrayList<>(); int numOfAgent = history.get(0).getAgentProfiles().size(); histUtils = new HashMap[numOfAgent]; maxUtilsInHist = new HashMap[numOfAgent]; maxUtilBidsByHist = new ArrayList[numOfAgent]; for (int i = 0; i < numOfAgent; i++) { histUtils[i] = new HashMap<>(); maxUtilsInHist[i] = new HashMap<>(); maxUtilBidsByHist[i] = new ArrayList<>(); } for (StandardInfo sessionInfo : history) { if (sessionInfo.getAgreement().get1() != null) { agreements.add(sessionInfo.getAgreement()); hasAgreementHist = true; } for (Tuple offered : sessionInfo .getUtilities()) { String party = offered.get1(); double util = offered.get2(); int index = Integer.parseInt(party.split("@")[1]) % numOfAgent; if (!histUtils[index].containsKey(party)) { List utils = new ArrayList<>(); utils.add(util); histUtils[index].put(party, utils); } else { histUtils[index].get(party).add(util); } } } maxAgreedBids = getMaxBidsInAgreements(); for (int partyIndex = 0; partyIndex < numOfAgent; partyIndex++) { for (String party : histUtils[partyIndex].keySet()) { String partyName = party.split("@")[0]; List utils = histUtils[partyIndex].get(party); double maxUtil = getMaxInArray(utils); if (!maxUtilsInHist[partyIndex].containsKey(partyName)) { maxUtilsInHist[partyIndex].put(partyName, maxUtil); } else if (maxUtilsInHist[partyIndex] .get(partyName) < maxUtil) { maxUtilsInHist[partyIndex].put(partyName, maxUtil); } } } } else { hasHistory = false; hasHistWithRightPosition = false; } nrChosenActions = 0; numOfIssues = getUtilitySpace().getDomain().getIssues().size(); fullUtilBids = new ArrayList<>(); fullUtilBids = getFullUtilBid(getUtilitySpace()); reservationValue = getUtilitySpace().getReservationValue(); sameBidsInOpps = new ArrayList<>(); maxUtilAdditionBidByOpps = new ArrayList<>(); lastPeriodBidList = new ArrayList<>(); maxUtilAdditionByOpps = 0.0; initialUpper = 0.95; initialExponent = 50; upper = initialUpper; lower = reservationValue; exponent = initialExponent; time1 = 0.9; time2 = 0.99; time3 = 0.996; hasInitParamByHist = false; } @Override public Action chooseAction(List> validActions) { nrChosenActions++; Action action = null; Bid bid = null; acceptUtil = getAccept(); if (lastReceivedBid != null) { if (utility >= acceptUtil && !hasProposedMyLastRound(lastReceivedBid)) { bid = new Bid(lastReceivedBid); action = new Accept(getPartyId(), bid); } else { if (timeline.getTime() > time3) { if (hasHistory) { if (!maxAgreedBids.isEmpty()) { bid = maxAgreedBids.get( nrChosenActions % maxAgreedBids.size()); action = new Offer(getPartyId(), bid); } else { if (!lastPeriodBidList.isEmpty()) { bid = lastPeriodBidList.get(nrChosenActions % lastPeriodBidList.size()); action = new Offer(getPartyId(), bid); } else { if (utility > reservationValue) { bid = lastReceivedBid; action = new Accept(getPartyId(), bid); return action; } else { bid = proposedBids[myIndex] .get(nrChosenActions % numOfBids[myIndex]); } } } } else { if (!lastPeriodBidList.isEmpty()) { bid = lastPeriodBidList.get( nrChosenActions % lastPeriodBidList.size()); } else { if (utility > reservationValue) { bid = lastReceivedBid; action = new Accept(getPartyId(), bid); myBid = bid; return action; } else { bid = proposedBids[myIndex].get( nrChosenActions % numOfBids[myIndex]); } } } action = new Offer(getPartyId(), bid); myBid = bid; } else if (timeline.getTime() > time2) { if (nrChosenActions % 3 == 1) { if (candidateBids.isEmpty()) { if (!acceptAction[myNextPartyIndex] && !acceptAction[myLastPartyIndex]) { generateCandidateFromMyTopBids(acceptUtil, candidateBids); generateCandidateFromOppTopBids(acceptUtil, candidateBids); } else if (!acceptAction[myNextPartyIndex]) { generateCandidateFromMyFullAndOppTopBids( acceptUtil, myNextPartyIndex, candidateBids); generateCandidateFromOppTopAndMyTopBids( myNextPartyIndex, acceptUtil, candidateBids); } else { generateCandidateFromMyFullAndOppTopBids( acceptUtil, myLastPartyIndex, candidateBids); generateCandidateFromOppTopAndMyTopBids( myLastPartyIndex, acceptUtil, candidateBids); } } if (!candidateBids.isEmpty()) { bid = candidateBids.remove(0); if (hasProposedMyLastRound(bid)) { bid = proposedBids[myIndex].get( nrChosenActions % numOfBids[myIndex]); } } else { bid = proposedBids[myIndex] .get(nrChosenActions % numOfBids[myIndex]); } action = new Offer(getPartyId(), bid); } else if (nrChosenActions % 3 == 0) { if (candidateBids.isEmpty()) { generateCandidateFromMyFullBids( proposedBids[myIndex]); generateCandidateFromMyTopBids(acceptUtil, proposedBids[myIndex]); } if (!candidateBids.isEmpty()) { bid = candidateBids.remove(0); } else { bid = proposedBids[myIndex] .get(nrChosenActions % numOfBids[myIndex]); } action = new Offer(getPartyId(), bid); } else { bid = proposedBids[myIndex] .get(nrChosenActions % numOfBids[myIndex]); action = new Offer(getPartyId(), bid); } if (lastPeriodBidList.isEmpty()) { lastPeriodBidList = getMaxUtilBidsInList( sameBidsInOpps); } if (lastPeriodBidList.isEmpty()) { mergeBids(proposedBids[myNextPartyIndex].get(0), proposedBids[myLastPartyIndex].get(0), lower, lastPeriodBidList, lastPeriodBidList); } } else if (timeline.getTime() > time1) { if (candidateBids.isEmpty()) { if (nrChosenActions % 3 == 0) { if (!acceptAction[myNextPartyIndex]) { generateCandidateFromMyFullAndOppTopBids( acceptUtil, myNextPartyIndex, candidateBids); generateCandidateFromMyFullAndMyTopBids( acceptUtil, myNextPartyIndex, candidateBids); generateCandidateFromOppTopAndMyTopBids( myNextPartyIndex, acceptUtil, candidateBids); } if (!acceptAction[myLastPartyIndex]) { generateCandidateFromMyFullAndOppTopBids( acceptUtil, myLastPartyIndex, candidateBids); generateCandidateFromMyFullAndMyTopBids( acceptUtil, myLastPartyIndex, candidateBids); generateCandidateFromOppTopAndMyTopBids( myLastPartyIndex, acceptUtil, candidateBids); } } else if (nrChosenActions % 3 == 1) { generateCandidateFromOppTopBids(acceptUtil, candidateBids); generateCandidateFromMyTopBids(acceptUtil, candidateBids); } else { generateCandidateFromMyFullBids( proposedBids[myIndex]); generateCandidateFromMyTopBids(acceptUtil, proposedBids[myIndex]); } } if (!candidateBids.isEmpty()) { bid = candidateBids.remove(0); if (hasProposedMyLastRound(bid)) { bid = proposedBids[myIndex] .get(nrChosenActions % numOfBids[myIndex]); } } else { bid = proposedBids[myIndex] .get(nrChosenActions % numOfBids[myIndex]); } } else { if (candidateBids.isEmpty()) { generateCandidateFromMyFullBids(proposedBids[myIndex]); generateCandidateFromMyTopBids(acceptUtil, proposedBids[myIndex]); generateCandidateFromMyFullAndMyTopBids(acceptUtil, myNextPartyIndex, proposedBids[myIndex]); generateCandidateFromMyFullAndMyTopBids(acceptUtil, myLastPartyIndex, proposedBids[myIndex]); } if (!candidateBids.isEmpty()) { bid = candidateBids.remove(0); } else { Bid nBid = fullUtilBids .get(nrChosenActions % fullUtilBids.size()); if (proposedBids[myIndex].contains(nBid)) { bid = proposedBids[myIndex] .get(nrChosenActions % numOfBids[myIndex]); } else { bid = nBid; } } } if (bid == null) { lastConcessionPoint = getBidWithLessBoundedUtil( lastConcessionPoint, acceptUtil); bid = lastConcessionPoint; if (hasProposedMyLastRound(bid)) { bid = proposedBids[myIndex] .get(nrChosenActions % numOfBids[myIndex]); } } if (bid == null) { bid = myBid; } action = new Offer(getPartyId(), bid); } } else { bid = new Bid( fullUtilBids.get(nrChosenActions % fullUtilBids.size())); action = new Offer(getPartyId(), bid); } myBid = bid; numOfBids[myIndex]++; proposedBids[myIndex].add(bid); return action; } @SuppressWarnings("unchecked") @Override public void receiveMessage(AgentID sender, Action action) { super.receiveMessage(sender, action); if (sender == null) { numOfParties = getNumberOfParties(); myIndex = Integer.parseInt(getPartyId().toString().split("@")[1]) % numOfParties; myNextPartyIndex = (myIndex + 1) % numOfParties; myLastPartyIndex = (myIndex + numOfParties - 1) % numOfParties; proposedBids = new ArrayList[numOfParties]; numOfBids = new int[numOfParties]; valueFrequences = new HashMap[numOfParties]; issueChangeFrequences = new HashMap[numOfParties]; acceptAction = new boolean[numOfParties]; maxUtils = new double[numOfParties]; minUtils = new double[numOfParties]; proposedMaxBid = new LinkedList[numOfParties]; proposedMinBid = new LinkedList[numOfParties]; pModel = new PreferModel[numOfParties]; acceptableBidsWithOppValues = new ArrayList[numOfParties]; candidateBids = new ArrayList<>(); maxProductBids = new ArrayList[numOfParties]; topBidsInOppsSpace = new ArrayList[numOfParties]; topBidsInMySpace = new LinkedList[numOfParties]; for (int i = 0; i < numOfParties; i++) { proposedBids[i] = new ArrayList<>(); valueFrequences[i] = new HashMap<>(); issueChangeFrequences[i] = new HashMap<>(); proposedMaxBid[i] = new LinkedList<>(); proposedMinBid[i] = new LinkedList<>(); pModel[i] = new PreferModel(getUtilitySpace(), numOfIssues); acceptableBidsWithOppValues[i] = new ArrayList<>(); maxProductBids[i] = new ArrayList<>(); topBidsInOppsSpace[i] = new ArrayList<>(); topBidsInMySpace[i] = new LinkedList<>(); } } else { oppName = sender.toString().split("@")[0]; oppIndex = Integer.parseInt(sender.toString().split("@")[1]) % numOfParties; if (action instanceof Offer) { acceptAction[oppIndex] = false; lastReceivedBid = ((Offer) action).getBid(); } if (action instanceof Accept) { acceptAction[oppIndex] = true; lastReceivedBid = ((Accept) action).getBid(); } utility = getUtility(lastReceivedBid); proposedBids[oppIndex].add(lastReceivedBid); numOfBids[oppIndex]++; updateMaxOrMinBids(oppIndex); if (isDifferentBid(oppIndex)) { updateSameBidsInOpps(oppIndex, lastReceivedBid); updateTopBidsInOppsSpace(oppIndex); updateTopBidsInMySpace(oppIndex); } if (hasHistory) { if (!hasInitParamByHist) { hasHistWithRightPosition = false; for (String name : maxUtilsInHist[oppIndex].keySet()) { if (oppName.equals(name)) { hasHistWithRightPosition = true; } } if (hasHistWithRightPosition) { double[] arrs = new double[3]; for (int i = 0; i < getNumberOfParties(); i++) { if (i == myIndex) { continue; } for (String name : maxUtilsInHist[i].keySet()) { if (oppIndex == i) { arrs[i] = maxUtilsInHist[oppIndex] .get(oppName); } else { if (!name.equals(oppName)) { arrs[i] = maxUtilsInHist[i].get(name); } } } } double max = 0.0; double min = 1.0; for (int i = 0; i < 3; i++) { if (i == myIndex) { continue; } if (max < arrs[i]) { max = arrs[i]; } if (min > arrs[i]) { min = arrs[i]; } } if (maxAgreedBids.isEmpty()) { if (min - 0.1 > reservationValue) { lower = min - 0.1; } else { lower = reservationValue; } } else { double agreedUtil = getUtility( maxAgreedBids.get(0)); double[] utilArrs = { max, min, agreedUtil }; upper = getMaxInArray(utilArrs); for (int i = 0; i < utilArrs.length; i++) { if (utilArrs[i] == upper) { utilArrs[i] = 0.0; } } lower = getMinInArray(utilArrs) - 0.05; if (lower <= 0) { lower = reservationValue; } } exponent = initialExponent * (upper - lower); } else { double[] arrs = new double[3]; for (int i = 0; i < getNumberOfParties(); i++) { if (i == myIndex) { continue; } for (String name : maxUtilsInHist[i].keySet()) { arrs[i] = maxUtilsInHist[i].get(name); } } double max = 0.0; double min = 1.0; for (int i = 0; i < 3; i++) { if (i == myIndex) { continue; } if (max < arrs[i]) { max = arrs[i]; } if (min > arrs[i]) { min = arrs[i]; } } if (maxAgreedBids.isEmpty()) { if (min - 0.1 > reservationValue) { lower = min - 0.1; } else { lower = reservationValue; } } else { double agreedUtil = getUtility( maxAgreedBids.get(0)); double[] utilArrs = { max, min, agreedUtil, 0.9 }; upper = getMaxInArray(utilArrs); for (int i = 0; i < utilArrs.length; i++) { if (utilArrs[i] == upper) { utilArrs[i] = 0.0; } } lower = getMinInArray(utilArrs) - 0.1; if (lower <= 0) { lower = reservationValue; } } exponent = initialExponent * (upper - lower); } hasInitParamByHist = true; } if (hasInitParamByHist) { if (hasHistWithRightPosition) { } else { } } } else { if (isDifferentBid(oppIndex)) { pModel[oppIndex].updateEvaluators(lastReceivedBid); if (timeline.getTime() > 0.5 && timeline.getTime() < 0.9) { updateMaxUtilAddition(oppIndex, lastReceivedBid); } } updateConcessionParam(); } } } @Override public String getDescription() { return "ANAC2017"; } private double getAccept() { double accept = 0.9; accept = upper - (upper + 0.001 - lower) * Math.pow(timeline.getTime(), exponent); return accept; } private List getFullUtilBid(AbstractUtilitySpace utilitySpace) { Bid bid = null; List bidList = new ArrayList<>(); try { bid = utilitySpace.getMaxUtilityBid(); } catch (Exception e) { e.printStackTrace(); System.err.println(e.toString()); } if (!bidList.contains(bid)) { bidList.add(bid); } List issues = getUtilitySpace().getDomain().getIssues(); for (Issue item : issues) { Bid newBid = null; switch (item.getType()) { case DISCRETE: IssueDiscrete discrete = (IssueDiscrete) item; for (Value value : discrete.getValues()) { newBid = bid.putValue(discrete.getNumber(), value); if (getUtility(newBid) == 1.0 && !bidList.contains(newBid)) { bidList.add(newBid); } } break; case INTEGER: break; default: break; } } return bidList; } @SuppressWarnings("unused") private Bid getBidWithLessUtil(Bid bid) { Bid srcBid = null; Bid nBid = null; if (bid == null) { srcBid = fullUtilBids.get(0); } else { srcBid = new Bid(bid); } double oldU = getUtility(srcBid); List bidList = new ArrayList<>(); for (int i = 0; i < numOfIssues; i++) { Issue issue = srcBid.getIssues().get(i); switch (issue.getType()) { case DISCRETE: IssueDiscrete issueDiscrete = (IssueDiscrete) issue; for (Value value : issueDiscrete.getValues()) { nBid = srcBid.putValue(i + 1, value); if (oldU > getUtility(nBid)) { bidList.add(nBid); } } break; case INTEGER: IssueInteger issueInteger = (IssueInteger) issue; for (int j = issueInteger.getLowerBound(); j <= issueInteger .getUpperBound(); j++) { nBid = srcBid.putValue(i + 1, new ValueInteger(j)); if (oldU > getUtility(nBid)) { bidList.add(nBid); } } break; default: break; } } if (bidList.isEmpty()) { nBid = new Bid(srcBid); } else { double distance = oldU - 0.0; for (Bid item : bidList) { double distance2 = oldU - getUtility(item); if (distance2 < distance) { nBid = new Bid(item); distance = distance2; } } } return nBid; } private Bid getBidWithLessBoundedUtil(Bid bid, double min) { Bid srcBid = null; Bid nBid = null; if (bid == null) { srcBid = fullUtilBids.get(0); } else { srcBid = new Bid(bid); } double oldU = getUtility(srcBid); List bidList = new ArrayList<>(); for (int i = 0; i < numOfIssues; i++) { Issue issue = srcBid.getIssues().get(i); double newU = 0.0; switch (issue.getType()) { case DISCRETE: IssueDiscrete issueDiscrete = (IssueDiscrete) issue; for (Value value : issueDiscrete.getValues()) { nBid = srcBid.putValue(i + 1, value); newU = getUtility(nBid); if (oldU > newU && newU >= min) { bidList.add(nBid); } } break; case INTEGER: IssueInteger issueInteger = (IssueInteger) issue; for (int j = issueInteger.getLowerBound(); j <= issueInteger .getUpperBound(); j++) { nBid = srcBid.putValue(i + 1, new ValueInteger(j)); newU = getUtility(nBid); if (oldU > newU && newU >= min) { bidList.add(nBid); } } break; default: break; } } if (bidList.isEmpty()) { nBid = new Bid(srcBid); } else { double distance = oldU - 0.0; for (Bid item : bidList) { double distance2 = oldU - getUtility(item); if (distance2 < distance) { nBid = new Bid(item); distance = distance2; } } } return nBid; } private void updateProposedMaxBid(int partyId) { if (proposedMaxBid[partyId].isEmpty()) { if (utility > maxUtils[partyId]) { maxUtils[partyId] = utility; proposedMaxBid[partyId].add(lastReceivedBid); } } else { if (maxUtils[partyId] > utility) { return; } if (maxUtils[partyId] == utility && !proposedMaxBid[partyId].contains(lastReceivedBid)) { proposedMaxBid[partyId].add(lastReceivedBid); } if (maxUtils[partyId] < utility) { proposedMaxBid[partyId].clear(); proposedMaxBid[partyId].add(lastReceivedBid); maxUtils[partyId] = utility; } } } private void updateProposedMinBid(int partyId) { if (proposedMinBid[partyId].isEmpty()) { proposedMinBid[partyId].add(lastReceivedBid); if (0 >= minUtils[partyId]) { minUtils[partyId] = utility; } } else { if (minUtils[partyId] < utility) { return; } if (minUtils[partyId] == utility && !proposedMinBid[partyId].contains(lastReceivedBid)) { proposedMinBid[partyId].add(lastReceivedBid); } if (minUtils[partyId] > utility) { proposedMinBid[partyId].clear(); proposedMinBid[partyId].add(lastReceivedBid); minUtils[partyId] = utility; } } } private void updateMaxOrMinBids(int partyId) { updateProposedMaxBid(partyId); updateProposedMinBid(partyId); } private void updateTopBidsInOppsSpace(int partyId) { if (topBidsInOppsSpace[partyId].size() < 5 && !topBidsInOppsSpace[partyId].contains(lastReceivedBid)) { topBidsInOppsSpace[partyId].add(lastReceivedBid); } } private void updateTopBidsInMySpace(int partyId) { if (topBidsInMySpace[partyId].contains(lastReceivedBid)) { return; } else { topBidsInMySpace[partyId] = proposedMaxBid[partyId]; } } private void updateConcessionParam() { if (!hasHistory) { // ����Ϊ�����������С��utility double maxInMinUtil = 0.0; double minInMinUtil = 1.0; double minInMaxUtil = 1.0; double[] avgUtil = new double[numOfParties]; for (int i = 0; i < numOfParties; i++) { if (i == myIndex) { avgUtil[i] = 1.0; continue; } if (maxUtils[i] == 0.0 || minUtils[i] == 0.0) { continue; } double utilInMin2 = minUtils[i]; if (utilInMin2 > maxInMinUtil) { maxInMinUtil = utilInMin2; } if (utilInMin2 < minInMinUtil) { minInMinUtil = utilInMin2; } double utilInMax = maxUtils[i]; if (minInMaxUtil > utilInMax) { minInMaxUtil = utilInMax; } avgUtil[i] = (3 * maxUtils[i] + minUtils[i]) / 4; } double lowerbound = 0.0; double minAvg = getMinInArray(avgUtil); if (reservationValue > minAvg - 0.001) { lowerbound = reservationValue; } else { lowerbound = minAvg - 0.001; } lower = lowerbound; if (minInMaxUtil <= 0.0) { exponent = initialExponent; } else { exponent = initialExponent * minInMaxUtil; } } else { } } private double getMinInArray(double arr[]) { double min = arr[0]; for (int i = 0; i < arr.length; i++) { if (min > arr[i]) { min = arr[i]; } } return min; } private double getMaxInArray(double[] arr) { double max = 0.0; for (int i = 0; i < arr.length; i++) { if (max < arr[i]) { max = arr[i]; } } return max; } private double getMaxInArray(List list) { double max = 0.0; for (double item : list) { if (item > max) { max = item; } } return max; } private boolean isDifferentBid(int partyId) { if (proposedBids[partyId].size() < 2) { return true; } else { if (proposedBids[partyId].get(numOfBids[partyId] - 1).equals( proposedBids[partyId].get(numOfBids[partyId] - 2))) { return false; } else { return true; } } } private void alterBidValue(Bid srcBid, Map valueMap, int issueNr, double acceptableUtil, List bidList, List validationList) { Bid nBid = new Bid(srcBid); if (getUtility(nBid) >= acceptableUtil && !validationList.contains(nBid)) { bidList.add(nBid); } if (!valueMap.containsKey(issueNr)) { return; } for (int j = issueNr; j <= valueMap.size(); j++) { Value value = valueMap.get(j); if (value.equals(srcBid.getValue(j))) { continue; } nBid = srcBid.putValue(j, value); int item = j + 1; alterBidValue(nBid, valueMap, item, acceptableUtil, bidList, validationList); } } private void mergeBids(Bid fir, Bid sec, double acceptableUtil, List bidList, List validationList) { if (fir == null || sec == null) { return; } if (fir.equals(sec)) { if (!validationList.contains(fir)) { bidList.add(fir); } return; } alterBidValue(fir, sec.getValues(), 1, acceptableUtil, bidList, validationList); } private void generateCandidateFromMyFullBidsAndOppsTopBids(double minUtil, int oppIndex, List validationList) { if (proposedBids[oppIndex].isEmpty()) { return; } for (Bid item : fullUtilBids) { for (Bid item2 : topBidsInOppsSpace[oppIndex]) { if (item.equals(item2)) { continue; } mergeBids(item, item2, minUtil, candidateBids, validationList); } } } private List getMaxSocialWelfareBidsInList(List bidList) { List maxAdditionBids = new ArrayList<>(); List maxProductBids = new ArrayList<>(); List maxSocialWelfareBids = new ArrayList<>(); double maxAddition = 0.0; double maxProduct = 0.0; for (Bid bid : bidList) { double bidAddition = 0.0; double bidProduct = 1.0; bidAddition = getUtilAddition(bid); bidProduct = getUtilProduct(bid); if (bidAddition > maxAddition) { maxAdditionBids.clear(); maxAdditionBids.add(bid); maxAddition = bidAddition; } else if (bidAddition == maxAddition && !maxAdditionBids.contains(bid)) { maxAdditionBids.add(bid); } if (bidProduct > maxProduct) { maxProductBids.clear(); maxProductBids.add(bid); maxProduct = bidProduct; } else if (bidProduct == maxProduct && !maxProductBids.contains(bid)) { maxProductBids.add(bid); } } maxSocialWelfareBids.addAll(maxAdditionBids); maxSocialWelfareBids.addAll(maxProductBids); return maxSocialWelfareBids; } private double getUtilProduct(Bid bid) { double product = 1.0; for (int i = 0; i < numOfParties; i++) { if (i == myIndex) { product *= getUtility(bid); } product *= pModel[i].getUtil(bid); } return product; } private double getUtilAddition(Bid bid) { double addition = 0.0; for (int i = 0; i < numOfParties; i++) { if (i == myIndex) { addition += getUtility(bid); } addition += pModel[i].getUtil(bid); } return addition; } private List getMaxUtilBidsInList(List bidList) { List bids = new ArrayList<>(); double maxUtil = 0.0; for (Bid item : bidList) { double util = getUtility(item); if (util < maxUtil) { continue; } if (util > maxUtil) { bids.clear(); bids.add(item); maxUtil = util; } else { bids.add(item); } } return bids; } private void updateSameBidsInOpps(int proposedPartyId, Bid bid) { boolean bidHasProposedByAllOpps = true; for (int i = 0; i < numOfParties; i++) { if (i == myIndex || i == proposedPartyId) { continue; } if (!proposedBids[i].contains(bid)) { bidHasProposedByAllOpps = false; return; } else { bidHasProposedByAllOpps = true; } } if (bidHasProposedByAllOpps) { sameBidsInOpps.add(bid); } } private void updateMaxUtilAddition(int partyId, Bid bid) { double utilAddition = 0.0; for (int i = 0; i < numOfParties; i++) { if (partyId == myIndex) { utilAddition += getUtility(bid); } else { utilAddition += pModel[i].getUtil(bid); } } if (utilAddition < maxUtilAdditionByOpps) { return; } if (utilAddition > maxUtilAdditionByOpps) { maxUtilAdditionBidByOpps.clear(); maxUtilAdditionBidByOpps.add(bid); maxUtilAdditionByOpps = utilAddition; } else { maxUtilAdditionBidByOpps.add(bid); } } private void generateCandidateFromOppTopAndMyTopBids(int partyId, double minUtil, List validationList) { if (proposedBids[partyId].isEmpty()) { return; } for (Bid item : topBidsInOppsSpace[partyId]) { for (Bid maxBid : topBidsInMySpace[partyId]) { mergeBids(maxBid, item, minUtil, candidateBids, candidateBids); } } } private List getMaxBidsInAgreements() { double maxUtil = 0.0; List maxBids = new ArrayList<>(); for (Tuple item : agreements) { if (item.get2() < maxUtil) { continue; } if (item.get2() > maxUtil) { maxBids.clear(); maxBids.add(item.get1()); maxUtil = item.get2(); } else { if (!maxBids.contains(item.get1())) { maxBids.add(item.get1()); } } } return maxBids; } private boolean hasProposedMyLastRound(Bid bid) { if (numOfBids[myIndex] <= 0) { return false; } Bid lastRoundBid = proposedBids[myIndex].get(numOfBids[myIndex] - 1); return lastRoundBid.equals(bid); } private void generateCandidateFromMyFullBids(List validationList) { for (Bid item1 : fullUtilBids) { for (Bid item2 : fullUtilBids) { if (item1.equals(item2)) { if (validationList.contains(item1)) { continue; } else { candidateBids.add(item1); continue; } } else { mergeBids(item1, item2, 0.9, candidateBids, validationList); } } } } private void generateCandidateFromMyFullAndMyTopBids(double accept, int partyId, List validationList) { for (Bid item1 : fullUtilBids) { for (Bid item2 : topBidsInMySpace[partyId]) { mergeBids(item1, item2, accept, candidateBids, validationList); } } } private void generateCandidateFromMyFullAndOppTopBids(double accept, int partyId, List validationList) { for (Bid item1 : fullUtilBids) { for (Bid item2 : topBidsInOppsSpace[partyId]) { mergeBids(item1, item2, accept, candidateBids, validationList); } } } private void generateCandidateFromMyTopBids(double acceptableUtil, List validationList) { for (Bid fBid : topBidsInMySpace[myNextPartyIndex]) { for (Bid sBid : topBidsInMySpace[myLastPartyIndex]) { alterBidValue(fBid, sBid.getValues(), 1, acceptableUtil, candidateBids, validationList); } } } private void generateCandidateFromOppTopBids(double acceptableUtil, List validationList) { if (numOfBids[myLastPartyIndex] == 0 || numOfBids[myNextPartyIndex] == 0) { return; } for (Bid item1 : topBidsInOppsSpace[myNextPartyIndex]) { for (Bid item2 : topBidsInOppsSpace[myLastPartyIndex]) { if (item1.equals(item2)) { continue; } mergeBids(item1, item2, acceptableUtil, candidateBids, validationList); } } } public class PreferModel { private UtilitySpace utilitySpace; private Set> evaluators; private int numOfIssues; private double[] weights; private int[] indexOfMaxFreq; private int numOfValues; private int learnRate; public PreferModel(UtilitySpace utilitySpace, int num) { this.utilitySpace = utilitySpace; numOfIssues = num; weights = new double[num]; initWeights(); initEvaluators(); setNumOfValues(); learnRate = 1; } public Set> getEvaluators() { return evaluators; } private void setEvaluators( Set> evaluators) { this.evaluators = evaluators; } public double[] getWeights() { return weights; } public void setWeights(double weights[]) { this.weights = weights; } public int[] getIndexOfMaxFreq() { return indexOfMaxFreq; } public void setIndexOfMaxFreq(int[] indexOfMaxFreq) { this.indexOfMaxFreq = indexOfMaxFreq; } public int getNumOfValues() { return numOfValues; } public void setNumOfValues() { int num = 0; List issues = utilitySpace.getDomain().getIssues(); for (Issue issue : issues) { switch (issue.getType()) { case DISCRETE: IssueDiscrete discrete = (IssueDiscrete) issue; num += discrete.getNumberOfValues(); break; case INTEGER: IssueInteger integer = (IssueInteger) issue; int distance = integer.getUpperBound() - integer.getLowerBound(); num += (distance + 1); break; default: break; } } numOfValues = num; } private void initEvaluators() { try { Object[] issuesXML = ((SimpleElement) (utilitySpace.toXML() .getChildByTagName("objective")[0])) .getChildByTagName("issue").clone(); Map map = new LinkedHashMap<>(); for (int i = 0; i < numOfIssues; i++) { Issue issue = utilitySpace.getDomain().getIssues().get(i); switch (issue.getType()) { case DISCRETE: List values = ((IssueDiscrete) utilitySpace .getDomain().getIssues().get(i)).getValues(); EvaluatorDiscrete ed = new EvaluatorDiscrete(); ed.loadFromXML((SimpleElement) issuesXML[i]); ed.setWeight(weights[i]); for (ValueDiscrete item : values) { ed.addEvaluation(item, 1); } map.put(issue, ed); break; case INTEGER: EvaluatorInteger et = new EvaluatorInteger(); et.loadFromXML((SimpleElement) issuesXML[i]); et.setWeight(weights[i]); et.setLinearFunction(0.0, 1.0); map.put(issue, et); break; default: System.err.println( "Unsuported issue type " + issue.getType()); break; } setEvaluators((map.entrySet())); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void loadEvaluatorFromMyPrefer() { try { Object[] issuesXML = ((SimpleElement) (utilitySpace.toXML() .getChildByTagName("objective")[0])) .getChildByTagName("issue").clone(); Object[] weightXML = ((SimpleElement) (utilitySpace.toXML() .getChildByTagName("objective")[0])) .getChildByTagName("weight"); Map map = new LinkedHashMap<>(); for (int i = 0; i < numOfIssues; i++) { Issue issue = utilitySpace.getDomain().getIssues().get(i); switch (issue.getType()) { case DISCRETE: EvaluatorDiscrete ed = new EvaluatorDiscrete(); ed.loadFromXML((SimpleElement) issuesXML[i]); ed.setWeight(Double .parseDouble(((SimpleElement) weightXML[i]) .getAttribute("value"))); map.put(issue, ed); break; case INTEGER: EvaluatorInteger et = new EvaluatorInteger(); et.loadFromXML((SimpleElement) issuesXML[i]); et.setWeight(Double .parseDouble(((SimpleElement) weightXML[i]) .getAttribute("value"))); map.put(issue, et); break; default: System.err.println( "Unsuported issue type " + issue.getType()); break; } setEvaluators((map.entrySet())); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void updateEvaluators(Bid bid, int learnRate) { HashMap values = bid.getValues(); List issues = bid.getIssues(); int i = 0; for (Entry evaluator : evaluators) { evaluator.getValue().setWeight(weights[i]); try { Value value = values.get(i + 1); Issue issue = issues.get(i); for (int j = 0; j < numOfIssues; j++) { if (evaluator.getKey().toString() .equals(issues.get(j).toString())) { value = values.get(j + 1); issue = issues.get(j); break; } } switch (value.getType()) { case DISCRETE: ValueDiscrete valueDiscrete = (ValueDiscrete) values .get(i + 1); int old = ((EvaluatorDiscrete) evaluator.getValue()) .getEvaluationNotNormalized(valueDiscrete); ((EvaluatorDiscrete) evaluator.getValue()) .setEvaluation(value, old + learnRate); break; case INTEGER: EvaluatorInteger ei = ((EvaluatorInteger) evaluator .getValue()); if (ei.weightLocked()) { continue; } IssueInteger issueInteger = (IssueInteger) issue; ValueInteger valueInteger = (ValueInteger) value; int iValue = valueInteger.getValue(); int distanceToUpper = Math .abs(issueInteger.getUpperBound() - iValue); int distanceToLower = Math .abs(issueInteger.getLowerBound() - iValue); if (distanceToUpper < distanceToLower) { ei.setLinearFunction(0.0, 1.0); } else { ei.setLinearFunction(1.0, 0.0); } ei.lockWeight(); break; default: break; } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } i++; } } private void initWeights() { for (int i = 0; i < weights.length; i++) { weights[i] = 1D / numOfIssues; } } public void updateEvaluators(Bid bid) { boolean hasUpadated = false; HashMap values = bid.getValues(); List issues = bid.getIssues(); int i = 0; for (Entry evaluator : evaluators) { try { Value value = values.get(i + 1); Issue issue = issues.get(i); for (int j = 0; j < numOfIssues; j++) { if (evaluator.getKey().toString() .equals(issues.get(j).toString())) { value = values.get(j + 1); issue = issues.get(j); break; } } switch (value.getType()) { case DISCRETE: ValueDiscrete valueDiscrete = (ValueDiscrete) values .get(i + 1); int old = ((EvaluatorDiscrete) evaluator.getValue()) .getEvaluationNotNormalized(valueDiscrete); ((EvaluatorDiscrete) evaluator.getValue()) .setEvaluation(value, old + 1); hasUpadated = true; break; case INTEGER: EvaluatorInteger ei = ((EvaluatorInteger) evaluator .getValue()); if (ei.weightLocked()) { continue; } IssueInteger issueInteger = (IssueInteger) issue; ValueInteger valueInteger = (ValueInteger) value; int iValue = valueInteger.getValue(); int distanceToUpper = Math .abs(issueInteger.getUpperBound() - iValue); int distanceToLower = Math .abs(issueInteger.getLowerBound() - iValue); if (distanceToUpper < distanceToLower) { ei.setLinearFunction(0.0, 1.0); } else { ei.setLinearFunction(1.0, 0.0); } hasUpadated = true; ei.lockWeight(); break; default: break; } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } i++; } if (hasUpadated) { learnRate--; } } public double getUtil(Bid bid) { double util = 0D; Map values = bid.getValues(); int issueNr = 1; for (Entry evaluator : evaluators) { try { Value value = values.get(issueNr); double weight = evaluator.getValue().getWeight(); double valueEvaluation = 0.0; switch (value.getType()) { case DISCRETE: EvaluatorDiscrete dEvaluator = (EvaluatorDiscrete) evaluator .getValue(); valueEvaluation = dEvaluator .getEvaluation((ValueDiscrete) value); util += weight * valueEvaluation; break; case INTEGER: EvaluatorInteger iEvaluator = (EvaluatorInteger) evaluator .getValue(); valueEvaluation = iEvaluator.getEvaluation( Integer.parseInt(value.toString())); util += weight * valueEvaluation; break; default: break; } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } issueNr++; } return util; } public double getValueEvaluation(int issueNr, Value value) { double evaluation = 0.0; int i = 1; for (Entry evaluator : evaluators) { if (i != issueNr) { i++; continue; } else { switch (value.getType()) { case DISCRETE: ValueDiscrete dValue = (ValueDiscrete) value; EvaluatorDiscrete dEvaluator = (EvaluatorDiscrete) evaluator .getValue(); try { evaluation = dEvaluator.getWeight() * dEvaluator.getEvaluation(dValue); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } break; case INTEGER: ValueInteger vInteger = (ValueInteger) value; EvaluatorInteger iEvaluator = (EvaluatorInteger) evaluator .getValue(); evaluation = iEvaluator.getWeight() * iEvaluator.getEvaluation(vInteger.getValue()); break; default: System.err.println( "Unsupported value type: " + value.getType()); break; } i++; } } return evaluation; } } }