-
Notifications
You must be signed in to change notification settings - Fork 3
Algorithm
This sorting algorithm was constructed by the F24 Team in conjunction with .
The algorithm takes two inputs:
Students: An array of Student objects.
Projects: An array of Project objects.
It outputs a mapping (of type TeamAssignments) that associates each project with a list of assigned students. The process involves:
- Initializing teams for each project.
- Sorting and grouping students based on their project preferences, degree (hardware/software/other), and class level.
- Assigning students to teams according to these groupings.
- Ensuring that each project team includes at least one upperclassman (3200-level student).
- Balancing team sizes so that no team is significantly over- or under-staffed.
Student
Each Student object contains:
-
id:ID Number -
name:Student’s name. -
major:The student’s field ("CS", "SE", "EE", etc.). -
seniority:Academic year (Freshman, Sophomore, Junior, Senior). -
choices:An ordered list of preferred project names. -
choicesString:A string representation of the project choices. -
class:Indicates class level ("2200" for lower-level, "3200" for upper-level).
Project
Each Project object includes:
-
id:Unique identifier. -
name:Project name. -
type:Category of project, e.g., "SW" (software), "HW" (hardware), or "Both".
TeamAssignments
A mapping (record) that links project names (as keys) to arrays of assigned Student objects.
Creates an empty team (array) for each project.
const teams: TeamAssignments = projects.reduce((acc, current) => {
acc[current.name] = [];
return acc;
}, {} as TeamAssignments);Creates a shallow copy of the students.
Sorts students by the number of project choices they provided (those with fewer choices are prioritized).
const sortedStudents = [...students].sort((a, b) => a.choices.length - b.choices.length);By Preference: Groups students by their highest-ranked (first) project preference.
By Degree Type: Within each preference group, further groups students based on degree type (Hardware, Software, or Other) using the getDegreeType helper.
By Class Level: Further groups these students into lower-level ("2200") and upper-level ("3200") categories.
const groupedByPreference = groupStudentsByPreference(sortedStudents);
const groupedByDegree = groupStudentsByDegree(groupedByPreference);
const groupedByClass = groupStudentsByClass(groupedByDegree);The function placeStudentsInTeams() assigns students to their top-ranked project. If a student has no preferences, they are assigned to the smallest team available..
For each project, the function ensureUpperClassmen() verifies if there is at least one upperclassman (3200-level). If a team lacks an upperclassman, it searches for one from other teams that have a surplus and moves them accordingly.
if (!team.some(student => student.class === "3200")) {
const availableUpperClassman = findAvailableUpperClassman(teams, project.name);
if (availableUpperClassman) {
const currentTeam = studentLocations.get(availableUpperClassman.name);
if (currentTeam) {
teams[currentTeam] = teams[currentTeam].filter(s => s.name !== availableUpperClassman.name);
teams[project.name].push(availableUpperClassman);
studentLocations.set(availableUpperClassman.name, project.name);
}
}
}Calculates the minimum number of students per team. Iteratively moves students from teams that are above this threshold to those below it. The selection of a student to move is based on an “impact score” which factors in how the move might affect the student’s preference and the project’s class level balance.
To ensure teams are evenly distributed, balanceTeamsFixed() redistributes students until all teams meet a minimum size. This is determined as:
const minStudents = Math.floor(students.length / projects.length);If a team is too small, a student is transferred from a larger team using findBestStudentToMove().
To find the best student to move, calculateImpactScore() computes a score based on:
- How much the move affects their preference ranking.
- Whether they are a 3200-level student.
const preferenceScore = preferenceIndex === -1 ? 100 : preferenceIndex + 1;
const classScore = student.class === "3200" ? 0.5 : 1;
return (preferenceScore + classScore) / 2;A lower impact score means the move is less disruptive to the student’s preferences.
Finally, the function returns the complete TeamAssignments mapping.
Wiki
Website Functionality
Demographics Workflows
Project Plans
- [S25] Team Formation Plan
- [S25] Demographics Plan
- [F24] Team Formation Plan
- [F24] GitHub/Discord Plan
- [F24] Demographics Plan
Resources