[31] | 1 | package geniusweb.protocol.tournament.allpermutationslearn;
|
---|
| 2 |
|
---|
| 3 | import java.math.BigInteger;
|
---|
| 4 | import java.net.URISyntaxException;
|
---|
| 5 | import java.util.ArrayList;
|
---|
| 6 | import java.util.Arrays;
|
---|
| 7 | import java.util.Collections;
|
---|
| 8 | import java.util.List;
|
---|
| 9 | import java.util.stream.Collectors;
|
---|
| 10 |
|
---|
| 11 | import com.fasterxml.jackson.annotation.JsonCreator;
|
---|
| 12 | import com.fasterxml.jackson.annotation.JsonProperty;
|
---|
| 13 | import com.fasterxml.jackson.databind.ObjectMapper;
|
---|
| 14 |
|
---|
| 15 | import geniusweb.actions.FileLocation;
|
---|
| 16 | import geniusweb.protocol.session.SessionSettings;
|
---|
| 17 | import geniusweb.protocol.session.TeamInfo;
|
---|
| 18 | import geniusweb.protocol.session.learn.LearnSettings;
|
---|
| 19 | import geniusweb.protocol.tournament.ProfileList;
|
---|
| 20 | import geniusweb.protocol.tournament.Team;
|
---|
| 21 | import geniusweb.protocol.tournament.TournamentProtocol;
|
---|
| 22 | import geniusweb.protocol.tournament.allpermutations.AllPermutationsSettings;
|
---|
| 23 | import geniusweb.references.Parameters;
|
---|
| 24 | import geniusweb.references.PartyWithProfile;
|
---|
| 25 | import geniusweb.references.ProfileRef;
|
---|
| 26 | import tudelft.utilities.immutablelist.FixedList;
|
---|
| 27 | import tudelft.utilities.immutablelist.ImmutableList;
|
---|
| 28 | import tudelft.utilities.immutablelist.JoinedList;
|
---|
| 29 | import tudelft.utilities.immutablelist.MapThreadList;
|
---|
| 30 | import tudelft.utilities.logging.Reporter;
|
---|
| 31 |
|
---|
| 32 | /**
|
---|
| 33 | * Almost the same as AllPermutationsSettings.
|
---|
| 34 | * <p>
|
---|
| 35 | * The only additional field is the additional learnTime. This has a maximum to
|
---|
| 36 | * the maximum number of sessions, {@link #MAX_SESSIONS}. This is because we
|
---|
| 37 | * need to store all the {@link FileLocation}s explicitly.
|
---|
| 38 | * <p>
|
---|
| 39 | * Only the first team member is actually getting the learn time.
|
---|
| 40 | * <p>
|
---|
| 41 | * We assume that all parties have the proper persistentstate parameter already.
|
---|
| 42 | * This is assumed to be set in the {@link Team} settings
|
---|
| 43 | */
|
---|
| 44 | public class AllPermutationsLearnSettings extends AllPermutationsSettings {
|
---|
| 45 |
|
---|
| 46 | /**
|
---|
| 47 | * MAX_SESSIONS is the maximum number of sessions in a tournament. It is
|
---|
| 48 | * depending on a number of factors:
|
---|
| 49 | * <ul>
|
---|
| 50 | * <li>The memory use to store all UUIDs for all parties
|
---|
| 51 | * <li>The MAX_MESSAGE_SIZE of a websocket message.
|
---|
| 52 | * </ul>
|
---|
| 53 | * The MAX_MESSAGE_SIZE of the partyserver currently is 20MB. A single UUID
|
---|
| 54 | * is about 45 bytes including double quotes and commas
|
---|
| 55 | * </ul>
|
---|
| 56 | */
|
---|
| 57 | private final static int MAX_SESSIONS = 400000;
|
---|
| 58 | private final static ObjectMapper jackson = new ObjectMapper();
|
---|
| 59 |
|
---|
| 60 | private final LearnSettings learnSettings;
|
---|
| 61 |
|
---|
| 62 | /**
|
---|
| 63 | *
|
---|
| 64 | * @param teams a list of {@link Team}s. Must contain at least
|
---|
| 65 | * {@link #teamsPerSession} elements. The
|
---|
| 66 | * {@link #teamsPerSession} must match the protocol:
|
---|
| 67 | * (SAOP:1, SHAOP:2)
|
---|
| 68 | * @param reuseTeams if true, we use PermutationsWithReturn, if false
|
---|
| 69 | * we use PermutationsWithoutReturn to create the
|
---|
| 70 | * teams.
|
---|
| 71 | * @param plists list of available {@link ProfileList}s to be
|
---|
| 72 | * permutated over the teams. Each
|
---|
| 73 | * {@link ProfileList} must contain
|
---|
| 74 | * {@link #teamsPerSession} elements.
|
---|
| 75 | * @param teamsPerSession number of parties per session, must be at least 2.
|
---|
| 76 | * @param sesettings The generic {@link SessionSettings}.
|
---|
| 77 | * {@link SessionSettings#with(TeamInfo)} will be
|
---|
| 78 | * used to add the required {@link TeamInfo}s. All
|
---|
| 79 | * settings must contain a 'persistentstate'
|
---|
| 80 | * parameter with a {@link FileLocation}.
|
---|
| 81 | * @param nTournaments the number of times the tournament should be run.
|
---|
| 82 | * @param learnSet the {@link LearnSettings} to be used for the
|
---|
| 83 | * learning phase. The participants list should be
|
---|
| 84 | * empty as this will be filled up from the teams
|
---|
| 85 | * provided above. Only the deadline is used.
|
---|
| 86 | */
|
---|
| 87 | @JsonCreator
|
---|
| 88 | public AllPermutationsLearnSettings(@JsonProperty("teams") List<Team> teams,
|
---|
| 89 | @JsonProperty("profileslists") List<ProfileList> plists,
|
---|
| 90 | @JsonProperty("reuseTeams") boolean reuseTeams,
|
---|
| 91 | @JsonProperty("teamsPerSession") int teamsPerSession,
|
---|
| 92 | @JsonProperty("sessionsettings") SessionSettings sesettings,
|
---|
| 93 | @JsonProperty("numberTournaments") int nTournaments,
|
---|
| 94 | @JsonProperty("learnSettings") LearnSettings learnSet) {
|
---|
| 95 | super(teams, plists, reuseTeams, teamsPerSession, sesettings,
|
---|
| 96 | nTournaments);
|
---|
| 97 | this.learnSettings = learnSet;
|
---|
| 98 | }
|
---|
| 99 |
|
---|
| 100 | @Override
|
---|
| 101 | public TournamentProtocol getProtocol(Reporter logger) {
|
---|
| 102 | AllPermutationsLearnState state = new AllPermutationsLearnState(this,
|
---|
| 103 | permutations(), Collections.emptyList());
|
---|
| 104 | return new AllPermutationsLearnProtocol(state, logger);
|
---|
| 105 | }
|
---|
| 106 |
|
---|
| 107 | @Override
|
---|
| 108 | public Double getMaxRunTime() {
|
---|
| 109 | return super.permutations().size().doubleValue()
|
---|
| 110 | * (sessionsettings.getMaxRunTime() + 2d)
|
---|
| 111 | + learnSettings.getMaxRunTime();
|
---|
| 112 | }
|
---|
| 113 |
|
---|
| 114 | /**
|
---|
| 115 | * @return {@link ImmutableList} containing all {@link SessionSettings} for
|
---|
| 116 | * all Sessions in the correct order.
|
---|
| 117 | */
|
---|
| 118 | @Override
|
---|
| 119 | public ImmutableList<SessionSettings> permutations() {
|
---|
| 120 | ImmutableList<SessionSettings> allsessionsettings = super.permutations();
|
---|
| 121 | if (allsessionsettings.size()
|
---|
| 122 | .compareTo(BigInteger.valueOf(MAX_SESSIONS)) > 0)
|
---|
| 123 | throw new IllegalArgumentException(
|
---|
| 124 | "learn-tournament exceeds max number of sessions "
|
---|
| 125 | + MAX_SESSIONS);
|
---|
| 126 |
|
---|
| 127 | FixedList<FixedList<FileLocation>> filelocs = createFileLocations(
|
---|
| 128 | allsessionsettings.size().longValue());
|
---|
| 129 |
|
---|
| 130 | ImmutableList<ImmutableList<TeamInfo>> partylistlist;
|
---|
| 131 | ImmutableList<Team> partieslist = new FixedList<Team>(teams);
|
---|
| 132 | ImmutableList<ProfileList> profileslist = new FixedList<ProfileList>(
|
---|
| 133 | profileslists);
|
---|
| 134 | partylistlist = getParticipants(partieslist, profileslist,
|
---|
| 135 | teamsPerSession, reuseTeams);
|
---|
| 136 | ImmutableList<SessionSettings> settings = new MapThreadList<>(
|
---|
| 137 | (parties, flocs) -> createSetting(parties, flocs),
|
---|
| 138 | partylistlist, filelocs);
|
---|
| 139 |
|
---|
| 140 | return new JoinedList<SessionSettings>(settings,
|
---|
| 141 | getLearnSessions(filelocs, partylistlist));
|
---|
| 142 | }
|
---|
| 143 |
|
---|
| 144 | @Override
|
---|
| 145 | public String toString() {
|
---|
| 146 | return "AllPermutationsLearnSettings[" + contentString() + ","
|
---|
| 147 | + learnSettings + "]";
|
---|
| 148 | }
|
---|
| 149 |
|
---|
| 150 | /**
|
---|
| 151 | *
|
---|
| 152 | * @param numsessions the number of sessions in the tournament
|
---|
| 153 | * @return A list of list of {@link FileLocation}s. The outer list has one
|
---|
| 154 | * entry for each session, the inner list has one
|
---|
| 155 | * {@link FileLocation} per party.
|
---|
| 156 | */
|
---|
| 157 | private FixedList<FixedList<FileLocation>> createFileLocations(
|
---|
| 158 | long numsessions) {
|
---|
| 159 | // like before, but all sessions need a new negotiationdata
|
---|
| 160 | List<FixedList<FileLocation>> filelocations = new ArrayList<>();
|
---|
| 161 | for (long sessionnr = 0; sessionnr < numsessions; sessionnr++) {
|
---|
| 162 | List<FileLocation> locs = new ArrayList<>();
|
---|
| 163 | for (int teamnr = 0; teamnr < teamsPerSession; teamnr++) {
|
---|
| 164 | locs.add(new FileLocation());
|
---|
| 165 | }
|
---|
| 166 | filelocations.add(new FixedList<>(locs));
|
---|
| 167 | }
|
---|
| 168 | FixedList<FixedList<FileLocation>> filelocs = new FixedList<>(
|
---|
| 169 | filelocations);
|
---|
| 170 | return filelocs;
|
---|
| 171 | }
|
---|
| 172 |
|
---|
| 173 | /**
|
---|
| 174 | * @param allsessionsettings the 'traditional session settings.
|
---|
| 175 | * @param filelocs the {@link FileLocation}s for each session, for
|
---|
| 176 | * each party
|
---|
| 177 | * @param partylistlist the lists of all teams for the sessions, with
|
---|
| 178 | * unaltered parameters matching the
|
---|
| 179 | * {@link #teams} list
|
---|
| 180 | * @return the final sessions, doing learning for all parties. In this
|
---|
| 181 | * session, the number of parties may be larger than
|
---|
| 182 | * {@link #teamsPerSession}. Learning may be spread over multiple
|
---|
| 183 | * sessions, although we don't do this currently.
|
---|
| 184 | */
|
---|
| 185 | private ImmutableList<SessionSettings> getLearnSessions(
|
---|
| 186 | FixedList<FixedList<FileLocation>> filelocs,
|
---|
| 187 | ImmutableList<ImmutableList<TeamInfo>> partylistlist) {
|
---|
| 188 | try {
|
---|
| 189 | ProfileRef NOPROFILE = new ProfileRef("not://aprofile");
|
---|
| 190 |
|
---|
| 191 | SessionSettings session = learnSettings;
|
---|
| 192 | // add all the teams, with updated parameters, to the session
|
---|
| 193 | for (Team team : teams) {
|
---|
| 194 | List<FileLocation> files = getNegoData(team, filelocs,
|
---|
| 195 | partylistlist);
|
---|
| 196 | // Tricky: correct parameter is list of UUID strings
|
---|
| 197 | List<String> filesstrings = files.stream()
|
---|
| 198 | .map(file -> file.getUUIDString())
|
---|
| 199 | .collect(Collectors.toList());
|
---|
| 200 | Parameters parameters = new Parameters().with("negotiationdata",
|
---|
| 201 | filesstrings);
|
---|
| 202 | // add all the FileLocations and NOPROFILE to all team members
|
---|
| 203 | List<PartyWithProfile> teaminfo = team.getParties().stream()
|
---|
| 204 | .map(pwp -> new PartyWithProfile(pwp.with(parameters),
|
---|
| 205 | NOPROFILE))
|
---|
| 206 | .collect(Collectors.toList());
|
---|
| 207 | session = session.with(new TeamInfo(teaminfo));
|
---|
| 208 | }
|
---|
| 209 |
|
---|
| 210 | return new FixedList<SessionSettings>(Arrays.asList(session));
|
---|
| 211 | } catch (URISyntaxException e) {
|
---|
| 212 | throw new RuntimeException("Failed creating learn session", e);
|
---|
| 213 | }
|
---|
| 214 | }
|
---|
| 215 |
|
---|
| 216 | /**
|
---|
| 217 | * @param team the team for which the {@link FileLocation}s are needed
|
---|
| 218 | * @param filelocs the used {@link FileLocation}s for all sessions, all
|
---|
| 219 | * teams.
|
---|
| 220 | * @param TeamInfo the TeamInfo used for each session, team. Same dimensions
|
---|
| 221 | * as filelocs
|
---|
| 222 | * @return the list of FileLocations that were provided to the given team in
|
---|
| 223 | * the negotiation sessions.
|
---|
| 224 | */
|
---|
| 225 | private List<FileLocation> getNegoData(Team team,
|
---|
| 226 | FixedList<FixedList<FileLocation>> filelocs,
|
---|
| 227 | ImmutableList<ImmutableList<TeamInfo>> partylistlist) {
|
---|
| 228 | List<FileLocation> locs = new ArrayList<>();
|
---|
| 229 | for (long sessionnr = 0; sessionnr < filelocs.size()
|
---|
| 230 | .longValue(); sessionnr++) {
|
---|
| 231 | for (int teamnr = 0; teamnr < teamsPerSession; teamnr++) {
|
---|
| 232 | if (team.equals(
|
---|
| 233 | partylistlist.get(sessionnr).get(teamnr).getTeam()))
|
---|
| 234 | locs.add(filelocs.get(sessionnr).get(teamnr));
|
---|
| 235 | }
|
---|
| 236 | }
|
---|
| 237 | return locs;
|
---|
| 238 |
|
---|
| 239 | }
|
---|
| 240 |
|
---|
| 241 | /**
|
---|
| 242 | *
|
---|
| 243 | * @param partyproflist a list of {@link PartyWithProfile} settings. Now,
|
---|
| 244 | * each party gets a new negotiationdata object in
|
---|
| 245 | * every session.
|
---|
| 246 | * @param locs the FileLocations for the negotiationdata for all
|
---|
| 247 | * teams
|
---|
| 248 | * @return {@link SessionSettings}, with each party parameters extended with
|
---|
| 249 | * its {@link FileLocation}
|
---|
| 250 | */
|
---|
| 251 | private SessionSettings createSetting(ImmutableList<TeamInfo> partyproflist,
|
---|
| 252 | ImmutableList<FileLocation> locs) {
|
---|
| 253 | SessionSettings settings = sessionsettings;
|
---|
| 254 | for (int teamnr = 0; teamnr < partyproflist.size()
|
---|
| 255 | .intValue(); teamnr++) {
|
---|
| 256 | Parameters extraparams = new Parameters().with("negotiationdata",
|
---|
| 257 | Arrays.asList(locs.get(teamnr)));
|
---|
| 258 | TeamInfo teaminfo = partyproflist.get(teamnr).with(extraparams);
|
---|
| 259 | settings = settings.with(teaminfo);
|
---|
| 260 | }
|
---|
| 261 | return settings;
|
---|
| 262 | }
|
---|
| 263 |
|
---|
| 264 | }
|
---|