2026-08-20 11:39:21 +08:00
|
|
|
|
# 排产算法 · CP-SAT / HYBRID v1(SC-03,工序级模型)
|
2026-07-23 13:38:43 +08:00
|
|
|
|
|
2026-08-20 11:39:21 +08:00
|
|
|
|
> 代码:`server/engines/cp_engine.py`
|
|
|
|
|
|
> 测试:`tests/golden/test_cp_engine.py`、`tests/golden/test_cp_operation_level.py`
|
2026-07-23 13:38:43 +08:00
|
|
|
|
> 工厂:`get_engine("CP"|"HYBRID")`
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 范围
|
|
|
|
|
|
|
|
|
|
|
|
| 引擎 | 管线 |
|
|
|
|
|
|
| --- | --- |
|
2026-08-20 11:39:21 +08:00
|
|
|
|
| CP | CP-SAT 工序级选线+排序(Interval/NoOverlap/换型/冻结窗)→ 班次占槽 |
|
2026-07-23 13:38:43 +08:00
|
|
|
|
| HYBRID | RULE 策略序/选线 hint → CP-SAT 改良 → 班次占槽 |
|
|
|
|
|
|
|
2026-08-20 11:39:21 +08:00
|
|
|
|
诚实留痕:`engineType` + `solverMeta`(backend / model / pipeline / warmStart / status / gap / wallTimeSec / operationSlots / totalChangeoverMin / frozenCount)。
|
2026-07-23 13:38:43 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-08-20 11:39:21 +08:00
|
|
|
|
## 2. 工序级模型摘要(方向 D)
|
2026-07-23 13:38:43 +08:00
|
|
|
|
|
2026-08-20 11:39:21 +08:00
|
|
|
|
决策与约束(对应 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` | 冻结窗内固定障碍工单数 |
|
2026-07-23 13:38:43 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-08-20 11:39:21 +08:00
|
|
|
|
## 4. 降级策略
|
2026-07-23 13:38:43 +08:00
|
|
|
|
|
|
|
|
|
|
| 场景 | CP | HYBRID |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| 缺 ortools | `ENGINE_UNAVAILABLE` 空版本 | `DEGRADED_RULE` 物化 RULE 序 |
|
|
|
|
|
|
| 求解无可行解 | 保留启发式序 | 保留 warm 强制线 |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-08-20 11:39:21 +08:00
|
|
|
|
## 5. 未做
|
2026-07-23 13:38:43 +08:00
|
|
|
|
|
2026-08-20 11:39:21 +08:00
|
|
|
|
- LNS 大邻域 / 插单局部修复
|
|
|
|
|
|
- GA / NSGA-II 多目标
|
|
|
|
|
|
- 班组/工装 Cumulative 聚合容量进 CP
|
|
|
|
|
|
- 换型矩阵与冻结工单之间的跨窗 setup(冻结障碍不参与换型路径)
|
2026-07-23 13:38:43 +08:00
|
|
|
|
|
|
|
|
|
|
见 [roadmap.md](./roadmap.md)。
|