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

Last change on this file since 16 was 16, checked in by bart, 4 years ago

Enhanced tournament runner

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