Пример #1
0
    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
Пример #2
0
    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)
Пример #3
0
    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
Пример #4
0
    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)))
Пример #5
0
 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)
Пример #6
0
    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)