source: protocol/src/main/java/geniusweb/protocol/tournament/allpermutations/AllPermutationsSettings.java@ 52

Last change on this file since 52 was 52, checked in by ruud, 14 months ago

Fixed small issues in domaineditor.

File size: 11.7 KB
Line 
1package geniusweb.protocol.tournament.allpermutations;
2
3import java.math.BigInteger;
4import java.util.Collections;
5import java.util.LinkedList;
6import java.util.List;
7import java.util.function.BiFunction;
8
9import com.fasterxml.jackson.annotation.JsonCreator;
10import com.fasterxml.jackson.annotation.JsonProperty;
11
12import geniusweb.protocol.session.SessionSettings;
13import geniusweb.protocol.session.TeamInfo;
14import geniusweb.protocol.session.saop.SAOPSettings;
15import geniusweb.protocol.session.shaop.SHAOPSettings;
16import geniusweb.protocol.tournament.ProfileList;
17import geniusweb.protocol.tournament.Team;
18import geniusweb.protocol.tournament.TournamentProtocol;
19import geniusweb.protocol.tournament.TournamentSettings;
20import geniusweb.references.PartyWithParameters;
21import geniusweb.references.PartyWithProfile;
22import geniusweb.references.ProfileRef;
23import tudelft.utilities.immutablelist.FixedList;
24import tudelft.utilities.immutablelist.ImmutableList;
25import tudelft.utilities.immutablelist.MapList;
26import tudelft.utilities.immutablelist.MapThreadList;
27import tudelft.utilities.immutablelist.Permutations;
28import tudelft.utilities.immutablelist.PermutationsOrderedWithoutReturn;
29import tudelft.utilities.immutablelist.PermutationsWithReturn;
30import tudelft.utilities.immutablelist.PermutationsWithoutReturn;
31import tudelft.utilities.immutablelist.Repeat;
32import tudelft.utilities.immutablelist.Tuple;
33import tudelft.utilities.immutablelist.Tuples;
34import tudelft.utilities.logging.Reporter;
35
36/**
37 * Takes a number of parties and profiles and makes all permutations of them
38 * with the given number of parties and profiles. All profiles must be in the
39 * same domain.
40 * <p>
41 * All sessions are based on the given {@link SessionSettings} (can be
42 * {@link SAOPSettings} or {@link SHAOPSettings}). The parties for each
43 * tournament session are added to this basic sessionsettings. sessionsettings
44 * contains basically all the normal run-sessionsettings. This is used as a
45 * "template" for all sessions of the tournament. You can put any use any
46 * session setting here, and each session will be run according to the protocol
47 * you select here.
48 *
49 * The participants list usually is empty. The AllPermutationsProtocol adds the
50 * the required parties to this list. So if you provide a non-empty list here,
51 * then these parties would be present in every session in the tournament.
52 * <p>
53 * If the tournament is used with a SHAOP sessionsettings, the first member of
54 * each team is assumed to be the SHAOP party, the second the COB party. To
55 * match this, the first element of the ProfileList will have to be a partial
56 * profile to fit the needs of the SHAOP party. The second profile will have to
57 * be a normal profile, to fit the needs of the COB party. Note that you can
58 * generate a partial profile using the <code>partial=N</code> option of the
59 * profiles server.
60 */
61public class AllPermutationsSettings implements TournamentSettings {
62
63 protected final List<Team> teams;
64 protected final List<ProfileList> profileslists;
65 protected final boolean reuseTeams;
66 protected final int teamsPerSession;
67 protected final SessionSettings sessionsettings;
68 protected final int numberTournaments;
69 private final transient ImmutableList<SessionSettings> perms; // cache
70
71 /**
72 *
73 * @param teams a list of {@link Team}s. Must contain at least
74 * {@link #teamsPerSession} elements. The
75 * {@link #teamsPerSession} must match the protocol:
76 * (SAOP:1, SHAOP:2)
77 * @param reuseTeams if true, we use PermutationsWithReturn, if false
78 * we use PermutationsWithoutReturn to create the
79 * teams.
80 * @param plists list of available {@link ProfileList}s to be
81 * permutated over the teams. Each
82 * {@link ProfileList} must contain
83 * {@link #teamsPerSession} elements.
84 * @param teamsPerSession number of parties per session, must be at least 2.
85 * @param sesettings The generic {@link SessionSettings}.
86 * {@link SessionSettings#with(TeamInfo)} will be
87 * used to add the required {@link TeamInfo}s
88 * @param nTournaments the number of times the tournament should be run.
89 */
90 @JsonCreator
91 public AllPermutationsSettings(@JsonProperty("teams") List<Team> teams,
92 @JsonProperty("profileslists") List<ProfileList> plists,
93 @JsonProperty("reuseTeams") boolean reuseTeams,
94 @JsonProperty("teamsPerSession") int teamsPerSession,
95 @JsonProperty("sessionsettings") SessionSettings sesettings,
96 @JsonProperty("numberTournaments") int nTournaments) {
97 if (teamsPerSession < 2)
98 throw new IllegalArgumentException("teamsPerSession must be >=2");
99 if (teams == null || teams.size() < teamsPerSession)
100 throw new IllegalArgumentException("teams must contain at least "
101 + teamsPerSession + " teams");
102 if (plists == null || plists.size() < 2)
103 throw new IllegalArgumentException(
104 "profileslist must contain at least " + teamsPerSession
105 + " ProfileList's");
106 if (nTournaments <= 0)
107 throw new IllegalArgumentException("nTournaments must be >0");
108 int teamsize = sesettings.getTeamSize();
109
110 for (Team team : teams) {
111 if (team.getParties().size() != teamsize) {
112 throw new IllegalArgumentException("All teams should have size "
113 + teamsize + " but found " + team.getParties().size());
114 }
115 }
116 for (ProfileList profile : plists) {
117 if (profile.getProfiles().size() != teamsize) {
118 throw new IllegalArgumentException(
119 "All profiles should have size equal to the team size "
120 + teamsize + " but found "
121 + profile.getProfiles().size());
122 }
123 }
124 this.teamsPerSession = teamsPerSession;
125 this.reuseTeams = reuseTeams;
126 this.teams = teams;
127 this.profileslists = plists;
128 this.sessionsettings = sesettings;
129 this.numberTournaments = nTournaments;
130
131 this.perms = permutations1();
132 }
133
134 @Override
135 public Double getMaxRunTime() {
136 return permutations().size().doubleValue()
137 * (sessionsettings.getMaxRunTime() + 2d);
138 }
139
140 /**
141 *
142 * @return number of times the entire tournament is repeated, &gt;0
143 */
144 public int getNrTournaments() {
145 return this.numberTournaments;
146 }
147
148 @Override
149 public TournamentProtocol getProtocol(Reporter logger) {
150 AllPermutationsState state = new AllPermutationsState(this,
151 Collections.emptyList());
152 return new AllPermutationsProtocol(state, logger);
153 }
154
155 /**
156 * @return All {@link SessionSettings} for the tournament, in the correct
157 * order.
158 */
159 public ImmutableList<SessionSettings> permutations() {
160 return perms;
161 }
162
163 /**
164 * @return list of all {@link SessionSettings} for this tournament
165 */
166 private ImmutableList<SessionSettings> permutations1() {
167 ImmutableList<ImmutableList<TeamInfo>> partylistlist;
168 ImmutableList<Team> partieslist = new FixedList<Team>(teams);
169 ImmutableList<ProfileList> profileslist = new FixedList<ProfileList>(
170 profileslists);
171 partylistlist = getParticipantsOneTournament(partieslist, profileslist,
172 teamsPerSession, reuseTeams);
173 partylistlist = new Repeat<ImmutableList<TeamInfo>>(partylistlist,
174 BigInteger.valueOf(numberTournaments), true);
175
176 return new MapList<>(partyproflist -> createSetting(partyproflist),
177 partylistlist);
178 }
179
180 @Override
181 public String toString() {
182 return "AllPermutationsSettings[" + contentString() + "]";
183 }
184
185 protected String contentString() {
186 return teams + "," + reuseTeams + "," + profileslists + ","
187 + teamsPerSession + "," + sessionsettings + ","
188 + numberTournaments;
189 }
190
191 @Override
192 public int hashCode() {
193 final int prime = 31;
194 int result = 1;
195 result = prime * result + numberTournaments;
196 result = prime * result
197 + ((profileslists == null) ? 0 : profileslists.hashCode());
198 result = prime * result + (reuseTeams ? 1231 : 1237);
199 result = prime * result
200 + ((sessionsettings == null) ? 0 : sessionsettings.hashCode());
201 result = prime * result + ((teams == null) ? 0 : teams.hashCode());
202 result = prime * result + teamsPerSession;
203 return result;
204 }
205
206 @Override
207 public boolean equals(Object obj) {
208 if (this == obj)
209 return true;
210 if (obj == null)
211 return false;
212 if (getClass() != obj.getClass())
213 return false;
214 AllPermutationsSettings other = (AllPermutationsSettings) obj;
215 if (numberTournaments != other.numberTournaments)
216 return false;
217 if (profileslists == null) {
218 if (other.profileslists != null)
219 return false;
220 } else if (!profileslists.equals(other.profileslists))
221 return false;
222 if (reuseTeams != other.reuseTeams)
223 return false;
224 if (sessionsettings == null) {
225 if (other.sessionsettings != null)
226 return false;
227 } else if (!sessionsettings.equals(other.sessionsettings))
228 return false;
229 if (teams == null) {
230 if (other.teams != null)
231 return false;
232 } else if (!teams.equals(other.teams))
233 return false;
234 if (teamsPerSession != other.teamsPerSession)
235 return false;
236 return true;
237 }
238
239 /**
240 *
241 * @param partyproflist a list of {@link PartyWithProfile} settings
242 * @return {@link SessionSettings}
243 */
244 protected SessionSettings createSetting(
245 ImmutableList<TeamInfo> partyproflist) {
246 SessionSettings settings = sessionsettings;
247 for (TeamInfo partyprof : partyproflist) {
248 settings = settings.with(partyprof);
249 }
250 return settings;
251 }
252
253 /**
254 *
255 * @param parties the parties in the tournament
256 * @param profiles the profiles in the tournament
257 * @param n number of items to draw. Assumed &ge;1.
258 * @param drawPartyWithPutback if parties can be drawn multiple times
259 * @return list of sessionsets where each sessionset contains settings for a
260 * session: a list with {@link TeamInfo}s. The sessionsets are made
261 * by making all combinations of parties and profiles. Profiles are
262 * drawn with replace.
263 */
264 protected ImmutableList<ImmutableList<TeamInfo>> getParticipantsOneTournament(
265 ImmutableList<Team> parties, ImmutableList<ProfileList> profiles,
266 int n, boolean drawPartyWithPutback) {
267
268 Permutations<Team> partiesPermutations;
269 if (drawPartyWithPutback) {
270 partiesPermutations = new PermutationsWithReturn<>(parties, n);
271 } else {
272 partiesPermutations = new PermutationsWithoutReturn<>(parties, n);
273 }
274
275 Permutations<ProfileList> profilesPermutations = new PermutationsOrderedWithoutReturn<>(
276 profiles, n);
277
278 // each tuple contains session info: a list of Team and a list of
279 // ProfileList.
280 Tuples<ImmutableList<Team>, ImmutableList<ProfileList>> tuples = new Tuples<>(
281 partiesPermutations, profilesPermutations);
282
283 return new MapList<Tuple<ImmutableList<Team>, ImmutableList<ProfileList>>, ImmutableList<TeamInfo>>(
284 tuple -> teamlist(tuple), tuples);
285 }
286
287 /**
288 *
289 * @param tuple a tuple with (1) ImmutableList<Team> (2)
290 * ImmutableList<Profiles>
291 * @return list of TeamOfPartiesAndProfiles, each picked from the two lists
292 * in order.
293 */
294 private ImmutableList<TeamInfo> teamlist(
295 Tuple<ImmutableList<Team>, ImmutableList<ProfileList>> tuple) {
296 BiFunction<Team, ProfileList, TeamInfo> makeparty = new BiFunction<Team, ProfileList, TeamInfo>() {
297 @Override
298 public TeamInfo apply(Team team, ProfileList profilelist) {
299 List<PartyWithParameters> parties = team.getParties();
300 List<ProfileRef> profiles = profilelist.getProfiles();
301 if (parties.size() != profiles.size())
302 throw new IllegalArgumentException(
303 "Parties and profiles list must match, but found "
304 + team + " and " + profilelist);
305
306 List<PartyWithProfile> theteams = new LinkedList<>();
307 for (int n = 0; n < parties.size(); n++) {
308 theteams.add(new PartyWithProfile(parties.get(n),
309 profiles.get(n)));
310 }
311 return new TeamInfo(theteams);
312 }
313
314 };
315 return new MapThreadList<TeamInfo, Team, ProfileList>(makeparty,
316 tuple.get1(), tuple.get2());
317 }
318
319}
Note: See TracBrowser for help on using the repository browser.