def go_to_minimums(self, all_staff_members, all_tasks, avoid_overtime, staff_members, tasks, use_preferences): self.print('Going to minimums:') while (len(tasks) > 0): hardest_to_assign_task = TaskSorter.get_most_difficult_task_to_assign( tasks, staff_members) if hardest_to_assign_task == None: break if use_preferences: working_staff_list = StaffMemberList( list( filter( lambda x: not x.is_at_minimum_hours_per_week( ) and x.likes_task(hardest_to_assign_task), staff_members))) if len(working_staff_list) == 0: working_staff_list = StaffMemberList( list( filter( lambda x: not x.is_at_minimum_hours_per_week() and x.indifferent_about_task( hardest_to_assign_task), staff_members))) if len(working_staff_list) == 0: working_staff_list = staff_members.where_not_at_minimum_hours_per_week( ) else: working_staff_list = staff_members.where_not_at_minimum_hours_per_week( ) if avoid_overtime: working_staff_list = working_staff_list.where_would_be_over_overtime_hours_if_task_was_assigned( hardest_to_assign_task) working_staff_list = StaffMemberSorter.get_least_available_staff_members_for_tasks( tasks, working_staff_list) if len(working_staff_list) == 0: break for s in working_staff_list: if s.try_assign_task(hardest_to_assign_task): self.print('\tAssigned Task ' + hardest_to_assign_task.name + ' to ' + s.name + ' @ ' + str(s.get_total_hours_working()) + ' / ' + str(s.get_minimum_hours_per_week())) # Only get here if assignment was successful if not hardest_to_assign_task.needs_staff( all_staff_members): # if we don't need any more staff for this task, break break tasks.remove(hardest_to_assign_task) self.print('Going to targets:') tasks = list( filter(lambda x: x.needs_staff(all_staff_members), all_tasks)) return hardest_to_assign_task, tasks
def advanced_schedule(self, settings, tasks, staff, roles): all_tasks = [] all_staff_members = StaffMemberList([]) all_roles = [] for t in tasks: all_tasks.append(t) for s in staff: all_staff_members.append(s) for r in roles: all_roles.append(r) use_preferences = settings.use_preferences start_overtime_at = settings.overtime_start_at avoid_overtime = settings.avoid_overtime self.assign_roles(all_staff_members, all_roles) tasks = list( filter(lambda x: x.needs_staff(all_staff_members), all_tasks)) members = [] for m in all_staff_members: m.overtime_at = start_overtime_at members.append(m) staff_members = StaffMemberList(members) hardest_to_assign_task, tasks = self.go_to_minimums( all_staff_members, all_tasks, avoid_overtime, staff_members, tasks, use_preferences) hardest_to_assign_task = self.go_to_targets(all_staff_members, avoid_overtime, staff_members, tasks, use_preferences) self.go_to_maximums(all_staff_members, all_tasks, avoid_overtime, staff_members, use_preferences) self.try_trade_tasks(all_staff_members, all_tasks) self.print('Unassigned: ') self.print(len(self.get_unassigned_tasks())) self.print_happy(all_staff_members) self.print_unhappy(all_staff_members) self.get_avg_happiness(all_staff_members) if use_preferences: self.try_increase_happiness(all_staff_members, all_tasks) self.get_avg_happiness(all_staff_members)
def shuffle_then_schedule(self, settings, all_tasks, all_staff_members, all_roles): self.should_print = False num_tries = 100 staff = all_staff_members tasks = all_tasks best_tasks = [] best_staff = [] best_happiness = -10000000 latest_best = 0 for i in range(num_tries): random.shuffle(staff) random.shuffle(tasks) self.advanced_schedule(settings, tasks, staff, all_roles) print('@ ' + str(i) + ' found : ' + str(self.get_avg_happiness(staff))) if self.get_avg_happiness(staff) > best_happiness: latest_best = i print('\t best!') best_tasks = [] best_staff = StaffMemberList([]) for t in tasks: best_tasks.append(t) for s in staff: best_staff.append(s) best_happiness = self.get_avg_happiness(staff) for s in staff: s.clear_roles() s.clear_tasks() self.should_print = True #self.advanced_schedule(settings, best_tasks, best_staff, all_roles) #print('Latest best: ' + str(latest_best)) #self.best_ittr = latest_best self.best_h = best_happiness
def schedule(self, settings, all_tasks, all_staff_members, all_roles): self.should_print = False num_tries = 100 if not settings.use_preferences: # Technicilly it'll still schedule twice but that's not really an issue. num_tries = 1 staff = all_staff_members tasks = all_tasks best_tasks = [] best_staff = [] best_happiness = -10000000 latest_best = 0 for i in range(num_tries): random.shuffle(staff) random.shuffle(tasks) self.advanced_schedule(settings, tasks, staff, all_roles) #print('@ ' + str(i) + ' found : ' + str(self.get_avg_happiness(staff))) if self.get_avg_happiness(staff) > best_happiness: latest_best = i #print('\t best!') best_tasks = [] best_staff = StaffMemberList([]) for t in tasks: best_tasks.append(t) for s in staff: best_staff.append(s) best_happiness = self.get_avg_happiness(staff) for s in staff: s.clear_roles() s.clear_tasks() #self.should_print = True self.advanced_schedule(settings, best_tasks, best_staff, all_roles) print(' found : ' + str(self.get_avg_happiness(staff)))
def __init__(self, staff_members, roles, tasks, *args, **kwargs): self.staff_members = StaffMemberList(staff_members) self.roles = roles self.tasks = tasks return super().__init__(*args, **kwargs)
def test_scheduling(self): generic = CommonTestFunctions() location = generic.location(1, 'Sarrack\'s Wine and Spirits') cashier_group = generic.group(1, 'Cashier') manager_group = generic.group(2, 'Manager') employee_group = generic.group(3, 'Employee') cashier_category = generic.category(1, 'Cashiering') beer_mover_category = generic.category(2, 'Moving Beer') floor_stocking_category = generic.category(3, 'Floor Stocking') wine_work_category = generic.category(4, 'Wine Work') shipment_receiving_category = generic.category(5, 'Receive Shipment') management_category = generic.category(6, 'Manage Plebs') #Preferences #region like_cashier = generic.preference(cashier_category, 1) dislike_cashier = generic.preference(cashier_category, -1) like_beer_mover = generic.preference(beer_mover_category, 1) dislike_beer_mover = generic.preference(beer_mover_category, -1) cannot_work_beer_mover = generic.preference(beer_mover_category, 0, False) like_floor_stocking = generic.preference(floor_stocking_category, 1) dislike_floor_stocking = generic.preference(floor_stocking_category, -1) like_wine_work = generic.preference(wine_work_category, 1) dislike_wine_work = generic.preference(wine_work_category, -1) like_shipment_receiving = generic.preference( shipment_receiving_category, 1) dislike_shipment_receiving = generic.preference( shipment_receiving_category, -1) #endregion #Sunday - 21 hours manager_sunday = generic.atask(manager_group, location, management_category, DurationGetter.sunday(11, 18), 'Manage Employees', 1) # stock_sunday = generic.atask(employee_group, location, floor_stocking_category, DurationGetter.sunday(11, 18), 'FLoor Help', 2) # 2 # Monday - 40 hours morning_manager_monday = generic.atask(manager_group, location, management_category, DurationGetter.monday(8, 15), 'Manage Employees', 1) # afternoon_manager_monday = generic.atask(manager_group, location, management_category, DurationGetter.monday(15, 22), 'Manage Employees', 1) # cashier_monday = generic.atask(cashier_group, location, cashier_category, DurationGetter.monday(15, 22), 'Cashier', 1) # 1 afternoon_help_monday = generic.atask(employee_group, location, floor_stocking_category, DurationGetter.monday(15, 20), 'Floor Help', 1) # 1 closer_monday = generic.atask(employee_group, location, floor_stocking_category, DurationGetter.monday(15, 22), 'Floor Help', 1) # 1 beer_mover_monday = generic.atask(employee_group, location, beer_mover_category, DurationGetter.monday(15, 22), 'Move beer / Floor Help', 1) # 1 #Tuesday - 40 hours morning_manager_tuesday = generic.atask(manager_group, location, management_category, DurationGetter.tuesday(8, 15), 'Manage Employees', 1) # afternoon_manager_tuesday = generic.atask( manager_group, location, management_category, DurationGetter.tuesday(15, 22), 'Manage Employees', 1) # cashier_tuesday = generic.atask(cashier_group, location, cashier_category, DurationGetter.tuesday(15, 22), 'Cashier', 1) # 1 afternoon_help_tuesday = generic.atask(employee_group, location, floor_stocking_category, DurationGetter.tuesday(15, 20), 'Floor Help', 1) # 1 closer_tuesday = generic.atask(employee_group, location, floor_stocking_category, DurationGetter.tuesday(15, 22), 'Floor Help', 1) # 1 beer_mover_tuesday = generic.atask(employee_group, location, beer_mover_category, DurationGetter.tuesday(15, 22), 'Move beer / Floor Help', 1) # 1 #Wednesday - 40 hours morning_manager_wednesday = generic.atask( manager_group, location, management_category, DurationGetter.wednesday(8, 15), 'Manage Employees', 1) # afternoon_manager_wednesday = generic.atask( manager_group, location, management_category, DurationGetter.wednesday(15, 22), 'Manage Employees', 1) # cashier_wednesday = generic.atask(cashier_group, location, cashier_category, DurationGetter.wednesday(15, 22), 'Cashier', 1) # 1 afternoon_help_wednesday = generic.atask( employee_group, location, floor_stocking_category, DurationGetter.wednesday(15, 20), 'Floor Help', 1) # 1 closer_wednesday = generic.atask(employee_group, location, floor_stocking_category, DurationGetter.wednesday(15, 22), 'Floor Help', 1) # 1 beer_mover_wednesday = generic.atask(employee_group, location, beer_mover_category, DurationGetter.wednesday(15, 22), 'Move beer / Floor Help', 1) # 1 #Thursday - 49 hours morning_manager_thursday = generic.atask( manager_group, location, management_category, DurationGetter.thursday(6, 15), 'Manage Employees', 1) # receive_shipment_thursday = generic.atask( employee_group, location, shipment_receiving_category, DurationGetter.thursday(6, 9), 'Receive Shipment', 1) # 1 afternoon_manager_thursday = generic.atask( manager_group, location, management_category, DurationGetter.thursday(15, 22), 'Manage Employees', 1) # cashier_thursday = generic.atask(cashier_group, location, cashier_category, DurationGetter.thursday(15, 22), 'Cashier', 1) # 1 afternoon_help_thursday = generic.atask( employee_group, location, floor_stocking_category, DurationGetter.thursday(15, 20), 'Floor Help', 1) # 1 closer_thursday = generic.atask(employee_group, location, floor_stocking_category, DurationGetter.thursday(15, 22), 'Floor Help', 1) # 1 beer_mover_thursday = generic.atask(employee_group, location, beer_mover_category, DurationGetter.thursday(15, 22), 'Move beer / Floor Help', 1) # 1 wine_work_thursday = generic.atask(employee_group, location, wine_work_category, DurationGetter.thursday(15, 20), 'Stock Wine', 1) # 1 #Friday - 68 hours morning_manager_friday = generic.atask(manager_group, location, management_category, DurationGetter.friday(8, 15), 'Manage Employees', 1) # afternoon_manager_friday = generic.atask(manager_group, location, management_category, DurationGetter.friday(15, 22), 'Manage Employees', 1) # cashier_friday = generic.atask(cashier_group, location, cashier_category, DurationGetter.friday(15, 22), 'Cashier', 2) # 1 afternoon_help_friday = generic.atask(employee_group, location, floor_stocking_category, DurationGetter.friday(15, 20), 'Floor Help', 1) # 1 midday_friday = generic.atask(employee_group, location, floor_stocking_category, DurationGetter.friday(10, 17), 'Floor Help', 1) # 1 closer_friday = generic.atask(employee_group, location, floor_stocking_category, DurationGetter.friday(15, 22), 'Floor Help', 3) # 3 beer_mover_friday = generic.atask(employee_group, location, beer_mover_category, DurationGetter.friday(15, 22), 'Move beer / Floor Help', 1) # 1 #Saturday - 61 hours morning_manager_saturday = generic.atask( manager_group, location, management_category, DurationGetter.saturday(8, 15), 'Manage Employees', 1) # afternoon_manager_saturday = generic.atask( manager_group, location, management_category, DurationGetter.saturday(15, 22), 'Manage Employees', 1) # cashier_saturday = generic.atask(cashier_group, location, cashier_category, DurationGetter.saturday(15, 22), 'Cashier', 2) # 1 afternoon_help_saturday = generic.atask( employee_group, location, floor_stocking_category, DurationGetter.saturday(15, 20), 'Floor Help', 1) # 1 midday_saturday = generic.atask(employee_group, location, floor_stocking_category, DurationGetter.saturday(10, 17), 'Floor Help', 1) # 1 closer_saturday = generic.atask(employee_group, location, floor_stocking_category, DurationGetter.saturday(15, 22), 'Floor Help', 2) # 2 beer_mover_saturday = generic.atask(employee_group, location, beer_mover_category, DurationGetter.saturday(15, 22), 'Move beer / Floor Help', 1) # 1 # Total hours - 320 morning_manager_tasks = [ morning_manager_monday, morning_manager_tuesday, morning_manager_thursday, morning_manager_friday, morning_manager_saturday, ] afternoon_manager_tasks = [ manager_sunday, afternoon_manager_monday, afternoon_manager_tuesday, afternoon_manager_wednesday, afternoon_manager_thursday, ] misc_manager_tasks = [ morning_manager_wednesday, afternoon_manager_friday, afternoon_manager_saturday, ] preferences = [] groups = [manager_group, employee_group, cashier_group] availability = [ AvailabilityGetter.sunday(6, 22), AvailabilityGetter.monday(6, 22), AvailabilityGetter.tuesday(6, 22), AvailabilityGetter.wednesday(6, 22), AvailabilityGetter.thursday(6, 22), AvailabilityGetter.friday(6, 22), AvailabilityGetter.saturday(6, 22), ] staff_dan = generic.astaff_member('Dan', 30, 40, 50, 10, availability, preferences, groups) preferences = [] groups = [manager_group, employee_group, cashier_group] availability = [ AvailabilityGetter.sunday(6, 22), AvailabilityGetter.monday(6, 22), AvailabilityGetter.tuesday(6, 22), AvailabilityGetter.wednesday(6, 22), AvailabilityGetter.thursday(6, 22), AvailabilityGetter.friday(6, 22), AvailabilityGetter.saturday(6, 22), ] staff_chris = generic.astaff_member('Chris', 30, 35, 44, 10, availability, preferences, groups) preferences = [] groups = [manager_group, employee_group, cashier_group] availability = [ AvailabilityGetter.sunday(6, 22), AvailabilityGetter.monday(6, 22), AvailabilityGetter.tuesday(6, 22), AvailabilityGetter.wednesday(6, 22), AvailabilityGetter.thursday(6, 22), AvailabilityGetter.friday(6, 22), AvailabilityGetter.saturday(6, 22), ] staff_brian = generic.astaff_member('Brian', 30, 35, 44, 10, availability, preferences, groups) preferences = [ like_shipment_receiving, like_wine_work, dislike_beer_mover, like_floor_stocking, dislike_cashier ] groups = [employee_group, cashier_group] availability = [ AvailabilityGetter.sunday(6, 22), AvailabilityGetter.monday(15, 22), AvailabilityGetter.tuesday(15, 22), AvailabilityGetter.thursday(6, 9), AvailabilityGetter.thursday(15, 22), AvailabilityGetter.friday(15, 22), AvailabilityGetter.saturday(6, 22), ] staff_wencel = generic.astaff_member('Wencel', 20, 24, 36, 10, availability, preferences, groups) preferences = [ dislike_beer_mover, like_floor_stocking, dislike_cashier ] groups = [employee_group, cashier_group] availability = [ AvailabilityGetter.sunday(6, 22), AvailabilityGetter.saturday(6, 22), ] staff_shawn = generic.astaff_member('Shawn', 20, 20, 24, 10, availability, preferences, groups) preferences = [ like_floor_stocking, dislike_wine_work, dislike_shipment_receiving, like_beer_mover ] groups = [employee_group] availability = [ AvailabilityGetter.sunday(6, 22), AvailabilityGetter.monday(15, 22), AvailabilityGetter.tuesday(15, 22), AvailabilityGetter.wednesday(15, 22), AvailabilityGetter.thursday(15, 22), AvailabilityGetter.friday(15, 22), AvailabilityGetter.saturday(6, 22), ] staff_adam = generic.astaff_member('Adam', 20, 24, 36, 10, availability, preferences, groups) preferences = [ like_beer_mover, dislike_cashier, like_floor_stocking, dislike_wine_work, dislike_shipment_receiving ] groups = [employee_group, cashier_group, manager_group] availability = [ AvailabilityGetter.sunday(6, 22), AvailabilityGetter.monday(6, 22), AvailabilityGetter.tuesday(6, 22), AvailabilityGetter.wednesday(6, 22), AvailabilityGetter.thursday(6, 22), AvailabilityGetter.friday(6, 22), AvailabilityGetter.saturday(6, 22), ] staff_keith = generic.astaff_member('Keith', 20, 36, 44, 10, availability, preferences, groups) preferences = [cannot_work_beer_mover, like_cashier] groups = [cashier_group] availability = [ AvailabilityGetter.monday(15, 22), AvailabilityGetter.tuesday(15, 22), AvailabilityGetter.wednesday(15, 22), AvailabilityGetter.thursday(15, 22), AvailabilityGetter.friday(15, 22), AvailabilityGetter.saturday(15, 22), ] staff_lenny = generic.astaff_member('Lenny', 20, 40, 44, 10, availability, preferences, groups) preferences = [cannot_work_beer_mover, like_cashier] groups = [cashier_group] availability = [ AvailabilityGetter.monday(15, 22), AvailabilityGetter.tuesday(15, 22), AvailabilityGetter.wednesday(15, 22), AvailabilityGetter.thursday(15, 22), AvailabilityGetter.friday(15, 22), AvailabilityGetter.saturday(15, 22), ] staff_ = generic.astaff_member('Venus', 20, 30, 40, 10, availability, preferences, groups) preferences = [ dislike_cashier, like_beer_mover, like_floor_stocking, dislike_wine_work, dislike_shipment_receiving ] groups = [employee_group] availability = [ AvailabilityGetter.sunday(6, 22), AvailabilityGetter.monday(6, 22), AvailabilityGetter.tuesday(6, 22), AvailabilityGetter.wednesday(6, 22), AvailabilityGetter.thursday(6, 22), AvailabilityGetter.friday(6, 22), AvailabilityGetter.saturday(6, 22), ] staff_ab = generic.astaff_member('AB', 30, 36, 44, 10, availability, preferences, groups) preferences = [ like_cashier, dislike_wine_work, dislike_shipment_receiving, ] groups = [employee_group, cashier_group] availability = [ AvailabilityGetter.sunday(6, 22), AvailabilityGetter.monday(6, 22), AvailabilityGetter.tuesday(6, 22), AvailabilityGetter.wednesday(6, 22), AvailabilityGetter.thursday(6, 22), AvailabilityGetter.friday(6, 22), AvailabilityGetter.saturday(6, 22), ] staff_jimbo = generic.astaff_member('Jimbo', 30, 36, 44, 10, availability, preferences, groups) all_staff = StaffMemberList(generic.created_staff_members) print(all_staff.total_minimum_hours()) print(all_staff.total_target_hours()) print(all_staff.total_maximum_hours()) task_hours = 0 for task in generic.created_tasks: addition = task.required_number_of_employees * task.get_length_in_hours( ) task_hours = task_hours + addition print(task_hours) morning_manager_role = generic.role(morning_manager_tasks, 1, 'Manage Employees - Morning') staff_dan.assign_role(morning_manager_role, True) afternoon_manager_role = generic.role(afternoon_manager_tasks, 1, 'Manage Employees - Afternon') staff_chris.assign_role(afternoon_manager_role, True) misc_manager_role = generic.role(misc_manager_tasks, 1, 'Manage Employees - Misc') self.assertFalse(morning_manager_role.needs_staff(all_staff)) self.assertFalse(afternoon_manager_role.needs_staff(all_staff)) all_roles = [ morning_manager_role, afternoon_manager_role, misc_manager_role, ] scheduler = ScheduleGenerator(all_staff, all_roles, generic.created_tasks) scheduler_settings1 = SchedulerSettings(True, 40, True, False) scheduler.schedule(scheduler_settings1, generic.created_tasks, all_staff, all_roles)