Timefold Python版能否在Planning Entity上使用ValueRangeProvider?
在Timefold Python中通过Planning Entity的ValueRangeProvider过滤技能匹配
Timefold Python完全支持在Planning Entity上使用ValueRangeProvider,这正是从规划阶段就排除不符合技能要求员工的最优方案——它直接缩小求解器的搜索空间,比用硬约束事后校验更高效。
实现步骤
1. 定义核心数据类
先明确班次(含技能要求)、员工(含技能列表)和排班任务(Planning Entity)的结构:
from timefold.solver import planning_entity, planning_variable, value_range_provider, planning_solution class Shift: def __init__(self, required_skill: str): self.required_skill = required_skill class Employee: def __init__(self, emp_id: str, skills: list[str]): self.emp_id = emp_id self.skills = skills
2. 在Planning Entity中实现带过滤的ValueRangeProvider
在代表排班任务的ShiftAssignment类中,定义ValueRangeProvider方法,基于当前班次的技能要求过滤可用员工:
@planning_entity class ShiftAssignment: def __init__(self, shift: Shift): self.shift = shift self.employee = None # 待分配的员工(Planning Variable) @planning_variable(Employee, value_range_provider_refs=["qualifiedEmployeeRange"]) def get_employee(self): return self.employee def set_employee(self, employee: Employee): self.employee = employee @value_range_provider(id="qualifiedEmployeeRange") def get_qualified_employees(self, planning_entity, planning_solution): # 获取当前班次所需技能 required_skill = planning_entity.shift.required_skill # 从全局员工列表中过滤出具备该技能的员工 return [emp for emp in planning_solution.employees if required_skill in emp.skills]
3. 配置Planning Solution
将员工列表作为Solution的一部分,方便ValueRangeProvider访问:
@planning_solution class RosterSolution: def __init__(self, shifts: list[Shift], employees: list[Employee], assignments: list[ShiftAssignment]): self.shifts = shifts self.employees = employees self.assignments = assignments # 需实现score计算相关方法(此处省略,按你的现有逻辑补充)
关键说明
- 这种方式会为每个
ShiftAssignment实例单独计算候选员工列表,求解器在规划阶段完全不会考虑不符合技能要求的员工,从根源避免了无效分配。 - 如果员工列表是静态的,也可以直接在
ValueRangeProvider方法中引用全局列表,无需通过planning_solution参数。 - 对比硬约束:硬约束是在分配后校验并扣分,而
ValueRangeProvider是提前排除无效选项,能大幅提升求解效率,尤其在员工和班次数量较多时效果明显。
内容的提问来源于stack exchange,提问作者Martyn Ezra
相关产品推荐
相关产品推荐

