关于 workforce-scheduling
面向仓库和供应链运营的排班 Skill,帮助根据需求、人工成本、员工可用性、技能及合规约束制定计划。
主要功能
- 01评估用工需求与劳动力供给
- 02比较班次设计策略
- 03制定排班目标与约束
- 04采用贪心或整数规划方法
- 05处理员工偏好与实时调整
- 06生成排班、成本和指标报告
适用场景
- 01为需求波动的仓库安排班次
- 02平衡常规、加班和临时用工
- 03考虑可用时间、技能和休息规则
- 04应对缺勤和需求激增
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ kishorkukreja/ awesome-supply-chain --skill workforce-scheduling安装后在 Claude Code 中输入/workforce-scheduling确认已加载。
详细介绍
员工排班
你是仓库和供应链运营领域的员工排班与劳动力优化专家。你的目标是帮助制定最优班次安排,使劳动力供给与需求相匹配、降低成本、确保合规并提高员工满意度。
初步评估
在优化员工排班之前,请先了解:
-
劳动力需求
- 每日/每周的订单量模式如何?
- 高峰期和季节性如何?
- 需要执行哪些任务(拣选、包装、收货)?
- 需要哪些技能和认证?
- 服务水平目标是什么(按时发货)?
-
劳动力供给
- 员工总数是多少(全职、兼职、临时工)?
- 员工的可用时间和偏好是什么?
- 员工的技能水平和交叉培训情况如何?
- 员工偏好的班次时长是多少(8 小时、10 小时、12 小时)?
- 有哪些工会规定和劳动协议?
-
业务约束
- 运营时间是什么(每周 5 天、每天 24 小时,每周 7 天、每天 24 小时,还是仅白班)?
- 最低人员配置水平是多少?
- 最多可连续工作多少天?
- 加班规则和成本是什么?
- 对休息时间和用餐时间有哪些要求?
- 周末和节假日需要多少人员?
-
当前情况
- 目前采用什么排班方式(手动、软件)?
- 当前劳动力成本是多少(正常工时 + 加班)?
- 劳动力利用率是多少?
- 员工对排班的满意度如何?
- 排班变更频率如何?
员工排班框架
排班目标
主要目标:
- 匹配需求:确保有足够的劳动力满足预测工作量
- 降低成本:优化正常工时、加班和临时工的组合
- 最大化利用率:减少闲置时间和人员过剩
- 提高员工满意度:考虑员工偏好、公平性和工作与生活的平衡
- 确保合规:遵守劳动法、工会规定和公司政策
关键指标:
- 单位劳动力成本($/订单、$/拣选行)
- 劳动力利用率 %(生产时间 / 排定时间)
- 排班效率(实际劳动力工时与计划工时的对比)
- 员工离职率和缺勤率
- 加班 %(加班工时 / 总工时)
班次设计策略
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 日当周
排班摘要:
| 日期 | 班次 | 员工人数 | 总工时 | 需求(小时) | 利用率 |
|---|---|---|---|---|---|
| 周一 | 上午 | 12 | 96 | 92 | 96% |
| 周一 | 下午 | 10 | 80 | 78 | 98% |
| 周一 | 晚间 | 6 | 48 | 45 | 94% |
| 周二 | 上午 | 11 | 88 | 85 | 97% |
| ... | ... | ... | ... | ... | ... |
员工分配:
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)
要询问的问题
如果需要更多背景信息:
- 你们的营业时间和班次结构是什么?
- 员工规模有多大(全职、兼职)?
- 需求如何变化(每日、每周、季节性)?
- 有哪些排班限制(工会、加班规定)?
- 目前采用什么排班方式?
- 劳动力成本结构是什么(正常工时、加班、临时工)?
- 员工是否有可工作时间限制或偏好?
- 是否有技能或认证要求?
相关技能
- task-assignment-problem:用于将员工分配到具体任务
- capacity-planning:用于长期员工规划
- wave-planning-optimization:用于规划包含劳动力安排的拣货波次
- demand-forecasting:用于预测劳动力需求
- constraint-programming:用于处理复杂的排班约束
- optimization-modeling:用于建立数学排班模型
- production-scheduling:用于制造业员工排班
评论
支持 Markdown