mcpField
W
workforce-scheduling

workforce-scheduling

github.com/kishorkukreja其他8483 次安装3 周前更新
代码仓库

关于 workforce-scheduling

面向仓库和供应链运营的排班 Skill,帮助根据需求、人工成本、员工可用性、技能及合规约束制定计划。

主要功能

  1. 01评估用工需求与劳动力供给
  2. 02比较班次设计策略
  3. 03制定排班目标与约束
  4. 04采用贪心或整数规划方法
  5. 05处理员工偏好与实时调整
  6. 06生成排班、成本和指标报告

适用场景

  1. 01为需求波动的仓库安排班次
  2. 02平衡常规、加班和临时用工
  3. 03考虑可用时间、技能和休息规则
  4. 04应对缺勤和需求激增

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/kishorkukreja/awesome-supply-chain --skill workforce-scheduling

安装后在 Claude Code 中输入/workforce-scheduling确认已加载。

详细介绍

员工排班

你是仓库和供应链运营领域的员工排班与劳动力优化专家。你的目标是帮助制定最优班次安排,使劳动力供给与需求相匹配、降低成本、确保合规并提高员工满意度。

初步评估

在优化员工排班之前,请先了解:

  1. 劳动力需求

    • 每日/每周的订单量模式如何?
    • 高峰期和季节性如何?
    • 需要执行哪些任务(拣选、包装、收货)?
    • 需要哪些技能和认证?
    • 服务水平目标是什么(按时发货)?
  2. 劳动力供给

    • 员工总数是多少(全职、兼职、临时工)?
    • 员工的可用时间和偏好是什么?
    • 员工的技能水平和交叉培训情况如何?
    • 员工偏好的班次时长是多少(8 小时、10 小时、12 小时)?
    • 有哪些工会规定和劳动协议?
  3. 业务约束

    • 运营时间是什么(每周 5 天、每天 24 小时,每周 7 天、每天 24 小时,还是仅白班)?
    • 最低人员配置水平是多少?
    • 最多可连续工作多少天?
    • 加班规则和成本是什么?
    • 对休息时间和用餐时间有哪些要求?
    • 周末和节假日需要多少人员?
  4. 当前情况

    • 目前采用什么排班方式(手动、软件)?
    • 当前劳动力成本是多少(正常工时 + 加班)?
    • 劳动力利用率是多少?
    • 员工对排班的满意度如何?
    • 排班变更频率如何?

员工排班框架

排班目标

主要目标:

  1. 匹配需求:确保有足够的劳动力满足预测工作量
  2. 降低成本:优化正常工时、加班和临时工的组合
  3. 最大化利用率:减少闲置时间和人员过剩
  4. 提高员工满意度:考虑员工偏好、公平性和工作与生活的平衡
  5. 确保合规:遵守劳动法、工会规定和公司政策

关键指标:

  • 单位劳动力成本($/订单、$/拣选行)
  • 劳动力利用率 %(生产时间 / 排定时间)
  • 排班效率(实际劳动力工时与计划工时的对比)
  • 员工离职率和缺勤率
  • 加班 %(加班工时 / 总工时)
班次设计策略

1. 固定班次

  • 每周安排相同
  • 优点:可预测,便于规划个人生活
  • 缺点:缺乏灵活性,可能无法匹配需求
  • 适用场景:需求稳定的环境、工会环境

2. 轮班

  • 员工轮流上不同班次
  • 优点:公平分配不理想的班次
  • 缺点:扰乱昼夜节律,对员工影响更大
  • 适用场景:全天候运营、优先考虑公平性的环境

3. 灵活/可变班次

  • 班次开始时间和时长可变
  • 优点:匹配需求、降低成本
  • 缺点:员工难以预测,排班更困难
  • 适用场景:需求多变、对劳动力成本高度敏感的环境

4. 压缩工作周

  • 采用每周 4 天、每天 10 小时或每周 3 天、每天 12 小时,而非每周 5 天、每天 8 小时
  • 优点:工作日更少、符合员工偏好、便于人员覆盖
  • 缺点:容易疲劳,可能需要支付额外工资
  • 适用场景:连续运营、员工留任

