3.2 KiB
3.2 KiB
排产算法 · CP-SAT / HYBRID v1(SC-03,工序级模型)
代码:
server/engines/cp_engine.py测试:tests/golden/test_cp_engine.py、tests/golden/test_cp_operation_level.py工厂:get_engine("CP"|"HYBRID")
1. 范围
| 引擎 | 管线 |
|---|---|
| CP | CP-SAT 工序级选线+排序(Interval/NoOverlap/换型/冻结窗)→ 班次占槽 |
| HYBRID | RULE 策略序/选线 hint → CP-SAT 改良 → 班次占槽 |
诚实留痕:engineType + solverMeta(backend / model / pipeline / warmStart / status / gap / wallTimeSec / operationSlots / totalChangeoverMin / frozenCount)。
2. 工序级模型摘要(方向 D)
决策与约束(对应 plan.md §9.2a 约束目录):
| 约束 | 建模 |
|---|---|
| 选线(C5) | 每订单恰好一条可行产线(OptionalBoolVar 互斥);只保留全线工序均有可用工位的产线 |
| 工序区间(C1) | 每订单每道工序一个 OptionalIntervalVar(准备 + 数量×单件/效率),按工艺路线 start[i+1] >= end[i] + 转移/等待 串联 |
| 工位/设备独占(C2) | 同工位/设备上全部工序 AddNoOverlap(跨订单聚合);同线不同工位允许并行(流水语义) |
| 换型矩阵(C10) | 产线工序序列用 next-link 单链路径建模:相邻订单首工序间 start >= 前序首工序 end + setup(族→族);同族/无前序为 0 |
| 冻结窗(C11) | freezeWindowHours 内已发布/isFrozen 工单作为 FixedSizeIntervalVar 障碍加入 NoOverlap;新排订单首工序不早于冻结窗末端 |
| 目标(C8/C9) | 加权延期最小化(客户等级 + 急单权重),与前版一致 |
其他说明:
- 无工艺路线或缺工位的产线不作为 CP 候选(物化阶段照常报
NO_LINE/NO_WORKSTATION,诚实留痕)。 - 二级资源当前采用「容量互斥」:同工位 NoOverlap;
Cumulative(班组/工装等聚合容量)为后续扩展点。 - 换型 setup 落在相邻订单的首工序之间(与 RuleEngine 物化把跨族分钟叠到首道工序的语义一致);
solverMeta.operationSlots中changeoverMin标注在首工序槽位。 - 工序级 Interval 与物化的班次占槽是两个层面:CP 决定选线与开工序,物化仍按班次日历落槽(
placement=shift-slot)。
3. solverMeta 新增字段
| 字段 | 内容 |
|---|---|
model |
"operation-level+no-overlap+changeover+freeze" |
operationSlots |
每个订单每道工序:lineId / workstationId / sequenceNo / operationId / startMin / endMin / durationMin / setupMin / changeoverMin / isFrozen |
totalChangeoverMin |
本版累计换型分钟(跨族 setup 求和) |
frozenCount |
冻结窗内固定障碍工单数 |
4. 降级策略
| 场景 | CP | HYBRID |
|---|---|---|
| 缺 ortools | ENGINE_UNAVAILABLE 空版本 |
DEGRADED_RULE 物化 RULE 序 |
| 求解无可行解 | 保留启发式序 | 保留 warm 强制线 |
5. 未做
- LNS 大邻域 / 插单局部修复
- GA / NSGA-II 多目标
- 班组/工装 Cumulative 聚合容量进 CP
- 换型矩阵与冻结工单之间的跨窗 setup(冻结障碍不参与换型路径)
见 roadmap.md。