package geniusweb.protocol.session.mopac; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import geniusweb.deadline.Deadline; import geniusweb.protocol.session.SessionSettings; import geniusweb.protocol.session.TeamInfo; import geniusweb.references.PartyWithProfile; import geniusweb.voting.VotingEvaluator; import tudelft.utilities.logging.Reporter; /** * Settings for MOPAC negotiation. in MOPAC, each party may get a "power" * parameter containing an natural number ≤1. */ public class MOPACSettings implements SessionSettings { private final List participants; private final Deadline deadline; private final VotingEvaluator votingevaluator; /** * * @param participants the list of {@link PartyWithProfile} in clockwise * order. There must be at least 2 to run the MOPAC * protocol. This is not tested in the constructor * because this can be initialized with less, for use in * TournamentSettings. * @param deadline the {@link Deadline} for the negotiation * @param votingeval the {@link VotingEvaluator} to use. */ @JsonCreator public MOPACSettings( @JsonProperty("participants") List participants, @JsonProperty("deadline") Deadline deadline, @JsonProperty("votingevaluator") VotingEvaluator votingeval) { this.participants = participants; this.deadline = deadline; if (participants == null || deadline == null || votingeval == null) throw new IllegalArgumentException( "participants, deadline and votingeval must be not null"); this.votingevaluator = votingeval; checkTeams(); } @Override public Double getMaxRunTime() { return deadline.getDuration() / 1000d; } @Override public MOPAC getProtocol(Reporter logger) { return new MOPAC(new MOPACState(this), logger); } @Override public List getTeams() { return Collections.unmodifiableList(participants); } /** * @return the deadline for this negotiation */ public Deadline getDeadline() { return deadline; } @Override public List getAllParties() { return participants.stream() .map(particip -> particip.getParties().get(0)) .collect(Collectors.toList()); } /** * @return a class that allows us to evaluate the voting results in * different ways, selectable by the user. */ public VotingEvaluator getVotingEvaluator() { return votingevaluator; } @Override public MOPACSettings with(TeamInfo team) { if (team.getSize() != 1) throw new IllegalArgumentException( "Added party must have one party but got " + team); List newparts = new LinkedList<>(participants); newparts.add(team); return new MOPACSettings(newparts, deadline, votingevaluator); } @Override public String toString() { return "MOPACSettings[" + participants + "," + deadline + "," + votingevaluator.getClass().getSimpleName() + "]"; } @Override public Integer getTeamSize() { return 1; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((deadline == null) ? 0 : deadline.hashCode()); result = prime * result + ((participants == null) ? 0 : participants.hashCode()); result = prime * result + ((votingevaluator == null) ? 0 : votingevaluator.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; MOPACSettings other = (MOPACSettings) obj; if (deadline == null) { if (other.deadline != null) return false; } else if (!deadline.equals(other.deadline)) return false; if (participants == null) { if (other.participants != null) return false; } else if (!participants.equals(other.participants)) return false; if (votingevaluator == null) { if (other.votingevaluator != null) return false; } else if (!votingevaluator.equals(other.votingevaluator)) return false; return true; } /** * @throws IllegalArgumentException if teams have improper power settings. */ private void checkTeams() { for (TeamInfo team : participants) { if (team.getSize() != 1) throw new IllegalArgumentException( "All teams must be size 1 but found " + team); PartyWithProfile party = team.getParties().get(0); Object power = party.getParty().getParameters().get("power"); if (power != null) { if (!(power instanceof Integer)) throw new IllegalArgumentException( "parameter 'power' for party" + party + " must be integer but found " + power); if ((Integer) power < 1) throw new IllegalArgumentException( "parameter 'power' for party" + party + " must be >=1 but found " + power); } } } }