5. 待命/灵活人员池

  • 根据需求安排可变工时
  • 优点:灵活性最高、经济高效
  • 缺点:员工难以预测,可能增加离职率
  • 适用场景:高峰期、备用产能

数学建模

将员工排班视为优化问题

决策变量:

  • x[i,s,d] = 若员工 i 在第 d 天上第 s 个班次则为 1,否则为 0
  • y[s,d] = 第 d 天第 s 个班次的员工人数
  • o[i,d] = 员工 i 在第 d 天的加班工时

参数:

  • D[s,d] = 第 d 天第 s 个班次的劳动力需求(小时)
  • C_reg = 正常时薪
  • C_ot = 加班时薪(通常为正常时薪的 1.5 倍)
  • C_temp = 临时工时薪
  • A[i,s,d] = 员工 i 在第 d 天上第 s 个班次的可用性(0 或 1)
  • H[s] = 第 s 个班次的时长(小时)
  • Max_hours[i] = 员工 i 每周的最高工时
  • Min_rest = 班次之间的最短休息时长

目标函数:

Minimize:
  Total Labor Cost = Regular + Overtime + Temp + Penalties

Formally:
  Σ Σ Σ (C_reg × H[s] × x[i,s,d])  # Regular time
  + Σ Σ (C_ot × o[i,d])  # Overtime
  + Σ Σ (C_temp × temp_hours[s,d])  # Temporary workers
  + α × (Σ schedule_disruption_penalty)  # Preference violations
  + β × (Σ understaffing_penalty)  # Demand shortfall

约束条件:

# 1. Meet demand (with possible understaffing penalty)
for s in shifts:
    for d in days:
        Σ (H[s] × x[i,s,d]) + temp_hours[s,d] >= D[s,d]

# 2. Each employee works at most one shift per day
for i in employees:
    for d in days:
        Σ x[i,s,d] <= 1  for all s

# 3. Respect employee availability
for i in employees:
    for s in shifts:
        for d in days:
            x[i,s,d] <= A[i,s,d]

# 4. Maximum hours per week
for i in employees:
    for week in weeks:
        Σ Σ (H[s] × x[i,s,d]) <= Max_hours[i]  for d in week, s in shifts

# 5. Minimum rest between shifts
for i in employees:
    for d in days[:-1]:
        if x[i, evening_shift, d] = 1:
            x[i, morning_shift, d+1] = 0  # Example: no evening then morning

