def random_initial_solution_for_diversity(students, projects, num_teams): """ Using the inputs, creates a random set of initial Project-Student pairings. """ # If length of projects < num_teams, raise an error if len(projects) < int(num_teams): raise CompError("There are fewer projects than the number of desired teams.") # Otherwise, pick num_teams projects (the first ones) projects = projects[0:num_teams] num_students_per_team = len(students) / num_teams # Copying the students over. unmatched_students = students[:] matched_projects = [] # If num MBAs per team == 0 or num Mengs per team == 0 raise an error if num_students_per_team == 0: raise CompError("There are not enough students to produce the desired number of teams.") # Sequentially go through the projects, and assign the proper number of students to them for project in projects: num_students_needed_for_this_team = num_students_per_team # Get the required number of students while num_students_needed_for_this_team > 0: cur_student = util.random_student_lst(unmatched_students, [], True) project.add_student(cur_student, False) unmatched_students.remove(cur_student) num_students_needed_for_this_team -= 1 matched_projects.append(project) # distributes the remainder evenly index = 0 while len(unmatched_students) > 0: project = projects[index] cur_student = util.random_student_lst(unmatched_students, [], True) project.add_student(cur_student, True) unmatched_students.remove(cur_student) if index == len(projects) - 1: index = 0 else: index += 1 for p in projects: print str(p.ID) + ":" + str([s.ID for s in p.students]) # Sanity check to make sure that all students were matched to projects. num_matched_students = sum([len(project.students) for project in projects]) if len(students) > num_matched_students: raise CompError("Not all students were matched to projects. Increase the team capacity in the config file.") elif len(students) < num_matched_students: raise CompError( "Somehow the number of students matched exceeds the number of students to begin with. This shouldn't happen." ) return projects
def random_initial_solution_for_diversity(students, projects, num_teams): ''' Using the inputs, creates a random set of initial Project-Student pairings. ''' # If length of projects < num_teams, raise an error if (len(projects) < int(num_teams)): raise CompError( "There are fewer projects than the number of desired teams.") # Otherwise, pick num_teams projects (the first ones) projects = projects[0:num_teams] num_students_per_team = len(students) / num_teams # Copying the students over. unmatched_students = students[:] matched_projects = [] # If num MBAs per team == 0 or num Mengs per team == 0 raise an error if (num_students_per_team == 0): raise CompError( "There are not enough students to produce the desired number of teams." ) # Sequentially go through the projects, and assign the proper number of students to them for project in projects: num_students_needed_for_this_team = num_students_per_team # Get the required number of students while (num_students_needed_for_this_team > 0): cur_student = util.random_student_lst(unmatched_students, [], True) project.add_student(cur_student, False) unmatched_students.remove(cur_student) num_students_needed_for_this_team -= 1 matched_projects.append(project) #distributes the remainder evenly index = 0 while (len(unmatched_students) > 0): project = projects[index] cur_student = util.random_student_lst(unmatched_students, [], True) project.add_student(cur_student, True) unmatched_students.remove(cur_student) if (index == len(projects) - 1): index = 0 else: index += 1 for p in projects: print str(p.ID) + ":" + str([s.ID for s in p.students]) # Sanity check to make sure that all students were matched to projects. num_matched_students = sum([len(project.students) for project in projects]) if (len(students) > num_matched_students): raise CompError( "Not all students were matched to projects. Increase the team capacity in the config file." ) elif (len(students) < num_matched_students): raise CompError( "Somehow the number of students matched exceeds the number of students to begin with. This shouldn't happen." ) return projects
matched_projects = [ project for project in feasible_projects if len(project.students) >= team_size ] def can_make_team_with_waiting(u_students): overall_number = (len(u_students) / team_size) > 0 return overall_number while (len(unmatched_students) > 0): if (can_make_team_with_waiting(unmatched_students)): # Pick a random project that does not have any students on it. project = util.random_project(feasible_projects, matched_projects, False) for i in range(team_size): st = util.random_student_lst(unmatched_students, [], False) unmatched_students.remove(st) project.add_student(st, False) matched_projects.append(project) else: #pass feasible_projects = filter( lambda project: len(project.students) == team_size, feasible_projects) available_projects = feasible_projects[:] for student in unmatched_students: project = util.random_project(available_projects, [], True) project.add_student(student, True) available_projects.remove(project) unmatched_students = []
def move_co(state, verbose=False, super_verbose=False): """ A move for conversations in the studio. There are exactly classes.number_project_rankings groups, so it does not make any sense to allow projects to change identity. In its place, this move type will swap a student that is matched with a student that is unmatched. """ student_exchange_probability = 0.01 projects = state[0] inv_cov_mat_tup = state[1] feasibles = state[2] students = state[3] if random.random() < student_exchange_probability: project_to_choose_from = util.random_project(projects, [], True) student_to_swap = util.random_student(project_to_choose_from) matched_students = [] for p in projects: matched_students.extend(p.students) other = util.random_student_lst(students, matched_students, False) if other == None: pass else: project_to_choose_from.students.remove(student_to_swap) project_to_choose_from.students.append(other) else: project_one = util.random_project(projects, [], True) project_two = util.random_project(projects, [], True) # Guarantee that the projects are not the same. # Continue to swap project two until it is diff from project one. while project_one.ID == project_two.ID: project_two = util.random_project(projects, [], True) if super_verbose: print "Project one and project two are the same." if super_verbose: print "Found two different projects." print "First team students are " + str([s.ID for s in project_one.students]) print "Second team students are " + str([s.ID for s in project_two.students]) print "CLEAR: made it to pick_team" # Team to pick first students from pick_team = util.random_two_choice() if pick_team == 0: first_team = project_one second_team = project_two else: first_team = project_two second_team = project_one # Pick a student from the first team, and this student will be swapped. student_one = util.random_student(first_team) student_two = util.random_student(second_team) # NOTE: this is problematic if teams aren't full. # 38 # Guarantee that the students are of the same type. # while (not (student_one.degree_pursuing == student_two.degree_pursuing)): # student_two = util.random_student(second_team) # Remove the students from their respective teams first_team.students.remove(student_one) if not (student_two in second_team.students): if super_verbose: print "Second team students is " + str([s.ID for s in second_team.students]) error = "Student two (" error += str(student_two.ID) error += ") is not in second_team.students (" error += str(second_team.ID) error += ") " raise CompError(error) second_team.students.remove(student_two) first_team.students.append(student_two) second_team.students.append(student_one) if verbose: print "AFTER MOVE:" for p in projects: print str(p.ID) + ": " + str([s.ID for s in p.students]) state_after_change = (projects, inv_cov_mat_tup, feasibles) # print energy(state_after_change) return projects
def random_initial_solution_for_diversity(students, projects, num_teams): ''' Using the inputs, creates a random set of initial Project-Student pairings. ''' # If length of projects < num_teams, raise an error if (len(projects) < int(num_teams)): raise CompError("There are fewer projects than the number of desired teams.") # Otherwise, pick num_teams projects (the first ones) projects = projects[0:num_teams] # Get the MBAs and MEngs MBAs = filter(lambda student: student.degree_pursuing == 0 or student.degree_pursuing == "MBA", students) MEngs = filter(lambda student: student.degree_pursuing == 1 or student.degree_pursuing == "MEng", students) num_MBAs_per_team = len(MBAs) / num_teams num_MEngs_per_team = len(MEngs) / num_teams # Copying the students over. unmatched_students = students[:] matched_projects = [] # If num MBAs per team == 0 or num Mengs per team == 0 raise an error if (num_MBAs_per_team == 0 or num_MEngs_per_team == 0): raise CompError ("There are not enough MBAs or MEngs to produce the desired teams.") # Sequentially go through the projects, and assign the proper number of MBAs and # MEngs to each project. for project in projects: num_MBAs_needed_for_this_team = num_MBAs_per_team num_MEngs_needed_for_this_team = num_MEngs_per_team # Get the required number of MBAs. while (num_MBAs_needed_for_this_team > 0): cur_MBA = util.random_student_lst(MBAs, [], True) project.students.append(cur_MBA) MBAs.remove(cur_MBA) unmatched_students.remove(cur_MBA) num_MBAs_needed_for_this_team -= 1 # Get the required number of MEngs. while (num_MEngs_needed_for_this_team > 0): cur_MEng = util.random_student_lst(MEngs, [], True) project.students.append(cur_MEng) MEngs.remove(cur_MEng) unmatched_students.remove(cur_MEng) num_MEngs_needed_for_this_team -= 1 matched_projects.append(project) index = 0 while (len(unmatched_students) > 0): project = projects[index] cur_student = util.random_student_lst(unmatched_students, [], True) project.students.append(cur_student) unmatched_students.remove(cur_student) if (index == len(projects) - 1): index = 0 else: index += 1 for p in projects: print str(p.ID) + ":" + str([s.ID for s in p.students]) # Sanity check to make sure that all students were matched to projects. num_total_students = sum([len(project.students) for project in projects]) if (not (len(students) == num_total_students)): raise CompError("Not all students were matched to projects.") return projects
for project in feasible_projects: if (not(len(project.students) == team_size)): project.students = [] matched_projects = [project for project in feasible_projects if len(project.students) >= team_size] def can_make_team_with_waiting(u_students): overall_number = (len(u_students)/ team_size) > 0 return overall_number while (len(unmatched_students) > 0): if (can_make_team_with_waiting(unmatched_students)): # Pick a random project that does not have any students on it. project = util.random_project(feasible_projects, matched_projects, False) for i in range(team_size): st = util.random_student_lst(unmatched_students, [], False) unmatched_students.remove(st) project.students.append(st) matched_projects.append(project) else: #pass feasible_projects = filter(lambda project: len(project.students) == team_size, feasible_projects) available_projects = feasible_projects[:] for student in unmatched_students: project = util.random_project(available_projects, [], True) project.add_student(student, True) available_projects.remove(project) unmatched_students = [] if (verbose): print "AFTER SECONDARY MATCHING PROCESS:"
def move_co(state, verbose=False, super_verbose=False): ''' A move for conversations in the studio. There are exactly classes.number_project_rankings groups, so it does not make any sense to allow projects to change identity. In its place, this move type will swap a student that is matched with a student that is unmatched. ''' student_exchange_probability = 0.01 projects = state[0] inv_cov_mat_tup = state[1] feasibles = state[2] students = state[3] if random.random() < student_exchange_probability: project_to_choose_from = util.random_project(projects, [], True) student_to_swap = util.random_student(project_to_choose_from) matched_students = [] for p in projects: matched_students.extend(p.students) other = util.random_student_lst(students, matched_students, False) if other == None: pass else: project_to_choose_from.students.remove(student_to_swap) project_to_choose_from.students.append(other) else: project_one = util.random_project(projects, [], True) project_two = util.random_project(projects, [], True) # Guarantee that the projects are not the same. # Continue to swap project two until it is diff from project one. while (project_one.ID == project_two.ID): project_two = util.random_project(projects, [], True) if (super_verbose): print "Project one and project two are the same." if (super_verbose): print "Found two different projects." print "First team students are " + str( [s.ID for s in project_one.students]) print "Second team students are " + str( [s.ID for s in project_two.students]) print "CLEAR: made it to pick_team" # Team to pick first students from pick_team = util.random_two_choice() if (pick_team == 0): first_team = project_one second_team = project_two else: first_team = project_two second_team = project_one # Pick a student from the first team, and this student will be swapped. student_one = util.random_student(first_team) student_two = util.random_student(second_team) # NOTE: this is problematic if teams aren't full. # 38 # Guarantee that the students are of the same type. # while (not (student_one.degree_pursuing == student_two.degree_pursuing)): # student_two = util.random_student(second_team) # Remove the students from their respective teams first_team.students.remove(student_one) if (not (student_two in second_team.students)): if (super_verbose): print "Second team students is " + str( [s.ID for s in second_team.students]) error = "Student two (" error += str(student_two.ID) error += ") is not in second_team.students (" error += str(second_team.ID) error += ") " raise CompError(error) second_team.students.remove(student_two) first_team.students.append(student_two) second_team.students.append(student_one) if (verbose): print "AFTER MOVE:" for p in projects: print str(p.ID) + ": " + str([s.ID for s in p.students]) state_after_change = (projects, inv_cov_mat_tup, feasibles) #print energy(state_after_change) return projects