You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Google OR-Tools的SAT人员调度技能约束添加咨询

给Google OR-Tools人员调度添加技能匹配约束的实现方案

核心逻辑前提

假设你的现有代码中:

  • 定义了布尔变量assignment[e][d][s][p]:表示员工e在日期d的班次s被指派到岗位p
  • 有技能映射数据employeeSkills:比如二维数组或字典,employeeSkills[e][p]为true时表示员工e具备岗位p的技能

思路一:直接禁用无技能员工的岗位指派

这种思路最直接——对所有不具备某岗位技能的员工,强制其不能被指派到该岗位的任何时段。

在C#中,通过SAT求解器的AddBoolNot约束实现:

var solver = new CpModel();
// 假设已初始化assignment变量和employeeSkills数据

foreach (var e in allEmployees)
{
    foreach (var p in allPositions)
    {
        if (!employeeSkills[e][p])
        {
            // 对所有日期、班次,强制该员工不能被指派到该岗位
            foreach (var d in allDays)
            {
                foreach (var s in allShifts)
                {
                    solver.AddBoolNot(assignment[e][d][s][p]);
                }
            }
        }
    }
}

优势:逻辑简单直观,适合岗位-技能映射固定的场景,求解器可直接排除无效指派组合。


思路二:基于岗位值守的技能校验约束

这种思路从岗位需求出发——确保每个岗位的每个值守时段,被指派的员工都属于具备该技能的员工集合。

实现时,先为每个岗位时段筛选合格员工,再约束指派范围:

foreach (var d in allDays)
{
    foreach (var s in allShifts)
    {
        foreach (var p in allPositions)
        {
            var qualifiedEmployees = allEmployees.Where(e => employeeSkills[e][p]).ToList();
            // 禁止不合格员工被指派到当前岗位时段
            foreach (var e in allEmployees.Except(qualifiedEmployees))
            {
                solver.AddBoolNot(assignment[e][d][s][p]);
            }
            // 可结合现有值守逻辑,比如要求该岗位时段必须有1人值守:
            // var validAssignments = qualifiedEmployees.Select(e => assignment[e][d][s][p]).ToList();
            // solver.Add(LinearExpr.Sum(validAssignments) == 1);
        }
    }
}

优势:贴合岗位需求视角,方便后续扩展技能等级、临时授权等复杂场景。


注意事项

  1. 若技能数据动态变化(如员工技能随时间更新),只需给employeeSkills增加日期维度,约束逻辑同步调整即可。
  2. 两种思路约束效果等价,可根据现有代码结构选择更易整合的方式。
  3. 确保新约束与现有排班逻辑(如工时限制、岗位人数要求)兼容,避免冲突。

内容的提问来源于stack exchange,提问作者Claes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 13:27:21