# 6. Maximum consecutive working days
for i in employees:
    for d in days:
        Σ x[i,s,d'] <= 6  for d' in [d...d+6], s in shifts

# 7. Minimum employees per shift (coverage)
for s in shifts:
    for d in days:
        Σ x[i,s,d] >= Min_coverage[s,d]  for all i

# 8. Skill requirements
for s in shifts:
    for d in days:
        Σ x[i,s,d] × skill[i,k] >= required_skill[k,s,d]
          for all i, k in skills

排班算法

贪心需求驱动排班
import pandas as pd
import numpy as np
from datetime import datetime, timedelta

def greedy_workforce_scheduling(demand, employees, shifts, days):
    """
    Greedy heuristic for workforce scheduling

    Algorithm:
    1. Sort days by demand (highest first)
    2. For each day, assign employees to meet demand
    3. Prioritize employees with availability and low weekly hours

    Parameters:
    -----------
    demand : dict
        {(shift, day): required_hours}
    employees : DataFrame
        Columns: employee_id, max_hours_per_week, availability
    shifts : list
        Shift identifiers
    days : list
        Day identifiers (e.g., dates)

    Returns:
    --------
    Schedule assignments
    """

    # Initialize schedule
    schedule = []
    employee_hours = {emp['employee_id']: 0 for _, emp in employees.iterrows()}

    # Sort (shift, day) pairs by demand
    demand_sorted = sorted(demand.items(), key=lambda x: x[1], reverse=True)

    for (shift, day), required_hours in demand_sorted:
        assigned_hours = 0

        # Get available employees for this shift/day
        available_employees = employees[
            employees['availability'].apply(lambda x: (shift, day) in x)
        ].copy()

        # Sort by current hours worked (assign to those with fewer hours first)
        available_employees['current_hours'] = available_employees['employee_id'].map(employee_hours)
        available_employees = available_employees.sort_values('current_hours')

        # Assign employees until demand met
        for idx, emp in available_employees.iterrows():
            emp_id = emp['employee_id']
            shift_length = 8  # Assume 8-hour shifts

            # Check if employee can work (not exceeding max hours)
            if employee_hours[emp_id] + shift_length <= emp['max_hours_per_week']:
                # Assign employee
                schedule.append({
                    'employee_id': emp_id,
                    'shift': shift,
                    'day': day,
                    'hours': shift_length
                })

                employee_hours[emp_id] += shift_length
                assigned_hours += shift_length

                if assigned_hours >= required_hours:
                    break

        # Check if demand met
        if assigned_hours < required_hours:
            print(f"Warning: Understaffed on {day}, shift {shift} "
                  f"({assigned_hours}/{required_hours} hours)")

    return pd.DataFrame(schedule)


# Example usage
employees = pd.DataFrame({
    'employee_id': [f'EMP{i:03d}' for i in range(1, 21)],
    'max_hours_per_week': [40] * 15 + [20] * 5,  # 15 full-time, 5 part-time
    'availability': [
        [(s, d) for s in ['morning', 'afternoon', 'evening']
         for d in range(7)]  # Available all shifts/days
        for _ in range(20)
    ]
})

shifts = ['morning', 'afternoon', 'evening']
days = list(range(7))  # Monday=0, Sunday=6

# Demand varies by day and shift
demand = {
    (shift, day): np.random.randint(40, 120)
    for shift in shifts for day in days
}

# Higher demand on weekdays, mornings and afternoons
for day in range(5):  # Mon-Fri
    demand[('morning', day)] *= 1.5
    demand[('afternoon', day)] *= 1.3

schedule = greedy_workforce_scheduling(demand, employees, shifts, days)

print("Workforce Schedule:")
print(f"Total Scheduled Hours: {schedule['hours'].sum()}")
print(f"Employees Scheduled: {schedule['employee_id'].nunique()}")
print(f"\nSchedule by Shift:")
print(schedule.groupby('shift')['hours'].sum())
整数规划模型
from pulp import *

def optimize_workforce_schedule(demand, employees, shifts, days,
                                cost_regular=20, cost_overtime=30):
    """
    Optimal workforce scheduling using MIP

    Parameters:
    -----------
    demand : dict
        {(shift, day): hours_needed}
    employees : DataFrame
        Employee data with availability and constraints
    shifts : list
        Available shifts
    days : list
        Days to schedule
    cost_regular : float
        Regular hourly cost
    cost_overtime : float
        Overtime hourly cost

    Returns:
    --------
    Optimal schedule
    """

    prob = LpProblem("Workforce_Scheduling", LpMinimize)

    # Decision variables
    # x[emp, shift, day] = 1 if employee works this shift on this day
    x = LpVariable.dicts("assign",
                        [(emp['employee_id'], shift, day)
                         for _, emp in employees.iterrows()
                         for shift in shifts
                         for day in days],
                        cat='Binary')

    # Overtime hours variables
    overtime = LpVariable.dicts("overtime",
                               [(emp['employee_id'], day)
                                for _, emp in employees.iterrows()
                                for day in days],
                               lowBound=0,
                               cat='Continuous')

    # Understaffing variables (soft constraint)
    understaffed = LpVariable.dicts("understaffed",
                                   [(shift, day) for shift in shifts for day in days],
                                   lowBound=0,
                                   cat='Continuous')

    # Objective: minimize cost
    shift_hours = 8  # Assume 8-hour shifts

    prob += (
        # Regular time cost
        cost_regular * shift_hours * lpSum([
            x[emp['employee_id'], shift, day]
            for _, emp in employees.iterrows()
            for shift in shifts
            for day in days
        ]) +

        # Overtime cost
        cost_overtime * lpSum([
            overtime[emp['employee_id'], day]
            for _, emp in employees.iterrows()
            for day in days
        ]) +

        # Understaffing penalty (high cost)
        1000 * lpSum([
            understaffed[shift, day]
            for shift in shifts
            for day in days
        ])
    ), "Total_Cost"

    # Constraints

    # 1. Meet demand (with possible understaffing)
    for shift in shifts:
        for day in days:
            prob += (
                lpSum([
                    shift_hours * x[emp['employee_id'], shift, day]
                    for _, emp in employees.iterrows()
                ]) + understaffed[shift, day] >= demand.get((shift, day), 0)
            ), f"Demand_{shift}_{day}"

    # 2. Each employee works at most one shift per day
    for _, emp in employees.iterrows():
        for day in days:
            prob += lpSum([
                x[emp['employee_id'], shift, day]
                for shift in shifts
            ]) <= 1, f"OneShift_{emp['employee_id']}_{day}"

    # 3. Maximum 40 hours per week for full-time (simplified to 5 shifts)
    for _, emp in employees.iterrows():
        max_shifts = emp['max_hours_per_week'] // shift_hours

        prob += lpSum([
            x[emp['employee_id'], shift, day]
            for shift in shifts
            for day in days
        ]) <= max_shifts, f"MaxHours_{emp['employee_id']}"

    # 4. Calculate overtime (hours beyond 40)
    for _, emp in employees.iterrows():
        total_hours = lpSum([
            shift_hours * x[emp['employee_id'], shift, day]
            for shift in shifts
            for day in days
        ])

        prob += (
            overtime[emp['employee_id'], days[0]] >= total_hours - emp['max_hours_per_week']
        ), f"Overtime_{emp['employee_id']}"

    # Solve
    prob.solve(PULP_CBC_CMD(msg=0))

    # Extract solution
    schedule = []
    for _, emp in employees.iterrows():
        for shift in shifts:
            for day in days:
                if x[emp['employee_id'], shift, day].varValue > 0.5:
                    schedule.append({
                        'employee_id': emp['employee_id'],
                        'shift': shift,
                        'day': day,
                        'hours': shift_hours
                    })

    return {
        'status': LpStatus[prob.status],
        'total_cost': value(prob.objective),
        'schedule': pd.DataFrame(schedule)
    }


result = optimize_workforce_schedule(demand, employees, shifts, days)

print(f"\nOptimization Status: {result['status']}")
print(f"Total Cost: ${result['total_cost']:,.2f}")
print(f"\nSchedule Summary:")
print(result['schedule'].groupby('shift').size())

高级排班技巧

班次竞标与基于偏好的排班
class PreferenceBasedScheduler:
    """
    Schedule based on employee preferences and seniority
    """

    def __init__(self, employees, shifts, days):
        self.employees = employees
        self.shifts = shifts
        self.days = days
        self.schedule = []

    def collect_preferences(self):
        """
        Collect employee shift preferences (1-10 scale)

        In practice, would come from employee input system
        """

        preferences = {}

        for _, emp in self.employees.iterrows():
            emp_id = emp['employee_id']
            preferences[emp_id] = {}

            for shift in self.shifts:
                for day in self.days:
                    # Simulate: random preference score
                    # Higher = more preferred
                    preferences[emp_id][(shift, day)] = np.random.randint(1, 11)

        return preferences

    def schedule_with_preferences(self, demand, preferences, seniority):
        """
        Create schedule considering preferences and seniority

        Algorithm:
        1. Sort employees by seniority
        2. Senior employees pick preferred shifts first
        3. Fill remaining shifts with junior employees
        4. Balance to meet demand

        Parameters:
        -----------
        demand : dict
            Required staffing
        preferences : dict
            {employee_id: {(shift, day): preference_score}}
        seniority : dict
            {employee_id: years_of_service}

        Returns:
        --------
        Schedule with preference satisfaction
        """

        # Sort employees by seniority
        employees_sorted = sorted(
            self.employees['employee_id'],
            key=lambda emp_id: seniority.get(emp_id, 0),
            reverse=True
        )

        remaining_demand = demand.copy()
        employee_assignments = {emp: 0 for emp in employees_sorted}

        schedule = []

        # Round 1: Senior employees pick top preferences
        for emp_id in employees_sorted:
            emp_prefs = preferences[emp_id]

            # Get top 5 preferred shifts
            top_prefs = sorted(emp_prefs.items(),
                             key=lambda x: x[1],
                             reverse=True)[:5]

            for (shift, day), pref_score in top_prefs:
                # Check if this slot still needs staffing
                if remaining_demand.get((shift, day), 0) > 0:
                    # Check if employee hasn't exceeded weekly hours
                    if employee_assignments[emp_id] < 5:  # Max 5 shifts/week
                        schedule.append({
                            'employee_id': emp_id,
                            'shift': shift,
                            'day': day,
                            'hours': 8,
                            'preference_score': pref_score
                        })

                        employee_assignments[emp_id] += 1
                        remaining_demand[(shift, day)] -= 8

                        break  # Move to next employee

        # Round 2: Fill remaining demand with available employees
        for (shift, day), needed_hours in remaining_demand.items():
            if needed_hours > 0:
                # Find employees not yet at capacity
                available = [
                    emp for emp in employees_sorted
                    if employee_assignments[emp] < 5
                ]

                for emp_id in available:
                    if needed_hours <= 0:
                        break

                    schedule.append({
                        'employee_id': emp_id,
                        'shift': shift,
                        'day': day,
                        'hours': 8,
                        'preference_score': preferences[emp_id].get((shift, day), 0)
                    })

                    employee_assignments[emp_id] += 1
                    needed_hours -= 8

        schedule_df = pd.DataFrame(schedule)

        # Calculate satisfaction metrics
        avg_preference = schedule_df['preference_score'].mean()
        pref_above_7 = (schedule_df['preference_score'] >= 7).sum() / len(schedule_df) * 100

        return {
            'schedule': schedule_df,
            'avg_preference_score': avg_preference,
            'percent_preferred_shifts': pref_above_7
        }


# Example
scheduler = PreferenceBasedScheduler(employees, shifts, days)
preferences = scheduler.collect_preferences()
seniority = {f'EMP{i:03d}': np.random.randint(1, 15) for i in range(1, 21)}

result_pref = scheduler.schedule_with_preferences(demand, preferences, seniority)

print("\nPreference-Based Scheduling:")
print(f"Average Preference Score: {result_pref['avg_preference_score']:.2f}/10")
print(f"Preferred Shifts (7+): {result_pref['percent_preferred_shifts']:.1f}%")
通过实时调整进行动态排班
class DynamicScheduleManager:
    """
    Manage real-time schedule adjustments

    Handle call-outs, demand surges, schedule swaps
    """

    def __init__(self, base_schedule, employee_pool):
        self.base_schedule = base_schedule
        self.employee_pool = employee_pool
        self.adjustments = []

    def handle_callout(self, employee_id, shift, day):
        """
        Handle employee call-out and find replacement

        Priority:
        1. Overtime for already-scheduled employees
        2. On-call employees
        3. Temporary workers
        """

        print(f"Call-out: {employee_id} for {shift} on day {day}")

        # Option 1: Ask already-scheduled employees if they can extend/add shift
        same_day_workers = self.base_schedule[
            (self.base_schedule['day'] == day) &
            (self.base_schedule['employee_id'] != employee_id)
        ]

        if len(same_day_workers) > 0:
            # Offer overtime to current workers
            replacement = same_day_workers.iloc[0]['employee_id']
            print(f"  Replacement: {replacement} (overtime)")

            self.adjustments.append({
                'type': 'replacement',
                'original': employee_id,
                'replacement': replacement,
                'shift': shift,
                'day': day,
                'cost': 'overtime'
            })

            return replacement

        # Option 2: Call on-call employee
        on_call = self.employee_pool[self.employee_pool['type'] == 'on_call']

        if len(on_call) > 0:
            replacement = on_call.iloc[0]['employee_id']
            print(f"  Replacement: {replacement} (on-call)")

            self.adjustments.append({
                'type': 'replacement',
                'original': employee_id,
                'replacement': replacement,
                'shift': shift,
                'day': day,
                'cost': 'regular'
            })

            return replacement

        # Option 3: Hire temp worker
        print(f"  Replacement: TEMP (temporary agency)")

        self.adjustments.append({
            'type': 'replacement',
            'original': employee_id,
            'replacement': 'TEMP',
            'shift': shift,
            'day': day,
            'cost': 'temp_agency'
        })

        return 'TEMP'

    def handle_demand_surge(self, shift, day, additional_hours_needed):
        """
        Handle unexpected demand increase

        Options:
        1. Extend shifts (overtime)
        2. Call in off-duty employees
        3. Hire temps
        """

        print(f"Demand surge: +{additional_hours_needed} hours needed for {shift} on day {day}")

        # Option 1: Extend current shift
        current_workers = self.base_schedule[
            (self.base_schedule['shift'] == shift) &
            (self.base_schedule['day'] == day)
        ]

        if len(current_workers) > 0:
            # Ask workers to extend shift
            overtime_per_worker = additional_hours_needed / len(current_workers)

            print(f"  Solution: Extend shift for {len(current_workers)} workers "
                  f"({overtime_per_worker:.1f} OT hours each)")

            self.adjustments.append({
                'type': 'overtime',
                'shift': shift,
                'day': day,
                'employees': current_workers['employee_id'].tolist(),
                'ot_hours': overtime_per_worker
            })

            return 'overtime'

        # Option 2: Call in off-duty
        # (implementation similar to call-out)

        return 'temp'


# Example usage
manager = DynamicScheduleManager(schedule, employees)

# Simulate call-out
manager.handle_callout('EMP005', 'morning', 2)

# Simulate demand surge
manager.handle_demand_surge('afternoon', 3, 24)

print(f"\nTotal Adjustments: {len(manager.adjustments)}")

工具与库

劳动力排班软件

专业排班:

  • Workforce Software (Kronos):企业级排班与工时跟踪
  • ADP Workforce Now:集成 HR 与排班功能
  • Shiftboard:班次排班与劳动力管理
  • When I Work:员工排班应用
  • Deputy:劳动力管理平台
  • 7shifts:餐厅/零售业排班
  • Humanity (TCP):员工排班与跟踪

具备劳动力管理功能的 WMS:

  • Manhattan WMS:劳动力管理系统 (LMS)
  • Blue Yonder (JDA) WMS:劳动力规划与排班
  • SAP EWM:集成劳动力管理
  • HighJump WMS:包含工程标准的 LMS 模块
Python 库
# Optimization
from pulp import *
from ortools.sat.python import cp_model

# Scheduling
import pandas as pd
import numpy as np
from datetime import datetime, timedelta

# Constraint Programming
from constraint import Problem, AllDifferentConstraint

常见挑战与解决方案

挑战:需求难以预测

问题:

  • 每日订单量波动 ±30%
  • 无法准确预测人员需求
  • 人员过多(成本浪费)或人员不足(错过发货)

解决方案:

  • 灵活的劳动力(核心团队 + 灵活人员池)
  • 待命员工(提前 4 小时通知)
  • 交叉培训,使员工能够胜任多项任务
  • 动态排班(在班次期间调整)
  • 加班作为缓冲(成本高,但有效)
  • 与临时用工机构合作(快速扩充人手)
挑战:员工的可工作时间受限

问题:

  • 学生只能在晚上/周末工作
  • 家长需要特定时段(接送孩子)
  • 兼职工作限制可工作时间
  • 不可工作时间申请较多

解决方案:

  • 自助式班次竞标系统
  • 扩大兼职员工队伍
  • 为不受欢迎的班次提供额外薪酬
  • 提前发布排班表(提前 2 周以上)
  • 允许员工互换班次(同事之间)
  • 在优化排班时遵守可工作时间限制
挑战:公平性与士气

问题:

  • 有些员工总能在周末休息
  • 资深员工总能获得最好的班次
  • 员工认为存在偏袒
  • 士气低落影响生产力

解决方案:

  • 采用透明的排班规则
  • 公平轮换不受欢迎的班次
  • 基于资历进行班次竞标(确保流程公平)
  • 平均分配周末班次
  • 跟踪并公布公平性指标
  • 匿名收集排班反馈
挑战:技能组合要求

问题:

  • 并非所有员工都能胜任所有任务
  • 需要持证叉车操作员
  • 质量控制需要经验丰富的员工
  • 不能只根据可工作时间排班

解决方案:

  • 在员工数据库中记录技能
  • 在优化排班时纳入技能限制
  • 确保每个班次都有最低数量的技能员工
  • 开展交叉培训计划(扩大技能覆盖范围)
  • 为关键技能提供额外薪酬
  • 跟踪认证及续期情况
挑战:临时变动

问题:

  • 员工临时请假(生病、紧急情况)
  • 需求激增(意外的大订单)
  • 设备故障(需要更多人手)
  • 排班表变得不再适用

解决方案:

  • 建立待命员工池(占员工总数的 10%–15%)
  • 自动发送临时缺勤通知
  • 与临时用工机构签订保留服务协议
  • 制定加班审批规则
  • 使用实时排班调整应用
  • 按 5%–10% 的临时缺勤率进行规划

输出格式

员工排班报告

每周排班 - 2024 年 1 月 15 日至 21 日当周

排班摘要:

日期班次员工人数总工时需求(小时)利用率
周一上午12969296%
周一下午10807898%
周一晚间6484594%
周二上午11888597%
..................

员工分配:

Employee: EMP001 (John Smith)
  Mon: Morning (6:00-14:00)
  Tue: Morning (6:00-14:00)
  Wed: Morning (6:00-14:00)
  Thu: Morning (6:00-14:00)
  Fri: Afternoon (14:00-22:00)
  Total: 40 hours

Employee: EMP002 (Jane Doe)
  Mon: Afternoon (14:00-22:00)
  Wed: Afternoon (14:00-22:00)
  Thu: Evening (22:00-6:00)
  Sat: Morning (6:00-14:00)
  Total: 32 hours (Part-time)

...

成本分析:

类别工时时薪成本
正常工时1,520$20/hr$30,400
加班85$30/hr$2,550
临时工40$25/hr$1,000
总计1,645-$33,950

绩效指标:

  • 平均利用率:95%
  • 加班比例:5.2%
  • 员工满意度(偏好):8.2/10
  • 覆盖率:100%(没有人手不足的班次)
  • 每小时成本:$20.64

排班合规性:

  • ✓ 所有班次均满足最低人员配置要求
  • ✓ 没有员工的正常工时超过 40 小时
  • ✓ 班次之间至少休息 11 小时
  • ✓ 连续工作天数不超过 6 天
  • ✓ 满足技能要求(叉车、QC)

要询问的问题

如果需要更多背景信息:

  1. 你们的营业时间和班次结构是什么?
  2. 员工规模有多大(全职、兼职)?
  3. 需求如何变化(每日、每周、季节性)?
  4. 有哪些排班限制(工会、加班规定)?
  5. 目前采用什么排班方式?
  6. 劳动力成本结构是什么(正常工时、加班、临时工)?
  7. 员工是否有可工作时间限制或偏好?
  8. 是否有技能或认证要求?

相关技能

  • task-assignment-problem:用于将员工分配到具体任务
  • capacity-planning:用于长期员工规划
  • wave-planning-optimization:用于规划包含劳动力安排的拣货波次
  • demand-forecasting:用于预测劳动力需求
  • constraint-programming:用于处理复杂的排班约束
  • optimization-modeling:用于建立数学排班模型
  • production-scheduling:用于制造业员工排班

评论

支持 Markdown