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

Last change on this file since 31 was 31, checked in by bart, 3 years ago

New protocols Learn and APPLearn. Fixed memory leak.

File size: 11.5 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
70 /**
71 *
72 * @param teams a list of {@link Team}s. Must contain at least
73 * {@link #teamsPerSession} elements. The
74 * {@link #teamsPerSession} must match the protocol:
75 * (SAOP:1, SHAOP:2)
76 * @param reuseTeams if true, we use PermutationsWithReturn, if false
77 * we use PermutationsWithoutReturn to create the
78 * teams.
79 * @param plists list of available {@link ProfileList}s to be
80 * permutated over the teams. Each
81 * {@link ProfileList} must contain
82 * {@link #teamsPerSession} elements.
83 * @param teamsPerSession number of parties per session, must be at least 2.
84 * @param sesettings The generic {@link SessionSettings}.
85 * {@link SessionSettings#with(TeamInfo)} will be
86 * used to add the required {@link TeamInfo}s
87 * @param nTournaments the number of times the tournament should be run.
88 */
89 @JsonCreator
90 public AllPermutationsSettings(@JsonProperty("teams") List<Team> teams,
91 @JsonProperty("profileslists") List<ProfileList> plists,
92 @JsonProperty("reuseTeams") boolean reuseTeams,
93 @JsonProperty("teamsPerSession") int teamsPerSession,
94 @JsonProperty("sessionsettings") SessionSettings sesettings,
95 @JsonProperty("numberTournaments") int nTournaments) {
96 if (teamsPerSession < 2)
97 throw new IllegalArgumentException("teamsPerSession must be >=2");
98 if (teams == null || teams.size() < teamsPerSession)
99 throw new IllegalArgumentException("teams must contain at least "
100 + teamsPerSession + " teams");
101 if (plists == null || plists.size() < 2)
102 throw new IllegalArgumentException(
103 "profileslist must contain at least " + teamsPerSession
104 + " ProfileList's");
105 if (nTournaments <= 0)
106 throw new IllegalArgumentException("nTournaments must be >0");
107 int teamsize = sesettings.getTeamSize();
108
109 for (Team team : teams) {
110 if (team.getParties().size() != teamsize) {
111 throw new IllegalArgumentException("All teams should have size "
112 + teamsize + " but found " + team.getParties().size());
113 }
114 }
115 for (ProfileList profile : plists) {
116 if (profile.getProfiles().size() != teamsize) {
117 throw new IllegalArgumentException(
118 "All profiles should have size equal to the team size "
119 + teamsize + " but found "
120 + profile.getProfiles().size());
121 }
122 }
123 this.teamsPerSession = teamsPerSession;
124 this.reuseTeams = reuseTeams;
125 this.teams = teams;
126 this.profileslists = plists;
127 this.sessionsettings = sesettings;
128 this.numberTournaments = nTournaments;
129 }
130
131 @Override
132 public Double getMaxRunTime() {
133 return permutations().size().doubleValue()
134 * (sessionsettings.getMaxRunTime() + 2d);
135 }
136
137 @Override
138 public TournamentProtocol getProtocol(Reporter logger) {
139 AllPermutationsState state = new AllPermutationsState(this,
140 permutations(), Collections.emptyList());
141 return new AllPermutationsProtocol(state, logger);
142 }
143
144 /**
145 * @return {@link ImmutableList} containing all {@link SessionSettings} for
146 * all Sessions in the correct order.
147 */
148 public ImmutableList<SessionSettings> permutations() {
149 ImmutableList<ImmutableList<TeamInfo>> partylistlist;
150 ImmutableList<Team> partieslist = new FixedList<Team>(teams);
151 ImmutableList<ProfileList> profileslist = new FixedList<ProfileList>(
152 profileslists);
153 partylistlist = getParticipants(partieslist, profileslist,
154 teamsPerSession, reuseTeams);
155 return new MapList<>(partyproflist -> createSetting(partyproflist),
156 partylistlist);
157 }
158
159 @Override
160 public String toString() {
161 return "AllPermutationsSettings[" + contentString() + "]";
162 }
163
164 protected String contentString() {
165 return teams + "," + reuseTeams + "," + profileslists + ","
166 + teamsPerSession + "," + sessionsettings + ","
167 + numberTournaments;
168 }
169
170 @Override
171 public int hashCode() {
172 final int prime = 31;
173 int result = 1;
174 result = prime * result + numberTournaments;
175 result = prime * result
176 + ((profileslists == null) ? 0 : profileslists.hashCode());
177 result = prime * result + (reuseTeams ? 1231 : 1237);
178 result = prime * result
179 + ((sessionsettings == null) ? 0 : sessionsettings.hashCode());
180 result = prime * result + ((teams == null) ? 0 : teams.hashCode());
181 result = prime * result + teamsPerSession;
182 return result;
183 }
184
185 @Override
186 public boolean equals(Object obj) {
187 if (this == obj)
188 return true;
189 if (obj == null)
190 return false;
191 if (getClass() != obj.getClass())
192 return false;
193 AllPermutationsSettings other = (AllPermutationsSettings) obj;
194 if (numberTournaments != other.numberTournaments)
195 return false;
196 if (profileslists == null) {
197 if (other.profileslists != null)
198 return false;
199 } else if (!profileslists.equals(other.profileslists))
200 return false;
201 if (reuseTeams != other.reuseTeams)
202 return false;
203 if (sessionsettings == null) {
204 if (other.sessionsettings != null)
205 return false;
206 } else if (!sessionsettings.equals(other.sessionsettings))
207 return false;
208 if (teams == null) {
209 if (other.teams != null)
210 return false;
211 } else if (!teams.equals(other.teams))
212 return false;
213 if (teamsPerSession != other.teamsPerSession)
214 return false;
215 return true;
216 }
217
218 /**
219 *
220 * @param partyproflist a list of {@link PartyWithProfile} settings
221 * @return {@link SessionSettings}
222 */
223 protected SessionSettings createSetting(
224 ImmutableList<TeamInfo> partyproflist) {
225 SessionSettings settings = sessionsettings;
226 for (TeamInfo partyprof : partyproflist) {
227 settings = settings.with(partyprof);
228 }
229 return settings;
230 }
231
232 /**
233 *
234 * @param parties the parties in the tournament
235 * @param profiles the profiles in the tournament
236 * @param n number of items to draw. Assumed &ge;1.
237 * @param drawPartyWithPutback if parties can be drawn multiple times
238 * @return list of sessionsets where each sessionset contains settings for a
239 * session: a list with {@link TeamInfo}s. The sessionsets are made
240 * by making all combinations of parties and profiles. Profiles are
241 * drawn with replace.
242 */
243 protected ImmutableList<ImmutableList<TeamInfo>> getParticipants(
244 ImmutableList<Team> parties, ImmutableList<ProfileList> profiles,
245 int n, boolean drawPartyWithPutback) {
246
247 Permutations<Team> partiesPermutations;
248 if (drawPartyWithPutback) {
249 partiesPermutations = new PermutationsWithReturn<>(parties, n);
250 } else {
251 partiesPermutations = new PermutationsWithoutReturn<>(parties, n);
252 }
253
254 Permutations<ProfileList> profilesPermutations = new PermutationsOrderedWithoutReturn<>(
255 profiles, n);
256
257 // each tuple contains session info: a list of Team and a list of
258 // ProfileList.
259 Tuples<ImmutableList<Team>, ImmutableList<ProfileList>> tuples = new Tuples<>(
260 partiesPermutations, profilesPermutations);
261
262 MapList<Tuple<ImmutableList<Team>, ImmutableList<ProfileList>>, ImmutableList<TeamInfo>> tournamentsettings = new MapList<Tuple<ImmutableList<Team>, ImmutableList<ProfileList>>, ImmutableList<TeamInfo>>(
263 tuple -> teamlist(tuple), tuples);
264 return new Repeat<ImmutableList<TeamInfo>>(tournamentsettings,
265 BigInteger.valueOf(numberTournaments), true);
266 }
267
268 /**
269 *
270 * @param tuple a tuple with (1) ImmutableList<Team> (2)
271 * ImmutableList<Profiles>
272 * @return list of TeamOfPartiesAndProfiles, each picked from the two lists
273 * in order.
274 */
275 private ImmutableList<TeamInfo> teamlist(
276 Tuple<ImmutableList<Team>, ImmutableList<ProfileList>> tuple) {
277 BiFunction<Team, ProfileList, TeamInfo> makeparty = new BiFunction<Team, ProfileList, TeamInfo>() {
278 @Override
279 public TeamInfo apply(Team team, ProfileList profilelist) {
280 List<PartyWithParameters> parties = team.getParties();
281 List<ProfileRef> profiles = profilelist.getProfiles();
282 if (parties.size() != profiles.size())
283 throw new IllegalArgumentException(
284 "Parties and profiles list must match, but found "
285 + team + " and " + profilelist);
286
287 List<PartyWithProfile> theteams = new LinkedList<>();
288 for (int n = 0; n < parties.size(); n++) {
289 theteams.add(new PartyWithProfile(parties.get(n),
290 profiles.get(n)));
291 }
292 return new TeamInfo(theteams);
293 }
294
295 };
296 return new MapThreadList<TeamInfo, Team, ProfileList>(makeparty,
297 tuple.get1(), tuple.get2());
298 }
299
300}
Note: See TracBrowser for help on using the repository browser.