Added correct algorithm! Yay!
This commit is contained in:
parent
7dff57ac98
commit
df92a2c2d5
|
@ -91,7 +91,7 @@ public abstract class Team<P extends Person> extends BasicEntity {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (P p : this.getMembers()) {
|
for (P p : this.getMembers()) {
|
||||||
sb.append(p.toString()).append(", ");
|
sb.append(p.getFullName()).append(", ");
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,10 @@ import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides some methods to streamline the process of transforming a CSV file of student data into a list of valid teams
|
* Provides some methods to streamline the process of transforming a CSV file of student data into a list of valid teams
|
||||||
|
@ -33,19 +36,27 @@ public class StudentTeamImporter {
|
||||||
|
|
||||||
List<StudentRecordEntry> studentEntries = extractStudentsFromRecords(records);
|
List<StudentRecordEntry> studentEntries = extractStudentsFromRecords(records);
|
||||||
|
|
||||||
|
System.out.println("<<< Entries (" + studentEntries.size() + ") >>>");
|
||||||
for (StudentRecordEntry entry : studentEntries) {
|
for (StudentRecordEntry entry : studentEntries) {
|
||||||
System.out.println(entry.toString());
|
System.out.println(entry.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ArrayList<>();
|
List<StudentTeam> studentTeams = generateTeamsFromStudentEntries(studentEntries, 0);
|
||||||
|
|
||||||
|
System.out.println("<<< Teams (" + studentTeams.size() + ") >>>");
|
||||||
|
for (StudentTeam team : studentTeams) {
|
||||||
|
System.out.println("Team: " + team);
|
||||||
|
}
|
||||||
|
|
||||||
|
return studentTeams;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts all student data from a list of records, and automatically discards outdated responses (those where the
|
* Extracts all student data from a list of records, and automatically discards outdated responses (those where the
|
||||||
* same student submitted more than once).
|
* same student submitted more than once).
|
||||||
* @param records The list of records in the CSV file.
|
* @param records The list of records in the CSV file.
|
||||||
* @return A mapping for each timestamp to
|
* @return A list of all student entries. A student entry is an intermediate object used to organize the parsed data
|
||||||
|
* from each record in the CSV file.
|
||||||
*/
|
*/
|
||||||
private static List<StudentRecordEntry> extractStudentsFromRecords(Iterable<CSVRecord> records) {
|
private static List<StudentRecordEntry> extractStudentsFromRecords(Iterable<CSVRecord> records) {
|
||||||
List<StudentRecordEntry> studentEntries = new ArrayList<>();
|
List<StudentRecordEntry> studentEntries = new ArrayList<>();
|
||||||
|
@ -73,7 +84,93 @@ public class StudentTeamImporter {
|
||||||
return studentEntries;
|
return studentEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a list of teams from a list of unique student entries. The algorithm is described as follows:
|
||||||
|
*
|
||||||
|
* 1. Select the next student from the list of entries.
|
||||||
|
* 2. If the student (A) has specified a partner (B), search for that partner (B) in the list of entries.
|
||||||
|
* 3. If the partner (B) also specified the student (A) as their preferred partner, a team is created from the two.
|
||||||
|
* a. Pop both student entries from the list of entries.
|
||||||
|
* 4. Else, place student (A) in a queue of single students.
|
||||||
|
* a. Pop student (A) from the list of entries.
|
||||||
|
* 5. If the list of entries is not empty, go to 1.
|
||||||
|
* 6. The list of entries is now empty, and zero or more entries exist in a queue of single students.
|
||||||
|
* 7. Pop two (or as many as possible) students randomly from the queue, and form a team from them.
|
||||||
|
* 8. Repeat until the queue of single students is empty.
|
||||||
|
* 9. There is now a list of student teams and no student should remain unprocessed.
|
||||||
|
*
|
||||||
|
* @param entries A list of record entries.
|
||||||
|
* @param seed A seed to use for randomization of single student teams.
|
||||||
|
* @return A list of student teams.
|
||||||
|
*/
|
||||||
|
private static List<StudentTeam> generateTeamsFromStudentEntries(List<StudentRecordEntry> entries, long seed) {
|
||||||
|
List<StudentTeam> teams = new ArrayList<>();
|
||||||
|
List<StudentRecordEntry> singleStudentsEntryQueue = new ArrayList<>();
|
||||||
|
Random random = new Random(seed);
|
||||||
|
|
||||||
|
// Realize step 5. Loop until there are no more processed entries.
|
||||||
|
while (!entries.isEmpty()) {
|
||||||
|
// Step 1. Select the next student from the list of entries.
|
||||||
|
StudentRecordEntry entry = entries.remove(0);
|
||||||
|
|
||||||
|
// Step 2. If the student has a partner, search for that partner.
|
||||||
|
if (entry.hasPartner()) {
|
||||||
|
boolean partnerFound = false; // Use this to keep track of if a partner is actually found.
|
||||||
|
for (int i = 0; i < entries.size(); i++) {
|
||||||
|
StudentRecordEntry secondEntry = entries.get(i);
|
||||||
|
// Step 3. If the partner specifies their partner as the student (both want each other), then create a team.
|
||||||
|
if (
|
||||||
|
entry.getPartnerStudent().equals(secondEntry.getStudent())
|
||||||
|
&& secondEntry.hasPartner()
|
||||||
|
&& secondEntry.getPartnerStudent().equals(entry.getStudent())
|
||||||
|
) {
|
||||||
|
partnerFound = true;
|
||||||
|
|
||||||
|
entries.remove(i); // Step 3a. The first student has been popped, so pop this one.
|
||||||
|
|
||||||
|
StudentTeam team = new StudentTeam();
|
||||||
|
team.addMember(entry.getStudent());
|
||||||
|
team.addMember(secondEntry.getStudent());
|
||||||
|
teams.add(team);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 4. If no partner was found, then add this entry to the queue of single students.
|
||||||
|
if (!partnerFound) {
|
||||||
|
singleStudentsEntryQueue.add(entry);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Also Step 4. The student chose to have no partner, so add this entry to the queue of single students.
|
||||||
|
singleStudentsEntryQueue.add(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are now at step 6.
|
||||||
|
while (!singleStudentsEntryQueue.isEmpty()) {
|
||||||
|
StudentTeam team = new StudentTeam();
|
||||||
|
StudentRecordEntry firstRandomEntry = singleStudentsEntryQueue.remove(random.nextInt(singleStudentsEntryQueue.size()));
|
||||||
|
team.addMember(firstRandomEntry.getStudent());
|
||||||
|
|
||||||
|
// Check if there's another student in the queue.
|
||||||
|
if (!singleStudentsEntryQueue.isEmpty()) {
|
||||||
|
StudentRecordEntry secondRandomEntry = singleStudentsEntryQueue.remove(random.nextInt(singleStudentsEntryQueue.size()));
|
||||||
|
team.addMember(secondRandomEntry.getStudent());
|
||||||
|
}
|
||||||
|
|
||||||
|
teams.add(team);
|
||||||
|
}
|
||||||
|
|
||||||
|
return teams;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scans a list of student entries and removes entries which are outdated by newer entries by the same student, such
|
||||||
|
* that the resulting list contains only one unique entry per student.
|
||||||
|
* @param studentEntries The list of student entries, possibly containing duplicates.
|
||||||
|
* @return A list of student entries in which all outdated duplicates have been removed.
|
||||||
|
*/
|
||||||
private static List<StudentRecordEntry> removeDuplicateEntries(List<StudentRecordEntry> studentEntries) {
|
private static List<StudentRecordEntry> removeDuplicateEntries(List<StudentRecordEntry> studentEntries) {
|
||||||
List<StudentRecordEntry> uniqueStudentEntries = new ArrayList<>();
|
List<StudentRecordEntry> uniqueStudentEntries = new ArrayList<>();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue