import java.io.IOException; import java.math.BigInteger; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Random; import java.util.Set; import java.util.logging.Level; import geniusweb.actions.Accept; import geniusweb.actions.Action; import geniusweb.actions.Offer; import geniusweb.actions.PartyId; import geniusweb.bidspace.AllBidsList; import geniusweb.inform.ActionDone; import geniusweb.inform.Finished; import geniusweb.inform.Inform; import geniusweb.inform.Settings; import geniusweb.inform.YourTurn; import geniusweb.issuevalue.Bid; import geniusweb.issuevalue.Value; import geniusweb.issuevalue.ValueSet; import geniusweb.party.Capabilities; import geniusweb.party.DefaultParty; import geniusweb.profile.DefaultPartialOrdering; import geniusweb.profile.Profile; import geniusweb.profileconnection.ProfileConnectionFactory; import geniusweb.profileconnection.ProfileInterface; import geniusweb.progress.Progress; import geniusweb.progress.ProgressRounds; import tudelft.utilities.logging.Reporter; public class HammingAgent extends DefaultParty { private Bid lastReceivedBid = null; private Set issues; private int n_issues; private final Map maxBid = new HashMap<>(); private final Map minBid = new HashMap<>(); private List SortedBid = null; private final Map values = new HashMap<>(); private PartyId me; private final Random random = new Random(); protected ProfileInterface profileint; private Progress progress; public HammingAgent() { } public HammingAgent(Reporter reporter) { super(reporter); } @Override public void notifyChange(Inform info) { try { if (info instanceof Settings) { Settings settings = (Settings) info; this.profileint = ProfileConnectionFactory.create(settings.getProfile().getURI(), getReporter()); this.me = settings.getID(); this.progress = settings.getProgress(); if (this.profileint.getProfile() instanceof DefaultPartialOrdering) { // Partial時だけ呼び出す this.initProfile((DefaultPartialOrdering) this.profileint.getProfile()); } } else if (info instanceof ActionDone) { Action otheract = ((ActionDone) info).getAction(); if (otheract instanceof Offer && otheract.getActor() != me) { lastReceivedBid = ((Offer) otheract).getBid(); } } else if (info instanceof YourTurn) { myTurn(); } else if (info instanceof Finished) { getReporter().log(Level.INFO, "Final outcome:" + info); } } catch (Exception e) { throw new RuntimeException("Failed to handle info", e); } } @Override public Capabilities getCapabilities() { return new Capabilities(new HashSet<>(Arrays.asList("SHAOP")), Collections.singleton(Profile.class)); } @Override public String getDescription() { return "Without elicitation agent"; } private void initProfile(DefaultPartialOrdering profile) { SortedBid = getSortedBids(profile); Bid maxBid = SortedBid.get(0); Bid minBid = SortedBid.get(SortedBid.size() - 1); issues = profile.getDomain().getIssues(); n_issues = issues.size(); for (String i : issues) { this.maxBid.put(i, maxBid.getValue(i)); this.minBid.put(i, minBid.getValue(i)); this.values.put(i, profile.getDomain().getValues(i)); } } private static List getSortedBids(DefaultPartialOrdering prof) { List bidslist = prof.getBids(); // 効用値降順にソート bidslist.sort((b1, b2) -> prof.isPreferredOrEqual(b1, b2) ? -1 : 1); return bidslist; } private void myTurn() throws IOException { Action action = SortedBid == null ? randomBid() : (isAcceptable() ? new Accept(me, lastReceivedBid) : makeBid()); if (progress instanceof ProgressRounds) { progress = ((ProgressRounds) progress).advance(); } getConnection().send(action); } private boolean isAcceptable() { if (lastReceivedBid == null) return false; if (progress instanceof ProgressRounds) { ProgressRounds rounds = (ProgressRounds) progress; if (rounds.getCurrentRound() + 1 == rounds.getTotalRounds()) { return true; } } int max_count = 0; int min_count = 0; for (String i : issues) { Value value = lastReceivedBid.getValue(i); if (value.equals(maxBid.get(i))) { max_count++; } else if (value.equals(minBid.get(i))) { min_count++; if (min_count >= threshold()) { max_count--; min_count = 0; } } } return max_count > n_issues - threshold(); } private int threshold() { int n; Double time = progress.get(System.currentTimeMillis()); if (time <= 0.3) { n = 1; } else if (time <= 0.5) { n = Math.min(2, (int) Math.ceil((double) n_issues / 3)); } else if (time <= 0.7) { n = Math.min(3, (int) Math.ceil((double) n_issues / 3)); } else if (time <= 0.9) { n = Math.min(4, (int) Math.ceil((double) n_issues / 3)); } else { n = Math.min(4, (int) Math.ceil((double) n_issues / 2)); } return n; } private Offer makeBid() { int count = 0; Set integerSet = new HashSet<>(); for (int i = 0; i < threshold(); i++) { integerSet.add(random.nextInt(n_issues)); } Map bid = new HashMap<>(); for (String i : issues) { if (integerSet.contains(count)) { ValueSet issueValues = values.get(i); Value minValue = minBid.get(i); int nextValueNum; Value nextValue; do { nextValueNum = random.nextInt(issueValues.size().intValue()); nextValue = issueValues.get(nextValueNum); } while (nextValue.equals(minValue)); bid.put(i, nextValue); } else { bid.put(i, maxBid.get(i)); } count++; } return new Offer(me, new Bid(bid)); } private Offer randomBid() throws IOException { AllBidsList bidspace = new AllBidsList(profileint.getProfile().getDomain()); long i = random.nextInt(bidspace.size().intValue()); Bid bid = bidspace.get(BigInteger.valueOf(i)); return new Offer(me, bid); } }