设备保养计划自动排程怎么实现?周期规则、浮动窗口与资源冲突的算法设计 📅 发布时间:2026/9/5 7:06:29 👁 浏览次数: 引言为什么每 30 天保养一次做不对很多团队觉得保养排程是个简单问题每台设备一个周期到日子生成工单结束。我们在第一个客户现场待了一周就发现这个认知有多天真这家厂的注塑机保养计划里写着每月 15 日保养但 15 日可能是周日、可能是赶大货订单的产能高峰日、保养班组那天可能全部被派去支援另一车间。结果就是——纸面上的计划很整齐实际执行一塌糊涂没人觉得计划有问题也没人按计划执行。真实的保养排程是一个带日历约束和资源约束的调度问题。本文把它拆开讲清楚怎么建模周期、怎么处理法定节假日不保养、怎么解决两个班组撞车。算法不复杂但每一步都要贴着现场逻辑走。一、问题抽象排程 日历 × 周期 × 资源先把整个问题形式化。一次排程要回答对设备集合 D 中的每台设备 d按照它的保养周期规则 R在未来 N 天的排产日历 C 上找到执行时间点 t 和执行班组 g满足周期约束成立、t 不落在禁排日上、g 在 t 时刻有可用工时。三个核心构件排产日历 C工作日/节假日/客户自定义停机日如月度盘点日 周期规则 R固定日历周期 | 累计量浮动周期 | 条件触发 资源池 G班组人员 × 技能 × 每日可用工时二、周期规则两种模型别混着用2.1 固定日历周期“每 30 天”“每月 15 日”“每季度首月第一周”——下一个保养日可以直接从日历推出来publicLocalDatenextDate(LocalDatelastDate,CycleRulerule,WorkCalendarcalendar){LocalDatecandidaterule.advance(lastDate);// 30天 / 下月15日 / ...// 禁排日顺延节假日、停机日往后找第一个可执行日while(calendar.isBlocked(candidate)){candidatecandidate.plusDays(rule.shiftPolicy()SHIFT_NEXT?1:0);if(rule.shiftPolicy()SHIFT_EARLIEST){/* 找窗口内最早可执行日 */}}returncandidate;}顺延策略本身是个业务决策必须在配置里显式化**顺延往后推还是提前往前挪最多顺延几天**我们见过客户要求最多顺延 3 天超过 3 天视为本月放弃也见过只能提前不能推后药厂 GMP 场景。没有唯一正确答案只有可配置。2.2 累计量浮动周期容易被漏掉的模型“每运行 500 小时保养一次”——这才是旋转类设备的真实逻辑。它没法从日历直接推需要用采集数据估算预计到达时点 今日 (500 - 当前累计运行小时) / 日均运行小时实现上有两个坑日均运行小时要用近期窗口算如近 14 天设备的开工强度是变的用历史平均值会越排越歪。估算到期日每天滚动更新但工单只生成一次。用首次进入触发窗口如剩余 50 小时作为生成事件的触发条件配合第一篇讲的bizKey幂等保证估算漂移不会导致重复生成。两类周期在系统里并存设备台账上每个保养项绑定其中一种绝不允许同一保养项同时配两种周期——我们真见过客户配了每 30 天且每 500 小时执行率统计直接乱套。三、资源冲突贪心 优先级够用且可控班组资源的约束是每个班组每天有可执行工时上限每个保养任务有预计工时。这是经典的装箱/调度问题但B 端系统不需要最优解需要稳定、可解释、可人工微调的解。我们用带优先级的贪心publicListAssignmentschedule(ListTasktasks,ListCrewcrews,WorkCalendarcal){// 1. 排序逾期任务 即将逾期 重要度等级 设备价值ListTasksortedtasks.stream().sorted(Comparator.comparing(Task::urgencyRank).thenComparing(Comparator.comparing(Task::importance).reversed())).collect(Collectors.toList());ListAssignmentresultnewArrayList();for(Taskt:sorted){// 2. 技能过滤 负载最轻优先并列时选历史做过该设备的班组Crewbestcrews.stream().filter(c-c.hasSkill(t.getRequiredSkill())).filter(c-cal.isWorkingDay(c,t.getTargetDate())).min(Comparator.comparingDouble(c-c.loadOn(t.getTargetDate())c.familiarityPenalty(t))).orElse(null);if(bestnull){t.markDeferred(findNextAvailableDay(t,cal));// 挤不进则顺延并标记}else{best.addLoad(t.getTargetDate(),t.getEstimatedHours());result.add(newAssignment(t,best,t.getTargetDate()));}}returnresult;}两个必须交代的取舍为什么不上运筹优化求解器试过 OR-Tools排出来的解确实更优但客户调度员完全看不懂为什么把我组的人排到隔壁车间最后全被手工改掉。贪心的结果虽然次优但每一单都符合人能理解的规则技能匹配、负载均衡被接受的概率高得多。排程算法在 B 端的价值在被接受不在最优。人工微调是一等公民。系统排完只是草案调度员拖拽改派是常态改派动作回写为下轮排程的固定约束。抢走调度员的控制权系统就会被绕开。四、排程结果的度量达成率口径要先锁死排程做得好不好靠数据说话但口径不统一数据就是吵架工具。我们把三个口径写进了需求文档并让客户签字计划达成率 按期完成工单 / 应执行计划补录不计入准时率 在周期窗口内完成的占比顺延在允许天数内仍算准时工时利用率 班组实际保养工时 / 可用工时。上线后有个有意思的发现某客户计划达成率从 68% 提到 93%但设备故障率只降了一点。复盘发现原来的 68% 里包含大量纸面完成而 93% 是系统验证过的真实完成——数字变好的一部分其实是数据变真了这个解释工作做在前面客户对系统的信任会深得多。五、踩坑记录坑一跨月周期边界。每月 1 号的保养在 12 月 31 日完成了算 12 月的完成还是 1 月的报表按计划周期归属统计而不是按执行日期归属——这个决定需要在设计期明确。**坑二批量生成风暴。**2000 台设备同一天到期的计划在同一秒生成工单把数据库写崩。方案生成任务按设备 ID 分片错峰与第一篇的军规三呼应并在生成入口加限流。**坑三保养项之间的依赖。**某些保养项必须同时做换油和换油滤拆成两个独立工单后现场要跑两趟。后来支持保养项组组内项目打包成一张工单排程时视为一个任务单元。写在最后保养排程的本质是把设备管理制度的节律翻译成可执行的日历和工单。算法上它不性感——贪心、顺延、装箱没有一篇论文会写它但工程上它极其敏感——一个边界条件没想清楚客户现场的保养体系就会系统性跑偏。这类功能的正确投入方式是多花时间在现场确认规则口径少花时间在算法炫技。下一篇回到数据层设备台账、设备树与保养计划的数据库建模——所有这些业务逻辑的地基。系列目录持续更新设备保养工单系统开发实战从计划自动生成到验收闭环的状态机设计从 0 到 1 开发设备运维管理系统整体架构设计与模块划分设备数据采集协议怎么选MQTT、Modbus、OPC UA 在运维场景的对比与落地预测性维护不用深度学习设备健康度评分的务实实现方案用规则引擎实现可配置的设备告警策略自研轻量引擎 vs Drools 落地对比设备巡检系统开发实战扫码打卡、离线缓存与防作弊的完整方案设备保养计划自动排程怎么实现周期规则、浮动窗口与资源冲突的算法设计本文作者长期从事设备管理与售后运维方向的软件开发主导过多个制造、物业机电现场的保养计划系统落地欢迎在评论区交流排程算法与调度规则设计中的问题。